?? web_egi.c
字號:
char *start, *end;
adp = (APPDATA *)ts->app;
if (adp->in && (len = buff_freelen(&ts->txb)) >= EGI_BUFFLEN)
{
if (adp->egi) /* If EGI is active.. */
{
len = fread(egibuff, 1, EGI_BUFFLEN, adp->in);
egibuff[len] = 0;
if (len <= 0)
{ /* If end of file, close it.. */
fclose(adp->in);
adp->in = 0;
close_tcp(ts); /* ..and start closing connection */
}
else
{ /* Check for start of EGI tag */
if ((start = strstr(egibuff, EGI_STARTS)) == 0)
start = strchr(&egibuff[len-EGI_STARTLEN], '<');
if (start==egibuff && (end=strstr(egibuff, EGI_ENDS))!=0)
{ /* If tag is at start of buffer.. */
n = (int)(end - start) + sizeof(EGI_ENDS) - 1;
fseek(adp->in, n-len, SEEK_CUR);
egibuff[n] = 0; /* ..call handler */
adp->egi(ts, egibuff);
len = 0;
} /* If tag not at start of buffer.. */
else if (start)
{ /* ..send file up to tag */
n = (int)(start - egibuff);
fseek(adp->in, n-len, SEEK_CUR);
len = n;
}
if (len > 0) /* Send next chunk of file */
buff_in(&ts->txb, (BYTE *)egibuff, (WORD)len);
}
}
else if (buff_infile(&ts->txb, adp->in, (WORD)len) == 0)
{ /* If end of file, close it.. */
fclose(adp->in);
adp->in = 0;
close_tcp(ts); /* ..and start closing connection */
}
}
}
/* Check for incoming packets, send response if required */
void do_receive(GENFRAME *gfp)
{
NODE node;
ARPKT *arp;
IPKT *ip;
ICMPKT *icmp;
int rxlen, txlen, len;
if ((rxlen=get_frame(gfp)) > 0) /* Any incoming frames? */
{
ip = getframe_datap(gfp);
if (is_arp(gfp, rxlen))
{ /* ARP response? */
arp = getframe_datap(gfp);
if (arp->op==ARPREQ && arp->dip==locnode.ip)
{ /* ARP request? */
node.ip = arp->sip; /* Make ARP response */
memcpy(node.mac, arp->smac, MACLEN);
txlen = make_arp(gfp, &locnode, &node, ARPRESP);
put_frame(gfp, txlen); /* Send packet */
}
if (arp->op==ARPRESP && arp->dip==locnode.ip)
{ /* ARP response? */
arp_receive(tsocks, NSOCKS, gfp);
}
}
else if ((rxlen=is_ip(gfp, rxlen))!=0 && /* IP datagram? */
ip->i.dip==locnode.ip || ip->i.dip==BCASTIP)
{
getip_srce(gfp, &node);
if ((len=is_icmp(ip, rxlen))!=0) /* ICMP? */
{
icmp = (ICMPKT *)ip;
if (icmp->c.type==ICREQ) /* Echo request? */
{
len = (WORD)maxi(len, 0); /* Make response */
txlen = make_icmp(gfp, &locnode, &node, ICREP,
icmp->c.code, (WORD)len);
put_frame(gfp, txlen); /* Send packet */
}
}
else if ((len=is_tcp(ip, rxlen))!=0) /* TCP? */
{
tcp_receive(tsocks, NSOCKS, gfp, len);
}
}
}
}
/* Poll the network interface to keep it alive */
void do_poll(GENFRAME *gfp)
{
tcp_poll(tsocks, NSOCKS, gfp);
poll_net(gfp->g.dtype);
}
/* Version of printf() to write a string into a circular buffer.
** Return string length, or zero if insufficient room in buffer */
int buff_inprintf(CBUFF *bp, char *str, ...)
{
char temps[200];
int len;
va_list argptr;
va_start(argptr, str);
len = vsprintf(temps, str, argptr);
va_end(argptr);
if (len<=0 || len>buff_freelen(bp))
len = 0;
else
buff_in(bp, (BYTE *)temps, (WORD)len);
return(len);
}
/* Add a variable to the connection variable space, return 0 if no room */
int put_connvar(TSOCK *ts, char *name, char *val)
{
return(put_connvarlen(ts, name, strlen(name), val, strlen(val)));
}
/* Add a variable to the connection variable space, return 0 if no room
** String aren't necessarily null-terminated; they are pointers & lengths */
int put_connvarlen(TSOCK *ts, char *name, int namlen, char *val, int valen)
{
int ok=0;
APPDATA *adp;
adp = (APPDATA *)ts->app;
if (adp->vlen+namlen+valen+3<VARSPACE &&
namlen<MAX_EGINAME && valen<MAX_EGIVAL)
{
adp->vars[adp->vlen++] = (char)(namlen | 0x80);
strncpy(&adp->vars[adp->vlen], name, namlen);
adp->vlen += namlen;
adp->vars[adp->vlen++] = 0;
strncpy(&adp->vars[adp->vlen], val, valen);
adp->vlen += valen;
adp->vars[adp->vlen++] = 0;
}
return(ok);
}
/* Get variable from the connection space, return null string if not found */
char *get_connvar(TSOCK *ts, char *name)
{
int n, len;
APPDATA *adp;
char *s=0, *end;
adp = (APPDATA *)ts->app;
end = &adp->vars[adp->vlen];
n = strlen(name);
if (n < MAX_EGINAME)
{
s = memchr(adp->vars, (char)(n | 0x80), adp->vlen-3);
while (s && strncmp(s+1, name, n) && (len=(int)(end-s))>3)
s = memchr(s+1, (char)(n | 0x80), len);
}
return(s ? s+n+2 : "");
}
/* Find variable in the connection space, by matching first few chars
** Return full name string, null string if not found */
char *find_connvar(TSOCK *ts, char *name)
{
int n;
APPDATA *adp;
char *s=0, *end;
adp = (APPDATA *)ts->app;
end = &adp->vars[adp->vlen];
n = strlen(name);
if (n < MAX_EGINAME)
{
s = adp->vars;
while (*s && strncmp(s+1, name, n) && (int)(end-s)>2)
{
do {
s++;
} while (s<end-2 && !(*s & 0x80));
}
}
return(*s & 0x80 ? s+1 : "");
}
/* Display all vars in the connection variable space, for debugging */
void disp_connvars(TSOCK *ts)
{
int len=0, n;
APPDATA *adp;
adp = (APPDATA *)ts->app;
while (len < adp->vlen)
{
n = (int)adp->vars[len++] & 0x7f;
printf("Var %s", &adp->vars[len]);
len += n + 1;
printf("=%s\n", &adp->vars[len]);
len += strlen(&adp->vars[len]) + 1;
}
}
/* Get connection variable values from URL */
void url_connvars(TSOCK *ts, char *str)
{
int nlen, vlen, n;
if (*str == '/')
str++;
vlen = strcspn(str, " .?");
put_connvarlen(ts, "fname", 5, str, vlen);
str += vlen;
if (*str == '.')
{
str++;
vlen = strcspn(str, " ?");
put_connvarlen(ts, "fext", 4, str, vlen);
str += vlen;
}
if (*str++ == '?')
{
while ((nlen=strcspn(str, "="))!=0 && (vlen=strcspn(str+nlen, "&"))!=0)
{
n = url_decode(str+nlen+1, vlen-1);
put_connvarlen(ts, str, nlen, str+nlen+1, n);
str += nlen + vlen;
if (*str == '&')
str++;
}
}
}
/* Decode a URL-encoded string (with length), return new length */
int url_decode(char *str, int len)
{
int n=0, d=0;
char c, c2, *dest;
dest = str;
while (n < len)
{
if ((c = str[n++]) == '+')
c = ' ';
else if (c=='%' && n+2<=len &&
isxdigit(c=str[n++]) && isxdigit(c2=str[n++]))
{
c = c<='9' ? (c-'0')*16 : (toupper(c)-'A'+10)*16;
c += c2<='9' ? c2-'0' : toupper(c2)-'A'+10;
}
dest[d++] = c;
}
return(d);
}
/* Open a file, given the URL filename. Return file handle, 0 if error */
FILE *url_fopen(char *str)
{
char fpath[MAXPATH+1];
int n;
if (*str == '/') /* Strip leading '/' */
str++;
strcpy(fpath, filedir); /* Copy base directory */
if (*str <= ' ') /* No filename left? */
{
strcat(fpath, DEFAULTFILE); /* Use default if none */
}
else
{
n = strlen(fpath); /* Copy requested filename */
while (n<MAXPATH && *str>' ' && *str!='?')
fpath[n++] = *str++;
fpath[n] = 0;
}
return(fopen(fpath, "rb")); /* Open file */
}
/* Execute the EGI function corresponding to a string, return 0 if not found */
int egi_execstr(TSOCK *ts, char *str)
{
int ok=0, n=0;
while (egifuncs[n].func && !(ok=!stricmp(str, egifuncs[n].name)))
n++;
if (ok)
egifuncs[n].func(ts, 0);
return(ok);
}
/* Display usage help */
void disp_usage(void)
{
printf("Usage: WEB_EGI [ options ] [ directory ]\n");
printf(" If no directory specified, default is '%s'\n", FILEDIR);
printf("Options: -c name Config filename (default %s)\n", CFGFILE);
printf(" -s State display\n");
printf(" -t TCP segment display\n");
printf(" -v Verbose packet display\n");
printf(" -w Web (HTTP) diagnostics\n");
printf(" -x Hex packet display\n");
printf("Example: WEBSERVE c:\\mydocs\n");
}
/* Ctrl-break handler: set flag and return */
void break_handler(int sig)
{
breakflag = sig;
}
/* EOF */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -