分类: C/C++
2009-06-19 23:03:17
#define B_USE_MALLOC 0x1 /* Okay to use malloc if required */
#define B_DEFAULT_MEM (64 * 1024) /* Default memory allocation 64K*/
#define B_USER_BUF 0x2 /* User supplied buffer for mem */
#define B_MAX_CLASS 13 /* Maximum class number + 1 */
/*
* Block classes are: 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192,
* 16384, 32768, 65536
*/
typedef struct {
union {
void *next; /* Pointer to next in q */
int size; /* Actual requested size */
} u;
int flags; /* Per block allocation flags */
} bType;
static bType *bQhead[B_MAX_CLASS]; /* Per class block q head */
static int bFreeSize; /* Size of free memory */
static int bFreeLeft; /* Size of free left for use */
static char *bFreeNext; /* Pointer to next free mem */
static char *bFreeBuf; /* Pointer to free memory */
static int bFlags = B_USE_MALLOC; /* Default to auto-malloc */
static int bopenCount = 0; /* Num tasks using balloc */
bopen(NULL, (60 * 1024), B_USE_MALLOC);
int bopen(void *buf, int bufsize, int flags)
{
bFlags = flags;
/*
* If bopen already called by a shared process, just increment the count
* and return;
*/
if (++bopenCount > 1) {
return 0;
}
if (buf == NULL) {
if (bufsize == 0) {
bufsize = B_DEFAULT_MEM;
}
if ((buf = malloc(bufsize)) == NULL) { /* resetting bopenCount lets client code decide to attempt to call
* bopen() again with a smaller memory request, should it desire to.
* Fix suggested by Simon Byholm.
*/
--bopenCount;
return -1;
}
} else {
bFlags |= B_USER_BUF;
}
bFreeSize = bFreeLeft = bufsize;
bFreeBuf = bFreeNext = buf;
memset(bQhead, 0, sizeof(bQhead));
return 0;
}
/*当服务器close一个连接时,若client端接着发数据。根据TCP协议的规定,会收到一个RST响应,client再往这个服务器发送数据时,系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了。
根据信号的默认处理规则SIGPIPE信号的默认执行动作是terminate(终止、退出),所以client会退出。若不想客户端退出可以把SIGPIPE设为SIG_IGN
如: signal(SIGPIPE,SIG_IGN);
这时SIGPIPE交给了系统处理。
服务器采用了fork的话,要收集垃圾进程,防止僵尸进程的产生,可以这样处理:
signal(SIGCHLD,SIG_IGN); 交给系统init去回收。
这里子进程就不会产生僵尸进程了。
*/
signal(SIGPIPE, SIG_IGN); ?
/*
* To convert strings to UNICODE. We have a level of indirection so things
* like T(__FILE__) will expand properly.
*/
#define T(x) __TXT(x)
#define __TXT(s) L ## s //?
#define E_L T(__FILE__), __LINE__
/*
* Error types
*/
#define E_ASSERT 0x1 /* Assertion error */
#define E_LOG 0x2 /* Log error to log file */
#define E_USER 0x3 /* Error that must be displayed */
/******************************************************************************/
/*
* Write pid to the pid file
*/
typedef unsigned short char_t;
static char_t *gopid = T("/mnt/jffs2/test/goahead.pid");
int writeGoPid(void)
{
FILE *fp;
fp = fopen(gopid, "w+");
if (NULL == fp) {
error(E_L, E_LOG, T("goahead.c: cannot open pid file"));
return (-1);
}
fprintf(fp, "%d", getpid());
fclose(fp);
return 0;
}
//结构体
#define MAX_LINE_LEN 255
#define MAX_PROP_SIZE 300
typedef struct cache_environment_s
{
char * name;
char * value;
} cache_t;
typedef struct item_s
{
char comment[MAX_LINE_LEN];
char def[MAX_LINE_LEN];
cache_t fb[MAX_PROP_SIZE];
int fb_size;
}item_t;
static item_t item;
void nvram_close(int index)
{
int i=0;
while(i
free(item.fb[i].name);
free(item.fb[i].value);
i++;
}
memset(&item,0,sizeof(item));
}
#define _CFG_405_ "/mnt/jffs2/test/EX405.dat"
#define RTN_SYMBOL 10 // '\n'
#define CMNT_SYMBOL 35 // '#'
#define EQ_SYMBOL 61 // '='
#define BLANK_SYMBOL 32 // ' '
void nvram_init(int index)
{
if(NULL==(fp=fopen(_CFG_405_,"r")))
{
printf("Open default configuration %s error! System exit.\n",_CFG_405_);
exit(1) ;
}
memset(&item,0,sizeof(item));
sprintf(item.comment,"#The word of \"Default\" must not be removed\n");
sprintf(item.def,"Default\n");
unsigned char line[MAX_LINE_LEN]="";
unsigned char left[MAX_LINE_LEN/2]="";
unsigned char right[MAX_LINE_LEN/2]="";
unsigned char ch[2]="";
int i=0;
while((ch[0]=fgetc(fp))!=EOF)
{
if(255==ch[0]) // 表明这一行什么也没有 ASC|| 表示为blank
{
break;
}
if(RTN_SYMBOL==ch[0])// '\n' 表示己读到行尾
{
trim_str(line);
if(0!=strlen(line))
{
if(CMNT_SYMBOL!=line[0]) // '#' 是这个的表示这一行是注释
{
split_str(line,EQ_SYMBOL,left,right); //以'=' 来切分这一行
if(0!=strlen(left))
{
if(MAX_PROP_SIZE==i)
{
printf("BAD property configuration data! System exit.\n");
exit(1);
}
item.fb[i].name=(unsigned char*)malloc(strlen(left)+1);
item.fb[i].value=(unsigned char*)malloc(strlen(right)+1);
memset(item.fb[i].name,'\0',strlen(left)+1); //peter
memset(item.fb[i].value,'\0',strlen(right)+1);
sprintf(item.fb[i].name,"%s",left);
sprintf(item.fb[i].value,"%s",right);
memset(left,0,sizeof(left));
memset(right,0,sizeof(right));
i++;
}
}
// printf("line is: %s\n",line);
memset(line,0,MAX_LINE_LEN);
}
}
else
{
strcat(line,ch);
}
}
//printf("end init nvram");
item.fb_size=i;
//printf("item.fb_size: %d\n",item.fb_size);
fclose(fp);
}
/*
* description: parse va and do system
*/
int doSystem(char_t *fmt, ...)
{
va_list vargs;
char_t *cmd = NULL;
int rc = 0;
va_start(vargs, fmt);
if (fmtValloc(&cmd, WEBS_BUFSIZE, fmt, vargs) >= WEBS_BUFSIZE) {
trace(0, T("doSystem: lost data, buffer overflow\n"));
}
va_end(vargs);
if (cmd) {
trace(0, T("%s\n"), cmd);
rc = system(cmd);
bfree(B_L, cmd);
}
return rc;
}
#define RT2860_NVRAM 0
#define RTINIC_NVRAM 1
#define RT2561_NVRAM 2
//完成对初始配置的解析
int setDefault(void)
{
nvram_close(RT2860_NVRAM);
nvram_init(RT2860_NVRAM);
return (0);
}
int get_idx(char * name)
{
int i=0;
while (i
if(!strcmp(name,item.fb[i].name)) //比较字符是否相等
return i;
i++;
}
return -1;
}
char *nvram_bufget(int index, char *name)
{
int idx=get_idx(name); //返回在结构体中的index
return (-1==idx)?"":item.fb[idx].value;
}
//http://hi.baidu.com/clcctc/blog/item/064e535105941a8a8d543062.html
//http://hi.baidu.com/lsng/blog/item/1a6c35556dbc2753574e004c.html
void ripdRestart(void)
{
char lan_ip[16], wan_ip[16], lan_mask[16], wan_mask[16];
char *opmode = nvram_bufget(RT2860_NVRAM, "OperationMode");
char *password = nvram_bufget(RT2860_NVRAM, "Password");
char *RIPEnable = nvram_bufget(RT2860_NVRAM, "RIPEnable");
doSystem("killall -q ripd");
if(!opmode||!strlen(opmode))
return;
if(!strcmp(opmode, "0")) // bridge
return;
if(!RIPEnable || !strlen(RIPEnable) || !strcmp(RIPEnable,"0"))
return;
if(!password || !strlen(password))
password = "rt2880";
doSystem("echo \"hostname linux.router1\" > /etc/ripd.conf ");
doSystem("echo \"password %s\" >> /etc/ripd.conf ", password);
doSystem("echo \"router rip\" >> /etc/ripd.conf ");
// deal with WAN
if(getIfIp(getWanIfName(), wan_ip) != -1){
if(getIfNetmask(getWanIfName(), wan_mask) != -1){
doSystem("echo \"network %s/%d\" >> /etc/ripd.conf", wan_ip, netmask_aton(wan_mask));
doSystem("echo \"network %s\" >> /etc/ripd.conf", getWanIfName());
}else
printf("ripdRestart(): The WAN IP is still undeterminated...\n");
}else
printf("ripdRestart(): The WAN IP is still undeterminated...\n");
// deal with LAN
if(getIfIp(getLanIfName(), lan_ip) != -1){
if(getIfNetmask(getLanIfName(), lan_mask) != -1){
doSystem("echo \"network %s/%d\" >> /etc/ripd.conf", lan_ip, netmask_aton(lan_mask));
doSystem("echo \"network %s\" >> /etc/ripd.conf", getLanIfName());
}
}
doSystem("echo \"version 2\" >> /etc/ripd.conf");
doSystem("echo \"log syslog\" >> /etc/ripd.conf");
doSystem("ripd -f /etc/ripd.conf -d");
}
static void dhcpcHandler(int signum)
{
ripdRestart();
}
/******************************************************************************/
/*
* Initialize System Parameters
*/
static int initSystem(void)
{
int setDefault(void);
signal(SIGUSR2, dhcpcHandler);
if (setDefault() < 0)
return (-1);
if (initInternet() < 0)
return (-1);
#if defined CONFIG_USER_STORAGE
signal(SIGTTIN, hotPluglerHandler);
hotPluglerHandler(SIGTTIN);
#endif
#ifdef CONFIG_RALINK_RT2880
signal(SIGUSR1, goaSigHandler);
#else
goaInitGpio();
#endif
signal(SIGXFSZ, WPSSingleTriggerHandler);
return 0;
}