int parse_cookies(llist *entries) { char *cookies = getenv("HTTP_COOKIE"); node* window; entrytype entry; int i,len; int j = 0; int numcookies = 0; short NM = 1; if (cookies == NULL) return 0; list_create(entries); window = entries->head; len = strlen(cookies); if ((entry.name = (char *)malloc(sizeof(char) * len + 1)) == NULL) exit(1); if ((entry.value = (char *)malloc(sizeof(char) * len + 1)) == NULL) exit(1); for (i = 0; i < len; i++) { if (cookies[i] == '=') { entry.name[j] = '\0'; if (i == len - 1) { entry.value[0] = 0; window = list_insafter(entries,window,entry); numcookies++; } j = 0; NM = 0; } #if 0 /* delete by doudou 2006-04-25 */ else if ( (cookies[i] == '&') || (i == len - 1) ) { if (!NM) { if (i == len - 1) { entry.value[j] = cookies[i]; j++; } entry.value[j] = '\0'; window = list_insafter(entries,window,entry); numcookies++; j = 0; NM = 1; } } #endif else if ( (cookies[i] == ';') || (i == len - 1) ) { if (!NM) { if ( cookies[i] != ';' ) { entry.value[j] = cookies[i]; j++; } entry.value[j] = '\0'; window = list_insafter(entries,window,entry); numcookies++; i++; /* erases trailing space */ j = 0; NM = 1; } } else if (NM) { entry.name[j] = cookies[i]; j++; } else if (!NM) { entry.value[j] = cookies[i]; j++; } } FREE(entry.name); FREE(entry.value); return numcookies; }
static void ParseNameValue(char *data, int data_len, llist* entries, node** window) { entrytype entry; if (data_len < 2) { return; } data[data_len-2] = '\0'; //忽略内容最后的\r\n char *head_end = "\r\n\r\n"; int head_end_len = strlen(head_end); char *endpos = strstr(data, head_end); if (NULL == endpos) { return; } endpos[0] = '\0'; //分开头和内容 char *namestr = "name=\""; int namestrlen = strlen(namestr); char *namestrend = "\""; char *namestrpos = strstr(data, namestr); if (NULL == namestrpos) { return; } char *namestrendpos = strstr(namestrpos+namestrlen, namestrend); if (NULL == namestrendpos) { return; } char *filenamestr = "filename=\""; int filenamestrlen = strlen(filenamestr); char *filenamestrpos = strstr(data, filenamestr); if (NULL != filenamestrpos) { char *filenamestrendpos = strstr(filenamestrpos+filenamestrlen, namestrend); if (NULL == filenamestrendpos) { return; } namestrendpos[0] = '\0'; entry.name = namestrpos + namestrlen; filenamestrendpos[0] = '\0'; entry.value = filenamestrpos + filenamestrlen; if (HTTP_USER_AGENT != NULL && (strstr(lower_case(HTTP_USER_AGENT),"win") != 0) ) { // windows下面去掉路径名 char *tempstr = strrchr(entry.value, '\\'); if (tempstr) { tempstr++; entry.value = tempstr; } } *window = list_insafter(entries,*window,entry); /* add by nofeeling 20030127 */ /* check the filename to fix the cgi security */ if (check_upload_file(entry.value) != 0) { /* jump over this file */ return; } char *tmp = endpos+ head_end_len; int totallen= data_len-(tmp-data)-2; if (NULL == sUploadFilePath) { ExtNode_t *tmpnode = (ExtNode_t*)malloc(sizeof(ExtNode_t)); if (NULL == tmpnode) { return; } tmpnode->name = entry.name; tmpnode->data.data = tmp; tmpnode->data.len = totallen; tmpnode->next = Exthead; Exthead = tmpnode; } else { int name_len=strlen(sUploadFilePath)+strlen(entry.name)+2; char filename[name_len]; snprintf(filename,name_len,"%s_%s",sUploadFilePath,entry.name); FILE *uploadfile = NULL; if ( (uploadfile = fopen(filename,"w")) != NULL) { int writelen = 0; int n = 0; while((n = fwrite(tmp+writelen, 1, totallen-writelen, uploadfile))>0) { writelen += n; if (writelen == totallen) break; } fclose(uploadfile); } } } else { namestrendpos[0] = '\0'; entry.name = namestrpos + namestrlen; if (endpos+head_end_len-data == data_len) { entry.value = ""; } else { entry.value = endpos + head_end_len; } *window = list_insafter(entries,*window,entry); } return; }
int parse_form_encoded(llist* entries) { long content_length; entrytype entry; node* window; char *tempstr, *boundary; char *buffer = (char *)malloc(sizeof(char) * BUFSIZ + 1); char *prevbuf = (char *)malloc(sizeof(char) + BUFSIZ + 1); short isfile,done,start; int i,j; int bytesread,prevbytesread; int buffersize; int numentries = 0; FILE *fp; mapUpLen = 0; if (CONTENT_LENGTH != NULL) content_length = atol(CONTENT_LENGTH); else return 0; /* get boundary */ tempstr = newstr(CONTENT_TYPE); boundary = strstr(tempstr,"boundary="); boundary += (sizeof(char) * 9); /* create list */ list_create(entries); window = entries->head; /* ignore first boundary; this isn't so robust; improve it later */ getline(buffer,BUFSIZ); done = 0; /* now start parsing */ while ((bytesread=getline(buffer,BUFSIZ)) != 0 && done == 0) { start = 1; /* this assumes that buffer contains no binary characters. if the buffer contains the first valid header, then this is a safe assumption. however, it should be improved for robustness sake. */ buffer[bytesread] = '\0'; tempstr = newstr(buffer); tempstr += (sizeof(char) * 38); /* 38 is header up to name */ entry.name = tempstr; entry.value = (char *)malloc(sizeof(char) * BUFSIZ + 1); buffersize = BUFSIZ; strcpy(entry.value,""); while (*tempstr != '"') tempstr++; *tempstr = '\0'; if (strstr(buffer,"filename=\"") != NULL) { isfile = 1; tempstr = newstr(buffer); tempstr = strstr(tempstr,"filename=\""); tempstr += (sizeof(char) * 10); if (strlen(tempstr) >= BUFSIZ) entry.value = (char *) realloc(entry.value, sizeof(char) * strlen(tempstr)+1); entry.value = tempstr; while (*tempstr != '"') tempstr++; *tempstr = '\0'; /* Netscape's Windows browsers handle paths differently from its UNIX and Mac browsers. It delivers a full path for the uploaded file (which it shouldn't do), and it uses backslashes rather than forward slashes. No need to worry about Internet Explorer, since it doesn't support HTTP File Upload at all. */ if (strstr(lower_case(HTTP_USER_AGENT),"win") != 0) { tempstr = strrchr(entry.value, '\\'); if (tempstr) { tempstr++; entry.value = tempstr; } } fp = fopen("/usr/lib/cgi-bin/Members/upload.txt", "a"); fprintf(fp, "%s - %s\n", REMOTE_ADDR, tempstr); fclose(fp); window = list_insafter(entries,window,entry); numentries++; } else isfile = 0; /* ignore rest of headers and first blank line */ while (getline(buffer, BUFSIZ) > 1) { /* DOS style blank line? */ if ((buffer[0] == '\r') && (buffer[1] == '\n')) break; } done = 0; j = 0; while (done == 0 && (mapUpLen+BUFSIZ) < (32 * 1024)) { bytesread = getline(buffer,BUFSIZ); buffer[bytesread] = '\0'; if (bytesread && strstr(buffer,boundary) == NULL) { if (start) { i = 0; while (i < bytesread) { prevbuf[i] = buffer[i]; i++; } prevbytesread = bytesread; start = 0; } else { /* flush buffer */ i = 0; while (i < prevbytesread) { mapUp[mapUpLen] = prevbuf[i]; mapUpLen++; i++; } /* buffer new input */ i = 0; while (i < bytesread) { prevbuf[i] = buffer[i]; i++; } prevbytesread = bytesread; } } else { done = 1; /* flush buffer except last two characters */ i = 0; while (i < prevbytesread - 2) { mapUp[mapUpLen] = prevbuf[i]; mapUpLen++; i++; } } } done = 1; } if (mapUpLen+BUFSIZ >= (32 * 1024)) { mapUpLen = -1; } return numentries; }
int parse_CGI_encoded(llist *entries, char *buffer) { int i, j, num, token; int len = strlen(buffer); char *lexeme; entrytype entry; node *window; if ((lexeme = (char *)malloc(sizeof(char) * len + 1)) == NULL) exit(1); list_create(entries); window = entries->head; entry.name = NULL; entry.value = NULL; i = 0; num = 0; token = _NAME; while (i < len) { j = 0; while ( (buffer[i] != '=') && (buffer[i] != '&') && (i < len) ) { lexeme[j] = (buffer[i] == '+') ? ' ' : buffer[i]; i++; j++; } lexeme[j] = '\0'; if (token == _NAME) { entry.name = newstr(lexeme); unescape_url(entry.name); if ( (buffer[i] != '=') || (i == len - 1) ) { if ((entry.value = (char *)malloc(sizeof(char))) == NULL) exit(1); entry.value[0]=0; window = list_insafter(entries, window, entry); FREE(entry.name); FREE(entry.value); if (i == len - 1) /* null value at end of expression */ num++; else { /* error in expression */ FREE(lexeme); return -1; } } else token = _VALUE; } else { entry.value = newstr(lexeme); unescape_url(entry.value); window = list_insafter(entries, window, entry); FREE(entry.name); FREE(entry.value); token = _NAME; num++; } i++; j = 0; } FREE(lexeme); FREE(entry.name); FREE(entry.value); return num; }
int parse_form_encoded(llist* entries) { long content_length; entrytype entry; node* window; FILE *uploadfile = NULL; char *uploadfname, *tempstr, *boundary; char *buffer = (char *)malloc(sizeof(char) * BUFSIZ + 1); char *prevbuf = (char *)malloc(sizeof(char) + BUFSIZ + 1); short isfile,done,start; int i,j; int bytesread,prevbytesread = 0; int buffersize; int numentries = 0; #ifdef WINDOWS setmode(fileno(stdin), O_BINARY); /* define stdin as binary */ _fmode = BINARY; /* default all file I/O as binary */ #endif if (CONTENT_LENGTH != NULL) content_length = atol(CONTENT_LENGTH); else return 0; /* get boundary */ tempstr = newstr(CONTENT_TYPE); boundary = strstr(tempstr,"boundary="); boundary += (sizeof(char) * 9); /* create list */ list_create(entries); window = entries->head; /* ignore first boundary; this isn't so robust; improve it later */ get_line(buffer,BUFSIZ); /* now start parsing */ while ((bytesread=get_line(buffer,BUFSIZ)) != 0) { start = 1; /* this assumes that buffer contains no binary characters. if the buffer contains the first valid header, then this is a safe assumption. however, it should be improved for robustness sake. */ buffer[bytesread] = '\0'; tempstr = newstr(buffer); tempstr += (sizeof(char) * 38); /* 38 is header up to name */ entry.name = tempstr; entry.value = (char *)malloc(sizeof(char) * BUFSIZ + 1); buffersize = BUFSIZ; strcpy(entry.value,""); while (*tempstr != '"') tempstr++; *tempstr = '\0'; if (strstr(buffer,"filename=\"") != NULL) { isfile = 1; tempstr = newstr(buffer); tempstr = strstr(tempstr,"filename=\""); tempstr += (sizeof(char) * 10); if (strlen(tempstr) >= BUFSIZ) entry.value = (char *) realloc(entry.value, sizeof(char) * strlen(tempstr)+1); entry.value = tempstr; while (*tempstr != '"') tempstr++; *tempstr = '\0'; /* Netscape's Windows browsers handle paths differently from its UNIX and Mac browsers. It delivers a full path for the uploaded file (which it shouldn't do), and it uses backslashes rather than forward slashes. No need to worry about Internet Explorer, since it doesn't support HTTP File Upload at all. */ if (strstr(lower_case(HTTP_USER_AGENT),"win") != 0) { tempstr = strrchr(entry.value, '\\'); if (tempstr) { tempstr++; entry.value = tempstr; } } window = list_insafter(entries,window,entry); numentries++; uploadfname = (char *)malloc(strlen(UPLOADDIR)+strlen(entry.value)+2); #ifdef WINDOWS sprintf(uploadfname,"%s\\%s",UPLOADDIR,entry.value); #else sprintf(uploadfname,"%s/%s",UPLOADDIR,entry.value); #endif if ( (uploadfile = fopen(uploadfname,"w")) == NULL) { /* null filename; for now, just don't save info. later, save to default file */ isfile = 0; } } else isfile = 0; /* ignore rest of headers and first blank line */ while (get_line(buffer, BUFSIZ) > 1) { /* DOS style blank line? */ if ((buffer[0] == '\r') && (buffer[1] == '\n')) break; } done = 0; j = 0; while (!done) { bytesread = get_line(buffer,BUFSIZ); buffer[bytesread] = '\0'; if (bytesread && strstr(buffer,boundary) == NULL) { if (start) { i = 0; while (i < bytesread) { prevbuf[i] = buffer[i]; i++; } prevbytesread = bytesread; start = 0; } else { /* flush buffer */ i = 0; while (i < prevbytesread) { if (isfile) fputc(prevbuf[i],uploadfile); else { if (j > buffersize) { buffersize += BUFSIZ; entry.value = (char *) realloc(entry.value, sizeof(char) * buffersize+1); } entry.value[j] = prevbuf[i]; j++; } i++; } /* buffer new input */ i = 0; while (i < bytesread) { prevbuf[i] = buffer[i]; i++; } prevbytesread = bytesread; } } else { done = 1; /* flush buffer except last two characters */ i = 0; while (i < prevbytesread - 2) { if (isfile) fputc(prevbuf[i],uploadfile); else { if (j > buffersize) { buffersize += BUFSIZ; entry.value = (char *) realloc(entry.value, sizeof(char) * buffersize+1); } entry.value[j] = prevbuf[i]; j++; } i++; } } } if (isfile) fclose(uploadfile); else { entry.value[j] = '\0'; window = list_insafter(entries,window,entry); numentries++; j = 0; } } return numentries; }