码迷,mamicode.com
首页 > Web开发 > 详细

嵌入式web服务器

时间:2015-08-19 11:04:17      阅读:244      评论:0      收藏:0      [点我收藏+]

标签:

要实现在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

嵌入式web服务器

标签:

原文地址:http://www.cnblogs.com/cenglinjinran/p/4741291.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!