标签:
要实现在PC上通过网页控制连接到嵌入式开发板的相机。
限于开发板的环境,不能选择appche等大型web服务器,选择了boa。
要想pc端跨平台,那就不能用ActiveX控件,如果仅在windows平台上是可以的,使用这种方法,PC端要装插件。
所以我选择纯html页面。
如果仅仅是显示静态内容,那么直接把html页面放到boa的根目录下即可,但如果要创建动态页面,那就得使用cgi接口。
在嵌入式上运行的web服务器基本也都只支持cgi接口,不支持什么asp,jsp。
cgi是通用网关接口的意思,只是接口而已,能使用任何能实现输入输出的语言进行编程实现,web服务器对输入输出进行了重定向
web服务器把从网页得到的输入全部重定向输出到cgi-bin目录的cgi程序作为输入,而cgi程序的输出重定向到web服务器,通过web服务器发送到浏览器。
在嵌入式环境里现成的编程语言就是shell,c/c++,这是肯定支持的,php,python,perl也是可以支持的,但脚本语言要执行,那肯定得另外配置环境,
如同java要运行需要jre一样。
在这里,web服务器程序不仅要进行显示,还要控制相机,要跟相机控制程序进行通信,所以用shell不太现实,所以还是选择c语言。
用c语言首先要有两类个基本的函数要实现,一是从网页发送过来的数据中提取传递的参数,二是读写配置文件。这是在没有加入通讯功能的阶段。
借鉴别人的代码,首先是提取网页参数
头文件:
/* cgivars.h */
#ifndef _CGIVARS_H
#define _CGIVARS_H
/* method */
#define GET 0
#define POST 1
/* function prototypes */
int getRequestMethod();
char **getGETvars();
char **getPOSTvars();
int cleanUp(int form_method, char **getvars, char **postvars);
void adminCheck();
#endif /* !_CGIVARS_H */
源文件:
/* cgivars.c
* (C) Copyright 2000, Moreton Bay (http://www.moretonbay.com).
* see HTTP (www.w3.org) and RFC
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "cgivars.h"
/* local function prototypes */
char hex2char(char *hex);
void unescape_url(char *url);
char x2c(char *what);
/* hex2char */
/* RFC */
char hex2char(char *hex) {
char char_value;
char_value = (hex[0] >= ‘A‘ ? ((hex[0] & 0xdf) - ‘A‘) + 10 : (hex[0] - ‘0‘));
char_value *= 16;
char_value += (hex[1] >= ‘A‘ ? ((hex[1] & 0xdf) - ‘A‘) + 10 : (hex[1] - ‘0‘));
return char_value;
}
/* unescape_url */
/* RFC */
void unescape_url(char *url) {
int n, k;
for(n=0, k=0;url[k];++n, ++k) {
if((url[n] = url[k]) == ‘%‘) {
url[n] = hex2char(&url[k+1]);
k += 2;
}
}
url[n] = ‘\0‘;
}
/* getRequestMethod
* retn: from_method (GET or POST) on success,
* -1 on failure. */
int getRequestMethod() {
char *request_method;
int form_method;
request_method = getenv("REQUEST_METHOD");
if(request_method == NULL)
return -1;
if (!strcmp(request_method, "GET") || !strcmp(request_method, "HEAD") ) {
form_method = GET;
} else if (!strcmp(request_method, "POST")) {
form_method = POST;
} else {
/* wtf was it then?!! */
return -1;
}
return form_method;
}
/* getGETvars
* retn: getvars */
char **getGETvars() {
int i;
char **getvars;
char *getinput;
char **pairlist;
int paircount = 0;
char *nvpair;
char *eqpos;
getinput = getenv("QUERY_STRING");
if (getinput)
getinput = strdup(getinput);
//DEBUGMSG(1, ("gin=%s\n", getinput));
/* Change all plusses back to spaces */
for(i=0; getinput && getinput[i]; i++)
if(getinput[i] == ‘+‘)
getinput[i] = ‘ ‘;
pairlist = (char **) malloc(256*sizeof(char **));
paircount = 0;
nvpair = getinput ? strtok(getinput, "&") : NULL;
while (nvpair) {
pairlist[paircount++]= strdup(nvpair);
if(!(paircount%256))
pairlist = (char **) realloc(pairlist,(paircount+256)*sizeof(char **));
nvpair = strtok(NULL, "&");
}
pairlist[paircount] = 0;
getvars = (char **) malloc((paircount*2+1)*sizeof(char **));
for (i= 0; i<paircount; i++) {
if(eqpos=strchr(pairlist[i], ‘=‘)) {
*eqpos = ‘\0‘;
unescape_url(getvars[i*2+1] = strdup(eqpos+1));
} else {
unescape_url(getvars[i*2+1] = strdup(""));
}
unescape_url(getvars[i*2] = strdup(pairlist[i]));
}
getvars[paircount*2] = 0;
for(i=0;pairlist[i];i++)
free(pairlist[i]);
free(pairlist);
if (getinput)
free(getinput);
return getvars;
}
/* getPOSTvars
* retn: postvars */
char **getPOSTvars() {
int i;
int content_length;
char **postvars;
char *postinput;
char **pairlist;
int paircount = 0;
char *nvpair;
char *eqpos;
postinput = getenv("CONTENT_LENGTH");
if (!postinput)
exit(1);
if(!(content_length = atoi(postinput)))
exit(1);
if(!(postinput = (char *) malloc(content_length+1)))
exit(1);
if (!fread(postinput, content_length, 1, stdin))
exit(1);
postinput[content_length] = ‘\0‘;
//DEBUGMSG(1, ("pin=%s\n", postinput));
for(i=0;postinput[i];i++)
if(postinput[i] == ‘+‘)
postinput[i] = ‘ ‘;
pairlist = (char **) malloc(256*sizeof(char **));
paircount = 0;
nvpair = strtok(postinput, "&");
while (nvpair) {
pairlist[paircount++] = strdup(nvpair);
if(!(paircount%256))
pairlist = (char **) realloc(pairlist, (paircount+256)*sizeof(char **));
nvpair = strtok(NULL, "&");
}
pairlist[paircount] = 0;
postvars = (char **) malloc((paircount*2+1)*sizeof(char **));
for(i = 0;i<paircount;i++) {
if(eqpos = strchr(pairlist[i], ‘=‘)) {
*eqpos= ‘\0‘;
unescape_url(postvars[i*2+1] = strdup(eqpos+1));
} else {
unescape_url(postvars[i*2+1] = strdup(""));
}
unescape_url(postvars[i*2]= strdup(pairlist[i]));
}
postvars[paircount*2] = 0;
for(i=0;pairlist[i];i++)
free(pairlist[i]);
free(pairlist);
free(postinput);
return postvars;
}
/* cleanUp
* free the mallocs */
int cleanUp(int form_method, char **getvars, char **postvars) {
int i;
if (postvars) {
for(i=0;postvars[i];i++)
free(postvars[i]);
free(postvars);
}
if (getvars) {
for(i=0;getvars[i];i++)
free(getvars[i]);
free(getvars);
}
return 0;
}
void adminCheck(){
char * userName = NULL;
char * errPage = "Location: UnauthorizedError.htm\n\n";
userName = getenv("REMOTE_USER");
if(userName == NULL) goto err;
if(!strcmp("admin",userName))
{
return;
}
err: printf("%s\n",errPage);
fflush(stdout);
exit(0);
}
读取配置文件借鉴别人的,别人的读取是从配置文件读取,而写配置则只是写进一个临时文件,写进配置文件是由实际控制相机的服务程序实现的。
我要将它改为直接将参数写进配置文件。
头文件:
/*config_phase.h*/
#ifndef _CONFIG_PHASE_H
#define _CONFIG_PHASE_H
#define CONFIG_FILE_NAME "/etc/cfg/config.ini"
#define CONFIG_TEMP_FILE_PROFIX "/tmp/change"
#define MAX_FILE_NAME_LEN 30
#define MAX_LINE_LENGTH 80
typedef struct
{
int index;
char * data;
int is_changed;
} config_item;
FILE *OpenGlobeConfig();
void CloseGlobeConfig(FILE * fp);
int ReadGlobeConfig(FILE *fp, int config_num, config_item *items[]);
void set_config_item(config_item *items[], int config_num ,int index ,char * value);
config_item ** init_config_item(config_item *items[], int config_num, int *config_list);
void free_config_item(config_item *items[], int config_num);
int GetConfValues(int *config_list, config_item *items[], int config_num);
void item_update(int index, config_item *items[], int config_num, char *data);
char *getdata(int index, config_item *items[], int config_num);
int SaveConfig(char **postvars, config_item **items, int *config_list, char **config_name, int config_num);
源文件:
/* config_phase.c: phase config.txt
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "config_phase.h"
#include "sysconf.h"
char trace_string[200];
void swap(config_item *a[], int i, int j)
{
config_item *temp = a[i];
a[i] = a[j];
a[j] = temp;
}
int partition(config_item *a[], int p, int r)
{
int x = a[r]->index;
int i = p-1;
int j;
for(j=p; j<r; j++)
{
if(a[j]->index <= x)
{
i++;
swap(a, i, j);
}
}
swap(a, i+1, r);
return i+1;
}
void quicksort(config_item *a[], int p, int r)
{
int q;
if(p < r)
{
q = partition(a, p, r);
quicksort(a, p, q-1);
quicksort(a, q+1, r);
}
}
FILE *OpenGlobeConfig() // return NULL for open error
{
FILE * fp;
fp = fopen(CONFIG_FILE_NAME, "rb");
return fp;
}
void CloseGlobeConfig(FILE * fp)
{
fclose(fp);
}
int ReadGlobeConfig(FILE *fp, int config_num, config_item *items[])
{
int i;
int j=0;
char temp_line[MAX_LINE_LENGTH];
char *fake_index, *fake_data;
quicksort(items, 0, config_num-1);
for(i=0; i<items[config_num-1]->index; i++) // index must start from 1
{
memset(temp_line, 0, MAX_LINE_LENGTH);
if( fgets(temp_line, MAX_LINE_LENGTH, fp))
{
if(items[j]->index == i+1)
{
fake_index = strtok(temp_line, "=");
fake_data = strtok(NULL, "=");
if(fake_data == NULL)
fake_data = "";
memset(items[j]->data, 0, strlen(items[j]->data));
strncpy(items[j]->data, fake_data, strlen(fake_data)); //with ‘/n‘
items[j]->data[strlen(items[j]->data)-1] = 0;
//sscanf(temp_line, "%s=%s", fake_index, items[j]->data);
j++;
}
}
else
{
ASSERT("read NULL line\n");
return 0;
}
}
return 1;
}
FILE *OpenTempConfig() // return NULL for open error
{
FILE * fp;
char temp_file_name[MAX_FILE_NAME_LEN];
memset(temp_file_name, 0, MAX_FILE_NAME_LEN);
sprintf(temp_file_name, "%s%d", CONFIG_TEMP_FILE_PROFIX, getpid());
fp = fopen(temp_file_name, "wb");
return fp;
}
void CloseTempConfig(FILE * fp)
{
fclose(fp);
}
void UnlinkTempConfig()
{
char temp_file_name[MAX_FILE_NAME_LEN];
memset(temp_file_name, 0, MAX_FILE_NAME_LEN);
sprintf(temp_file_name, "%s%d", CONFIG_TEMP_FILE_PROFIX, getpid());
unlink(temp_file_name);
}
int WriteTempConfig(FILE *fp, int config_num, config_item *items[])
{
int i; //make sure we have sorted items in ReadGlobeConfig();
int j = 0;
for(i=0; i<config_num; i++) // index must start from 1
{
if(1 == items[i]->is_changed)
j++;
}
fprintf(fp, "%d\n", j);
for(i=0; i<config_num; i++)
{
if(1== items[i]->is_changed)
fprintf(fp, "%d=%s\n", items[i]->index, items[i]->data);
}
return 1;
}
int SaveTempConfig(int config_num, config_item *items[])
{
FILE * fp,*w_fd,*r_fd;
int i, j=0;
for(i=0; i<config_num; i++) // index must start from 1
{
if(1 == items[i]->is_changed )
j++;
}
if(j > 0){
fp = OpenTempConfig();
fprintf(fp, "%d\n", j);
for(i=0; i<config_num; i++)
{
if(1 == items[i]->is_changed )
fprintf(fp, "%d=%s\n", items[i]->index, items[i]->data);
}
fclose(fp);
r_fd = open_read_fifo();
w_fd = open_write_fifo();
notify_config(w_fd);
close_write_fifo(w_fd);
read_fifo(r_fd);
close_read_fifo();
UnlinkTempConfig();
}
return j;
}
config_item ** init_config_item(config_item *items[], int config_num, int *config_list)
{
int i;
items = malloc(sizeof(config_item *)*config_num);
for(i=0; i<config_num; i++)
{
items[i] = malloc(sizeof(config_item));
items[i]->data = malloc(MAX_LINE_LENGTH);
memset(items[i]->data, 0, MAX_LINE_LENGTH);
items[i]->index = config_list[i];
items[i]->is_changed = 0;
}
return items;
}
void set_config_item(config_item *items[], int config_num ,int index ,char * value)
{
int i;
for(i = 0; i < config_num ; i++)
if(items[i]->index == index)
strcat(items[i]->data,value);
}
void free_config_item(config_item *items[], int config_num)
{
int i;
for(i=0; i<config_num; i++)
{
free(items[i]->data);
items[i]->data = NULL;
free(items[i]);
items[i] = NULL;
}
free(items);
items = NULL;
}
int GetConfValues(int *config_list, config_item *items[], int config_num)
{
int i;
FILE * fp;
fp = OpenGlobeConfig();
if(!ReadGlobeConfig(fp, config_num, items))
{
ASSERT("read config error\n");
CloseGlobeConfig(fp);
return 0;
}
CloseGlobeConfig(fp);
return 1;
}
void item_update(int index, config_item *items[], int config_num, char *data)
{
int i;
for(i=0; i<config_num; i++)
{
if(items[i]->index == index)
{
if(strcmp(items[i]->data, data)) // what‘s the matter
{
memset(trace_string, 0, 200);
sprintf(trace_string, "old:%d: %d :%s\n", items[i]->index, strlen(items[i]->data),items[i]->data);
trace(trace_string);
memset(items[i]->data, 0, strlen(items[i]->data));
strcpy(items[i]->data, data);
items[i]->is_changed = 1;
memset(trace_string, 0, 200);
sprintf(trace_string, "new:%d: %d: %s?%d\n", items[i]->index, strlen(items[i]->data),items[i]->data,items[i]->is_changed);
trace(trace_string);
}
}
}
}
char *getdata(int index, config_item *items[], int config_num)
{
int i;
int len;
for(i=0; i<config_num; i++)
{
if(items[i]->index == index)
{
/*
if(!strcmp(items[i]->data, "\n"))
memcpy(items[i]->data, "NULL", sizeof("NULL"));
else
{
len = strlen(items[i]->data);
*(items[i]->data+len-1) = 0;
}
*/
return items[i]->data;
}
}
return NULL;
}
int SaveConfig(char **postvars, config_item **items, int *config_list, char **config_name, int config_num)
{
int i, j;
//GetConfValues(config_list, items, config_num);
if (postvars == 0)
return 0;
for (i=0; postvars[i]; i = i + 2)
{
for(j=0; j<config_num; j++)
{
if(!strcmp(postvars[i], config_name[j]))
item_update(config_list[j], items, config_num, postvars[i+1]);
}
}
return SaveTempConfig(config_num, items);
}
#endif
标签:
原文地址:http://www.cnblogs.com/cenglinjinran/p/4741291.html