lv17 CGI移植 5-1

news2024/10/7 1:23:47

简介

CGIC是一个支持CGI开发的开放源码的标准C库,可以免费使用,只需要在开发的站点和程序文档中有个公开声明即可,表明程序使用了CGIC库,用户也可以购买商业授权而无需公开声明。

CGIC能够提供以下功能:

  • 分析数据,并自动校正一些有缺陷的浏览器发来的数据;
  • 透明接收用GET或 POST方法发来的Form数据;
  • 能接受上传文件;
  • 能够设置和接收cookies;
  • 用一致的方式处理From元素里的回车;
  • 提供字符串,整数,浮点数,单选或多选功能来接收数据;
  • 提供数字字段的边界检查;
  • 能够将CGI环境变量转化成C中的非空字符串;
  • 提供CGI程序的调试手段,能够回放CGI程序执行时的CGI状态; 提供CGI程序的调试手段,能够回放CGI程序执行时的CGI状态;

总之,CGIC是一个功能比较强大的支持CGI开发的标准C库,并支持Linux, Unix 和Windows等多操作系统。

两句话点破cgi本质

gcc -o login.cgi login.c  

gcc -o login.o login.c  

cgi把html语言解析转发给c语言,c语言转发给html,中间数据通过form表单传递

1 下载源码:

   从CGIC的主站点http://www.boutell.com/cgic/下载源码,当前最新版本是2.05版。将其解压并进入源码目录

 cgic is available via the web from www.boutell.com:
		Obtain cgic: gzipped tar file
		Obtain cgic: .ZIP file

考虑到这是最新版的问题,不建议采用最新版,所以从网上下载了cgic205版本

 

    # tar xzf cgic205.tar.gz
    # cd cgic205

2 cgi文件分析:

cd cgic205-arm

里面有大约10个文件:

cgic.h:头文件;

cgic.c:CGIC的源代码文件;

cgictest.c:CGIC库的作者提供的一个CGI程序例子;

capture.c:用于调试CGI程序的工具;

Makefile:安装CGIC的脚本文件;

可以看到,整个库实际上就是cgic.c一个文件,可以说是非常的精炼。

可以把CGIC安装为操作系统的一个动态链接库,这样我们每次编译的时候,就不需要有cgic.c这个源文件了。

但是由于需要(以后将会看到),我们将修改cgic.c代码,所以我们不把它安装进系统。每次编译的时候,只要把cgic.c和cgic.h放到当前文件夹就好了。

3 搭建交叉编译环境(因为默认x86平台)

Makefile分析

makefile的三要素:目标、依赖、命令

要点

     修改Makefile文件,找到CC=gcc,将其改成CC=arm-linux-gcc,
	 找到AR=ar,将其改成AR=arm-linux-ar,
	 找到RANLIB=ranlib,将其改成RANLIB=arm-linux-ranlib。
	 找到gcc cgictest.o -o cgictest.cgi ${LIBS},将其改成$(CC) $(CFLAGS) cgictest.o -o cgictest.cgi ${LIBS},
	 找到gcc capture.o -o capture ${LIBS},将其改成$(CC) $(CFLAGS) capture.o -o capture ${LIBS},
     保存退出。

 修改后的Makefile

CFLAGS=-g -Wall
CROSS_COMPILE=arm-linux-
#CROSS_COMPILE=
CC=$(CROSS_COMPILE)gcc
AR=$(CROSS_COMPILE)ar
RANLIB=$(CROSS_COMPILE)ranlib
LIBS=-L./ -lcgic


NFSBOA_CGIBIN=~/source/rootfs/boa/cgi-bin

#默认目标,依赖于libcgic.a、cgictest.cgi、mycgitest.cgi和capture
all: libcgic.a cgictest.cgi mycgitest.cgi capture

#将libcgic.a拷贝到/usr/local/lib目录,将cgic.h拷贝到/usr/local/include目录。
install: libcgic.a
	cp libcgic.a /usr/local/lib
	cp cgic.h /usr/local/include
	@echo libcgic.a is in /usr/local/lib. cgic.h is in /usr/local/include.

#libcgic.a:依赖于cgic.o和cgic.h,用来创建静态库libcgic.a
#ar来创建一个名为libcgic.a的静态库文件,并将cgic.o对象文件插入到这个库中。
#RANLIB 生成静态库索引的工具。
libcgic.a: cgic.o cgic.h
	rm -f libcgic.a
	$(AR) rc libcgic.a cgic.o
	$(RANLIB) libcgic.a

#mingw32 and cygwin users: replace .cgi with .exe

#cgictest.cgi:依赖于cgictest.o和libcgic.a,将其链接为可执行文件cgictest.cgi
cgictest.cgi: cgictest.o libcgic.a
	$(CC) cgictest.o -o cgictest.cgi ${LIBS}

capture: capture.o libcgic.a
	$(CC) capture.o -o capture ${LIBS}

#案例,以后代码中需要链接这个 libcgic.a静态库
mycgitest.cgi: mycgitest.o libcgic.a
	$(CC) mycgitest.o -o mycgitest.cgi ${LIBS}

#nfsdeal:移动生成的目标文件和可执行文件到相应的目录,并将可执行文件拷贝到指定的NFS目录。
nfsdeal:
	mv *.o ./obj/
	mv *.a *.cgi capture ./cgi-bin/
	sudo cp ./cgi-bin/* $(NFSBOA_CGIBIN)

clean:
	rm -f *.o *.a cgictest.cgi capture
	rm -f ./cgi-bin/* ./obj/*

根据Makefile编译可以看出,有两个拷贝的过程:

cp       libcgic.a    /usr/local/lib  
cp       cgic.h        /usr/local/include

 两个命令的学习:

ar命令可以用来创建、修改库,也可以从库中提出单个模块。库是一单独的文件,
	里面包含了按照特定的结构组织起来的其它的一些文件(称做此库文件的member)。
	原始文件的内容、模式、时间戳、属主、组等属性都保留在库文件中。 
同时:这个也是很好的可以学习的Makefile文件,阅读源码应该慢慢的养成一种习惯。

原生myctitest可以保留,拷贝一份,移植的程序可以在此基础上做修改

make编译cgi源码:

	make
	得到的CGIC库libcgic.a,

我们通过调试辅助程序capture和测试程序cgictest.cgi,来验证生成CGIC库的正确性。 将capture和cgictest.cgi拷贝到主机的/home/fengjunhui/source/rootfs/boa/cgi-bin目录下。

	cp capture cgictest.cgi  /home/fengjunhui/source/rootfs/boa/cgi-bin
	cp libcgic.a  /home/fengjunhui/source/rootfs/lib

5 测试安装 

在开始编写你自己的CGI程序之前,一定要先走通他的例子程序,免得后来程序出错的时候还不知道是配置有问题,还是你的程序代码有问题。

我们用他自带cgictest.c来实现自己的第一个C语言CGI程序。

先运行boa服务器(后台运行)
./boa  &
 在工作站的浏览器地址栏输入http://192.168.1.100/cgi-bin/cgictest.cgi, (直接指定要运行的程序)
(指定网页运行举例:http://192.168.1.100/pass.html    板子ip/网页名)
可以看到页面,表示CGIC库和测试脚本都移植成功。cgictest.cgi比较完整的展现了CGIC库的功能,
在开发基于CGIC库的CGI程序前最好先掌握cgictest.cgi程序,这个应用程序是十分重要的参考范例。

6 问题与解决思路

1、Unable to connect

Firefox can't establish a connection to the server at 192.168.1.100.
Boa服务器没有运行:

2、he requested URL /cgi-bin/cgictest.cgi was not found on this server

404 Not Found

The requested URL /index.html was not found on this server.

​​​​​​​404 在boa的/cgi-bin目录下找不到对应的cgi文件或在www目录下找不到对应的html文件

7 理论准备:

前期理论准备1:

Web方式的应用开发一般都会将界面设计(CSS/JS等)和程序逻辑脱离开来,允许在一定程度下更改界面,
如改变界面文本的属性,建立多语言版本等,而无需改动程序逻辑。界面一般由美工来进行制作,而程序员负责具体功能的实现。

前期理论准备2:

在 HTML中,表单 (FORM)是最主要的传递信息的手段,它适用于任何浏览器。 ----应用范围广---任何浏览器 FORM 

表单中有很多元素,包括输入文本框,单选框,多选框,按钮,等等,可以提供信息的交互。    ----表单的关键组成部分

具体对象说明和语法请参见其他HTML书籍,在这里不作介绍。

根据应用需求,美工或其他设计人员将最后的Web页面设计出来,作为程序员进行开发的模板。 

CGI程序的工作一般就是接收表单数据,进行数据处理,最后根据处理结果生成新的页面返回给浏览器。  

三步: 接收表单数据,解析数据,将解析后的数据返回给页面

	表单数据一般是以POST方法提交给服务器,由CGI程序获得,程序必须要将界面数据和内部数据对应起来才能够进行下一步的处理。  ---数据提交方式:post
	CGI程序从页面获取数据就根据元素名字/值中的元素名字来进行区分。但CGI返回页面就比较麻烦。由于界面在程序开发完成后还有可能会改变,
	而且有些需要程序处理的地方可能没有表单元素,
	因此对程序来说,不能以表单元素名作为区分的基础,一般方法是采用HTML中的注释<!-xxx-->来标记。

前期理论准备3:

程序员需要在模板中为每一个表单元素以及其他任何需要程序处理的地方,按照一定规则,如注释的下一行就是表单元素行,建立其注释标记。
	CGI程序就可以根据注释标记来判断表单元素信息并进行处理。程序逐行读取模板文件,检查有无注释标记,如有的话,则下一行需要进行处理,
	给表单元素赋上数据,最后就可以返回带数据的页面给浏览器。
    HTML模板还需要关注的是输入的检查。根据输入检查越早越好的原则,需要在用户界面上就对用户提交的数据进行检查。
	目前一般是采用javascript脚本的方式。当用户提交数据时,表单对象的onSubmit方法就会被调用,在该方法里就可以对用户的输入进行检查。
	常用的检查有是否必需、最大/小长度、是否字符、是否数字、email地址、IP地址是否正确、是否匹配一个正则表达式等。

前期理论准备4:

CGI程序的开发

CGI程序的工作流程:

程序一般逻辑为:
	1.   接收表单数据,根据应用需求进行数据处理,最后根据处理结果生成新的页面返回给浏览器。
	2.   表单数据一般是以POST方法提交给服务器,由CGI程序获得,程序根据元素名字/值中的元素名字来区分数据,
	3.   完成数据处理后,再读取相应的模板文件,根据注释标记将对应的数据填充到HTML文本中去,生成最后的页面返回给浏览器。

6、HTML模板的制作--CGIC的基本思路

从cgic.c的代码可以看出,它定义了main函数,
	而在cgictest.c中定义了一个cgiMain函数。
	也就是说,对于使用CGIC编写的CGI程序,都是从cgic.c中的代码进入,在库函数完成了一系列必要的操作(比如解析参数、获取系统环境变量)之后,
	它才会调用你的代码(从你定义的cgiMain进入)。
另外一点就是,cgi程序输出HTML页面的方式都是使用printf把页面一行一行地打印出来,比如cgictest.c中的这一段代码:
	fprintf(cgiOut, "<textarea NAME=\"address\" ROWS=4 COLS=40>\n");  //cgiOut实际上就是stdin
	fprintf(cgiOut, "Default contents go here. \n");
	fprintf(cgiOut, "</textarea>\n");
	上面这段代码的运行结果就是在页面上输出一个textarea。 
第一个参数cgiOut实际上就是stdin,所以我们可以直接使用printf,而不必使用fprintf。不过在调试的时候会用到fprintf来重定向输出。
	这种方式与Java Servlet非常类似,Servlet也是通过调用打印语句System.out.println(…)来输出一个页面。(不过后来Java推出了JSP来克服这种不便。)
	但是与Servlet不同的地方在于,使用C语言的我们还要自己输出HTML头部(声明文档类型):
cgiHeaderContentType("text/html");
	这个语句的调用一定要在所有printf语句之前。而这个语句执行的任务实际上就是:
	void cgiHeaderContentType(char *mimeType) {
	   fprintf(cgiOut, "Content-type: %s\r\n\r\n", mimeType);
	}
	这个语句告诉浏览器,这次传来的数据是什么类型,是一个HTML文档,还是一个bin文件… 
	如果是个HTML文档,就通过浏览器窗口显示,如果是一个bin(二进制)文件,则打开下载窗口,让用户选择是否保存文件以及保存文件的路径。
	理解了这几点之后,你就可以编写自己的CGIC程序了。新建一个文件mycgitest.c试试:
	
	下载: mycgitest.c
#include <stdio.h>
	#include "cgic.h"
	#include <string.h>
	#include <stdlib.h>
	
	int cgiMain() {
		cgiHeaderContentType("text/html");
		fprintf(cgiOut, "<HTML><HEAD>\n");
		fprintf(cgiOut, "<TITLE>My First CGI</TITLE></HEAD>\n");
		fprintf(cgiOut, "<BODY><H1>Hello CGIC</H1></BODY>\n");
		fprintf(cgiOut, "</HTML>\n");
		return 0;
	}

在Makefile文件中的末尾仿照cgitest.c添加自己的mycgitest.c文件,注意添加到目标文件

保存,再执行make命令即可(良好的习惯帮助你快速成长,参考别人的代码然后自己模仿)。

12 all: libcgic.a cgictest.cgi mycgitest.cgi capture
 .....
 32 mycgitest.cgi: mycgitest.o libcgic.a
 33     $(CC) mycgitest.o -o mycgitest.cgi ${LIBS}

	将capture和mycgitest..cgi拷贝到主机的/home/fengjunhui/source/rootfs/boa/cgi-bin目录下。
	cp  mycgitest.cgi  /home/fengjunhui/source/rootfs/boa/cgi-bin

 扩展学习:官网学习教程:

cgic官网学习教程:
	https://boutell.com/cgic/
	cgic: an ANSI C library for CGI Programming
参考博客:(吃水不忘挖井人哇,继续加油,同志们)
http://blog.csdn.net/tiantang46800/article/details/7530930
http://3633188.blog.51cto.com/3623188/826606

8 其他问题汇总:

问题一:

1、A9服务器 没有运行   ./smart_storage

2、A9和CGI的进程间通信失败:

注意查看进程间通信的ftok获得的秘钥是否是一致的。

问题二:

404的错误:

诊断:html网页找不到对应的cgi程序;

解决思路:

  1. 右键、查看网页源代码,确定IP地址没有问题
  2. 查看form表单,form表单对应的/cgi-bin/xxx.cgi在boa的cgi-bin目录下是否存在;

够用就行,不在于多

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1574992.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

疲劳驾驶预警系统项目知识点整理

参考&#xff1a; 重磅&#xff01;头部姿态估计「原理详解 实战代码」来啦&#xff01;-阿里云开发者社区 (aliyun.com) Dlib模型之驾驶员疲劳检测三&#xff08;瞌睡点头&#xff09;_疲劳检测 点头-CSDN博客 python毕业设计 深度学习疲劳检测 驾驶行为检测 - opencv cnn…

面试:HashMap

目录 1、底层数据结构&#xff0c;1.7 与1.8有何不同? 2、为何要用红黑树&#xff0c;为何一上来不树化&#xff0c;树化阈值为何是8&#xff0c;何时会树化&#xff0c;何时会退化为链表? 3、索引如何计算? hashCode都有了&#xff0c;为何还要提供hash()方法?数组容量为…

交换机与队列的简介

1.流程 首先先介绍一个简单的一个消息推送到接收的流程&#xff0c;提供一个简单的图 黄色的圈圈就是我们的消息推送服务&#xff0c;将消息推送到 中间方框里面也就是 rabbitMq的服务器&#xff0c;然后经过服务器里面的交换机、队列等各种关系&#xff08;后面会详细讲&…

保研复习数据结构-图(10)

一.图的定义和基本术语 1.什么是图&#xff1f; 图(Graph)是由顶点的有穷非空集合V(G)和顶点之间边的集合E(G)组成&#xff0c;通常表示为:G(V,E)&#xff0c;其中&#xff0c;G表示图&#xff0c;V是图G中顶点的集合&#xff0c;E是图G中边的集合。 2.什么是完全图&#xf…

【第十二篇】使用BurpSuite实现CSRF(实战案例)

CSRF存在前提:简单的身份验证只能保证请求是发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的 业务场景:新增、删除、收藏、编辑、保存使用Burp发现CSRF漏洞的过程如下。 1、如图,存在修改邮箱的功能点如下: 2、修改邮箱的流量包,此时邮箱已被修改: 思路:是…

12、最小覆盖子串

如何想到这个解法 问题的特点&#xff1a; 首先&#xff0c;认识到这是一个关于子串的问题&#xff0c;而且需要考虑子串的最小长度。这提示我们可能需要使用一种方式来逐步探索不同的子串。滑动窗口的适用性&#xff1a;滑动窗口是处理子串问题的常用技巧&#xff0c;特别是当…

X年后,ChatGPT会替代底层程序员吗?

能不能替代&#xff0c;真的很难说&#xff0c;因为机器换掉人&#xff0c;这其实是一个伦理问题。 其实说白了&#xff0c;任何行业在未来都会被AI或多或少的冲击到&#xff0c;因为ChatGPT做为一个可以持续提升智能的AI&#xff0c;在某些方面的智能程度超过人类并不是什么难…

笛卡尔树[天梯赛二叉树专项训练]

文章目录 题目描述思路AC代码 题目描述 输入样例1 6 8 27 5 1 9 40 -1 -1 10 20 0 3 12 21 -1 4 15 22 -1 -1 5 35 -1 -1 输出样例1 YES 输入样例2 6 8 27 5 1 9 40 -1 -1 10 20 0 3 12 11 -1 4 15 22 -1 -1 50 35 -1 -1 输出样例2 NO思路 见注释 AC代码 #include <bits/st…

5. 4 二重循环将二维数组的某列、某矩形转大写

5. 4 二重循环将二维数组的某列、某矩形转大写 1. 把每一行的b都变成大写 assume cs:codesg,ds:data,ss:stack data segmeNTstr db aaaaabbbbbcccccdb aaaaabbbbbcccccdb aaaaabbbbbcccccdb aaaaabbbbbccccc,$ data endsstack segmentdb 10 dup(0) stack endscodesg SEgments…

【Vue】Vue3中的OptionsAPI与CompositionAPI

文章目录 OptionsAPICompositionAPI对比总结 OptionsAPI 中文名:选项式API通过定义methods,computed,watch,data等属性方法&#xff0c;处理页面逻辑。以下是OptionsAPI代码结构 实例代码: <script lang"ts">// js或者tsimport { defineComponent } from vu…

豆瓣9.7,这部Java神作第3版重磅上市!

Java 程序员们开年就有重磅好消息&#xff0c;《Effective Java 中文版&#xff08;原书第 3 版&#xff09;》要上市啦&#xff01; 该书的第1版出版于 2001 年&#xff0c;当时就在业界流传开来&#xff0c;受到广泛赞誉。时至今日&#xff0c;已热销近20年&#xff0c;本书…

React - 连连看小游戏

简介 小时候经常玩连连看小游戏。在游戏中&#xff0c;当找到2个相同的元素就可以消除元素。 本文会借助react实现连连看小游戏。 实现效果 实现难点 1.item 生成 1. 每一个图片都是一个item&#xff0c;items数组的大小为size*size。 item对象包括grid布局的位置&#xff0c;…

UE小:UE5.3无法创建C++工程

当您在使用Unreal Engine (UE) 构建项目时&#xff0c;如果遇到以下问题&#xff1a; Running C:/Program Files/Epic Games/UE\_5.3/Engine/Build/BatchFiles/Build.bat -projectfiles -project"C:/UEProject/Shp\_1/Shp\_1.uproject" -game -rocket -progress Usi…

网络基础三——初识IP协议

网络基础三 ​ 数据通过应用层、传输层将数据传输到了网络层&#xff1b; ​ 传输层协议&#xff0c;如&#xff1a;TCP协议提供可靠性策略或者高效性策略&#xff0c;UDP提供实时性策略&#xff0c;保证向下层交付的数据是符合要求的的&#xff1b;而网络层&#xff0c;如&a…

websokcet服务端实现

一/websokcet服务端实现 步骤一&#xff1a; springboot底层帮我们自动配置了websokcet&#xff0c;引入maven依赖 1 2 3 4 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</arti…

分享10个免费高可用的GPT3.5和4.0网站并做功能测试【第一个】

1.介绍 网址&#xff1a;直接点&#xff1a;aicnn 或者 www.aicnn.cn 基于ChatGPT可以实现智能聊天、绘画生成、高清文本转语音、论文润色等多种功能&#xff0c;基于sd和mj实现的绘画功能&#xff0c;下面是功能测试&#xff1a; 博主从 1.GPT3.5是否完全免费/是否限制频率、…

基于SSM的基于个人需求和地域特色的外卖推荐系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的基于个人需求和地域特色的外卖推荐系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

作为一个前端,在入职新公司如何快速安装好开发环境

由于电脑运行内存才16G有点卡&#xff0c;今天公司给我们换了32G内存&#xff0c;是直接整个主机都换了&#xff0c;环境自然得重新安装&#xff0c;在装的过程中&#xff0c;自己会有些心得体会&#xff0c;就是想着一个新人如何快速安装环境。 个人说一下我的思路&#xff1a…

SPI接口原理以及读写接口用例的详细介绍

一&#xff0c;spi接口原理 SPI接口&#xff0c;即串行外设接口&#xff08;Serial Peripheral Interface&#xff09;&#xff0c;是一种同步串行数据传输协议。它主要用于连接微处理器和各种外设&#xff0c;如存储器、传感器、ADC&#xff08;模数转换器&#xff09;和DAC&…

LLM 构建Data Multi-Agents 赋能数据分析平台的实践之②:数据治理之二(自动处理)

前述 在前文的multi Agents for Data Analysis的设计说起&#xff0c;本文将继续探索和测试借助llm实现基于私有知识库的数据治理全自动化及智能化。整体设计如下&#xff1a; 整个体系设计了3个Agent以及一个Planer&Execute Agent&#xff0c;第一个Agent用于从企业数据…