00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00149 #ifndef DISABLE_CGI
00150
00151 #ifdef ENABLE_FASTCGI
00152 #include "fcgi_stdio.h"
00153 #else
00154 #include <stdio.h>
00155 #endif
00156 #include <stdlib.h>
00157 #include <stdbool.h>
00158 #include <string.h>
00159 #include <unistd.h>
00160 #include <sys/types.h>
00161 #include <sys/stat.h>
00162 #include <fcntl.h>
00163 #ifndef _WIN32
00164 #include <dirent.h>
00165 #endif
00166 #include "qDecoder.h"
00167 #include "qInternal.h"
00168
00169
00170
00171
00172 static int _parse_multipart(Q_ENTRY *request);
00173 static char *_parse_multipart_value_into_memory(char *boundary, int *valuelen, bool *finish);
00174 static char *_parse_multipart_value_into_disk(const char *boundary, const char *savedir, const char *filename, int *filelen, bool *finish);
00175
00176 static char *_upload_getsavedir(char *upload_savedir, int size, const char *upload_id, const char *upload_basepath);
00177 static void _upload_progressbar(Q_ENTRY *request, const char *upload_id, const char *upload_basepath);
00178 static bool _upload_getstatus(const char *upload_id, const char *upload_basepath, int *upload_tsize, int *upload_csize, char *upload_cname, int upload_cname_size);
00179 static bool _upload_clear_savedir(char *dirpath);
00180 static bool _upload_clear_base(const char *upload_basepath, int upload_clearold);
00181
00202 Q_ENTRY *qCgiRequestParseOption(bool filemode, const char *basepath, int clearold) {
00203
00204 Q_ENTRY *request = qEntryInit();
00205 if(request == NULL) return NULL;
00206
00207 if(filemode == true) {
00208 if(basepath == NULL || qFileExist(basepath) == false) {
00209 qEntryFree(request);
00210 return NULL;
00211 }
00212 qEntryPutStr(request, "_Q_UPLOAD_BASEPATH", basepath, true);
00213 qEntryPutInt(request, "_Q_UPLOAD_CLEAROLD", clearold, true);
00214 }
00215
00216 return request;
00217 }
00218
00237 Q_ENTRY *qCgiRequestParse(Q_ENTRY *request) {
00238
00239 if(request == NULL) {
00240 request = qEntryInit();
00241 if(request == NULL) return NULL;
00242 }
00243
00244 qCgiRequestParseCookies(request);
00245 qCgiRequestParseQueries(request, NULL);
00246
00247 return request;
00248 }
00249
00268 Q_ENTRY *qCgiRequestParseQueries(Q_ENTRY *request, const char *method) {
00269
00270 if(request == NULL) {
00271 request = qEntryInit();
00272 if(request == NULL) return NULL;
00273 }
00274
00275 if(method == NULL || !strcmp(method, "GET")) {
00276 char *query = qCgiRequestGetQueryString("GET");
00277 if(query != NULL) {
00278 qDecodeQueryString(request, query, '=', '&', NULL);
00279 free(query);
00280 }
00281
00282
00283 const char *upload_id = qEntryGetStr(request, "Q_UPLOAD_ID");
00284 if (upload_id != NULL) {
00285 const char *upload_basepath = qEntryGetStr(request, "_Q_UPLOAD_BASEPATH");
00286 if (upload_basepath != NULL) {
00287 _upload_progressbar(request, upload_id, upload_basepath);
00288 exit(EXIT_SUCCESS);
00289 } else {
00290 DEBUG("Force to switch to memory operation mode.");
00291 }
00292 }
00293 }
00294
00295 if(method == NULL || !strcmp(method, "POST")) {
00296 const char *content_type = qSysGetEnv("CONTENT_TYPE", "");
00297 if (!strncmp(content_type, "application/x-www-form-urlencoded", CONST_STRLEN("application/x-www-form-urlencoded"))) {
00298 char *query = qCgiRequestGetQueryString("POST");
00299 if(query != NULL) {
00300 qDecodeQueryString(request, query, '=', '&', NULL);
00301 free(query);
00302 }
00303 } else if (!strncmp(content_type, "multipart/form-data", CONST_STRLEN("multipart/form-data"))) {
00304 _parse_multipart(request);
00305 }
00306 }
00307
00308 return request;
00309 }
00310
00324 Q_ENTRY *qCgiRequestParseCookies(Q_ENTRY *request) {
00325
00326 if(request == NULL) {
00327 request = qEntryInit();
00328 if(request == NULL) return NULL;
00329 }
00330
00331
00332 char *query = qCgiRequestGetQueryString("COOKIE");
00333 if(query != NULL) {
00334 qDecodeQueryString(request, query, '=', ';', NULL);
00335 free(query);
00336 }
00337
00338 return request;
00339 }
00340
00356 char *qCgiRequestGetQueryString(const char *query_type) {
00357 if (!strcmp(query_type, "GET")) {
00358 char *request_method = getenv("REQUEST_METHOD");
00359 if (request_method != NULL && strcmp(request_method, "GET")) return NULL;
00360
00361 char *query_string = getenv("QUERY_STRING");
00362 char *req_uri = getenv("REQUEST_URI");
00363 if (query_string == NULL) return NULL;
00364
00365 char *query = NULL;
00366
00367 if (strlen(query_string) == 0 && req_uri != NULL) {
00368 char *cp;
00369 for (cp = req_uri; *cp != '\0'; cp++) {
00370 if (*cp == '?') {
00371 cp++;
00372 break;
00373 }
00374 }
00375 query = strdup(cp);
00376 } else {
00377 query = strdup(query_string);
00378 }
00379
00380 return query;
00381 } else if (!strcmp(query_type, "POST")) {
00382 char *request_method = getenv("REQUEST_METHOD");
00383 char *content_length = getenv("CONTENT_LENGTH");
00384 if (request_method == NULL || strcmp(request_method, "POST") || content_length == NULL) return NULL;
00385
00386 int i, cl = atoi(content_length);
00387 char *query = (char *)malloc(sizeof(char) * (cl + 1));
00388 for (i = 0; i < cl; i++)query[i] = fgetc(stdin);
00389 query[i] = '\0';
00390 return query;
00391 } else if (!strcmp(query_type, "COOKIE")) {
00392 char *http_cookie = getenv("HTTP_COOKIE");
00393 if (http_cookie == NULL) return NULL;
00394 char *query = strdup(http_cookie);
00395 return query;
00396 }
00397
00398 return NULL;
00399 }
00400
00401
00402 static int _parse_multipart(Q_ENTRY *request) {
00403 #ifdef _WIN32
00404 setmode(fileno(stdin), _O_BINARY);
00405 setmode(fileno(stdout), _O_BINARY);
00406 #endif
00407
00408 char buf[MAX_LINEBUF];
00409 int amount = 0;
00410
00411
00412
00413
00414
00415
00416 char boundary[256];
00417 int maxboundarylen = CONST_STRLEN("--");
00418 maxboundarylen += strlen(strstr(getenv("CONTENT_TYPE"), "boundary=") + CONST_STRLEN("boundary="));
00419 maxboundarylen += CONST_STRLEN("--");
00420 maxboundarylen += CONST_STRLEN("\r\n");
00421 if (maxboundarylen >= sizeof(boundary)) {
00422 DEBUG("The boundary string is too long(Overflow Attack?). stopping process.");
00423 return amount;
00424 }
00425
00426
00427 char boundary_orig[256];
00428 qStrCpy(boundary_orig, sizeof(boundary_orig), strstr(getenv("CONTENT_TYPE"), "boundary=") + CONST_STRLEN("boundary="), sizeof(boundary_orig));
00429 qStrTrim(boundary_orig);
00430 qStrUnchar(boundary_orig, '"', '"');
00431 snprintf(boundary, sizeof(boundary), "--%s", boundary_orig);
00432
00433
00434
00435 if (false) {
00436 int i, j;
00437 qCgiResponseSetContentType(request, "text/html");
00438
00439 printf("Content Length = %s<br>\n", getenv("CONTENT_LENGTH"));
00440 printf("Boundary len %d : %s<br>\n", strlen(boundary), boundary);
00441 for (i = 0; boundary[i] != '\0'; i++) printf("%02X ", boundary[i]);
00442 printf("<p>\n");
00443
00444 for (j = 1; _q_fgets(buf, sizeof(buf), stdin) != NULL; j++) {
00445 printf("Line %d, len %d : %s<br>\n", j, strlen(buf), buf);
00446
00447 printf("<br>\n");
00448 }
00449 exit(EXIT_SUCCESS);
00450 }
00451
00452
00453 if (_q_fgets(buf, sizeof(buf), stdin) == NULL) {
00454 DEBUG("Bbrowser sent a non-HTTP compliant message.");
00455 return amount;
00456 }
00457
00458
00459 if (!strcmp(buf, "\r\n")) _q_fgets(buf, sizeof(buf), stdin);
00460
00461 if (strncmp(buf, boundary, strlen(boundary)) != 0) {
00462 DEBUG("Invalid string format.");
00463 return amount;
00464 }
00465
00466 bool upload_filesave = false;
00467 const char *upload_basepath = qEntryGetStr(request, "_Q_UPLOAD_BASEPATH");
00468 char upload_savedir[MAX_PATHLEN];
00469 bool finish;
00470 for (finish = false; finish == false; amount++) {
00471
00472 while(upload_filesave == false && upload_basepath != NULL && amount == 1) {
00473 char *content_length = getenv("CONTENT_LENGTH");
00474 if(content_length == NULL) {
00475 break;
00476 }
00477
00478 char upload_id_new[32+1];
00479 char *upload_id = (char *)qEntryGetStr(request, "Q_UPLOAD_ID");
00480 if (upload_id == NULL || strlen(upload_id) == 0) {
00481
00482 char *uniq = qStrUnique(getenv("REMOTE_ADDR"));
00483 qStrCpy(upload_id_new, sizeof(upload_id_new), uniq, sizeof(upload_id_new));
00484 free(uniq);
00485 upload_id = upload_id_new;
00486 }
00487
00488
00489 if (_upload_getsavedir(upload_savedir, sizeof(upload_savedir), upload_id, upload_basepath) == NULL) {
00490 DEBUG("Invalid base path %s", upload_basepath);
00491 break;
00492 }
00493
00494
00495 int upload_clearold = qEntryGetInt(request, "_Q_UPLOAD_CLEAROLD");
00496 if (_upload_clear_base(upload_basepath, upload_clearold) == false) {
00497 DEBUG("Can't remove old temporary files at %s", upload_basepath);
00498 }
00499
00500
00501 if (qFileExist(upload_savedir) == true && _upload_clear_savedir(upload_savedir) == false) {
00502 DEBUG("Can not remove temporary uploading directory %s", upload_savedir);
00503 break;
00504 }
00505
00506
00507 if (mkdir(upload_savedir, DEF_DIR_MODE) != 0) {
00508 DEBUG("Can not make temporary uploading directory %s", upload_savedir);
00509 break;
00510 }
00511
00512
00513 char upload_tmppath[MAX_PATHLEN];
00514 snprintf(upload_tmppath, sizeof(upload_tmppath), "%s/Q_UPLOAD_TSIZE", upload_savedir);
00515 if (qCountSave(upload_tmppath, atoi(content_length)) == false) {
00516 DEBUG("Can not save uploading information at %s", upload_tmppath);
00517 break;
00518 }
00519
00520
00521 snprintf(upload_tmppath, sizeof(upload_tmppath), "%s/Q_UPLOAD_START", upload_savedir);
00522 if (qCountSave(upload_tmppath, time(NULL)) == false) {
00523 DEBUG("Can't save uploading information at %s", upload_tmppath);
00524 break;
00525 }
00526
00527
00528 upload_filesave = true;
00529 break;
00530 }
00531
00532 char *name = NULL, *value = NULL, *filename = NULL, *contenttype = NULL;
00533 int valuelen = 0;
00534
00535
00536 while (_q_fgets(buf, sizeof(buf), stdin)) {
00537 if (!strcmp(buf, "\r\n")) break;
00538 else if (!strncasecmp(buf, "Content-Disposition: ", CONST_STRLEN("Content-Disposition: "))) {
00539 int c_count;
00540
00541
00542 name = strdup(buf + CONST_STRLEN("Content-Disposition: form-data; name=\""));
00543 for (c_count = 0; (name[c_count] != '\"') && (name[c_count] != '\0'); c_count++);
00544 name[c_count] = '\0';
00545
00546
00547 if (strstr(buf, "; filename=\"") != NULL) {
00548 int erase;
00549 filename = strdup(strstr(buf, "; filename=\"") + CONST_STRLEN("; filename=\""));
00550 for (c_count = 0; (filename[c_count] != '\"') && (filename[c_count] != '\0'); c_count++);
00551 filename[c_count] = '\0';
00552
00553 for (erase = 0, c_count = strlen(filename) - 1; c_count >= 0; c_count--) {
00554 if (erase == 1) filename[c_count] = ' ';
00555 else {
00556 if (filename[c_count] == '\\') {
00557 erase = 1;
00558 filename[c_count] = ' ';
00559 }
00560 }
00561 }
00562 qStrTrim(filename);
00563
00564 if(strlen(filename) == 0) {
00565 free(filename);
00566 filename = NULL;
00567 }
00568 }
00569 } else if (!strncasecmp(buf, "Content-Type: ", CONST_STRLEN("Content-Type: "))) {
00570 contenttype = strdup(buf + CONST_STRLEN("Content-Type: "));
00571 qStrTrim(contenttype);
00572 }
00573 }
00574
00575
00576 if(name == NULL) {
00577 DEBUG("bug or invalid format.");
00578 continue;
00579 }
00580
00581
00582 if (filename != NULL && upload_filesave == true) {
00583 char *savename = qStrReplace("tn", filename, " ", "_");
00584 value = _parse_multipart_value_into_disk(boundary, upload_savedir, savename, &valuelen, &finish);
00585 free(savename);
00586
00587 if(value != NULL) qEntryPutStr(request, name, value, false);
00588 else qEntryPutStr(request, name, "(parsing failure)", false);
00589 } else {
00590 value = _parse_multipart_value_into_memory(boundary, &valuelen, &finish);
00591
00592 if(value != NULL) qEntryPut(request, name, value, valuelen+1, false);
00593 else qEntryPutStr(request, name, "(parsing failure)", false);
00594 }
00595
00596
00597 if (value != NULL && filename != NULL) {
00598 char ename[255+10+1];
00599
00600
00601 snprintf(ename, sizeof(ename), "%s.length", name);
00602 qEntryPutInt(request, ename, valuelen, false);
00603
00604
00605 snprintf(ename, sizeof(ename), "%s.filename", name);
00606 qEntryPutStr(request, ename, filename, false);
00607
00608
00609 snprintf(ename, sizeof(ename), "%s.contenttype", name);
00610 qEntryPutStr(request, ename, ((contenttype!=NULL)?contenttype:""), false);
00611
00612 if (upload_filesave == true) {
00613 snprintf(ename, sizeof(ename), "%s.savepath", name);
00614 qEntryPutStr(request, ename, value, false);
00615 }
00616 }
00617
00618
00619 if(name != NULL) free(name);
00620 if(value != NULL) free(value);
00621 if(filename != NULL) free(filename);
00622 if(contenttype != NULL) free(contenttype);
00623 }
00624
00625 if (upload_filesave == true) {
00626 char upload_tmppath[MAX_PATHLEN];
00627 snprintf(upload_tmppath, sizeof(upload_tmppath), "%s/Q_UPLOAD_END", upload_savedir);
00628 if (qCountSave(upload_tmppath, time(NULL)) == false) {
00629 DEBUG("Can't save uploading information at %s", upload_tmppath);
00630 }
00631 }
00632
00633 return amount;
00634 }
00635
00636 #define _Q_MULTIPART_CHUNK_SIZE (64 * 1024)
00637 static char *_parse_multipart_value_into_memory(char *boundary, int *valuelen, bool *finish) {
00638 char boundaryEOF[256], rnboundaryEOF[256];
00639 char boundaryrn[256], rnboundaryrn[256];
00640 int boundarylen, boundaryEOFlen;
00641
00642 char *value;
00643 int length;
00644 int c, c_count, mallocsize;
00645
00646
00647 snprintf(boundaryEOF, sizeof(boundaryEOF), "%s--", boundary);
00648 snprintf(rnboundaryEOF, sizeof(rnboundaryEOF), "\r\n%s", boundaryEOF);
00649 snprintf(boundaryrn, sizeof(boundaryrn), "%s\r\n", boundary);
00650 snprintf(rnboundaryrn, sizeof(rnboundaryrn), "\r\n%s\r\n", boundary);
00651
00652 boundarylen = strlen(boundary);
00653 boundaryEOFlen = strlen(boundaryEOF);
00654
00655 for (value = NULL, length = 0, mallocsize = _Q_MULTIPART_CHUNK_SIZE, c_count = 0; (c = fgetc(stdin)) != EOF; ) {
00656 if (c_count == 0) {
00657 value = (char *)malloc(sizeof(char) * mallocsize);
00658 if (value == NULL) {
00659 DEBUG("Memory allocation fail.");
00660 *finish = true;
00661 return NULL;
00662 }
00663 } else if (c_count == mallocsize - 1) {
00664 char *valuetmp;
00665
00666 mallocsize *= 2;
00667
00668
00669 valuetmp = (char *)malloc(sizeof(char) * mallocsize);
00670 if (valuetmp == NULL) {
00671 DEBUG("Memory allocation fail.");
00672 free(value);
00673 *finish = true;
00674 return NULL;
00675 }
00676 memcpy(valuetmp, value, c_count);
00677 free(value);
00678 value = valuetmp;
00679 }
00680 value[c_count++] = (char)c;
00681
00682
00683 if ((c == '\n') || (c == '-')) {
00684 value[c_count] = '\0';
00685
00686 if ((c_count - (2 + boundarylen + 2)) >= 0) {
00687 if (!strcmp(value + (c_count - (2 + boundarylen + 2)), rnboundaryrn)) {
00688 value[c_count - (2 + boundarylen + 2)] = '\0';
00689 length = c_count - (2 + boundarylen + 2);
00690 break;
00691 }
00692 }
00693 if ((c_count - (2 + boundaryEOFlen)) >= 0) {
00694 if (!strcmp(value + (c_count - (2 + boundaryEOFlen)), rnboundaryEOF)) {
00695 value[c_count - (2 + boundaryEOFlen)] = '\0';
00696 length = c_count - (2 + boundaryEOFlen);
00697 *finish = true;
00698 break;
00699 }
00700 }
00701
00702
00703 if ((c_count - (boundarylen + 2)) == 0) {
00704 if (!strcmp(value, boundaryrn)) {
00705 value[0] = '\0';
00706 length = 0;
00707 break;
00708 }
00709 }
00710 if ((c_count - boundaryEOFlen) == 0) {
00711 if (!strcmp(value, boundaryEOF)) {
00712 value[0] = '\0';
00713 length = 0;
00714 *finish = true;
00715 break;
00716 }
00717 }
00718 }
00719 }
00720
00721 if (c == EOF) {
00722 DEBUG("Broken stream.");
00723 if(value != NULL) free(value);
00724 *finish = true;
00725 return NULL;
00726 }
00727
00728 *valuelen = length;
00729 return value;
00730 }
00731
00732 static char *_parse_multipart_value_into_disk(const char *boundary, const char *savedir, const char *filename, int *filelen, bool *finish) {
00733 char boundaryEOF[256], rnboundaryEOF[256];
00734 char boundaryrn[256], rnboundaryrn[256];
00735 int boundarylen, boundaryEOFlen;
00736
00737
00738 char buffer[_Q_MULTIPART_CHUNK_SIZE];
00739 int bufc;
00740 int c;
00741
00742
00743 snprintf(boundaryEOF, sizeof(boundaryEOF), "%s--", boundary);
00744 snprintf(rnboundaryEOF, sizeof(rnboundaryEOF), "\r\n%s", boundaryEOF);
00745 snprintf(boundaryrn, sizeof(boundaryrn), "%s\r\n", boundary);
00746 snprintf(rnboundaryrn, sizeof(rnboundaryrn), "\r\n%s\r\n", boundary);
00747
00748 boundarylen = strlen(boundary);
00749 boundaryEOFlen = strlen(boundaryEOF);
00750
00751
00752 char upload_file[MAX_PATHLEN];
00753 snprintf(upload_file, sizeof(upload_file), "%s/Q_UPLOAD_FILE", savedir);
00754 qFileSave(upload_file, filename, strlen(filename), false);
00755
00756
00757 char upload_path[MAX_PATHLEN];
00758 snprintf(upload_path, sizeof(upload_path), "%s/Q_FILE_XXXXXX", savedir);
00759
00760 int upload_fd = mkstemp(upload_path);
00761 if (upload_fd < 0) {
00762 DEBUG("Can't open file %s", upload_path);
00763 *finish = true;
00764 return NULL;
00765 }
00766
00767
00768 fchmod(upload_fd, DEF_FILE_MODE);
00769
00770
00771 int upload_length;
00772 for (upload_length = 0, bufc = 0, upload_length = 0; (c = fgetc(stdin)) != EOF; ) {
00773 if (bufc == sizeof(buffer) - 1) {
00774
00775 int leftsize = boundarylen + 8;
00776 int savesize = bufc - leftsize;
00777 write(upload_fd, buffer, savesize);
00778 memcpy(buffer, buffer+savesize, leftsize);
00779 bufc = leftsize;
00780 }
00781 buffer[bufc++] = (char)c;
00782 upload_length++;
00783
00784
00785 if ((c == '\n') || (c == '-')) {
00786 buffer[bufc] = '\0';
00787
00788 if ((bufc - (2 + boundarylen + 2)) >= 0) {
00789 if (!strcmp(buffer + (bufc - (2 + boundarylen + 2)), rnboundaryrn)) {
00790 bufc -= (2 + boundarylen + 2);
00791 upload_length -= (2 + boundarylen + 2);
00792 break;
00793 }
00794 }
00795 if ((bufc - (2 + boundaryEOFlen)) >= 0) {
00796 if (!strcmp(buffer + (bufc - (2 + boundaryEOFlen)), rnboundaryEOF)) {
00797 bufc -= (2 + boundaryEOFlen);
00798 upload_length -= (2 + boundaryEOFlen);
00799 *finish = true;
00800 break;
00801 }
00802 }
00803
00804
00805 if (upload_length == bufc) {
00806 if ((bufc - (boundarylen + 2)) == 0) {
00807 if (!strcmp(buffer, boundaryrn)) {
00808 bufc = 0;
00809 upload_length = 0;
00810 break;
00811 }
00812 }
00813 if ((bufc - boundaryEOFlen) == 0) {
00814 if (!strcmp(buffer, boundaryEOF)) {
00815 bufc = 0;
00816 upload_length = 0;
00817 *finish = true;
00818 break;
00819 }
00820 }
00821 }
00822 }
00823 }
00824
00825 if (c == EOF) {
00826 DEBUG("Broken stream.");
00827 *finish = true;
00828 return NULL;
00829 }
00830
00831
00832 write(upload_fd, buffer, bufc);
00833 close(upload_fd);
00834
00835 *filelen = upload_length;
00836
00837 return strdup(upload_path);
00838 }
00839
00840 static char *_upload_getsavedir(char *upload_savedir, int size, const char *upload_id, const char *upload_basepath) {
00841 if(upload_savedir == NULL || upload_id == NULL || upload_basepath == NULL || strlen(upload_basepath) == 0) return NULL;
00842
00843 char md5seed[1024];
00844 snprintf(md5seed, sizeof(md5seed), "%s|%s|%s", QDECODER_PRIVATEKEY, qSysGetEnv("REMOTE_ADDR", ""), upload_id);
00845 char *md5str = qHashMd5Str(md5seed, strlen(md5seed));
00846 snprintf(upload_savedir, size, "%s/Q_%s", upload_basepath, md5str);
00847 free(md5str);
00848
00849 return upload_savedir;
00850 }
00851
00852 static void _upload_progressbar(Q_ENTRY *request, const char *upload_id, const char *upload_basepath) {
00853 int drawrate = qEntryGetInt(request, "Q_UPLOAD_DRAWRATE");
00854 const char *template = qEntryGetStr(request, "Q_UPLOAD_TEMPLATE");
00855
00856 int last_csize = 0, freezetime = 0;
00857 int upload_tsize = 0, upload_csize = 0;
00858 char upload_cname[256];
00859
00860
00861 if(drawrate == 0) drawrate = 1000;
00862 else if(drawrate < 100) drawrate = 100;
00863 else if(drawrate > 3000) drawrate = 3000;
00864
00865
00866 if (!strcmp(upload_id, "")) {
00867 DEBUG("Q_UPLOAD_ID is invalid.");
00868 return;
00869 }
00870 if (template == NULL) {
00871 DEBUG("Q_UPLOAD_TEMPLATE query not found.");
00872 return;
00873 }
00874
00875
00876 qCgiResponseSetContentType(request, "text/html");
00877
00878
00879 if(qSedFile(NULL, template, stdout) == 0) {
00880 DEBUG("Can't open %s", template);
00881 return;
00882 }
00883 if(fflush(stdout) != 0) return;
00884
00885
00886 int failcnt = 0;
00887 while(failcnt < 5) {
00888 upload_tsize = upload_csize = 0;
00889
00890 if(_upload_getstatus(upload_id, upload_basepath, &upload_tsize, &upload_csize, upload_cname, sizeof(upload_cname)) == false) {
00891 failcnt++;
00892 sleep(1);
00893 continue;
00894 }
00895
00896 if(upload_tsize == 0 && upload_csize > 0) break;
00897
00898 if (last_csize < upload_csize) {
00899 qStrReplace("tr", upload_cname, "'", "`");
00900
00901 printf("<script language='JavaScript'>");
00902 printf("if(qSetProgress)qSetProgress(%d,%d,'%s');", upload_tsize, upload_csize, upload_cname);
00903 printf("</script>\n");
00904
00905 last_csize = upload_csize;
00906 freezetime = 0;
00907 } else if (last_csize > upload_csize) {
00908 break;
00909 } else {
00910 if (freezetime > 10000) {
00911 break;
00912 }
00913
00914 if (upload_csize > 0) {
00915 printf("<script language='JavaScript'>");
00916 printf("if(qSetProgress)qSetProgress(%d,%d,'%s');", upload_tsize, upload_csize, upload_cname);
00917 printf("</script>\n");
00918 }
00919
00920 freezetime += drawrate;
00921 }
00922
00923 fflush(stdout);
00924 usleep(drawrate * 1000);
00925 }
00926
00927 printf("<script language='JavaScript'>");
00928 printf("window.close();");
00929 printf("</script>\n");
00930
00931 fflush(stdout);
00932 }
00933
00934 static bool _upload_getstatus(const char *upload_id, const char *upload_basepath, int *upload_tsize, int *upload_csize, char *upload_cname, int upload_cname_size) {
00935 #ifdef _WIN32
00936 return false;
00937 #else
00938 DIR *dp;
00939 struct dirent *dirp;
00940 char upload_savedir[MAX_PATHLEN], tmppath[MAX_PATHLEN];
00941
00942
00943 if (_upload_getsavedir(upload_savedir, sizeof(upload_savedir), upload_id, upload_basepath) == NULL) {
00944 DEBUG("Q_UPLOAD_ID is not set.");
00945 return false;
00946 }
00947
00948
00949 dp = opendir(upload_savedir);
00950 if (dp == NULL) {
00951 DEBUG("Can't open %s", upload_savedir);
00952 return false;
00953 }
00954
00955
00956 snprintf(tmppath, sizeof(tmppath), "%s/Q_UPLOAD_TSIZE", upload_savedir);
00957 *upload_tsize = qCountRead(tmppath);
00958
00959
00960 snprintf(tmppath, sizeof(tmppath), "%s/Q_UPLOAD_FILE", upload_savedir);
00961 char *upload_file = qFileLoad(tmppath, NULL);
00962 if(upload_file != NULL) {
00963 qStrCpy(upload_cname, upload_cname_size, upload_file, upload_cname_size);
00964 free(upload_file);
00965 } else {
00966 qStrCpy(upload_cname, upload_cname_size, "-", upload_cname_size);
00967 }
00968
00969
00970 *upload_csize = 0;
00971 while ((dirp = readdir(dp)) != NULL) {
00972 if (strncmp(dirp->d_name, "Q_FILE_", CONST_STRLEN("Q_FILE_"))) continue;
00973
00974 snprintf(tmppath, sizeof(tmppath), "%s/%s", upload_savedir, dirp->d_name);
00975 *upload_csize += qFileGetSize(tmppath);
00976 }
00977 closedir(dp);
00978
00979 return true;
00980 #endif
00981 }
00982
00983 static bool _upload_clear_savedir(char *dirpath) {
00984 #ifdef _WIN32
00985 return false;
00986 #else
00987
00988 DIR *dp;
00989 if ((dp = opendir(dirpath)) == NULL) return false;
00990
00991 struct dirent *dirp;
00992 while ((dirp = readdir(dp)) != NULL) {
00993 if (strncmp(dirp->d_name, "Q_", CONST_STRLEN("Q_"))) continue;
00994
00995 char filepath[MAX_PATHLEN];
00996 snprintf(filepath, sizeof(filepath), "%s/%s", dirpath, dirp->d_name);
00997 unlink(filepath);
00998 }
00999 closedir(dp);
01000
01001 if (rmdir(dirpath) != 0) return false;
01002 return true;
01003 #endif
01004 }
01005
01006 static bool _upload_clear_base(const char *upload_basepath, int upload_clearold) {
01007 #ifdef _WIN32
01008 return false;
01009 #else
01010 if (upload_clearold <= 0) return false;
01011
01012 bool haserror = false;
01013
01014
01015 DIR *dp;
01016 if ((dp = opendir(upload_basepath)) == NULL) return false;
01017
01018 time_t now = time(NULL);
01019 struct dirent *dirp;
01020 while ((dirp = readdir(dp)) != NULL) {
01021 time_t starttime;
01022
01023 if (!strcmp(dirp->d_name, ".") || !strcmp(dirp->d_name, "..") || strncmp(dirp->d_name, "Q_", 2) != 0) continue;
01024
01025 char filepath[MAX_PATHLEN];
01026 snprintf(filepath, sizeof(filepath), "%s/%s/Q_UPLOAD_START", upload_basepath, dirp->d_name);
01027 starttime = qCountRead(filepath);
01028 if (starttime > 0 && now - starttime < upload_clearold) continue;
01029
01030 snprintf(filepath, sizeof(filepath), "%s/%s", upload_basepath, dirp->d_name);
01031 if (_upload_clear_savedir(filepath) == false) {
01032 haserror = true;
01033 break;
01034 }
01035 }
01036 closedir(dp);
01037
01038 if(haserror == true) return false;
01039 return true;
01040 #endif
01041 }
01042
01043 #endif