lv17 CGI移植 5-1

简介

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 fileObtain 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./ -lcgicNFSBOA_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.acp libcgic.a /usr/local/libcp 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.hrm -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 capturerm -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-bincp 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程序获得,程序必须要将界面数据和内部数据对应起来才能够进行下一步的处理。  ---数据提交方式:postCGI程序从页面获取数据就根据元素名字/值中的元素名字来进行区分。但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实际上就是stdinfprintf(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.a33     $(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.mzph.cn/news/798561.shtml

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

相关文章

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

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

【leetcode】将x减到0的最小操作数/水果成篮/找到字符串中所有字母异位词{史上最容易懂的解析}

文章目录 1.将x减到0的最小操作数2.水果成篮3.找到字符串中所有字母异位词 1.将x减到0的最小操作数 分析题目 x不断地减去数组两端的值 看能否减到0&#xff1b;是不是就是在问&#xff1a;nums数组中存不存在【左端右端】组成的连续区间&#xff0c;区间上数的和为x 继续分析 …

【三十七】【算法分析与设计】STL 练习,凌波微步,栈和排序,吐泡泡,[HNOI2003]操作系统,优先队列自定义类型

凌波微步 链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 时间限制&#xff1a;C/C 1 秒&#xff0c;其他语言 2 秒 空间限制&#xff1a;C/C 32768K&#xff0c;其他语言 65536K 64bit IO Format: %lld 题目描述 小 Z 的体型实在是太胖了&…

小程序如何通过公众号发送新订单提醒

当客户在小程序上下单后&#xff0c;公众号会发送订单通知&#xff0c;这可以让管理员及时获知用户下单情况&#xff0c;方便及时处理订单和提供服务。下面是具体介绍如何设置公众号来发送订单服务通知。 方式一&#xff1a;通过采云公众号发送订单通知 此种方式是默认的通知…

vulhub打靶记录——Corrosion2

文章目录 主机发现端口扫描ssh—22search openssh EXP web服务—8080目录扫描登录tomcat后台 提权切换用户查看用户权限寻找SUID命令破解登录密文 总结 主机发现 使用nmap扫描局域网内存活的主机&#xff0c;命令如下&#xff1a; nmap -sP 192.168.151.0/24192.168.151.1&am…

真实对比kimi、通义千问、文心一言的写代码能力,到底谁强?

&#x1f916;AI改变生活&#xff1a;最近都在说月之暗面的kimi的各项能力吊打国内其他大模型&#xff0c;今天我们真实感受下 kimi、通义千问、文心一言的根据需求写代码的能力。 测评结果让人震惊&#xff01; kimi kimi编程过程 我们先看一下热捧的月之暗面的kimi模型。 …

【PyQt5篇】和子线程进行通信

文章目录 &#x1f354;使用QtDesigner进行设计&#x1f6f8;和子线程进行通信&#x1f388;运行结果 &#x1f354;使用QtDesigner进行设计 我们首先使用QtDesigner设计界面 得到代码login.ui <?xml version"1.0" encoding"UTF-8"?> <ui …

Win10 桌面上应用程序的图标快捷键失效都变成白色图标 怎么修复?

环境&#xff1a; Win10 专业版 问题描述&#xff1a; Win10 桌面上应用程序的图标快捷键失效都变成白色图标 怎么修复 解决方案&#xff1a; 1.资源管理器&#xff0c;把“隐藏的项目”的打钩去掉,打开隐藏文件 2.在文件资源管理器的地址栏输入%localappdata%快速访问这…

C顺序表:通讯录

目录 前言 通讯录数据结构 通讯录初始化 查找名字 增加联系人 删除联系人 展示所有联系人 查找联系人 修改信息 销毁通讯录 完整通讯录代码 前言 数据结构中的顺序表如果已经学会了&#xff0c;那么我们就可以基于顺序表来完成一个通讯录了 通讯录其实我们使用前…

Coding and Paper Letter(八十八)

系列重启之CPL。 1 Coding: 1.一个Python库用来分析城市路网的工具箱&#xff0c;城市形态分析工具。 Madina 2.SkyPilot&#xff1a;在任何云上运行 LLM、AI 和 Batch。 通过简单的界面即可实现最大程度的节省性能、最高的 GPU 可用性和托管执行。 skypilot 3.探索美国卫…

creo扫描杯子学习笔记

creo扫描杯子学习笔记 扫描2要素&#xff1a; 轨迹&#xff0c; 截面。 多用于曲线扫描&#xff0c;区别于拉伸命令。 大小自定 旋转扫描 抽壳 草绘把手 扫描把手 复制曲面 实例化切除 成型

08 | Swoole 源码分析之 Timer 定时器模块

原文首发链接&#xff1a;Swoole 源码分析之 Timer 定时器模块 大家好&#xff0c;我是码农先森。 引言 Swoole 中的毫秒精度的定时器。底层基于 epoll_wait 和 setitimer 实现&#xff0c;数据结构使用最小堆&#xff0c;可支持添加大量定时器。 在同步 IO 进程中使用 seti…

今年过去了多少天?(switch)

//今年已经过去了几天&#xff1f; #include <stdio.h> int monthday(int year,int month){switch(month){case 1:return 31;case 2:if ((year % 4 0 && year % 100 ! 0)||year % 400 0){return 29;}else{return 28;}break;case 3:return 31;case 4:return 30;…

C语言进阶课程学习记录-第24课 - #pragma 使用分析

C语言进阶课程学习记录-第24课 - #pragma 使用分析 #pragma实验-#pragma messagecmd窗口运行 实验-pragma oncebcc编译报错gcc编译成功global.h代码优化 #pragma pack实验BCC编译器输出 小结 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程&#xff0c;图片全部来源于课程…

k8s1(1),Linux运维基础开发与实践

#设置主机名 hostnamectl hostnameXXX #配置免密(包括操作机) ssh-keygen ssh-copy-id master*/slave* #传输hosts cat > /etc/hosts <<EOF 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain loca…

【Qt 学习笔记】Qt 中出现乱码的解释及讨论

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt 中出现乱码的解释及讨论 文章编号&#xff1a;Qt 学习笔记 / 06 文…

工单派单-saas工单处理软件效益分析,智能解决企业管理痛点亿发

企业对引入工单管理系统是有迫切需求的&#xff0c;工单管理系统可以有效地管理任务和工作流程&#xff0c;提高工作效率和客户满意度。 在没有工单管理系统之前&#xff0c;许多企业可能面临着诸如任务分配不清晰、信息不透明、工作流程混乱等管理挑战。举例来说&#xff0c;…

C#.手术麻醉系统源码 手麻系统如何与医院信息系统进行集成?

C#.手术麻醉系统源码 手麻系统如何与医院信息系统进行集成&#xff1f; 手术麻醉系统与医院信息系统的集成是一个关键步骤&#xff0c;它有助于实现信息的共享和流程的协同&#xff0c;从而提高医疗服务的效率和质量。手麻系统与lis、his、pacs等系统的对接是医院信息化建设的重…

Leetcode 148. 排序链表

心路历程&#xff1a; 这道题通过很简单&#xff0c;但是如果想要用O(1)的空间复杂度O(nlogn)的时间复杂度的话&#xff0c;可能得需要双指针快排的思路。 解法&#xff1a;遍历模拟 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0…

Java基础入门--Java API课后题

五、编程题 1.编写一个每次随机生成 10个 0&#xff08;包括&#xff09; 到 100 之间的随机正整数。 import java.util.Random;public class Example01{public static void main(String[] args) {for(int i0;i<10;i) {System.out.println(new Random().nextInt(0,100));}}…