diff options
author | ptt <ptt@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2002-10-18 22:43:58 +0800 |
---|---|---|
committer | ptt <ptt@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2002-10-18 22:43:58 +0800 |
commit | 86672771393d552ac6d9c742fa1d80c34cc1cf74 (patch) | |
tree | 559e636d1dca81d54c8d5a7a929bba73a9f62646 /web/args.c | |
parent | d87c20433e1a16e5ec3d31b00c1dd491e995b1ea (diff) | |
download | pttbbs-86672771393d552ac6d9c742fa1d80c34cc1cf74.tar pttbbs-86672771393d552ac6d9c742fa1d80c34cc1cf74.tar.gz pttbbs-86672771393d552ac6d9c742fa1d80c34cc1cf74.tar.bz2 pttbbs-86672771393d552ac6d9c742fa1d80c34cc1cf74.tar.lz pttbbs-86672771393d552ac6d9c742fa1d80c34cc1cf74.tar.xz pttbbs-86672771393d552ac6d9c742fa1d80c34cc1cf74.tar.zst pttbbs-86672771393d552ac6d9c742fa1d80c34cc1cf74.zip |
*** empty log message ***
git-svn-id: http://opensvn.csie.org/pttbbs/pttbbs/trunk/pttbbs@539 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'web/args.c')
-rwxr-xr-x | web/args.c | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/web/args.c b/web/args.c new file mode 100755 index 00000000..02e0fad0 --- /dev/null +++ b/web/args.c @@ -0,0 +1,228 @@ +/* 使用方法: 自己先用 r->method_number 判斷是 M_GET 或 M_POST + */ +#include "mod_ptt.h" + +unsigned char xtoc(char ch1, char ch2) { + unsigned char d, up1, up2; + + if (!isxdigit(ch1) || !isxdigit(ch2)) return ' '; + + up1 = toupper(ch1); + up2 = toupper(ch2); + + if (up1>='0' && up1<='9') d = up1-'0'; + else d = up1-'A'+10; + d <<= 4; + if (up2>='0' && up2<='9') d += up2-'0'; + else d += up2-'A'+10; + + return d; +} + +char * cstoxs(pool *p, char *str) +{ + char * newstr = pstrdup(p,""), *po = str; + + for(po = str; *po; po++) + { + if(isprint(*po) && *po!=' ') newstr=psprintf(p, "%s%c", newstr,*po); + else newstr=psprintf(p, "%s%%%X", newstr, *po& 0xFF); + } + return newstr; +} + +int // Ptt: 我重寫拿掉mygetchar 並加上fileupload的功能 +inital_postdata(request_rec *r, int *fileupload, char *boundary, + char **data) +{ + char *buf, *mb; + int size, off = 0, len_read; + void (*handler)(); + + buf = table_get(r->subprocess_env,"CONTENT_TYPE"); + if(!buf || + (strncasecmp(buf,"application/x-www-form-urlencoded",33) && + strncasecmp(buf,"multipart/form-data",19))) + return -1; + + if(!strncasecmp(buf,"multipart/form-data",19)) { + if(!fileupload) return -1; + *fileupload=1; + mb = strchr(buf,'='); + if(mb) { + strcpy(boundary,mb+1); + strtok(boundary, " ;\n"); + } + else return -1; + } + + buf = table_get(r->subprocess_env,"CONTENT_LENGTH"); + if(buf==NULL) return -1; + + size = atoi(buf); + mb = (char *)palloc(r->pool,(size+1)*sizeof(char)); + + if(!mb || + (setup_client_block(r ,REQUEST_CHUNKED_ERROR) != 0) || + (should_client_block(r) == 0)) + return -1; + + hard_timeout("args.c copy script args", r); + handler = signal(SIGPIPE, SIG_IGN); + + while(size-off > 0 && (len_read = get_client_block + (r, mb + off, size - off)) > 0) { + off += len_read; + } + + signal(SIGPIPE, handler); + kill_timeout(r); + + if(len_read < 0) return -1; // 讀的中途有中斷 + mb[size]=0; // Ptt:截掉不需要吧 因為不是用字串處理方式 + (*data) = mb; + return size; +} + +#define ENCODED_NAME " name=\"" +#define ENCODED_FILENAME " filename=\"" +#define ENCODED_CONTENT "Content-Type: " + +//#define FILEDATAFILE DATABASEDIR "/" FDATA + +int +unescape(request_rec *r, char** name, char** value) { + static char *sp=NULL, boundary[150]; + static int fileupload, boundarylen, dsize; + pool *p = r->pool; + char ch, ch1, *dp, *p0, *p1, *temp_sp, *ftype; + int type; + + if (sp==NULL) { + fileupload=0; + switch (r->method_number) { + case M_GET: + if (r->args) sp = pstrdup(p, r->args); + else {sp=NULL; return -1;} + break; + case M_POST: + if ((dsize = + inital_postdata(r, &fileupload, boundary,&sp))<0) + {sp=NULL; return -1; } + if(fileupload) boundarylen = strlen(boundary); + break; + default: + sp=NULL; + return -1; + } + } + + if(fileupload) + { + if(dsize >0 && (temp_sp = memstr(sp, boundary, dsize))) + { + temp_sp += boundarylen; + p0 = strstr(temp_sp, "\r\n\r\n"); + p1 = strstr(temp_sp, "\n\n"); + + if(!((*name) = strstr(temp_sp, ENCODED_NAME))) + {sp=NULL; return -1; } + (*name) += strlen(ENCODED_NAME); + strtok((*name) + 1 , "\""); + if( (!p0 && p1) || (p0 && p1 && p1<p0)) + { + (*value) = sp = p1 + 2; + type = 2; + } + else if(p0) + { + (*value) = sp = p0 + 4; + type = 4; + } + else + { + sp=NULL; + return -1; + } + + if((p1 = memstr(temp_sp, boundary, dsize - boundarylen))) + temp_sp = p1; + else + temp_sp = sp + dsize; + + *(temp_sp - type) = 0; + + // 檢查是不是file 若是就給fileinfo + if((dp=memstr( + (*name) + strlen(*name) +1, ENCODED_FILENAME, dsize)) && + dp < *value) + { + dp += strlen(ENCODED_FILENAME); + p0 = strchr(dp,'"'); + *p0 = 0; + if(p0 - dp>3) + { + fileheader_t *file=(fileheader_t *)pcalloc(p, sizeof(fileheader_t)); + if((ftype = strstr(p0 + 1, ENCODED_CONTENT))) + { + ftype += strlen(ENCODED_CONTENT); + strtok(ftype, "\r\n"); + } + while(p0 > dp && *p0 !='/' && *p0 !='\\') p0--; + strcpy(file->name, p0+1); + strcpy(file->content_type, ftype); + file->icontent_type = filetype(ftype); + // if(file->icontent_type & (FILE_TXT | FILE_HTML)) + // file->size = strlen(sp); + // else + file->size = temp_sp - sp - type; + file->uploadtime = time(NULL); + file->data = (*value); + (*value) = (char *)file; + } + else + { + (*value) = NULL; + } + } + + dsize -= (temp_sp - sp); + sp = temp_sp; + return 1; + } + else + { + sp=NULL; + return -1; + } + } + + dp = (*name) = sp; + while(1) { + ch = *sp++; + switch(ch) { + case '+': + *dp++ = ' '; + break; + case '=': + *dp++ = '\0'; + (*value) = dp; + break; + case '&': case '|': + *dp++ = '\0'; + return 1; + case '\0': case EOF: + *dp = '\0'; + sp=NULL; + return 0; + case '%': + ch = *sp++; ch1 = *sp++; + *dp++ = xtoc(ch, ch1); + break; + default: + *dp++=ch; + break; + } + } +} + |