diff options
author | Xavier Roche <xroche@users.noreply.github.com> | 2013-05-14 20:30:28 +0000 |
---|---|---|
committer | Xavier Roche <xroche@users.noreply.github.com> | 2013-05-14 20:30:28 +0000 |
commit | 07f4b003675260004c49755dde413944a16ca2d3 (patch) | |
tree | 11050b4c7fbe1d7c63a38f5f9a6b5ba6d8260ae1 /src/proxy | |
parent | b09def438c5e47305e4a5ab18d8a646a3b004fdc (diff) |
Indenting cleanup for all *.[ch] files, except htsparse.c (too ugly to be automatically indented for now) and /minizip/, /mmsrip/ (external files)
setup:
indent -l80 -lc80 -nhnl -nut -bad -bap -bbo -br -brf -bli2 -brs -bls -br -ss -sai -pmt -nsaw -nsaf -nprs -i2 -ce -npsl -npcs -cs -sob -cdw -nbc -lp
logs:
indent: ./src/htsback.c:157: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsback.c:1417: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsback.c:1826: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsback.c:1833: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsback.c:1981: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsback.c:2685: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsback.c:2747: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsback.c:2861: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsback.c:3128: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsback.c:3512: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htswizard.c:140: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htswizard.c:597: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htswizard.c:598: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htswizard.c:611: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htscoremain.c:97: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htscoremain.c:106: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htscoremain.c:106: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htscoremain.c:256: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htscoremain.c:262: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htscoremain.c:935: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/httrack.c:271: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/httrack.c:272: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/httrack.c:273: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/httrack.c:274: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/httrack.c:275: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/httrack.c:276: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/httrack.c:277: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/httrack.c:278: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/httrack.c:279: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/httrack.c:280: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/httrack.c:281: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/httrack.c:662: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/httrack.c:752: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsweb.c:413: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsweb.c:414: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsweb.c:415: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsweb.c:416: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsweb.c:417: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsweb.c:418: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsweb.c:419: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsweb.c:420: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsweb.c:421: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsweb.c:422: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsweb.c:423: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.c:188: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.c:507: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.c:508: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.c:509: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.c:510: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.c:511: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.c:512: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.c:580: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.c:581: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.h:115: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.h:246: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.h:247: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.h:248: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.h:249: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.h:250: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.h:251: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.h:314: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/proxy/proxytrack.h:315: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htstools.c:151: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htstools.c:158: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htstools.c:161: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htstools.c:166: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htstools.c:174: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htstools.c:177: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htstools.c:188: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htstools.c:243: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htstools.c:245: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htstools.c:248: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htstools.c:257: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htstools.c:647: Warning:old style assignment ambiguity in "=*". Assuming "= *"
indent: ./src/htsbauth.c:364: Warning:old style assignment ambiguity in "=&". Assuming "= &"
indent: ./src/htsbauth.c:387: Warning:old style assignment ambiguity in "=&". Assuming "= &"
indent: ./src/htscache.c:473: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsserver.h:112: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsserver.h:187: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsjava.c:312: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsjava.c:379: Warning:old style assignment ambiguity in "=&". Assuming "= &"
indent: ./src/htsjava.c:407: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsjava.c:472: Warning:old style assignment ambiguity in "=&". Assuming "= &"
indent: ./src/htsjava.c:483: Warning:old style assignment ambiguity in "=*". Assuming "= *"
indent: ./src/htslib.c:593: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:809: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:1743: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:1874: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:1896: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:1984: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:2085: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:2604: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:2605: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:2606: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:2607: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:2608: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:2609: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:2672: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:2673: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:2906: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:2928: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:2996: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:4802: Warning:old style assignment ambiguity in "=&". Assuming "= &"
indent: ./src/htslib.c:5353: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:5354: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:5355: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:5357: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:5429: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htslib.c:5435: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htscore.c:208: Warning:old style assignment ambiguity in "=&". Assuming "= &"
indent: ./src/htscore.c:277: Warning:old style assignment ambiguity in "=&". Assuming "= &"
indent: ./src/htscore.c:279: Warning:old style assignment ambiguity in "=&". Assuming "= &"
indent: ./src/htscore.c:357: Warning:old style assignment ambiguity in "=*". Assuming "= *"
indent: ./src/htscore.c:394: Warning:old style assignment ambiguity in "=*". Assuming "= *"
indent: ./src/htscore.c:1544: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htscore.c:3330: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htscore.c:3361: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htshash.c:140: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htshash.c:217: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsname.c:733: Warning:old style assignment ambiguity in "=*". Assuming "= *"
indent: ./src/htsname.c:749: Warning:old style assignment ambiguity in "=*". Assuming "= *"
indent: ./src/htsname.c:933: Warning:old style assignment ambiguity in "=*". Assuming "= *"
indent: ./src/htsname.c:1520: Warning:old style assignment ambiguity in "=*". Assuming "= *"
indent: ./src/htszlib.c:76: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htszlib.c:81: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htscatchurl.c:268: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsinthash.c:156: Warning:old style assignment ambiguity in "=&". Assuming "= &"
indent: ./src/htsinthash.c:159: Warning:old style assignment ambiguity in "=&". Assuming "= &"
indent: ./src/htsinthash.c:176: Warning:old style assignment ambiguity in "=&". Assuming "= &"
indent: ./src/htsinthash.c:179: Warning:old style assignment ambiguity in "=&". Assuming "= &"
indent: ./src/htsinthash.c:226: Warning:old style assignment ambiguity in "=&". Assuming "= &"
indent: ./src/htsinthash.c:253: Warning:old style assignment ambiguity in "=&". Assuming "= &"
indent: ./src/htsftp.c:169: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsftp.c:177: Warning:old style assignment ambiguity in "=-". Assuming "= -"
indent: ./src/htsfilters.c:67: Warning:old style assignment ambiguity in "=*". Assuming "= *"
indent: ./src/htsfilters.c:80: Warning:old style assignment ambiguity in "=*". Assuming "= *"
Diffstat (limited to 'src/proxy')
-rw-r--r-- | src/proxy/main.c | 219 | ||||
-rwxr-xr-x | src/proxy/proxystrings.h | 81 | ||||
-rw-r--r-- | src/proxy/proxytrack.c | 2492 | ||||
-rw-r--r-- | src/proxy/proxytrack.h | 328 | ||||
-rw-r--r-- | src/proxy/store.c | 3554 | ||||
-rw-r--r-- | src/proxy/store.h | 60 |
6 files changed, 3523 insertions, 3211 deletions
diff --git a/src/proxy/main.c b/src/proxy/main.c index bb81810..8bce9bb 100644 --- a/src/proxy/main.c +++ b/src/proxy/main.c @@ -40,45 +40,47 @@ Please visit our Website: http://www.httrack.com #ifndef _WIN32 #include <signal.h> -static void sig_brpipe( int code ) { +static void sig_brpipe(int code) { /* ignore */ } #endif -static int scanHostPort(const char* str, char *host, int *port) { - char* pos = strrchr(str, ':'); - if (pos != NULL) { - int n = (int) ( pos - str ); - if (n < 256) { - host[0] = '\0'; - strncat(host, str, n); - if (sscanf(pos + 1, "%d", port) == 1) { - return 1; - } - } - } - return 0; +static int scanHostPort(const char *str, char *host, int *port) { + char *pos = strrchr(str, ':'); + + if (pos != NULL) { + int n = (int) (pos - str); + + if (n < 256) { + host[0] = '\0'; + strncat(host, str, n); + if (sscanf(pos + 1, "%d", port) == 1) { + return 1; + } + } + } + return 0; } -int main(int argc, char* argv[]) -{ +int main(int argc, char *argv[]) { int i; int ret = 0; - int proxyPort = 0, icpPort = 0; - char proxyAddr[256 + 1], icpAddr[256 + 1]; - PT_Indexes index; + int proxyPort = 0, icpPort = 0; + char proxyAddr[256 + 1], icpAddr[256 + 1]; + PT_Indexes index; #ifdef _WIN32 { - WORD wVersionRequested; // requested version WinSock API + WORD wVersionRequested; // requested version WinSock API WSADATA wsadata; // Windows Sockets API data int stat; + wVersionRequested = 0x0101; - stat = WSAStartup( wVersionRequested, &wsadata ); + stat = WSAStartup(wVersionRequested, &wsadata); if (stat != 0) { fprintf(stderr, "Winsock not found!\n"); return -1; - } else if (LOBYTE(wsadata.wVersion) != 1 && HIBYTE(wsadata.wVersion) != 1) { + } else if (LOBYTE(wsadata.wVersion) != 1 && HIBYTE(wsadata.wVersion) != 1) { fprintf(stderr, "WINSOCK.DLL does not support version 1.1\n"); WSACleanup(); return -1; @@ -86,93 +88,103 @@ int main(int argc, char* argv[]) } #endif - /* Args */ - printf("ProxyTrack %s, build proxies upon HTTrack Website Copier Archives\n", PROXYTRACK_VERSION); - printf("Copyright (C) Xavier Roche and other contributors\n"); - printf("\n"); - printf("This program is free software; you can redistribute it and/or\n"); - printf("modify it under the terms of the GNU General Public License\n"); - printf("as published by the Free Software Foundation; either version 3\n"); - printf("of the License, or any later version.\n"); - printf("\n"); - printf("*** This version is a development release ***\n"); - printf("\n"); - if (argc < 3 - || ( - strcmp(argv[1], "--convert") != 0 - && - ( - !scanHostPort(argv[1], proxyAddr, &proxyPort) - || !scanHostPort(argv[2], icpAddr, &icpPort) - ) - ) - ) - { - fprintf(stderr, "proxy mode:\n"); - fprintf(stderr, "usage: %s <proxy-addr:proxy-port> <ICP-addr:ICP-port> [ ( <new.zip path> | <new.ndx path> | <archive.arc path> | --list <file-list> ) ..]\n", argv[0]); - fprintf(stderr, "\texample:%s proxy:8080 localhost:3130 /home/archives/www-archive-01.zip /home/old-archives/www-archive-02.ndx\n", argv[0]); - fprintf(stderr, "convert mode:\n"); - fprintf(stderr, "usage: %s --convert <archive-output-path> [ ( <new.zip path> | <new.ndx path> | <archive.arc path> | --list <file-list> ) ..]\n", argv[0]); - fprintf(stderr, "\texample:%s proxy:8080 localhost:3130 /home/archives/www-archive-01.zip /home/old-archives/www-archive-02.ndx\n", argv[0]); + /* Args */ + printf("ProxyTrack %s, build proxies upon HTTrack Website Copier Archives\n", + PROXYTRACK_VERSION); + printf("Copyright (C) Xavier Roche and other contributors\n"); + printf("\n"); + printf("This program is free software; you can redistribute it and/or\n"); + printf("modify it under the terms of the GNU General Public License\n"); + printf("as published by the Free Software Foundation; either version 3\n"); + printf("of the License, or any later version.\n"); + printf("\n"); + printf("*** This version is a development release ***\n"); + printf("\n"); + if (argc < 3 + || (strcmp(argv[1], "--convert") != 0 + && (!scanHostPort(argv[1], proxyAddr, &proxyPort) + || !scanHostPort(argv[2], icpAddr, &icpPort) + ) + ) + ) { + fprintf(stderr, "proxy mode:\n"); + fprintf(stderr, + "usage: %s <proxy-addr:proxy-port> <ICP-addr:ICP-port> [ ( <new.zip path> | <new.ndx path> | <archive.arc path> | --list <file-list> ) ..]\n", + argv[0]); + fprintf(stderr, + "\texample:%s proxy:8080 localhost:3130 /home/archives/www-archive-01.zip /home/old-archives/www-archive-02.ndx\n", + argv[0]); + fprintf(stderr, "convert mode:\n"); + fprintf(stderr, + "usage: %s --convert <archive-output-path> [ ( <new.zip path> | <new.ndx path> | <archive.arc path> | --list <file-list> ) ..]\n", + argv[0]); + fprintf(stderr, + "\texample:%s proxy:8080 localhost:3130 /home/archives/www-archive-01.zip /home/old-archives/www-archive-02.ndx\n", + argv[0]); return 1; } - index = PT_New(); - for(i = 3 ; i < argc ; i++) { - if (argv[i][0] == '-') { - if (strcmp(argv[i], "--list") == 0) { - if (i + 1 < argc) { - char line[256 + 1]; - FILE *fp = fopen(argv[++i], "rb"); - if (fp == NULL) { - fprintf(stderr, "error: could not process list %s\n", argv[i]); - exit(1); - } - while(linput(fp, line, 256)) { - int itemsAdded = PT_AddIndex(index, line); - if (itemsAdded > 0) { - fprintf(stderr, "processed: %s (%d items added)\n", line, itemsAdded); - } else if (itemsAdded == 0) { - fprintf(stderr, "processed: %s (no items added)\n", line); - } else { - fprintf(stderr, "error: could not process %s\n", line); - } - } - fclose(fp); - } - } else { - fprintf(stderr, "* bad arg %s\n", argv[i]); - exit(1); - } - } else { - int itemsAdded = PT_AddIndex(index, argv[i]); - if (itemsAdded > 0) { - fprintf(stderr, "processed: %s (%d items added)\n", argv[i], itemsAdded); - } else if (itemsAdded == 0) { - fprintf(stderr, "processed: %s (no items added)\n", argv[i]); - } else { - fprintf(stderr, "error: could not process %s\n", argv[i]); - } - } - } - - /* sigpipe */ + index = PT_New(); + for(i = 3; i < argc; i++) { + if (argv[i][0] == '-') { + if (strcmp(argv[i], "--list") == 0) { + if (i + 1 < argc) { + char line[256 + 1]; + FILE *fp = fopen(argv[++i], "rb"); + + if (fp == NULL) { + fprintf(stderr, "error: could not process list %s\n", argv[i]); + exit(1); + } + while(linput(fp, line, 256)) { + int itemsAdded = PT_AddIndex(index, line); + + if (itemsAdded > 0) { + fprintf(stderr, "processed: %s (%d items added)\n", line, + itemsAdded); + } else if (itemsAdded == 0) { + fprintf(stderr, "processed: %s (no items added)\n", line); + } else { + fprintf(stderr, "error: could not process %s\n", line); + } + } + fclose(fp); + } + } else { + fprintf(stderr, "* bad arg %s\n", argv[i]); + exit(1); + } + } else { + int itemsAdded = PT_AddIndex(index, argv[i]); + + if (itemsAdded > 0) { + fprintf(stderr, "processed: %s (%d items added)\n", argv[i], + itemsAdded); + } else if (itemsAdded == 0) { + fprintf(stderr, "processed: %s (no items added)\n", argv[i]); + } else { + fprintf(stderr, "error: could not process %s\n", argv[i]); + } + } + } + + /* sigpipe */ #ifndef _WIN32 - signal( SIGPIPE , sig_brpipe ); // broken pipe (write into non-opened socket) + signal(SIGPIPE, sig_brpipe); // broken pipe (write into non-opened socket) #endif /* Go */ - if (strcmp(argv[1], "--convert") != 0) { - ret = proxytrack_main(proxyAddr, proxyPort, icpAddr, icpPort, index); - } else { - if ((ret = PT_SaveCache(index, argv[2])) == 0) { - fprintf(stderr, "processed: '%s'\n", argv[2]); - } else { - fprintf(stderr, "error: could not save '%s'\n", argv[2]); - } - } - - /* Wipe */ - PT_Delete(index); + if (strcmp(argv[1], "--convert") != 0) { + ret = proxytrack_main(proxyAddr, proxyPort, icpAddr, icpPort, index); + } else { + if ((ret = PT_SaveCache(index, argv[2])) == 0) { + fprintf(stderr, "processed: '%s'\n", argv[2]); + } else { + fprintf(stderr, "error: could not save '%s'\n", argv[2]); + } + } + + /* Wipe */ + PT_Delete(index); #ifdef _WIN32 WSACleanup(); @@ -180,4 +192,3 @@ int main(int argc, char* argv[]) return ret; } - diff --git a/src/proxy/proxystrings.h b/src/proxy/proxystrings.h index 23456a7..09d0f9f 100755 --- a/src/proxy/proxystrings.h +++ b/src/proxy/proxystrings.h @@ -20,7 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Please visit our Website: http://www.httrack.com */ - /* ------------------------------------------------------------ */ /* File: Strings */ /* Author: Xavier Roche */ @@ -29,89 +28,93 @@ Please visit our Website: http://www.httrack.com // Strings a bit safer than static buffers #ifndef HTS_PROXYSTRINGS_DEFSTATIC -#define HTS_PROXYSTRINGS_DEFSTATIC +#define HTS_PROXYSTRINGS_DEFSTATIC #include "htsstrings.h" - /* Tools */ static int ehexh(char c) { - if ((c>='0') && (c<='9')) return c-'0'; - if ((c>='a') && (c<='f')) c-=('a'-'A'); - if ((c>='A') && (c<='F')) return (c-'A'+10); + if ((c >= '0') && (c <= '9')) + return c - '0'; + if ((c >= 'a') && (c <= 'f')) + c -= ('a' - 'A'); + if ((c >= 'A') && (c <= 'F')) + return (c - 'A' + 10); return 0; } -static int ehex(const char* s) { - return 16*ehexh(*s)+ehexh(*(s+1)); +static int ehex(const char *s) { + return 16 * ehexh(*s) + ehexh(*(s + 1)); } -static void unescapehttp(const char* s, String* tempo) { +static void unescapehttp(const char *s, String * tempo) { int i; - for (i = 0; s[i] != '\0' ; i++) { - if (s[i]=='%' && s[i+1]=='%') { + + for(i = 0; s[i] != '\0'; i++) { + if (s[i] == '%' && s[i + 1] == '%') { i++; StringAddchar(*tempo, '%'); - } else if (s[i]=='%') { + } else if (s[i] == '%') { char hc; + i++; - hc = (char) ehex(s+i); + hc = (char) ehex(s + i); StringAddchar(*tempo, (char) hc); - i++; // sauter 2 caractères finalement - } - else if (s[i]=='+') { + i++; // sauter 2 caractères finalement + } else if (s[i] == '+') { StringAddchar(*tempo, ' '); - } - else + } else StringAddchar(*tempo, s[i]); } } -static void escapexml(const char* s, String* tempo) { +static void escapexml(const char *s, String * tempo) { int i; - for (i=0 ; s[i] != '\0' ; i++) { + + for(i = 0; s[i] != '\0'; i++) { if (s[i] == '&') StringCat(*tempo, "&"); - else if (s[i] == '<') + else if (s[i] == '<') StringCat(*tempo, "<"); - else if (s[i] == '>') + else if (s[i] == '>') StringCat(*tempo, ">"); - else if (s[i] == '\"') + else if (s[i] == '\"') StringCat(*tempo, """); else StringAddchar(*tempo, s[i]); } } -static char* concat(char *catbuff,const char* a,const char* b) { - if (a != NULL && a[0] != '\0') { - strcpy(catbuff, a); - } else { - catbuff[0] = '\0'; - } - if (b != NULL && b[0] != '\0') { - strcat(catbuff, b); - } +static char *concat(char *catbuff, const char *a, const char *b) { + if (a != NULL && a[0] != '\0') { + strcpy(catbuff, a); + } else { + catbuff[0] = '\0'; + } + if (b != NULL && b[0] != '\0') { + strcat(catbuff, b); + } return catbuff; } -static char* __fconv(char* a) { +static char *__fconv(char *a) { #ifdef WIN32 int i; - for(i = 0 ; a[i] != 0 ; i++) - if (a[i] == '/') // Unix-to-DOS style + + for(i = 0; a[i] != 0; i++) + if (a[i] == '/') // Unix-to-DOS style a[i] = '\\'; #endif return a; } -static char* fconcat(char *catbuff, const char* a, const char* b) { - return __fconv(concat(catbuff,a,b)); +static char *fconcat(char *catbuff, const char *a, const char *b) { + return __fconv(concat(catbuff, a, b)); } -static char* fconv(char *catbuff, const char* a) { - return __fconv(concat(catbuff,a,"")); +static char *fconv(char *catbuff, const char *a) { + return __fconv(concat(catbuff, a, "")); } #endif diff --git a/src/proxy/proxytrack.c b/src/proxy/proxytrack.c index ded2e13..e78f457 100644 --- a/src/proxy/proxytrack.c +++ b/src/proxy/proxytrack.c @@ -25,7 +25,6 @@ Please visit our Website: http://www.httrack.com /* Author: Xavier Roche */ /* ------------------------------------------------------------ */ - /* /\/\/\/\/\/\/\/\/\/\/\/\/\ PENDING WORK /\/\/\/\/\/\/\/\/\/\/\/\/\ @@ -45,7 +44,6 @@ Aim: Building a sub-proxy to be linked with other top level proxies (such as Squ Basic design: Classical HTTP/1.0 proxy server, with ICP server support Internal data design: HTTrack cache indexing in fast hashtables, with 'pluggable' design (add/removal of caches on-the-fly) - Index structure organization: ----------------------------- @@ -59,7 +57,6 @@ Indexes are hashtables with URL (STRING) -> INTEGER lookup. URL -----> CIL Ask for index ID URL -----> Index[ID] Ask for index properties (ZIP cache index) - Lookup of an entry: ------------------- @@ -70,7 +67,6 @@ Else return FAILURE EndIf - Fetching of an entry: --------------------- @@ -83,7 +79,6 @@ If ID is valid Then EndIf EndIf - Removal of index N: ------------------- @@ -94,7 +89,6 @@ For all entries in Index[N] Done Delete Index[N] - Adding of index N: ------------------ @@ -146,65 +140,81 @@ Remark: If no cache newer than the added one is found, all entries can be added /* threads */ #ifdef _WIN32 -#include <process.h> /* _beginthread, _endthread */ +#include <process.h> /* _beginthread, _endthread */ #else #include <pthread.h> #endif /* External references */ // htsErrorCallback htsCallbackErr = NULL; -int htsMemoryFastXfr = 1; /* fast xfr by default */ -void abortLog__fnc(char* msg, char* file, int line); -void abortLog__fnc(char* msg, char* file, int line) { - FILE* fp = fopen("CRASH.TXT", "wb"); - if (!fp) fp = fopen("/tmp/CRASH.TXT", "wb"); - if (!fp) fp = fopen("C:\\CRASH.TXT", "wb"); - if (!fp) fp = fopen("CRASH.TXT", "wb"); +int htsMemoryFastXfr = 1; /* fast xfr by default */ +void abortLog__fnc(char *msg, char *file, int line); +void abortLog__fnc(char *msg, char *file, int line) { + FILE *fp = fopen("CRASH.TXT", "wb"); + + if (!fp) + fp = fopen("/tmp/CRASH.TXT", "wb"); + if (!fp) + fp = fopen("C:\\CRASH.TXT", "wb"); + if (!fp) + fp = fopen("CRASH.TXT", "wb"); if (fp) { - fprintf(fp, "HTTrack " HTTRACK_VERSIONID " closed at '%s', line %d\r\n", file, line); + fprintf(fp, "HTTrack " HTTRACK_VERSIONID " closed at '%s', line %d\r\n", + file, line); fprintf(fp, "Reason:\r\n%s\r\n", msg); fflush(fp); fclose(fp); } } + // HTSEXT_API t_abortLog abortLog__ = abortLog__fnc; /* avoid VC++ inlining */ #define webhttrack_lock(A) do{}while(0) /* Static definitions */ -static int linputsoc(T_SOC soc, char* s, int max) { +static int linputsoc(T_SOC soc, char *s, int max) { int c; - int j=0; + int j = 0; + do { unsigned char ch; + if (recv(soc, &ch, 1, 0) == 1) { c = ch; } else { c = EOF; } - if (c!=EOF) { - switch(c) { - case 13: break; // sauter CR - case 10: c=-1; break; - case 9: case 12: break; // sauter ces caractères - default: s[j++]=(char) c; break; + if (c != EOF) { + switch (c) { + case 13: + break; // sauter CR + case 10: + c = -1; + break; + case 9: + case 12: + break; // sauter ces caractères + default: + s[j++] = (char) c; + break; } } - } while((c!=-1) && (c!=EOF) && (j<(max-1))); - s[j]='\0'; + } while((c != -1) && (c != EOF) && (j < (max - 1))); + s[j] = '\0'; return j; } static int check_readinput_t(T_SOC soc, int timeout) { if (soc != INVALID_SOCKET) { - fd_set fds; // poll structures + fd_set fds; // poll structures struct timeval tv; // structure for select + FD_ZERO(&fds); - FD_SET(soc,&fds); - tv.tv_sec=timeout; - tv.tv_usec=0; - select((int)(soc + 1),&fds,NULL,NULL,&tv); - if (FD_ISSET(soc,&fds)) + FD_SET(soc, &fds); + tv.tv_sec = timeout; + tv.tv_usec = 0; + select((int) (soc + 1), &fds, NULL, NULL, &tv); + if (FD_ISSET(soc, &fds)) return 1; else return 0; @@ -212,102 +222,107 @@ static int check_readinput_t(T_SOC soc, int timeout) { return 0; } -static int linputsoc_t(T_SOC soc, char* s, int max, int timeout) { +static int linputsoc_t(T_SOC soc, char *s, int max, int timeout) { if (check_readinput_t(soc, timeout)) { return linputsoc(soc, s, max); } return -1; } -static int gethost(const char* hostname, SOCaddr *server, size_t server_size) { +static int gethost(const char *hostname, SOCaddr * server, size_t server_size) { if (hostname != NULL && *hostname != '\0') { #if HTS_INET6==0 - /* - ipV4 resolver - */ - t_hostent* hp=gethostbyname(hostname); - if (hp!=NULL) { - if (hp->h_length) { - SOCaddr_copyaddr(*server, server_size, hp->h_addr_list[0], hp->h_length); - return 1; - } - } + /* + ipV4 resolver + */ + t_hostent *hp = gethostbyname(hostname); + + if (hp != NULL) { + if (hp->h_length) { + SOCaddr_copyaddr(*server, server_size, hp->h_addr_list[0], + hp->h_length); + return 1; + } + } #else - /* - ipV6 resolver - */ - struct addrinfo* res = NULL; - struct addrinfo hints; - memset(&hints, 0, sizeof(hints)); + /* + ipV6 resolver + */ + struct addrinfo *res = NULL; + struct addrinfo hints; + + memset(&hints, 0, sizeof(hints)); #if 0 - if (IPV6_resolver == 1) // V4 only (for bogus V6 entries) - hints.ai_family = PF_INET; - else if (IPV6_resolver == 2) // V6 only (for testing V6 only) - hints.ai_family = PF_INET6; - else + if (IPV6_resolver == 1) // V4 only (for bogus V6 entries) + hints.ai_family = PF_INET; + else if (IPV6_resolver == 2) // V6 only (for testing V6 only) + hints.ai_family = PF_INET6; + else #endif - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - if (getaddrinfo(hostname, NULL, &hints, &res) == 0) { - if (res) { - if ( (res->ai_addr) && (res->ai_addrlen) ) { - SOCaddr_copyaddr(*server, server_size, res->ai_addr, res->ai_addrlen); - freeaddrinfo(res); - return 1; - } - } - } - if (res) { - freeaddrinfo(res); - } - + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + if (getaddrinfo(hostname, NULL, &hints, &res) == 0) { + if (res) { + if ((res->ai_addr) && (res->ai_addrlen)) { + SOCaddr_copyaddr(*server, server_size, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + return 1; + } + } + } + if (res) { + freeaddrinfo(res); + } #endif - } - return 0; + } + return 0; } -static String getip(SOCaddr *server, int serverLen) { - String s = STRING_EMPTY; +static String getip(SOCaddr * server, int serverLen) { + String s = STRING_EMPTY; + #if HTS_INET6==0 - unsigned int sizeMax = sizeof("999.999.999.999:65535"); + unsigned int sizeMax = sizeof("999.999.999.999:65535"); #else - unsigned int sizeMax = sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:65535"); + unsigned int sizeMax = sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:65535"); #endif - char * dotted = malloc(sizeMax + 1); - unsigned short port = ntohs(SOCaddr_sinport(*server)); - if (dotted == NULL) { - proxytrack_print_log(CRITICAL, "memory exhausted"); - return s; - } - SOCaddr_inetntoa(dotted, sizeMax, *server, serverLen); - sprintf(dotted + strlen(dotted), ":%d", port); - StringAttach(&s, &dotted); - return s; + char *dotted = malloc(sizeMax + 1); + unsigned short port = ntohs(SOCaddr_sinport(*server)); + + if (dotted == NULL) { + proxytrack_print_log(CRITICAL, "memory exhausted"); + return s; + } + SOCaddr_inetntoa(dotted, sizeMax, *server, serverLen); + sprintf(dotted + strlen(dotted), ":%d", port); + StringAttach(&s, &dotted); + return s; } +static T_SOC smallserver_init(const char *adr, int port, int family) { + SOCaddr server; + size_t server_size = sizeof(server); -static T_SOC smallserver_init(const char* adr, int port, int family) { - SOCaddr server; - size_t server_size = sizeof(server); + memset(&server, 0, sizeof(server)); + SOCaddr_initany(server, server_size); + if (gethost(adr, &server, server_size)) { // host name + T_SOC soc = INVALID_SOCKET; - memset(&server, 0, sizeof(server)); - SOCaddr_initany(server, server_size); - if (gethost(adr, &server, server_size)) { // host name - T_SOC soc = INVALID_SOCKET; - if ( (soc = (T_SOC) socket(SOCaddr_sinfamily(server), family, 0)) != INVALID_SOCKET) { + if ((soc = + (T_SOC) socket(SOCaddr_sinfamily(server), family, + 0)) != INVALID_SOCKET) { SOCaddr_initport(server, port); - if ( bind(soc,(struct sockaddr*) &server, (int)server_size) == 0 ) { - if (family != SOCK_STREAM - || listen(soc, 10) >=0 ) { - return soc; + if (bind(soc, (struct sockaddr *) &server, (int) server_size) == 0) { + if (family != SOCK_STREAM || listen(soc, 10) >= 0) { + return soc; } else { #ifdef _WIN32 closesocket(soc); #else close(soc); #endif - soc=INVALID_SOCKET; + soc = INVALID_SOCKET; } } else { #ifdef _WIN32 @@ -315,7 +330,7 @@ static T_SOC smallserver_init(const char* adr, int port, int family) { #else close(soc); #endif - soc=INVALID_SOCKET; + soc = INVALID_SOCKET; } } } @@ -323,26 +338,26 @@ static T_SOC smallserver_init(const char* adr, int port, int family) { } static int proxytrack_start(PT_Indexes indexes, T_SOC soc, T_SOC socICP); -int proxytrack_main(char* proxyAddr, int proxyPort, - char* icpAddr, int icpPort, - PT_Indexes index) { +int proxytrack_main(char *proxyAddr, int proxyPort, char *icpAddr, int icpPort, + PT_Indexes index) { int returncode = 0; T_SOC soc = smallserver_init(proxyAddr, proxyPort, SOCK_STREAM); T_SOC socICP = smallserver_init(proxyAddr, icpPort, SOCK_DGRAM); - if (soc != INVALID_SOCKET - && socICP != INVALID_SOCKET) - { - char url[HTS_URLMAXSIZE*2]; + + if (soc != INVALID_SOCKET && socICP != INVALID_SOCKET) { + char url[HTS_URLMAXSIZE * 2]; char method[32]; char data[32768]; - url[0]=method[0]=data[0]='\0'; + + url[0] = method[0] = data[0] = '\0'; // printf("HTTP Proxy installed on %s:%d/\n", proxyAddr, proxyPort); printf("ICP Proxy installed on %s:%d/\n", icpAddr, icpPort); #ifndef _WIN32 { pid_t pid = getpid(); - printf("PID=%d\n", (int)pid); + + printf("PID=%d\n", (int) pid); } #endif fflush(stdout); @@ -350,7 +365,9 @@ int proxytrack_main(char* proxyAddr, int proxyPort, // if (!proxytrack_start(index, soc, socICP)) { int last_errno = errno; - fprintf(stderr, "Unable to create the server: %s\n", strerror(last_errno)); + + fprintf(stderr, "Unable to create the server: %s\n", + strerror(last_errno)); #ifdef _WIN32 closesocket(soc); #else @@ -363,7 +380,9 @@ int proxytrack_main(char* proxyAddr, int proxyPort, } } else { int last_errno = errno; - fprintf(stderr, "Unable to initialize a temporary server : %s\n", strerror(last_errno)); + + fprintf(stderr, "Unable to initialize a temporary server : %s\n", + strerror(last_errno)); returncode = 1; } printf("EXITED\n"); @@ -372,1020 +391,1104 @@ int proxytrack_main(char* proxyAddr, int proxyPort, return returncode; } -static const char* GetHttpMessage(int statuscode) { +static const char *GetHttpMessage(int statuscode) { // Erreurs HTTP, selon RFC - switch( statuscode) { - case 100: return "Continue"; break; - case 101: return "Switching Protocols"; break; - case 200: return "OK"; break; - case 201: return "Created"; break; - case 202: return "Accepted"; break; - case 203: return "Non-Authoritative Information"; break; - case 204: return "No Content"; break; - case 205: return "Reset Content"; break; - case 206: return "Partial Content"; break; - case 207: return "Multi-Status"; break; - case 300: return "Multiple Choices"; break; - case 301: return "Moved Permanently"; break; - case 302: return "Moved Temporarily"; break; - case 303: return "See Other"; break; - case 304: return "Not Modified"; break; - case 305: return "Use Proxy"; break; - case 306: return "Undefined 306 error"; break; - case 307: return "Temporary Redirect"; break; - case 400: return "Bad Request"; break; - case 401: return "Unauthorized"; break; - case 402: return "Payment Required"; break; - case 403: return "Forbidden"; break; - case 404: return "Not Found"; break; - case 405: return "Method Not Allowed"; break; - case 406: return "Not Acceptable"; break; - case 407: return "Proxy Authentication Required"; break; - case 408: return "Request Time-out"; break; - case 409: return "Conflict"; break; - case 410: return "Gone"; break; - case 411: return "Length Required"; break; - case 412: return "Precondition Failed"; break; - case 413: return "Request Entity Too Large"; break; - case 414: return "Request-URI Too Large"; break; - case 415: return "Unsupported Media Type"; break; - case 416: return "Requested Range Not Satisfiable"; break; - case 417: return "Expectation Failed"; break; - case 500: return "Internal Server Error"; break; - case 501: return "Not Implemented"; break; - case 502: return "Bad Gateway"; break; - case 503: return "Service Unavailable"; break; - case 504: return "Gateway Time-out"; break; - case 505: return "HTTP Version Not Supported"; break; - default: return "Unknown HTTP Error"; break; - } + switch (statuscode) { + case 100: + return "Continue"; + break; + case 101: + return "Switching Protocols"; + break; + case 200: + return "OK"; + break; + case 201: + return "Created"; + break; + case 202: + return "Accepted"; + break; + case 203: + return "Non-Authoritative Information"; + break; + case 204: + return "No Content"; + break; + case 205: + return "Reset Content"; + break; + case 206: + return "Partial Content"; + break; + case 207: + return "Multi-Status"; + break; + case 300: + return "Multiple Choices"; + break; + case 301: + return "Moved Permanently"; + break; + case 302: + return "Moved Temporarily"; + break; + case 303: + return "See Other"; + break; + case 304: + return "Not Modified"; + break; + case 305: + return "Use Proxy"; + break; + case 306: + return "Undefined 306 error"; + break; + case 307: + return "Temporary Redirect"; + break; + case 400: + return "Bad Request"; + break; + case 401: + return "Unauthorized"; + break; + case 402: + return "Payment Required"; + break; + case 403: + return "Forbidden"; + break; + case 404: + return "Not Found"; + break; + case 405: + return "Method Not Allowed"; + break; + case 406: + return "Not Acceptable"; + break; + case 407: + return "Proxy Authentication Required"; + break; + case 408: + return "Request Time-out"; + break; + case 409: + return "Conflict"; + break; + case 410: + return "Gone"; + break; + case 411: + return "Length Required"; + break; + case 412: + return "Precondition Failed"; + break; + case 413: + return "Request Entity Too Large"; + break; + case 414: + return "Request-URI Too Large"; + break; + case 415: + return "Unsupported Media Type"; + break; + case 416: + return "Requested Range Not Satisfiable"; + break; + case 417: + return "Expectation Failed"; + break; + case 500: + return "Internal Server Error"; + break; + case 501: + return "Not Implemented"; + break; + case 502: + return "Bad Gateway"; + break; + case 503: + return "Service Unavailable"; + break; + case 504: + return "Gateway Time-out"; + break; + case 505: + return "HTTP Version Not Supported"; + break; + default: + return "Unknown HTTP Error"; + break; + } } #ifndef NO_WEBDAV -static void proxytrack_add_DAV_Item(String *item, String *buff, - const char* filename, - size_t size, - time_t timestamp, - const char* mime, - int isDir, - int isRoot, - int isDefault) -{ - struct tm * timetm; - if (timestamp == (time_t) 0 || timestamp == (time_t) -1) { - timestamp = time(NULL); - } - if ((timetm = gmtime(×tamp)) != NULL) { - char tms[256 + 1]; - const char * name; - strftime(tms, 256, "%a, %d %b %Y %H:%M:%S GMT", timetm); /* Sun, 18 Sep 2005 11:45:45 GMT */ - - if (mime == NULL || *mime == 0) - mime = "application/octet-stream"; - - StringLength(*buff) = 0; - escapexml(filename, buff); - - name = strrchr(StringBuff(*buff), '/'); - if (name != NULL) - name++; - if (name == NULL || *name == 0) { - if (strcmp(mime, "text/html") == 0) - name = "Default Document for the Folder.html"; - else - name = "Default Document for the Folder"; - } - - StringRoom(*item, 1024); - sprintf(StringBuffRW(*item), - "<response xmlns=\"DAV:\">\r\n" - "<href>/webdav%s%s</href>\r\n" - "<propstat>\r\n" - "<prop>\r\n" - "<displayname>%s</displayname>\r\n" - "<iscollection>%d</iscollection>\r\n" - "<haschildren>%d</haschildren>\r\n" - "<isfolder>%d</isfolder>\r\n" - "<resourcetype>%s</resourcetype>\r\n" - "<creationdate>%d-%02d-%02dT%02d:%02d:%02dZ</creationdate>\r\n" - "<getlastmodified>%s</getlastmodified>\r\n" - "<supportedlock></supportedlock>\r\n" - "<lockdiscovery/>\r\n" - "<getcontenttype>%s</getcontenttype>\r\n" - "<getcontentlength>%d</getcontentlength>\r\n" - "<isroot>%d</isroot>\r\n" - "</prop>\r\n" - "<status>HTTP/1.1 200 OK</status>\r\n" - "</propstat>\r\n" - "</response>\r\n", - /* */ - ( StringBuff(*buff)[0] == '/' ) ? "" : "/", StringBuff(*buff), - name, - isDir ? 1 : 0, - isDir ? 1 : 0, - isDir ? 1 : 0, - isDir ? "<collection/>" : "", - timetm->tm_year + 1900, timetm->tm_mon + 1, timetm->tm_mday, timetm->tm_hour, timetm->tm_min, timetm->tm_sec, - tms, - isDir ? "httpd/unix-directory" : mime, - (int)size, - isRoot ? 1 : 0 - ); - StringLength(*item) = (int) strlen(StringBuff(*item)); - } +static void proxytrack_add_DAV_Item(String * item, String * buff, + const char *filename, size_t size, + time_t timestamp, const char *mime, + int isDir, int isRoot, int isDefault) { + struct tm *timetm; + + if (timestamp == (time_t) 0 || timestamp == (time_t) - 1) { + timestamp = time(NULL); + } + if ((timetm = gmtime(×tamp)) != NULL) { + char tms[256 + 1]; + const char *name; + + strftime(tms, 256, "%a, %d %b %Y %H:%M:%S GMT", timetm); /* Sun, 18 Sep 2005 11:45:45 GMT */ + + if (mime == NULL || *mime == 0) + mime = "application/octet-stream"; + + StringLength(*buff) = 0; + escapexml(filename, buff); + + name = strrchr(StringBuff(*buff), '/'); + if (name != NULL) + name++; + if (name == NULL || *name == 0) { + if (strcmp(mime, "text/html") == 0) + name = "Default Document for the Folder.html"; + else + name = "Default Document for the Folder"; + } + + StringRoom(*item, 1024); + sprintf(StringBuffRW(*item), + "<response xmlns=\"DAV:\">\r\n" "<href>/webdav%s%s</href>\r\n" + "<propstat>\r\n" "<prop>\r\n" "<displayname>%s</displayname>\r\n" + "<iscollection>%d</iscollection>\r\n" + "<haschildren>%d</haschildren>\r\n" "<isfolder>%d</isfolder>\r\n" + "<resourcetype>%s</resourcetype>\r\n" + "<creationdate>%d-%02d-%02dT%02d:%02d:%02dZ</creationdate>\r\n" + "<getlastmodified>%s</getlastmodified>\r\n" + "<supportedlock></supportedlock>\r\n" "<lockdiscovery/>\r\n" + "<getcontenttype>%s</getcontenttype>\r\n" + "<getcontentlength>%d</getcontentlength>\r\n" + "<isroot>%d</isroot>\r\n" "</prop>\r\n" + "<status>HTTP/1.1 200 OK</status>\r\n" "</propstat>\r\n" + "</response>\r\n", + /* */ + (StringBuff(*buff)[0] == '/') ? "" : "/", StringBuff(*buff), name, + isDir ? 1 : 0, isDir ? 1 : 0, isDir ? 1 : 0, + isDir ? "<collection/>" : "", timetm->tm_year + 1900, + timetm->tm_mon + 1, timetm->tm_mday, timetm->tm_hour, + timetm->tm_min, timetm->tm_sec, tms, + isDir ? "httpd/unix-directory" : mime, (int) size, isRoot ? 1 : 0); + StringLength(*item) = (int) strlen(StringBuff(*item)); + } } /* Convert a RFC822 time to time_t */ -static time_t get_time_rfc822(const char* s) { +static time_t get_time_rfc822(const char *s) { struct tm result; + /* */ - char months[]="jan feb mar apr may jun jul aug sep oct nov dec"; + char months[] = "jan feb mar apr may jun jul aug sep oct nov dec"; char str[256]; - char* a; - int i; + char *a; + int i; + /* */ - int result_mm=-1; - int result_dd=-1; - int result_n1=-1; - int result_n2=-1; - int result_n3=-1; - int result_n4=-1; + int result_mm = -1; + int result_dd = -1; + int result_n1 = -1; + int result_n2 = -1; + int result_n3 = -1; + int result_n4 = -1; + /* */ if ((int) strlen(s) > 200) - return (time_t)0; - for(i = 0 ; s[i] != 0 ; i++) { - if (s[i] >= 'A' && s[i] <= 'Z') - str[i] = s[i] + ('a' - 'A'); - else - str[i] = s[i]; - } - str[i] = 0; + return (time_t) 0; + for(i = 0; s[i] != 0; i++) { + if (s[i] >= 'A' && s[i] <= 'Z') + str[i] = s[i] + ('a' - 'A'); + else + str[i] = s[i]; + } + str[i] = 0; /* éliminer :,- */ - while( (a=strchr(str,'-')) ) *a=' '; - while( (a=strchr(str,':')) ) *a=' '; - while( (a=strchr(str,',')) ) *a=' '; + while((a = strchr(str, '-'))) + *a = ' '; + while((a = strchr(str, ':'))) + *a = ' '; + while((a = strchr(str, ','))) + *a = ' '; /* tokeniser */ - a=str; + a = str; while(*a) { - char *first,*last; + char *first, *last; char tok[256]; + /* découper mot */ - while(*a==' ') a++; /* sauter espaces */ - first=a; - while((*a) && (*a!=' ')) a++; - last=a; - tok[0]='\0'; - if (first!=last) { - char* pos; - strncat(tok,first,(int) (last - first)); + while(*a == ' ') + a++; /* sauter espaces */ + first = a; + while((*a) && (*a != ' ')) + a++; + last = a; + tok[0] = '\0'; + if (first != last) { + char *pos; + + strncat(tok, first, (int) (last - first)); /* analyser */ - if ( (pos=strstr(months,tok)) ) { /* month always in letters */ - result_mm=((int) (pos - months))/4; + if ((pos = strstr(months, tok))) { /* month always in letters */ + result_mm = ((int) (pos - months)) / 4; } else { int number; - if (sscanf(tok,"%d",&number) == 1) { /* number token */ - if (result_dd<0) /* day always first number */ - result_dd=number; - else if (result_n1<0) - result_n1=number; - else if (result_n2<0) - result_n2=number; - else if (result_n3<0) - result_n3=number; - else if (result_n4<0) - result_n4=number; - } /* sinon, bruit de fond(+1GMT for exampel) */ + + if (sscanf(tok, "%d", &number) == 1) { /* number token */ + if (result_dd < 0) /* day always first number */ + result_dd = number; + else if (result_n1 < 0) + result_n1 = number; + else if (result_n2 < 0) + result_n2 = number; + else if (result_n3 < 0) + result_n3 = number; + else if (result_n4 < 0) + result_n4 = number; + } /* sinon, bruit de fond(+1GMT for exampel) */ } } } - if ((result_n1>=0) && (result_mm>=0) && (result_dd>=0) && (result_n2>=0) && (result_n3>=0) && (result_n4>=0)) { - if (result_n4>=1000) { /* Sun Nov 6 08:49:37 1994 */ - result.tm_year=result_n4-1900; - result.tm_hour=result_n1; - result.tm_min=result_n2; - result.tm_sec=max(result_n3,0); - } else { /* Sun, 06 Nov 1994 08:49:37 GMT or Sunday, 06-Nov-94 08:49:37 GMT */ - result.tm_hour=result_n2; - result.tm_min=result_n3; - result.tm_sec=max(result_n4,0); - if (result_n1<=50) /* 00 means 2000 */ - result.tm_year=result_n1+100; - else if (result_n1<1000) /* 99 means 1999 */ - result.tm_year=result_n1; - else /* 2000 */ - result.tm_year=result_n1-1900; + if ((result_n1 >= 0) && (result_mm >= 0) && (result_dd >= 0) + && (result_n2 >= 0) && (result_n3 >= 0) && (result_n4 >= 0)) { + if (result_n4 >= 1000) { /* Sun Nov 6 08:49:37 1994 */ + result.tm_year = result_n4 - 1900; + result.tm_hour = result_n1; + result.tm_min = result_n2; + result.tm_sec = max(result_n3, 0); + } else { /* Sun, 06 Nov 1994 08:49:37 GMT or Sunday, 06-Nov-94 08:49:37 GMT */ + result.tm_hour = result_n2; + result.tm_min = result_n3; + result.tm_sec = max(result_n4, 0); + if (result_n1 <= 50) /* 00 means 2000 */ + result.tm_year = result_n1 + 100; + else if (result_n1 < 1000) /* 99 means 1999 */ + result.tm_year = result_n1; + else /* 2000 */ + result.tm_year = result_n1 - 1900; } - result.tm_isdst=0; /* assume GMT */ - result.tm_yday=-1; /* don't know */ - result.tm_wday=-1; /* don't know */ - result.tm_mon=result_mm; - result.tm_mday=result_dd; + result.tm_isdst = 0; /* assume GMT */ + result.tm_yday = -1; /* don't know */ + result.tm_wday = -1; /* don't know */ + result.tm_mon = result_mm; + result.tm_mday = result_dd; return mktime(&result); } return (time_t) 0; } -static PT_Element proxytrack_process_DAV_Request(PT_Indexes indexes, const char * urlFull, int depth) { - const char * file = jump_protocol_and_auth(urlFull); - if ( (file = strchr(file, '/')) == NULL) - return NULL; - - if (strncmp(file, "/webdav", 7) != 0) { - PT_Element elt = PT_ElementNew(); - elt->statuscode = 405; - strcpy(elt->msg, "Method Not Allowed"); - return elt; - } - - /* Skip /webdav */ - file += 7; - - /* */ - { - PT_Element elt = PT_ElementNew(); - int i, isDir; - String url = STRING_EMPTY; - String response = STRING_EMPTY; - String item = STRING_EMPTY; - String itemUrl = STRING_EMPTY; - String buff = STRING_EMPTY; - StringClear(response); - StringClear(item); - StringClear(itemUrl); - StringClear(buff); - - /* Canonize URL */ - StringCopy(url, file + ((file[0] == '/') ? 1 : 0)); - if (StringLength(url) > 0) { - if (StringBuff(url)[StringLength(url) - 1] == '/') { - StringBuffRW(url)[StringLength(url) - 1] = '\0'; - StringLength(url)--; - } - } - - /* Form response */ - StringRoom(response, 1024); - sprintf(StringBuffRW(response), - "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" - "<multistatus xmlns=\"DAV:\">\r\n"); - StringLength(response) = (int) strlen(StringBuff(response)); - /* */ - - /* Root */ - StringLength(item) = 0; - proxytrack_add_DAV_Item(&item, &buff, - StringBuff(url), /*size*/0, /*timestamp*/(time_t) 0, /*mime*/NULL, /*isDir*/1, /*isRoot*/1, /*isDefault*/0); - StringMemcat(response, StringBuff(item), StringLength(item)); - - /* Childrens (Depth > 0) */ - if (depth > 0) { - time_t timestampRep = (time_t) -1; - const char * prefix = StringBuff(url); - unsigned int prefixLen = (unsigned int) strlen(prefix); - char ** list = PT_Enumerate(indexes, prefix, 0); - if (list != NULL) { - for(isDir = 1 ; isDir >= 0 ; isDir--) { - for(i = 0 ; list[i] != NULL ; i++) { - const char * thisUrl = list[i]; - const char * mimeType = "application/octet-stream"; - unsigned int thisUrlLen = (unsigned int) strlen(thisUrl); - int thisIsDir = (thisUrl[thisUrlLen - 1] == '/') ? 1 : 0; - - /* Item URL */ - StringRoom(itemUrl, thisUrlLen + prefixLen + sizeof("/webdav/") + 1); - StringClear(itemUrl); - sprintf(StringBuffRW(itemUrl), "/%s/%s", prefix, thisUrl); - if (!thisIsDir) - StringLength(itemUrl) = (int) strlen(StringBuff(itemUrl)); - else - StringLength(itemUrl) = (int) strlen(StringBuff(itemUrl)) - 1; - StringBuffRW(itemUrl)[StringLength(itemUrl)] = '\0'; - - if (thisIsDir == isDir) { - size_t size = 0; - time_t timestamp = (time_t) 0; - PT_Element file = NULL; - - /* Item stats */ - if (!isDir) { - file = PT_ReadIndex(indexes, StringBuff(itemUrl) + 1, FETCH_HEADERS); - if (file != NULL && file->statuscode == HTTP_OK ) { - size = file->size; - if (file->lastmodified) { - timestamp = get_time_rfc822(file->lastmodified); - } - if (timestamp == (time_t) 0) { - if (timestampRep == (time_t) -1) { - timestampRep = 0; - if (file->indexId != -1) { - timestampRep = PT_Index_Timestamp(PT_GetIndex(indexes, file->indexId)); - } - } - timestamp = timestampRep; - } - if (file->contenttype) { - mimeType = file->contenttype; - } - } - } - - /* Add item */ - StringLength(item) = 0; - proxytrack_add_DAV_Item(&item, &buff, - StringBuff(itemUrl), size, timestamp, mimeType, isDir, /*isRoot*/0, /*isDefault*/(thisUrlLen == 0)); - StringMemcat(response, StringBuff(item), StringLength(item)); - - /* Wipe element */ - if (file != NULL) - PT_Element_Delete(&file); - } - } - } - PT_Enumerate_Delete(&list); - } /* items != NULL */ - } /* Depth > 0 */ - - /* End of responses */ - StringCat(response, - "</multistatus>\r\n" - ); - - StringFree(item); - StringFree(itemUrl); - StringFree(url); - StringFree(buff); - - elt->size = StringLength(response); - elt->adr = StringAcquire(&response); - elt->statuscode = 207; /* Multi-Status */ - strcpy(elt->charset, "utf-8"); - strcpy(elt->contenttype, "text/xml"); - strcpy(elt->msg, "Multi-Status"); - StringFree(response); - - fprintf(stderr, "RESPONSE:\n%s\n", elt->adr); - - return elt; - } - return NULL; +static PT_Element proxytrack_process_DAV_Request(PT_Indexes indexes, + const char *urlFull, + int depth) { + const char *file = jump_protocol_and_auth(urlFull); + + if ((file = strchr(file, '/')) == NULL) + return NULL; + + if (strncmp(file, "/webdav", 7) != 0) { + PT_Element elt = PT_ElementNew(); + + elt->statuscode = 405; + strcpy(elt->msg, "Method Not Allowed"); + return elt; + } + + /* Skip /webdav */ + file += 7; + + /* */ + { + PT_Element elt = PT_ElementNew(); + int i, isDir; + String url = STRING_EMPTY; + String response = STRING_EMPTY; + String item = STRING_EMPTY; + String itemUrl = STRING_EMPTY; + String buff = STRING_EMPTY; + + StringClear(response); + StringClear(item); + StringClear(itemUrl); + StringClear(buff); + + /* Canonize URL */ + StringCopy(url, file + ((file[0] == '/') ? 1 : 0)); + if (StringLength(url) > 0) { + if (StringBuff(url)[StringLength(url) - 1] == '/') { + StringBuffRW(url)[StringLength(url) - 1] = '\0'; + StringLength(url)--; + } + } + + /* Form response */ + StringRoom(response, 1024); + sprintf(StringBuffRW(response), + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" + "<multistatus xmlns=\"DAV:\">\r\n"); + StringLength(response) = (int) strlen(StringBuff(response)); + /* */ + + /* Root */ + StringLength(item) = 0; + proxytrack_add_DAV_Item(&item, &buff, StringBuff(url), /*size */ 0, + /*timestamp */ (time_t) 0, /*mime */ NULL, /*isDir */ 1, /*isRoot */ 1, +/*isDefault */ 0); + StringMemcat(response, StringBuff(item), StringLength(item)); + + /* Childrens (Depth > 0) */ + if (depth > 0) { + time_t timestampRep = (time_t) - 1; + const char *prefix = StringBuff(url); + unsigned int prefixLen = (unsigned int) strlen(prefix); + char **list = PT_Enumerate(indexes, prefix, 0); + + if (list != NULL) { + for(isDir = 1; isDir >= 0; isDir--) { + for(i = 0; list[i] != NULL; i++) { + const char *thisUrl = list[i]; + const char *mimeType = "application/octet-stream"; + unsigned int thisUrlLen = (unsigned int) strlen(thisUrl); + int thisIsDir = (thisUrl[thisUrlLen - 1] == '/') ? 1 : 0; + + /* Item URL */ + StringRoom(itemUrl, + thisUrlLen + prefixLen + sizeof("/webdav/") + 1); + StringClear(itemUrl); + sprintf(StringBuffRW(itemUrl), "/%s/%s", prefix, thisUrl); + if (!thisIsDir) + StringLength(itemUrl) = (int) strlen(StringBuff(itemUrl)); + else + StringLength(itemUrl) = (int) strlen(StringBuff(itemUrl)) - 1; + StringBuffRW(itemUrl)[StringLength(itemUrl)] = '\0'; + + if (thisIsDir == isDir) { + size_t size = 0; + time_t timestamp = (time_t) 0; + PT_Element file = NULL; + + /* Item stats */ + if (!isDir) { + file = + PT_ReadIndex(indexes, StringBuff(itemUrl) + 1, FETCH_HEADERS); + if (file != NULL && file->statuscode == HTTP_OK) { + size = file->size; + if (file->lastmodified) { + timestamp = get_time_rfc822(file->lastmodified); + } + if (timestamp == (time_t) 0) { + if (timestampRep == (time_t) - 1) { + timestampRep = 0; + if (file->indexId != -1) { + timestampRep = + PT_Index_Timestamp(PT_GetIndex + (indexes, file->indexId)); + } + } + timestamp = timestampRep; + } + if (file->contenttype) { + mimeType = file->contenttype; + } + } + } + + /* Add item */ + StringLength(item) = 0; + proxytrack_add_DAV_Item(&item, &buff, StringBuff(itemUrl), size, + timestamp, mimeType, isDir, /*isRoot */ 0, + /*isDefault */ (thisUrlLen == 0)); + StringMemcat(response, StringBuff(item), StringLength(item)); + + /* Wipe element */ + if (file != NULL) + PT_Element_Delete(&file); + } + } + } + PT_Enumerate_Delete(&list); + } /* items != NULL */ + } + + /* Depth > 0 */ + /* End of responses */ + StringCat(response, "</multistatus>\r\n"); + + StringFree(item); + StringFree(itemUrl); + StringFree(url); + StringFree(buff); + + elt->size = StringLength(response); + elt->adr = StringAcquire(&response); + elt->statuscode = 207; /* Multi-Status */ + strcpy(elt->charset, "utf-8"); + strcpy(elt->contenttype, "text/xml"); + strcpy(elt->msg, "Multi-Status"); + StringFree(response); + + fprintf(stderr, "RESPONSE:\n%s\n", elt->adr); + + return elt; + } + return NULL; } #endif -static PT_Element proxytrack_process_HTTP_List(PT_Indexes indexes, const char * url) { - char ** list = PT_Enumerate(indexes, url, 0); - if (list != NULL) { - PT_Element elt = PT_ElementNew(); - int i, isDir; - String html = STRING_EMPTY; - StringClear(html); - StringCat(html, - "<html>" - PROXYTRACK_COMMENT_HEADER - DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES - "<head>\r\n" - "<title>ProxyTrack " PROXYTRACK_VERSION " Catalog</title>" - "</head>\r\n" - "<body>\r\n" - "<h3>Directory index:</h3><br />" - "<br />" - "<hr>" - "<tt>[DIR] <a href=\"..\">..</a></tt><br />" - ); - for(isDir = 1 ; isDir >= 0 ; isDir--) { - for(i = 0 ; list[i] != NULL ; i++) { - char * thisUrl = list[i]; - unsigned int thisUrlLen = (unsigned int) strlen(thisUrl); - int thisIsDir = (thisUrl[thisUrlLen - 1] == '/') ? 1 : 0; - if (thisIsDir == isDir) { - if (isDir) - StringCat(html, "<tt>[DIR] "); - else - StringCat(html, "<tt> "); - StringCat(html, "<a href=\""); - if (isDir) { - StringCat(html, "http://proxytrack/"); - } - StringCat(html, url); - StringCat(html, list[i]); - StringCat(html, "\">"); - StringCat(html, list[i]); - StringCat(html, "</a></tt><br />"); - } - } - } - StringCat(html, - "</body>" - "</html>"); - PT_Enumerate_Delete(&list); - elt->size = StringLength(html); - elt->adr = StringAcquire(&html); - elt->statuscode = HTTP_OK; - strcpy(elt->charset, "iso-8859-1"); - strcpy(elt->contenttype, "text/html"); - strcpy(elt->msg, "OK"); - StringFree(html); - return elt; - } - return NULL; +static PT_Element proxytrack_process_HTTP_List(PT_Indexes indexes, + const char *url) { + char **list = PT_Enumerate(indexes, url, 0); + + if (list != NULL) { + PT_Element elt = PT_ElementNew(); + int i, isDir; + String html = STRING_EMPTY; + + StringClear(html); + StringCat(html, + "<html>" PROXYTRACK_COMMENT_HEADER + DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES "<head>\r\n" + "<title>ProxyTrack " PROXYTRACK_VERSION " Catalog</title>" + "</head>\r\n" "<body>\r\n" "<h3>Directory index:</h3><br />" + "<br />" "<hr>" "<tt>[DIR] <a href=\"..\">..</a></tt><br />"); + for(isDir = 1; isDir >= 0; isDir--) { + for(i = 0; list[i] != NULL; i++) { + char *thisUrl = list[i]; + unsigned int thisUrlLen = (unsigned int) strlen(thisUrl); + int thisIsDir = (thisUrl[thisUrlLen - 1] == '/') ? 1 : 0; + + if (thisIsDir == isDir) { + if (isDir) + StringCat(html, "<tt>[DIR] "); + else + StringCat(html, "<tt> "); + StringCat(html, "<a href=\""); + if (isDir) { + StringCat(html, "http://proxytrack/"); + } + StringCat(html, url); + StringCat(html, list[i]); + StringCat(html, "\">"); + StringCat(html, list[i]); + StringCat(html, "</a></tt><br />"); + } + } + } + StringCat(html, "</body>" "</html>"); + PT_Enumerate_Delete(&list); + elt->size = StringLength(html); + elt->adr = StringAcquire(&html); + elt->statuscode = HTTP_OK; + strcpy(elt->charset, "iso-8859-1"); + strcpy(elt->contenttype, "text/html"); + strcpy(elt->msg, "OK"); + StringFree(html); + return elt; + } + return NULL; } static void proxytrack_process_HTTP(PT_Indexes indexes, T_SOC soc_c) { - int timeout=30; - int buffer_size = 32768; - char * buffer = (char*)malloc(buffer_size); - int line1Size = 1024; - char * line1 = (char*)malloc(line1Size); - int lineSize = 8192; - char * line = (char*)malloc(lineSize); - int length = 0; - int keepAlive = 1; - - String url = STRING_EMPTY; - String urlRedirect = STRING_EMPTY; - String headers = STRING_EMPTY; - String output = STRING_EMPTY; - String host = STRING_EMPTY; - String localhost = STRING_EMPTY; + int timeout = 30; + int buffer_size = 32768; + char *buffer = (char *) malloc(buffer_size); + int line1Size = 1024; + char *line1 = (char *) malloc(line1Size); + int lineSize = 8192; + char *line = (char *) malloc(lineSize); + int length = 0; + int keepAlive = 1; + + String url = STRING_EMPTY; + String urlRedirect = STRING_EMPTY; + String headers = STRING_EMPTY; + String output = STRING_EMPTY; + String host = STRING_EMPTY; + String localhost = STRING_EMPTY; + #ifndef NO_WEBDAV - String davHeaders = STRING_EMPTY; - String davRequest = STRING_EMPTY; + String davHeaders = STRING_EMPTY; + String davRequest = STRING_EMPTY; #endif - StringRoom(localhost, 256); - if (gethostname(StringBuffRW(localhost), (int) StringCapacity(localhost) - 1) == 0) { - StringLength(localhost) = (int) strlen(StringBuff(localhost)); - } else { - StringCopy(localhost, "localhost"); - } + StringRoom(localhost, 256); + if (gethostname(StringBuffRW(localhost), (int) StringCapacity(localhost) - 1) + == 0) { + StringLength(localhost) = (int) strlen(StringBuff(localhost)); + } else { + StringCopy(localhost, "localhost"); + } #ifdef _DEBUG - Sleep(1000); + Sleep(1000); #endif - if (buffer == NULL || line == NULL || line1 == NULL) { - proxytrack_print_log(CRITICAL, "proxytrack_process_HTTP:memory exhausted"); + if (buffer == NULL || line == NULL || line1 == NULL) { + proxytrack_print_log(CRITICAL, "proxytrack_process_HTTP:memory exhausted"); #ifdef _WIN32 - closesocket(soc_c); + closesocket(soc_c); #else - close(soc_c); + close(soc_c); #endif - return ; - } - - do { - const char* msgError = NULL; - int msgCode = 0; - PT_Element element = NULL; - char* command; - char* proto; - char* surl; - int directHit = 0; - int headRequest = 0; - int listRequest = 0; + return; + } + + do { + const char *msgError = NULL; + int msgCode = 0; + PT_Element element = NULL; + char *command; + char *proto; + char *surl; + int directHit = 0; + int headRequest = 0; + int listRequest = 0; + #ifndef NO_WEBDAV - int davDepth = 0; + int davDepth = 0; #endif - /* Clear context */ - line[0] = line1[0] = '\0'; - buffer[0] = '\0'; - command = line1; - StringClear(url); - StringClear(urlRedirect); - StringClear(headers); - StringClear(output); - StringClear(host); + /* Clear context */ + line[0] = line1[0] = '\0'; + buffer[0] = '\0'; + command = line1; + StringClear(url); + StringClear(urlRedirect); + StringClear(headers); + StringClear(output); + StringClear(host); #ifndef NO_WEBDAV - StringClear(davHeaders); - StringClear(davRequest); + StringClear(davHeaders); + StringClear(davRequest); #endif - /* line1: "GET http://www.example.com/ HTTP/1.0" */ - if (linputsoc_t(soc_c, line1, line1Size - 2, timeout) > 0 - && ( surl = strchr(line1, ' ') ) - && !(*surl = '\0') - && ++surl - && (proto = strchr(surl, ' ')) && !(*proto = '\0') && ++proto) - { - /* Flush headers */ - while(linputsoc_t(soc_c, line, lineSize - 2, timeout) > 0 - && line[0] != 0) - { - int p; - if ((p = strfield(line, "Content-length:"))!=0) { - if (sscanf(line+p, "%d", &length) != 1) { - msgCode = 500; - msgError = "Bad HTTP Content-Length Field"; - keepAlive = 0; - length = 0; - } - } else if (strcasecmp(line, "Connection: close") == 0) { - keepAlive = 0; - } else if (strcasecmp(line, "Connection: keep-alive") == 0) { - keepAlive = 1; - } else if ((p = strfield(line, "Host:"))) { - char* chost = line + p; - if (*chost == ' ') - chost++; - StringCopy(host, chost); - } + /* line1: "GET http://www.example.com/ HTTP/1.0" */ + if (linputsoc_t(soc_c, line1, line1Size - 2, timeout) > 0 + && (surl = strchr(line1, ' ')) + && !(*surl = '\0') + && ++surl && (proto = strchr(surl, ' ')) && !(*proto = '\0') && ++proto) { + /* Flush headers */ + while(linputsoc_t(soc_c, line, lineSize - 2, timeout) > 0 && line[0] != 0) { + int p; + + if ((p = strfield(line, "Content-length:")) != 0) { + if (sscanf(line + p, "%d", &length) != 1) { + msgCode = 500; + msgError = "Bad HTTP Content-Length Field"; + keepAlive = 0; + length = 0; + } + } else if (strcasecmp(line, "Connection: close") == 0) { + keepAlive = 0; + } else if (strcasecmp(line, "Connection: keep-alive") == 0) { + keepAlive = 1; + } else if ((p = strfield(line, "Host:"))) { + char *chost = line + p; + + if (*chost == ' ') + chost++; + StringCopy(host, chost); + } #ifndef NO_WEBDAV - else if ((p = strfield(line, "Depth: "))) { - char* depth = line + p; - if (sscanf(depth, "%d", &davDepth) != 1) { - davDepth = 0; - } - } + else if ((p = strfield(line, "Depth: "))) { + char *depth = line + p; + + if (sscanf(depth, "%d", &davDepth) != 1) { + davDepth = 0; + } + } #endif - } + } - /* Flush body */ + /* Flush body */ #ifndef NO_WEBDAV - if (length > 0) { - if (length < 32768) { - StringRoom(davRequest, length + 1); - if (recv(soc_c, StringBuffRW(davRequest), length, 0) == length) { - StringBuffRW(davRequest)[length] = 0; - } else { - msgCode = 500; - msgError = "Posted Data Read Error"; - keepAlive = 0; - } - } else { - msgCode = 500; - msgError = "Posted Data Too Large"; - keepAlive = 0; - } - } + if (length > 0) { + if (length < 32768) { + StringRoom(davRequest, length + 1); + if (recv(soc_c, StringBuffRW(davRequest), length, 0) == length) { + StringBuffRW(davRequest)[length] = 0; + } else { + msgCode = 500; + msgError = "Posted Data Read Error"; + keepAlive = 0; + } + } else { + msgCode = 500; + msgError = "Posted Data Too Large"; + keepAlive = 0; + } + } #endif - /* Switch protocol ID */ - if (strcasecmp(command, "post") == 0) { + /* Switch protocol ID */ + if (strcasecmp(command, "post") == 0) { #ifndef NO_WEBDAV - msgCode = 404; + msgCode = 404; #else - msgCode = 501; - keepAlive = 0; + msgCode = 501; + keepAlive = 0; #endif - msgError = "Proxy Error (POST Request Forbidden)"; - } - else if (strcasecmp(command, "get") == 0) { - headRequest = 0; - } - else if (strcasecmp(command, "head") == 0) { - headRequest = 1; - } + msgError = "Proxy Error (POST Request Forbidden)"; + } else if (strcasecmp(command, "get") == 0) { + headRequest = 0; + } else if (strcasecmp(command, "head") == 0) { + headRequest = 1; + } #ifndef NO_WEBDAV - else if (strcasecmp(command, "options") == 0) { - const char * options = "GET, HEAD, OPTIONS, POST, PROPFIND, TRACE" - ", MKCOL, DELETE, PUT"; /* Not supported */ - msgCode = HTTP_OK; - StringRoom(headers, 8192); - sprintf(StringBuffRW(headers), - "HTTP/1.1 %d %s\r\n" - "DAV: 1, 2\r\n" - "MS-Author-Via: DAV\r\n" - "Cache-Control: private\r\n" - "Allow: %s\r\n", - msgCode, GetHttpMessage(msgCode), options); - StringLength(headers) = (int) strlen(StringBuff(headers)); - } - else if (strcasecmp(command, "propfind") == 0) { - if (davDepth > 1) { - msgCode = 403; - msgError = "DAV Depth Limit Forbidden"; - } else { - fprintf(stderr, "DEBUG: DAV-DATA=<%s>\n", StringBuff(davRequest)); - listRequest = 2; /* propfind */ - } - } - else if (strcasecmp(command, "mkcol") == 0 - || strcasecmp(command, "delete") == 0 - || strcasecmp(command, "put") == 0 - || strcasecmp(command, "proppatch") == 0 - || strcasecmp(command, "lock") == 0 - || strcasecmp(command, "unlock") == 0 - || strcasecmp(command, "copy") == 0 - || strcasecmp(command, "trace") == 0) - { - msgCode = 403; - msgError = "Method Forbidden"; - } + else if (strcasecmp(command, "options") == 0) { + const char *options = "GET, HEAD, OPTIONS, POST, PROPFIND, TRACE" ", MKCOL, DELETE, PUT"; /* Not supported */ + + msgCode = HTTP_OK; + StringRoom(headers, 8192); + sprintf(StringBuffRW(headers), + "HTTP/1.1 %d %s\r\n" "DAV: 1, 2\r\n" "MS-Author-Via: DAV\r\n" + "Cache-Control: private\r\n" "Allow: %s\r\n", msgCode, + GetHttpMessage(msgCode), options); + StringLength(headers) = (int) strlen(StringBuff(headers)); + } else if (strcasecmp(command, "propfind") == 0) { + if (davDepth > 1) { + msgCode = 403; + msgError = "DAV Depth Limit Forbidden"; + } else { + fprintf(stderr, "DEBUG: DAV-DATA=<%s>\n", StringBuff(davRequest)); + listRequest = 2; /* propfind */ + } + } else if (strcasecmp(command, "mkcol") == 0 + || strcasecmp(command, "delete") == 0 + || strcasecmp(command, "put") == 0 + || strcasecmp(command, "proppatch") == 0 + || strcasecmp(command, "lock") == 0 + || strcasecmp(command, "unlock") == 0 + || strcasecmp(command, "copy") == 0 + || strcasecmp(command, "trace") == 0) { + msgCode = 403; + msgError = "Method Forbidden"; + } #endif - else { - msgCode = 501; - msgError = "Proxy Error (Unsupported or Unknown HTTP Command Request)"; - keepAlive = 0; - } - if (strcasecmp(proto, "http/1.1") == 0) { - keepAlive = 1; - } else if (strcasecmp(proto, "http/1.0") == 0) { - keepAlive = 0; - } else { - msgCode = 505; - msgError = "Proxy Error (Unknown HTTP Version)"; - keepAlive = 0; - } - - /* Post-process request */ - if (link_has_authority(surl)) { - if (strncasecmp(surl, "http://proxytrack/", sizeof("http://proxytrack/") - 1) == 0) { - directHit = 1; /* Another direct hit hack */ - } - StringCopy(url, surl); - } else { - if (StringLength(host) > 0) { - /* Direct hit */ - if ( + else { + msgCode = 501; + msgError = "Proxy Error (Unsupported or Unknown HTTP Command Request)"; + keepAlive = 0; + } + if (strcasecmp(proto, "http/1.1") == 0) { + keepAlive = 1; + } else if (strcasecmp(proto, "http/1.0") == 0) { + keepAlive = 0; + } else { + msgCode = 505; + msgError = "Proxy Error (Unknown HTTP Version)"; + keepAlive = 0; + } + + /* Post-process request */ + if (link_has_authority(surl)) { + if (strncasecmp + (surl, "http://proxytrack/", + sizeof("http://proxytrack/") - 1) == 0) { + directHit = 1; /* Another direct hit hack */ + } + StringCopy(url, surl); + } else { + if (StringLength(host) > 0) { + /* Direct hit */ + if ( #ifndef NO_WEBDAV - listRequest != 2 - && + listRequest != 2 && #endif - strncasecmp(StringBuff(host), StringBuff(localhost), StringLength(localhost)) == 0 - && - (StringBuff(host)[StringLength(localhost)] == '\0' - || StringBuff(host)[StringLength(localhost)] == ':') - && surl[0] == '/' - ) - { - const char * toHit = surl + 1; - if (strncmp(toHit, "webdav/", 7) == 0) { - toHit += 7; - } - /* Direct hit */ - directHit = 1; - StringCopy(url, ""); - if (!link_has_authority(toHit)) - StringCat(url, "http://"); - StringCat(url, toHit); - } else if (strncasecmp(surl, "/proxytrack/", sizeof("/proxytrack/") - 1) == 0) { - const char * toHit = surl + sizeof("/proxytrack/") - 1; - /* Direct hit */ - directHit = 1; - StringCopy(url, ""); - if (!link_has_authority(toHit)) - StringCat(url, "http://"); - StringCat(url, toHit); - } else { - /* Transparent proxy */ - StringCopy(url, "http://"); - StringCat(url, StringBuff(host)); - StringCat(url, surl); - } - } else { - msgCode = 500; - msgError = "Transparent Proxy Error ('Host' HTTP Request Header Field Missing)"; - keepAlive = 0; - } - } - - /* Response */ - if (msgCode == 0) { - if (listRequest == 1) { - element = proxytrack_process_HTTP_List(indexes, StringBuff(url)); - } + strncasecmp(StringBuff(host), StringBuff(localhost), + StringLength(localhost)) == 0 + && (StringBuff(host)[StringLength(localhost)] == '\0' + || StringBuff(host)[StringLength(localhost)] == ':') + && surl[0] == '/') { + const char *toHit = surl + 1; + + if (strncmp(toHit, "webdav/", 7) == 0) { + toHit += 7; + } + /* Direct hit */ + directHit = 1; + StringCopy(url, ""); + if (!link_has_authority(toHit)) + StringCat(url, "http://"); + StringCat(url, toHit); + } else + if (strncasecmp(surl, "/proxytrack/", sizeof("/proxytrack/") - 1) == + 0) { + const char *toHit = surl + sizeof("/proxytrack/") - 1; + + /* Direct hit */ + directHit = 1; + StringCopy(url, ""); + if (!link_has_authority(toHit)) + StringCat(url, "http://"); + StringCat(url, toHit); + } else { + /* Transparent proxy */ + StringCopy(url, "http://"); + StringCat(url, StringBuff(host)); + StringCat(url, surl); + } + } else { + msgCode = 500; + msgError = + "Transparent Proxy Error ('Host' HTTP Request Header Field Missing)"; + keepAlive = 0; + } + } + + /* Response */ + if (msgCode == 0) { + if (listRequest == 1) { + element = proxytrack_process_HTTP_List(indexes, StringBuff(url)); + } #ifndef NO_WEBDAV - else if (listRequest == 2) { - if ((element = proxytrack_process_DAV_Request(indexes, StringBuff(url), davDepth)) != NULL) { - msgCode = element->statuscode; - StringRoom(davHeaders, 1024); - sprintf(StringBuffRW(davHeaders), - "DAV: 1, 2\r\n" - "MS-Author-Via: DAV\r\n" - "Cache-Control: private\r\n"); - StringLength(davHeaders) = (int) strlen(StringBuff(davHeaders)); - } - } + else if (listRequest == 2) { + if ((element = + proxytrack_process_DAV_Request(indexes, StringBuff(url), + davDepth)) != NULL) { + msgCode = element->statuscode; + StringRoom(davHeaders, 1024); + sprintf(StringBuffRW(davHeaders), + "DAV: 1, 2\r\n" "MS-Author-Via: DAV\r\n" + "Cache-Control: private\r\n"); + StringLength(davHeaders) = (int) strlen(StringBuff(davHeaders)); + } + } #endif - else { - element = PT_ReadIndex(indexes, StringBuff(url), FETCH_BODY); - } - if (element == NULL + else { + element = PT_ReadIndex(indexes, StringBuff(url), FETCH_BODY); + } + if (element == NULL #ifndef NO_WEBDAV - && listRequest == 2 + && listRequest == 2 #endif - && StringLength(url) > 0 - && StringBuff(url)[StringLength(url) - 1] == '/' - ) - { - element = PT_Index_HTML_BuildRootInfo(indexes); - if (element != NULL) { - element->statuscode = 404; /* HTML page, but in error */ - } - } - if (element != NULL) { - msgCode = element->statuscode; - StringRoom(headers, 8192); - sprintf(StringBuffRW(headers), - "HTTP/1.1 %d %s\r\n" + && StringLength(url) > 0 + && StringBuff(url)[StringLength(url) - 1] == '/') { + element = PT_Index_HTML_BuildRootInfo(indexes); + if (element != NULL) { + element->statuscode = 404; /* HTML page, but in error */ + } + } + if (element != NULL) { + msgCode = element->statuscode; + StringRoom(headers, 8192); + sprintf(StringBuffRW(headers), "HTTP/1.1 %d %s\r\n" #ifndef NO_WEBDAV - "%s" + "%s" #endif - "Content-Type: %s%s%s%s\r\n" - "%s%s%s" - "%s%s%s" - "%s%s%s", - /* */ - msgCode, - element->msg, + "Content-Type: %s%s%s%s\r\n" "%s%s%s" "%s%s%s" "%s%s%s", + /* */ + msgCode, element->msg, #ifndef NO_WEBDAV - /* DAV */ - StringBuff(davHeaders), + /* DAV */ + StringBuff(davHeaders), #endif - /* Content-type: foo; [ charset=bar ] */ - element->contenttype, - ( ( element->charset[0]) ? "; charset=\"" : ""), - element->charset, - ( ( element->charset[0]) ? "\"" : ""), - /* location */ - ( ( element->location != NULL && element->location[0]) ? "Location: " : ""), - ( ( element->location != NULL && element->location[0]) ? element->location : ""), - ( ( element->location != NULL && element->location[0]) ? "\r\n" : ""), - /* last-modified */ - ( ( element->lastmodified[0]) ? "Last-Modified: " : ""), - ( ( element->lastmodified[0]) ? element->lastmodified : ""), - ( ( element->lastmodified[0]) ? "\r\n" : ""), - /* etag */ - ( ( element->etag[0]) ? "ETag: " : ""), - ( ( element->etag[0]) ? element->etag : ""), - ( ( element->etag[0]) ? "\r\n" : "") - ); - StringLength(headers) = (int) strlen(StringBuff(headers)); - } else { - /* No query string, no ending / : check the the <url>/ page */ - if (StringLength(url) > 0 && StringBuff(url)[StringLength(url) - 1] != '/' && strchr(StringBuff(url), '?') == NULL) { - StringCopy(urlRedirect, StringBuff(url)); - StringCat(urlRedirect, "/"); - if (PT_LookupIndex(indexes, StringBuff(urlRedirect))) { - msgCode = 301; /* Moved Permanently */ - StringRoom(headers, 8192); - sprintf(StringBuffRW(headers), - "HTTP/1.1 %d %s\r\n" - "Content-Type: text/html\r\n" - "Location: %s\r\n", - /* */ - msgCode, - GetHttpMessage(msgCode), - StringBuff(urlRedirect) - ); - StringLength(headers) = (int) strlen(StringBuff(headers)); - /* */ - StringRoom(output, 1024 + sizeof(PROXYTRACK_COMMENT_HEADER) + sizeof(DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES)); - sprintf(StringBuffRW(output), - "<html>" - PROXYTRACK_COMMENT_HEADER - DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES - "<head>" - "<title>ProxyTrack - Page has moved</title>" - "</head>\r\n" - "<body>" - "<h3>The correct location is:</h3><br />" - "<b><a href=\"%s\">%s</a></b><br />" - "<br />" - "<br />\r\n" - "<i>Generated by ProxyTrack " PROXYTRACK_VERSION ", (C) Xavier Roche and other contributors</i>" - "\r\n" - "</body>" - "</header>", - StringBuff(urlRedirect), - StringBuff(urlRedirect)); - StringLength(output) = (int) strlen(StringBuff(output)); - } - } - if (msgCode == 0) { - msgCode = 404; - msgError = "Not Found in this cache"; - } - } - } - } else { - msgCode = 500; - msgError = "Server Error"; - keepAlive = 0; - } - if (StringLength(headers) == 0) { - if (msgCode == 0) { - msgCode = 500; - msgError = "Internal Proxy Error"; - } else if (msgError == NULL) { - msgError = GetHttpMessage(msgCode); - } - StringRoom(headers, 256); - sprintf(StringBuffRW(headers), - "HTTP/1.1 %d %s\r\n" - "Content-type: text/html\r\n", - msgCode, - msgError); - StringLength(headers) = (int) strlen(StringBuff(headers)); - StringRoom(output, 1024 + sizeof(PROXYTRACK_COMMENT_HEADER) + sizeof(DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES)); - sprintf(StringBuffRW(output), - "<html>" - PROXYTRACK_COMMENT_HEADER - DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES - "<head>" - "<title>ProxyTrack - HTTP Proxy Error %d</title>" - "</head>\r\n" - "<body>" - "<h3>A proxy error has occured while processing the request.</h3><br />" - "<b>Error HTTP %d: <i>%s</i></b><br />" - "<br />" - "<br />\r\n" - "<i>Generated by ProxyTrack " PROXYTRACK_VERSION ", (C) Xavier Roche and other contributors</i>" - "\r\n" - "</body>" - "</html>", - msgCode, - msgCode, - msgError); - StringLength(output) = (int) strlen(StringBuff(output)); - } - { - char tmp[20 + 1]; /* 2^64 = 18446744073709551616 */ - size_t dataSize = 0; - if (!headRequest) { - dataSize = StringLength(output); - if (dataSize == 0 && element != NULL) { - dataSize = element->size; - } - } - sprintf(tmp, "%d", (int) dataSize); - StringCat(headers, "Content-length: "); - StringCat(headers, tmp); - StringCat(headers, "\r\n"); - } - if (keepAlive) { - StringCat(headers, - "Connection: Keep-Alive\r\n" - "Proxy-Connection: Keep-Alive\r\n"); - } else { - StringCat(headers, - "Connection: Close\r\n" - "Proxy-Connection: Close\r\n"); - } - if (msgCode != 500) - StringCat(headers, "X-Cache: HIT from "); - else - StringCat(headers, "X-Cache: MISS from "); - StringCat(headers, StringBuff(localhost)); - StringCat(headers, "\r\n"); - - /* Logging */ - { - const char * contentType = "text/html"; - size_t size = StringLength(output) ? StringLength(output) : ( element ? element->size : 0 ); - /* */ - String ip = STRING_EMPTY; - SOCaddr serverClient; - SOClen lenServerClient = (int) sizeof(serverClient); - memset(&serverClient, 0, sizeof(serverClient)); - if (getsockname(soc_c, (struct sockaddr*) &serverClient, &lenServerClient) == 0) { - ip = getip(&serverClient, lenServerClient); - } else { - StringCopy(ip, "unknown"); - } - if (element != NULL && element->contenttype[0] != '\0') { - contentType = element->contenttype; - } - proxytrack_print_log(LOG, "HTTP %s %d %d %s %s %s", StringBuff(ip), msgCode, (int)size, command, StringBuff(url), contentType); - StringFree(ip); - } - - /* Send reply */ - StringCat(headers, "Server: ProxyTrack " PROXYTRACK_VERSION " (HTTrack " HTTRACK_VERSIONID ")\r\n"); - StringCat(headers, "\r\n"); /* Headers separator */ - if (send(soc_c, StringBuff(headers), (int)StringLength(headers), 0) != StringLength(headers) - || ( !headRequest && StringLength(output) > 0 && send(soc_c, StringBuff(output), (int)StringLength(output), 0) != StringLength(output)) - || ( !headRequest && StringLength(output) == 0 && element != NULL && element->adr != NULL && send(soc_c, element->adr, (int)element->size, 0) != element->size) - ) - { - keepAlive = 0; /* Error, abort connection */ - } - PT_Element_Delete(&element); - - /* Shutdown (FIN) and wait until confirmed */ - if (!keepAlive) { - char c; + /* Content-type: foo; [ charset=bar ] */ + element->contenttype, + ((element->charset[0]) ? "; charset=\"" : ""), + element->charset, ((element->charset[0]) ? "\"" : ""), + /* location */ + ((element->location != NULL + && element->location[0]) ? "Location: " : ""), + ((element->location != NULL + && element->location[0]) ? element->location : ""), + ((element->location != NULL + && element->location[0]) ? "\r\n" : ""), + /* last-modified */ + ((element->lastmodified[0]) ? "Last-Modified: " : ""), + ((element->lastmodified[0]) ? element->lastmodified : ""), + ((element->lastmodified[0]) ? "\r\n" : ""), + /* etag */ + ((element->etag[0]) ? "ETag: " : ""), + ((element->etag[0]) ? element->etag : ""), + ((element->etag[0]) ? "\r\n" : "") + ); + StringLength(headers) = (int) strlen(StringBuff(headers)); + } else { + /* No query string, no ending / : check the the <url>/ page */ + if (StringLength(url) > 0 + && StringBuff(url)[StringLength(url) - 1] != '/' + && strchr(StringBuff(url), '?') == NULL) { + StringCopy(urlRedirect, StringBuff(url)); + StringCat(urlRedirect, "/"); + if (PT_LookupIndex(indexes, StringBuff(urlRedirect))) { + msgCode = 301; /* Moved Permanently */ + StringRoom(headers, 8192); + sprintf(StringBuffRW(headers), + "HTTP/1.1 %d %s\r\n" "Content-Type: text/html\r\n" + "Location: %s\r\n", + /* */ + msgCode, GetHttpMessage(msgCode), StringBuff(urlRedirect) + ); + StringLength(headers) = (int) strlen(StringBuff(headers)); + /* */ + StringRoom(output, + 1024 + sizeof(PROXYTRACK_COMMENT_HEADER) + + sizeof(DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES)); + sprintf(StringBuffRW(output), + "<html>" PROXYTRACK_COMMENT_HEADER + DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES "<head>" + "<title>ProxyTrack - Page has moved</title>" "</head>\r\n" + "<body>" "<h3>The correct location is:</h3><br />" + "<b><a href=\"%s\">%s</a></b><br />" "<br />" "<br />\r\n" + "<i>Generated by ProxyTrack " PROXYTRACK_VERSION + ", (C) Xavier Roche and other contributors</i>" "\r\n" + "</body>" "</header>", StringBuff(urlRedirect), + StringBuff(urlRedirect)); + StringLength(output) = (int) strlen(StringBuff(output)); + } + } + if (msgCode == 0) { + msgCode = 404; + msgError = "Not Found in this cache"; + } + } + } + } else { + msgCode = 500; + msgError = "Server Error"; + keepAlive = 0; + } + if (StringLength(headers) == 0) { + if (msgCode == 0) { + msgCode = 500; + msgError = "Internal Proxy Error"; + } else if (msgError == NULL) { + msgError = GetHttpMessage(msgCode); + } + StringRoom(headers, 256); + sprintf(StringBuffRW(headers), + "HTTP/1.1 %d %s\r\n" "Content-type: text/html\r\n", msgCode, + msgError); + StringLength(headers) = (int) strlen(StringBuff(headers)); + StringRoom(output, + 1024 + sizeof(PROXYTRACK_COMMENT_HEADER) + + sizeof(DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES)); + sprintf(StringBuffRW(output), + "<html>" PROXYTRACK_COMMENT_HEADER + DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES "<head>" + "<title>ProxyTrack - HTTP Proxy Error %d</title>" "</head>\r\n" + "<body>" + "<h3>A proxy error has occured while processing the request.</h3><br />" + "<b>Error HTTP %d: <i>%s</i></b><br />" "<br />" "<br />\r\n" + "<i>Generated by ProxyTrack " PROXYTRACK_VERSION + ", (C) Xavier Roche and other contributors</i>" "\r\n" "</body>" + "</html>", msgCode, msgCode, msgError); + StringLength(output) = (int) strlen(StringBuff(output)); + } + { + char tmp[20 + 1]; /* 2^64 = 18446744073709551616 */ + size_t dataSize = 0; + + if (!headRequest) { + dataSize = StringLength(output); + if (dataSize == 0 && element != NULL) { + dataSize = element->size; + } + } + sprintf(tmp, "%d", (int) dataSize); + StringCat(headers, "Content-length: "); + StringCat(headers, tmp); + StringCat(headers, "\r\n"); + } + if (keepAlive) { + StringCat(headers, + "Connection: Keep-Alive\r\n" + "Proxy-Connection: Keep-Alive\r\n"); + } else { + StringCat(headers, "Connection: Close\r\n" "Proxy-Connection: Close\r\n"); + } + if (msgCode != 500) + StringCat(headers, "X-Cache: HIT from "); + else + StringCat(headers, "X-Cache: MISS from "); + StringCat(headers, StringBuff(localhost)); + StringCat(headers, "\r\n"); + + /* Logging */ + { + const char *contentType = "text/html"; + size_t size = + StringLength(output) ? StringLength(output) : (element ? element-> + size : 0); + /* */ + String ip = STRING_EMPTY; + SOCaddr serverClient; + SOClen lenServerClient = (int) sizeof(serverClient); + + memset(&serverClient, 0, sizeof(serverClient)); + if (getsockname + (soc_c, (struct sockaddr *) &serverClient, &lenServerClient) == 0) { + ip = getip(&serverClient, lenServerClient); + } else { + StringCopy(ip, "unknown"); + } + if (element != NULL && element->contenttype[0] != '\0') { + contentType = element->contenttype; + } + proxytrack_print_log(LOG, "HTTP %s %d %d %s %s %s", StringBuff(ip), + msgCode, (int) size, command, StringBuff(url), + contentType); + StringFree(ip); + } + + /* Send reply */ + StringCat(headers, + "Server: ProxyTrack " PROXYTRACK_VERSION " (HTTrack " + HTTRACK_VERSIONID ")\r\n"); + StringCat(headers, "\r\n"); /* Headers separator */ + if (send(soc_c, StringBuff(headers), (int) StringLength(headers), 0) != + StringLength(headers) + || (!headRequest && StringLength(output) > 0 + && send(soc_c, StringBuff(output), (int) StringLength(output), + 0) != StringLength(output)) + || (!headRequest && StringLength(output) == 0 && element != NULL + && element->adr != NULL + && send(soc_c, element->adr, (int) element->size, + 0) != element->size) + ) { + keepAlive = 0; /* Error, abort connection */ + } + PT_Element_Delete(&element); + + /* Shutdown (FIN) and wait until confirmed */ + if (!keepAlive) { + char c; + #ifdef _WIN32 - shutdown(soc_c, SD_SEND); + shutdown(soc_c, SD_SEND); #else - shutdown(soc_c, 1); + shutdown(soc_c, 1); #endif - while(recv(soc_c, ((char*)&c), 1, 0) > 0); - } - } while(keepAlive); + while(recv(soc_c, ((char *) &c), 1, 0) > 0) ; + } + } while(keepAlive); #ifdef _WIN32 - closesocket(soc_c); + closesocket(soc_c); #else - close(soc_c); + close(soc_c); #endif - StringFree(url); - StringFree(urlRedirect); - StringFree(headers); - StringFree(output); - StringFree(host); - StringFree(localhost); + StringFree(url); + StringFree(urlRedirect); + StringFree(headers); + StringFree(output); + StringFree(host); + StringFree(localhost); #ifndef NO_WEBDAV - StringFree(davHeaders); - StringFree(davRequest); + StringFree(davHeaders); + StringFree(davRequest); #endif - if (buffer) - free(buffer); - if (line) - free(line); - if (line1) - free(line1); + if (buffer) + free(buffer); + if (line) + free(line); + if (line1) + free(line1); } /* Generic threaded function start */ -static int startThread(void (*funct)(void*), void* param) -{ - if (param != NULL) { +static int startThread(void (*funct) (void *), void *param) { + if (param != NULL) { #ifdef _WIN32 - if (_beginthread(funct, 0, param) == -1) { - free(param); - return 0; - } - return 1; + if (_beginthread(funct, 0, param) == -1) { + free(param); + return 0; + } + return 1; #else - pthread_t handle = 0; - int retcode; - retcode = pthread_create(&handle, NULL, funct, param); - if (retcode != 0) { /* error */ - free(param); - return 0; - } else { - /* detach the thread from the main process so that is can be independent */ - pthread_detach(handle); - return 1; - } + pthread_t handle = 0; + int retcode; + + retcode = pthread_create(&handle, NULL, funct, param); + if (retcode != 0) { /* error */ + free(param); + return 0; + } else { + /* detach the thread from the main process so that is can be independent */ + pthread_detach(handle); + return 1; + } #endif - } else { - return 0; - } + } else { + return 0; + } } /* Generic socket/index structure */ typedef struct proxytrack_process_th_p { - T_SOC soc_c; - PT_Indexes indexes; - void (*process)(PT_Indexes indexes, T_SOC soc_c); + T_SOC soc_c; + PT_Indexes indexes; + void (*process) (PT_Indexes indexes, T_SOC soc_c); } proxytrack_process_th_p; /* Generic socket/index function stub */ -static void proxytrack_process_th(void* param_) { - proxytrack_process_th_p *param = (proxytrack_process_th_p *) param_; - T_SOC soc_c = param->soc_c; - PT_Indexes indexes = param->indexes; - void (*process)(PT_Indexes indexes, T_SOC soc_c) = param->process; - free(param); - process(indexes, soc_c); - return ; +static void proxytrack_process_th(void *param_) { + proxytrack_process_th_p *param = (proxytrack_process_th_p *) param_; + T_SOC soc_c = param->soc_c; + PT_Indexes indexes = param->indexes; + void (*process) (PT_Indexes indexes, T_SOC soc_c) = param->process; + + free(param); + process(indexes, soc_c); + return; } /* Process generic socket/index operation */ -static int proxytrack_process_generic(void (*process)(PT_Indexes indexes, T_SOC soc_c), - PT_Indexes indexes, T_SOC soc_c) -{ - proxytrack_process_th_p *param = calloc(sizeof(proxytrack_process_th_p), 1); - if (param != NULL) { - param->soc_c = soc_c; - param->indexes = indexes; - param->process = process; - return startThread(proxytrack_process_th, param); - } else { - proxytrack_print_log(CRITICAL, "proxytrack_process_generic:Memory exhausted"); - return 0; - } - return 0; +static int +proxytrack_process_generic(void (*process) (PT_Indexes indexes, T_SOC soc_c), + PT_Indexes indexes, T_SOC soc_c) { + proxytrack_process_th_p *param = calloc(sizeof(proxytrack_process_th_p), 1); + + if (param != NULL) { + param->soc_c = soc_c; + param->indexes = indexes; + param->process = process; + return startThread(proxytrack_process_th, param); + } else { + proxytrack_print_log(CRITICAL, + "proxytrack_process_generic:Memory exhausted"); + return 0; + } + return 0; } /* Process HTTP proxy requests */ static int proxytrack_process_HTTP_threaded(PT_Indexes indexes, T_SOC soc) { - return proxytrack_process_generic(proxytrack_process_HTTP, indexes, soc); + return proxytrack_process_generic(proxytrack_process_HTTP, indexes, soc); } /* HTTP Server */ static int proxytrack_start_HTTP(PT_Indexes indexes, T_SOC soc) { - while(soc != INVALID_SOCKET) { + while(soc != INVALID_SOCKET) { T_SOC soc_c; - if ( (soc_c = (T_SOC) accept(soc, NULL, NULL)) != INVALID_SOCKET) { - if (!proxytrack_process_HTTP_threaded(indexes, soc_c)) { - proxytrack_print_log(CRITICAL, "proxytrack_start_HTTP::Can not fork a thread"); - } - } - } - if (soc != INVALID_SOCKET) { + + if ((soc_c = (T_SOC) accept(soc, NULL, NULL)) != INVALID_SOCKET) { + if (!proxytrack_process_HTTP_threaded(indexes, soc_c)) { + proxytrack_print_log(CRITICAL, + "proxytrack_start_HTTP::Can not fork a thread"); + } + } + } + if (soc != INVALID_SOCKET) { #ifdef _WIN32 - closesocket(soc); + closesocket(soc); #else - close(soc); + close(soc); #endif - } - return 1; + } + return 1; } /* Network order is big endian */ @@ -1403,191 +1506,208 @@ static int proxytrack_start_HTTP(PT_Indexes indexes, T_SOC soc) { WRITE_NET16(((unsigned char*)buffer) + 2, ( ((unsigned int)(value)) ) & 0xffff); \ } while(0) -static int ICP_reply(struct sockaddr * clientAddr, - int clientAddrLen, - T_SOC soc, - /* */ - unsigned char Opcode, - unsigned char Version, - unsigned short Message_Length, - unsigned int Request_Number, - unsigned int Options, - unsigned int Option_Data, - unsigned int Sender_Host_Address, - unsigned char *Message - ) -{ - int ret = 0; - unsigned long int BufferSize; - unsigned char * buffer; - if (Message_Length == 0 && Message != NULL) /* We have to get the message size */ - Message_Length = (unsigned int) strlen(Message) + 1; /* NULL terminated */ - BufferSize = 20 + Message_Length; - buffer = malloc(BufferSize); - if (buffer != NULL) { - WRITE_NET8(&buffer[0], Opcode); - WRITE_NET8(&buffer[1], Version); - WRITE_NET16(&buffer[2], Message_Length); - WRITE_NET32(&buffer[4], Request_Number); - WRITE_NET32(&buffer[8], Options); - WRITE_NET32(&buffer[12], Option_Data); - WRITE_NET32(&buffer[16], Sender_Host_Address); - if (Message != NULL && Message_Length > 0) { - memcpy(buffer + 20, Message, Message_Length); - } - if (sendto(soc, buffer, BufferSize, 0, clientAddr, clientAddrLen) == BufferSize) { - ret = 1; - } - free(buffer); - } - return ret; +static int ICP_reply(struct sockaddr *clientAddr, int clientAddrLen, T_SOC soc, + /* */ + unsigned char Opcode, unsigned char Version, + unsigned short Message_Length, unsigned int Request_Number, + unsigned int Options, unsigned int Option_Data, + unsigned int Sender_Host_Address, unsigned char *Message) { + int ret = 0; + unsigned long int BufferSize; + unsigned char *buffer; + + if (Message_Length == 0 && Message != NULL) /* We have to get the message size */ + Message_Length = (unsigned int) strlen(Message) + 1; /* NULL terminated */ + BufferSize = 20 + Message_Length; + buffer = malloc(BufferSize); + if (buffer != NULL) { + WRITE_NET8(&buffer[0], Opcode); + WRITE_NET8(&buffer[1], Version); + WRITE_NET16(&buffer[2], Message_Length); + WRITE_NET32(&buffer[4], Request_Number); + WRITE_NET32(&buffer[8], Options); + WRITE_NET32(&buffer[12], Option_Data); + WRITE_NET32(&buffer[16], Sender_Host_Address); + if (Message != NULL && Message_Length > 0) { + memcpy(buffer + 20, Message, Message_Length); + } + if (sendto(soc, buffer, BufferSize, 0, clientAddr, clientAddrLen) == + BufferSize) { + ret = 1; + } + free(buffer); + } + return ret; } /* ICP Server */ static int proxytrack_start_ICP(PT_Indexes indexes, T_SOC soc) { - /* "ICP messages MUST not exceed 16,384 octets in length." (RFC2186) */ - int bufferSize = 16384; - unsigned char * buffer = (unsigned char*) malloc(bufferSize + 1); - if (buffer == NULL) { - proxytrack_print_log(CRITICAL, "proxytrack_start_ICP:memory exhausted"); + /* "ICP messages MUST not exceed 16,384 octets in length." (RFC2186) */ + int bufferSize = 16384; + unsigned char *buffer = (unsigned char *) malloc(bufferSize + 1); + + if (buffer == NULL) { + proxytrack_print_log(CRITICAL, "proxytrack_start_ICP:memory exhausted"); #ifdef _WIN32 - closesocket(soc); + closesocket(soc); #else - close(soc); + close(soc); #endif - return -1; - } - while(soc != INVALID_SOCKET) { - struct sockaddr clientAddr; - SOClen clientAddrLen = sizeof(struct sockaddr); - int n; - memset(&clientAddr, 0, sizeof(clientAddr)); - n = recvfrom(soc, (char*)buffer, bufferSize, 0, &clientAddr, &clientAddrLen); - if (n != -1) { - const char * LogRequest = "ERROR"; - const char * LogReply = "ERROR"; - unsigned char * UrlRequest = NULL; - if (n >= 20) { - enum { - ICP_OP_MIN = 0, - ICP_OP_INVALID = 0, - ICP_OP_QUERY = 1, - ICP_OP_HIT = 2, - ICP_OP_MISS = 3, - ICP_OP_ERR = 4, - ICP_OP_SECHO = 10, - ICP_OP_DECHO = 11, - ICP_OP_MISS_NOFETCH = 21, - ICP_OP_DENIED = 22, - ICP_OP_HIT_OBJ = 23, - ICP_OP_MAX = ICP_OP_HIT_OBJ - }; - unsigned char Opcode = buffer[0]; - unsigned char Version = buffer[1]; - unsigned short Message_Length = READ_NET16(&buffer[2]); - unsigned int Request_Number = READ_NET32(&buffer[4]); /* Session ID */ - unsigned int Options = READ_NET32(&buffer[8]); - unsigned int Option_Data = READ_NET32(&buffer[12]); /* ICP_FLAG_SRC_RTT */ - unsigned int Sender_Host_Address = READ_NET32(&buffer[16]); /* ignored */ - unsigned char* Payload = &buffer[20]; - buffer[bufferSize] = '\0'; /* Ensure payload is NULL terminated */ - if (Message_Length <= bufferSize - 20) { - if (Opcode >= ICP_OP_MIN && Opcode <= ICP_OP_MAX) { - if (Version == 2) { - switch(Opcode) { - case ICP_OP_QUERY: - { - unsigned int UrlRequestSize; - UrlRequest = &Payload[4]; - UrlRequestSize = (unsigned int)strlen((char*)UrlRequest); - LogRequest = "ICP_OP_QUERY"; - if (indexes == NULL) { - ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_DENIED, Version, 0, Request_Number, 0, 0, 0, UrlRequest); - LogReply = "ICP_OP_DENIED"; - } else if (PT_LookupIndex(indexes, UrlRequest)) { - ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_HIT, Version, 0, Request_Number, 0, 0, 0, UrlRequest); - LogReply = "ICP_OP_HIT"; - } else { - if (UrlRequestSize > 0 && UrlRequest[UrlRequestSize - 1] != '/' && strchr(UrlRequest, '?') == NULL) { - char * UrlRedirect = malloc(UrlRequestSize + 1 + 1); - if (UrlRedirect != NULL) { - sprintf(UrlRedirect, "%s/", UrlRequest); - if (PT_LookupIndex(indexes, UrlRedirect)) { /* We'll generate a redirect */ - ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_HIT, Version, 0, Request_Number, 0, 0, 0, UrlRequest); - LogReply = "ICP_OP_HIT"; - free(UrlRedirect); - break; - } - free(UrlRedirect); - } - } - /* We won't retrive the cache MISS online, no way! */ - ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_MISS_NOFETCH, Version, 0, Request_Number, 0, 0, 0, UrlRequest); - LogReply = "ICP_OP_MISS_NOFETCH"; - } - } - break; - case ICP_OP_SECHO: - { - UrlRequest = &Payload[4]; - LogRequest = "ICP_OP_QUERY"; - LogReply = "ICP_OP_QUERY"; - ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_SECHO, Version, 0, Request_Number, 0, 0, 0, UrlRequest); - } - break; - default: - LogRequest = "NOTIMPLEMENTED"; - LogReply = "ICP_OP_ERR"; - ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_ERR, Version, 0, Request_Number, 0, 0, 0, NULL); - break; - } - } else { - ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_ERR, 2, 0, Request_Number, 0, 0, 0, NULL); - } - } /* Ignored (RFC2186) */ - } else { - ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_ERR, Version, 0, Request_Number, 0, 0, 0, NULL); - } - } - - /* Logging */ - { - String ip = STRING_EMPTY; - SOCaddr serverClient; - int lenServerClient = (int) sizeof(serverClient); - SOCaddr_copyaddr(serverClient, lenServerClient, &clientAddr, clientAddrLen); - if (lenServerClient > 0) { - ip = getip(&serverClient, lenServerClient); - } else { - StringCopy(ip, "unknown"); - } - proxytrack_print_log(LOG, "ICP %s %s/%s %s", StringBuff(ip), LogRequest, LogReply, (UrlRequest ? UrlRequest : "-") ); - StringFree(ip); - } - - } - } - if (soc != INVALID_SOCKET) { + return -1; + } + while(soc != INVALID_SOCKET) { + struct sockaddr clientAddr; + SOClen clientAddrLen = sizeof(struct sockaddr); + int n; + + memset(&clientAddr, 0, sizeof(clientAddr)); + n = + recvfrom(soc, (char *) buffer, bufferSize, 0, &clientAddr, + &clientAddrLen); + if (n != -1) { + const char *LogRequest = "ERROR"; + const char *LogReply = "ERROR"; + unsigned char *UrlRequest = NULL; + + if (n >= 20) { + enum { + ICP_OP_MIN = 0, + ICP_OP_INVALID = 0, + ICP_OP_QUERY = 1, + ICP_OP_HIT = 2, + ICP_OP_MISS = 3, + ICP_OP_ERR = 4, + ICP_OP_SECHO = 10, + ICP_OP_DECHO = 11, + ICP_OP_MISS_NOFETCH = 21, + ICP_OP_DENIED = 22, + ICP_OP_HIT_OBJ = 23, + ICP_OP_MAX = ICP_OP_HIT_OBJ + }; + unsigned char Opcode = buffer[0]; + unsigned char Version = buffer[1]; + unsigned short Message_Length = READ_NET16(&buffer[2]); + unsigned int Request_Number = READ_NET32(&buffer[4]); /* Session ID */ + unsigned int Options = READ_NET32(&buffer[8]); + unsigned int Option_Data = READ_NET32(&buffer[12]); /* ICP_FLAG_SRC_RTT */ + unsigned int Sender_Host_Address = READ_NET32(&buffer[16]); /* ignored */ + unsigned char *Payload = &buffer[20]; + + buffer[bufferSize] = '\0'; /* Ensure payload is NULL terminated */ + if (Message_Length <= bufferSize - 20) { + if (Opcode >= ICP_OP_MIN && Opcode <= ICP_OP_MAX) { + if (Version == 2) { + switch (Opcode) { + case ICP_OP_QUERY: + { + unsigned int UrlRequestSize; + + UrlRequest = &Payload[4]; + UrlRequestSize = (unsigned int) strlen((char *) UrlRequest); + LogRequest = "ICP_OP_QUERY"; + if (indexes == NULL) { + ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_DENIED, + Version, 0, Request_Number, 0, 0, 0, UrlRequest); + LogReply = "ICP_OP_DENIED"; + } else if (PT_LookupIndex(indexes, UrlRequest)) { + ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_HIT, + Version, 0, Request_Number, 0, 0, 0, UrlRequest); + LogReply = "ICP_OP_HIT"; + } else { + if (UrlRequestSize > 0 + && UrlRequest[UrlRequestSize - 1] != '/' + && strchr(UrlRequest, '?') == NULL) { + char *UrlRedirect = malloc(UrlRequestSize + 1 + 1); + + if (UrlRedirect != NULL) { + sprintf(UrlRedirect, "%s/", UrlRequest); + if (PT_LookupIndex(indexes, UrlRedirect)) { /* We'll generate a redirect */ + ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_HIT, + Version, 0, Request_Number, 0, 0, 0, + UrlRequest); + LogReply = "ICP_OP_HIT"; + free(UrlRedirect); + break; + } + free(UrlRedirect); + } + } + /* We won't retrive the cache MISS online, no way! */ + ICP_reply(&clientAddr, clientAddrLen, soc, + ICP_OP_MISS_NOFETCH, Version, 0, Request_Number, + 0, 0, 0, UrlRequest); + LogReply = "ICP_OP_MISS_NOFETCH"; + } + } + break; + case ICP_OP_SECHO: + { + UrlRequest = &Payload[4]; + LogRequest = "ICP_OP_QUERY"; + LogReply = "ICP_OP_QUERY"; + ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_SECHO, + Version, 0, Request_Number, 0, 0, 0, UrlRequest); + } + break; + default: + LogRequest = "NOTIMPLEMENTED"; + LogReply = "ICP_OP_ERR"; + ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_ERR, Version, + 0, Request_Number, 0, 0, 0, NULL); + break; + } + } else { + ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_ERR, 2, 0, + Request_Number, 0, 0, 0, NULL); + } + } /* Ignored (RFC2186) */ + } else { + ICP_reply(&clientAddr, clientAddrLen, soc, ICP_OP_ERR, Version, 0, + Request_Number, 0, 0, 0, NULL); + } + } + + /* Logging */ + { + String ip = STRING_EMPTY; + SOCaddr serverClient; + int lenServerClient = (int) sizeof(serverClient); + + SOCaddr_copyaddr(serverClient, lenServerClient, &clientAddr, + clientAddrLen); + if (lenServerClient > 0) { + ip = getip(&serverClient, lenServerClient); + } else { + StringCopy(ip, "unknown"); + } + proxytrack_print_log(LOG, "ICP %s %s/%s %s", StringBuff(ip), LogRequest, + LogReply, (UrlRequest ? UrlRequest : "-")); + StringFree(ip); + } + + } + } + if (soc != INVALID_SOCKET) { #ifdef _WIN32 - closesocket(soc); + closesocket(soc); #else - close(soc); + close(soc); #endif - } - free(buffer); - return 1; + } + free(buffer); + return 1; } static int proxytrack_start(PT_Indexes indexes, T_SOC soc, T_SOC socICP) { - int ret = 1; - if (proxytrack_process_generic(proxytrack_start_ICP, indexes, socICP)) { - //if (!proxytrack_process_generic(proxytrack_start_HTTP, indexes, soc)) - if (!proxytrack_start_HTTP(indexes, soc)) { - ret = 0; - } - } else { - ret = 0; - } - return ret; -} + int ret = 1; + if (proxytrack_process_generic(proxytrack_start_ICP, indexes, socICP)) { + //if (!proxytrack_process_generic(proxytrack_start_HTTP, indexes, soc)) + if (!proxytrack_start_HTTP(indexes, soc)) { + ret = 0; + } + } else { + ret = 0; + } + return ret; +} diff --git a/src/proxy/proxytrack.h b/src/proxy/proxytrack.h index ae5af27..6152919 100644 --- a/src/proxy/proxytrack.h +++ b/src/proxy/proxytrack.h @@ -53,9 +53,8 @@ Please visit our Website: http://www.httrack.com /* generic */ -int proxytrack_main(char* proxyAddr, int proxyPort, - char* icpAddr, int icpPort, - PT_Indexes index); +int proxytrack_main(char *proxyAddr, int proxyPort, char *icpAddr, int icpPort, + PT_Indexes index); /* Spaces: CR,LF,TAB,FF */ #define is_space(c) ( ((c)==' ') || ((c)=='\"') || ((c)==10) || ((c)==13) || ((c)==9) || ((c)==12) || ((c)==11) || ((c)=='\'') ) @@ -71,6 +70,7 @@ static void proxytrack_print_log(const char *severity, const char *format, ...) const int error = errno; FILE *const fp = stderr; va_list args; + fprintf(fp, " * %s: ", severity); va_start(args, format); (void) vfprintf(fp, format, args); @@ -110,90 +110,105 @@ static void proxytrack_print_log(const char *severity, const char *format, ...) "<!-- _-._.--._._-._.--._._-._.--._._-._.--._._-._.--._. -->\r\n" \ "<!-- End Disable IE Friendly HTTP Error Messages -->\r\n" -static char* gethomedir(void) { - char* home = getenv( "HOME" ); +static char *gethomedir(void) { + char *home = getenv("HOME"); + if (home) return home; else return "."; } -static int linput(FILE* fp,char* s,int max) { +static int linput(FILE * fp, char *s, int max) { int c; - int j=0; + int j = 0; + do { - c=fgetc(fp); - if (c!=EOF) { - switch(c) { - case 13: break; // sauter CR - case 10: c=-1; break; - case 0: case 9: case 12: break; // sauter ces caractères - default: s[j++]=(char) c; break; + c = fgetc(fp); + if (c != EOF) { + switch (c) { + case 13: + break; // sauter CR + case 10: + c = -1; + break; + case 0: + case 9: + case 12: + break; // sauter ces caractères + default: + s[j++] = (char) c; + break; } } - } while((c!=-1) && (c!=EOF) && (j<(max-1))); - s[j]='\0'; + } while((c != -1) && (c != EOF) && (j < (max - 1))); + s[j] = '\0'; return j; } -static int link_has_authority(const char* lien) { - const char* a=lien; - if (isalpha((const unsigned char)*a)) { +static int link_has_authority(const char *lien) { + const char *a = lien; + + if (isalpha((const unsigned char) *a)) { // Skip scheme? - while (isalpha((const unsigned char)*a)) + while(isalpha((const unsigned char) *a)) a++; if (*a == ':') a++; else return 0; } - if (strncmp(a,"//",2) == 0) + if (strncmp(a, "//", 2) == 0) return 1; return 0; } -static const char* jump_protocol(const char* source) { +static const char *jump_protocol(const char *source) { int p; + // scheme // "Comparisons of scheme names MUST be case-insensitive" (RFC2616) - if ((p = strfield(source,"http:"))) - source+=p; - else if ((p = strfield(source,"ftp:"))) - source+=p; - else if ((p = strfield(source,"https:"))) - source+=p; - else if ((p = strfield(source,"file:"))) - source+=p; - else if ((p = strfield(source,"mms:"))) - source+=p; + if ((p = strfield(source, "http:"))) + source += p; + else if ((p = strfield(source, "ftp:"))) + source += p; + else if ((p = strfield(source, "https:"))) + source += p; + else if ((p = strfield(source, "file:"))) + source += p; + else if ((p = strfield(source, "mms:"))) + source += p; // net_path - if (strncmp(source,"//",2)==0) - source+=2; + if (strncmp(source, "//", 2) == 0) + source += 2; return source; } -static const char* strrchr_limit(const char* s, char c, const char* limit) { +static const char *strrchr_limit(const char *s, char c, const char *limit) { if (limit == NULL) { - char* p = strrchr(s, c); - return p?(p+1):NULL; + char *p = strrchr(s, c); + + return p ? (p + 1) : NULL; } else { - char *a=NULL, *p; + char *a = NULL, *p; + for(;;) { - p=strchr((a)?a:s, c); + p = strchr((a) ? a : s, c); if ((p >= limit) || (p == NULL)) return a; - a=p+1; + a = p + 1; } } } -static const char* jump_protocol_and_auth(const char* source) { - const char *a,*trytofind; +static const char *jump_protocol_and_auth(const char *source) { + const char *a, *trytofind; + if (strcmp(source, "file://") == 0) - return source; + return source; a = jump_protocol(source); - trytofind = strrchr_limit(a, '@', strchr(a,'/')); - return (trytofind != NULL)?trytofind:a; + trytofind = strrchr_limit(a, '@', strchr(a, '/')); + return (trytofind != NULL) ? trytofind : a; } #ifndef min @@ -202,27 +217,29 @@ static const char* jump_protocol_and_auth(const char* source) { #ifndef max #define max(a,b) ((a)>(b)?(a):(b)) #endif -static int linput_trim(FILE* fp,char* s,int max) { - int rlen=0; - char* ls=(char*) malloc(max+2); - s[0]='\0'; +static int linput_trim(FILE * fp, char *s, int max) { + int rlen = 0; + char *ls = (char *) malloc(max + 2); + + s[0] = '\0'; if (ls) { - char* a; + char *a; + // lire ligne - rlen=linput(fp,ls,max); + rlen = linput(fp, ls, max); if (rlen) { // sauter espaces et tabs en fin - while( (rlen>0) && is_realspace(ls[max(rlen-1,0)]) ) - ls[--rlen]='\0'; + while((rlen > 0) && is_realspace(ls[max(rlen - 1, 0)])) + ls[--rlen] = '\0'; // sauter espaces en début - a=ls; - while((rlen>0) && ((*a==' ') || (*a=='\t'))) { + a = ls; + while((rlen > 0) && ((*a == ' ') || (*a == '\t'))) { a++; rlen--; } - if (rlen>0) { - memcpy(s,a,rlen); // can copy \0 chars - s[rlen]='\0'; + if (rlen > 0) { + memcpy(s, a, rlen); // can copy \0 chars + s[rlen] = '\0'; } } // @@ -234,8 +251,9 @@ static int linput_trim(FILE* fp,char* s,int max) { #ifndef S_ISREG #define S_ISREG(m) ((m) & _S_IFREG) #endif -static int fexist(char* s) { +static int fexist(char *s) { struct stat st; + memset(&st, 0, sizeof(st)); if (stat(s, &st) == 0) { if (S_ISREG(st.st_mode)) { @@ -243,137 +261,155 @@ static int fexist(char* s) { } } return 0; -} +} /* convertir une chaine en temps */ -static void set_lowcase(char* s) { +static void set_lowcase(char *s) { int i; - for(i=0;i<(int) strlen(s);i++) - if ((s[i]>='A') && (s[i]<='Z')) - s[i]+=('a'-'A'); + + for(i = 0; i < (int) strlen(s); i++) + if ((s[i] >= 'A') && (s[i] <= 'Z')) + s[i] += ('a' - 'A'); } -static struct tm* convert_time_rfc822(struct tm *result,const char* s) { - char months[]="jan feb mar apr may jun jul aug sep oct nov dec"; +static struct tm *convert_time_rfc822(struct tm *result, const char *s) { + char months[] = "jan feb mar apr may jun jul aug sep oct nov dec"; char str[256]; - char* a; + char *a; + /* */ - int result_mm=-1; - int result_dd=-1; - int result_n1=-1; - int result_n2=-1; - int result_n3=-1; - int result_n4=-1; + int result_mm = -1; + int result_dd = -1; + int result_n1 = -1; + int result_n2 = -1; + int result_n3 = -1; + int result_n4 = -1; + /* */ if ((int) strlen(s) > 200) return NULL; - strcpy(str,s); + strcpy(str, s); set_lowcase(str); /* éliminer :,- */ - while( (a=strchr(str,'-')) ) *a=' '; - while( (a=strchr(str,':')) ) *a=' '; - while( (a=strchr(str,',')) ) *a=' '; + while((a = strchr(str, '-'))) + *a = ' '; + while((a = strchr(str, ':'))) + *a = ' '; + while((a = strchr(str, ','))) + *a = ' '; /* tokeniser */ - a=str; + a = str; while(*a) { char *first, *last; char tok[256]; + /* découper mot */ - while(*a==' ') a++; /* sauter espaces */ - first=a; - while((*a) && (*a!=' ')) a++; - last=a; - tok[0]='\0'; - if (first!=last) { - char* pos; - strncat(tok,first,(int) (last - first)); + while(*a == ' ') + a++; /* sauter espaces */ + first = a; + while((*a) && (*a != ' ')) + a++; + last = a; + tok[0] = '\0'; + if (first != last) { + char *pos; + + strncat(tok, first, (int) (last - first)); /* analyser */ - if ( (pos=strstr(months,tok)) ) { /* month always in letters */ - result_mm=((int) (pos - months))/4; + if ((pos = strstr(months, tok))) { /* month always in letters */ + result_mm = ((int) (pos - months)) / 4; } else { int number; - if (sscanf(tok,"%d",&number) == 1) { /* number token */ - if (result_dd<0) /* day always first number */ - result_dd=number; - else if (result_n1<0) - result_n1=number; - else if (result_n2<0) - result_n2=number; - else if (result_n3<0) - result_n3=number; - else if (result_n4<0) - result_n4=number; - } /* sinon, bruit de fond(+1GMT for exampel) */ + + if (sscanf(tok, "%d", &number) == 1) { /* number token */ + if (result_dd < 0) /* day always first number */ + result_dd = number; + else if (result_n1 < 0) + result_n1 = number; + else if (result_n2 < 0) + result_n2 = number; + else if (result_n3 < 0) + result_n3 = number; + else if (result_n4 < 0) + result_n4 = number; + } /* sinon, bruit de fond(+1GMT for exampel) */ } } } - if ((result_n1>=0) && (result_mm>=0) && (result_dd>=0) && (result_n2>=0) && (result_n3>=0) && (result_n4>=0)) { - if (result_n4>=1000) { /* Sun Nov 6 08:49:37 1994 */ - result->tm_year=result_n4-1900; - result->tm_hour=result_n1; - result->tm_min=result_n2; - result->tm_sec=max(result_n3,0); - } else { /* Sun, 06 Nov 1994 08:49:37 GMT or Sunday, 06-Nov-94 08:49:37 GMT */ - result->tm_hour=result_n2; - result->tm_min=result_n3; - result->tm_sec=max(result_n4,0); - if (result_n1<=50) /* 00 means 2000 */ - result->tm_year=result_n1+100; - else if (result_n1<1000) /* 99 means 1999 */ - result->tm_year=result_n1; - else /* 2000 */ - result->tm_year=result_n1-1900; + if ((result_n1 >= 0) && (result_mm >= 0) && (result_dd >= 0) + && (result_n2 >= 0) && (result_n3 >= 0) && (result_n4 >= 0)) { + if (result_n4 >= 1000) { /* Sun Nov 6 08:49:37 1994 */ + result->tm_year = result_n4 - 1900; + result->tm_hour = result_n1; + result->tm_min = result_n2; + result->tm_sec = max(result_n3, 0); + } else { /* Sun, 06 Nov 1994 08:49:37 GMT or Sunday, 06-Nov-94 08:49:37 GMT */ + result->tm_hour = result_n2; + result->tm_min = result_n3; + result->tm_sec = max(result_n4, 0); + if (result_n1 <= 50) /* 00 means 2000 */ + result->tm_year = result_n1 + 100; + else if (result_n1 < 1000) /* 99 means 1999 */ + result->tm_year = result_n1; + else /* 2000 */ + result->tm_year = result_n1 - 1900; } - result->tm_isdst=0; /* assume GMT */ - result->tm_yday=-1; /* don't know */ - result->tm_wday=-1; /* don't know */ - result->tm_mon=result_mm; - result->tm_mday=result_dd; + result->tm_isdst = 0; /* assume GMT */ + result->tm_yday = -1; /* don't know */ + result->tm_wday = -1; /* don't know */ + result->tm_mon = result_mm; + result->tm_mday = result_dd; return result; } return NULL; } static struct tm PT_GetTime(time_t t) { - struct tm tmbuf; + struct tm tmbuf; + #ifdef _WIN32 - struct tm * tm = gmtime(&t); + struct tm *tm = gmtime(&t); #else - struct tm * tm = gmtime_r(&t, &tmbuf); + struct tm *tm = gmtime_r(&t, &tmbuf); #endif - if (tm != NULL) - return *tm; - else { - memset(&tmbuf, 0, sizeof(tmbuf)); - return tmbuf; - } + if (tm != NULL) + return *tm; + else { + memset(&tmbuf, 0, sizeof(tmbuf)); + return tmbuf; + } } -static int set_filetime(const char* file, struct tm* tm_time) { +static int set_filetime(const char *file, struct tm *tm_time) { struct utimbuf tim; + #ifndef HTS_DO_NOT_USE_FTIME struct timeb B; + memset(&B, 0, sizeof(B)); - B.timezone=0; - ftime( &B ); - tim.actime = tim.modtime = mktime(tm_time) - B.timezone*60; + B.timezone = 0; + ftime(&B); + tim.actime = tim.modtime = mktime(tm_time) - B.timezone * 60; #else // bogus time (GMT/local).. - tim.actime=tim.modtime=mktime(tm_time); + tim.actime = tim.modtime = mktime(tm_time); #endif return utime(file, &tim); } -static int set_filetime_time_t(const char* file, time_t t) { - if (t != (time_t) 0 && t != (time_t) -1) { - struct tm tm = PT_GetTime(t); - return set_filetime(file, &tm); - } - return -1; +static int set_filetime_time_t(const char *file, time_t t) { + if (t != (time_t) 0 && t != (time_t) - 1) { + struct tm tm = PT_GetTime(t); + + return set_filetime(file, &tm); + } + return -1; } -static int set_filetime_rfc822(const char* file, const char* date) { - struct tm buffer; - struct tm* tm_s = convert_time_rfc822(&buffer,date); +static int set_filetime_rfc822(const char *file, const char *date) { + struct tm buffer; + struct tm *tm_s = convert_time_rfc822(&buffer, date); + if (tm_s) { - return set_filetime(file,tm_s); - } else return -1; + return set_filetime(file, tm_s); + } else + return -1; } #endif diff --git a/src/proxy/store.c b/src/proxy/store.c index e5d0c8f..2f2b92c 100644 --- a/src/proxy/store.c +++ b/src/proxy/store.c @@ -34,7 +34,7 @@ Please visit our Website: http://www.httrack.com /* Locking */ #ifdef _WIN32 -#include <process.h> /* _beginthread, _endthread */ +#include <process.h> /* _beginthread, _endthread */ #else #include <pthread.h> #endif @@ -57,49 +57,52 @@ Please visit our Website: http://www.httrack.com /* Unlocked functions */ -static int PT_LookupCache__New_u(PT_Index index, const char* url); -static PT_Element PT_ReadCache__New_u(PT_Index index, const char* url, int flags); +static int PT_LookupCache__New_u(PT_Index index, const char *url); +static PT_Element PT_ReadCache__New_u(PT_Index index, const char *url, + int flags); -static int PT_LookupCache__Old_u(PT_Index index, const char* url); -static PT_Element PT_ReadCache__Old_u(PT_Index index, const char* url, int flags); +static int PT_LookupCache__Old_u(PT_Index index, const char *url); +static PT_Element PT_ReadCache__Old_u(PT_Index index, const char *url, + int flags); -static int PT_LookupCache__Arc_u(PT_Index index, const char* url); -static PT_Element PT_ReadCache__Arc_u(PT_Index index, const char* url, int flags); +static int PT_LookupCache__Arc_u(PT_Index index, const char *url); +static PT_Element PT_ReadCache__Arc_u(PT_Index index, const char *url, + int flags); /* Locking */ #ifdef _WIN32 -void MutexInit(PT_Mutex *pMutex) { - *pMutex = CreateMutex(NULL,FALSE,NULL); +void MutexInit(PT_Mutex * pMutex) { + *pMutex = CreateMutex(NULL, FALSE, NULL); } -void MutexLock(PT_Mutex *pMutex) { - WaitForSingleObject(*pMutex, INFINITE); +void MutexLock(PT_Mutex * pMutex) { + WaitForSingleObject(*pMutex, INFINITE); } -void MutexUnlock(PT_Mutex *pMutex) { - ReleaseMutex(*pMutex); +void MutexUnlock(PT_Mutex * pMutex) { + ReleaseMutex(*pMutex); } -void MutexFree(PT_Mutex *pMutex) { - CloseHandle(*pMutex); - *pMutex = NULL; +void MutexFree(PT_Mutex * pMutex) { + CloseHandle(*pMutex); + *pMutex = NULL; } #else -void MutexInit(PT_Mutex *pMutex) { - (void) pthread_mutex_init(pMutex, 0); +void MutexInit(PT_Mutex * pMutex) { + (void) pthread_mutex_init(pMutex, 0); } -void MutexLock(PT_Mutex *pMutex) { - pthread_mutex_lock(pMutex); +void MutexLock(PT_Mutex * pMutex) { + pthread_mutex_lock(pMutex); } -void MutexUnlock(PT_Mutex *pMutex) { - pthread_mutex_unlock(pMutex); +void MutexUnlock(PT_Mutex * pMutex) { + pthread_mutex_unlock(pMutex); } -void MutexFree(PT_Mutex *pMutex) { - pthread_mutex_destroy(pMutex); +void MutexFree(PT_Mutex * pMutex) { + pthread_mutex_destroy(pMutex); } #endif @@ -116,47 +119,48 @@ typedef struct _PT_Index__Arc *PT_Index__Arc; typedef struct _PT_Index_Functions *PT_Index_Functions; enum { - PT_CACHE_UNDEFINED = -1, - PT_CACHE_MIN = 0, - PT_CACHE__NEW = PT_CACHE_MIN, - PT_CACHE__OLD, - PT_CACHE__ARC, - PT_CACHE_MAX = PT_CACHE__ARC + PT_CACHE_UNDEFINED = -1, + PT_CACHE_MIN = 0, + PT_CACHE__NEW = PT_CACHE_MIN, + PT_CACHE__OLD, + PT_CACHE__ARC, + PT_CACHE_MAX = PT_CACHE__ARC }; static int PT_LoadCache__New(PT_Index index, const char *filename); -static void PT_Index_Delete__New(PT_Index *pindex); -static PT_Element PT_ReadCache__New(PT_Index index, const char* url, int flags); -static int PT_LookupCache__New(PT_Index index, const char* url); +static void PT_Index_Delete__New(PT_Index * pindex); +static PT_Element PT_ReadCache__New(PT_Index index, const char *url, int flags); +static int PT_LookupCache__New(PT_Index index, const char *url); static int PT_SaveCache__New(PT_Indexes indexes, const char *filename); -/**/ -static int PT_LoadCache__Old(PT_Index index, const char *filename); -static void PT_Index_Delete__Old(PT_Index *pindex); -static PT_Element PT_ReadCache__Old(PT_Index index, const char* url, int flags); -static int PT_LookupCache__Old(PT_Index index, const char* url); -/**/ -static int PT_LoadCache__Arc(PT_Index index, const char *filename); -static void PT_Index_Delete__Arc(PT_Index *pindex); -static PT_Element PT_ReadCache__Arc(PT_Index index, const char* url, int flags); -static int PT_LookupCache__Arc(PT_Index index, const char* url); + /**/ static int PT_LoadCache__Old(PT_Index index, const char *filename); +static void PT_Index_Delete__Old(PT_Index * pindex); +static PT_Element PT_ReadCache__Old(PT_Index index, const char *url, int flags); +static int PT_LookupCache__Old(PT_Index index, const char *url); + /**/ static int PT_LoadCache__Arc(PT_Index index, const char *filename); +static void PT_Index_Delete__Arc(PT_Index * pindex); +static PT_Element PT_ReadCache__Arc(PT_Index index, const char *url, int flags); +static int PT_LookupCache__Arc(PT_Index index, const char *url); static int PT_SaveCache__Arc(PT_Indexes indexes, const char *filename); struct _PT_Index_Functions { - /* Mandatory services */ - int (*PT_LoadCache)(PT_Index index, const char *filename); - void (*PT_Index_Delete)(PT_Index *pindex); - PT_Element (*PT_ReadCache)(PT_Index index, const char* url, int flags); - int (*PT_LookupCache)(PT_Index index, const char* url); - - /* Optional services */ - int (*PT_SaveCache)(PT_Indexes indexes, const char *filename); + /* Mandatory services */ + int (*PT_LoadCache) (PT_Index index, const char *filename); + void (*PT_Index_Delete) (PT_Index * pindex); + PT_Element(*PT_ReadCache) (PT_Index index, const char *url, int flags); + int (*PT_LookupCache) (PT_Index index, const char *url); + + /* Optional services */ + int (*PT_SaveCache) (PT_Indexes indexes, const char *filename); }; static _PT_Index_Functions _IndexFuncts[] = { - { PT_LoadCache__New, PT_Index_Delete__New, PT_ReadCache__New, PT_LookupCache__New, PT_SaveCache__New }, - { PT_LoadCache__Old, PT_Index_Delete__Old, PT_ReadCache__Old, PT_LookupCache__Old, NULL }, - { PT_LoadCache__Arc, PT_Index_Delete__Arc, PT_ReadCache__Arc, PT_LookupCache__Arc, PT_SaveCache__Arc }, - { NULL, NULL, NULL, NULL } + {PT_LoadCache__New, PT_Index_Delete__New, PT_ReadCache__New, + PT_LookupCache__New, PT_SaveCache__New}, + {PT_LoadCache__Old, PT_Index_Delete__Old, PT_ReadCache__Old, + PT_LookupCache__Old, NULL}, + {PT_LoadCache__Arc, PT_Index_Delete__Arc, PT_ReadCache__Arc, + PT_LookupCache__Arc, PT_SaveCache__Arc}, + {NULL, NULL, NULL, NULL} }; #define PT_INDEX_COMMON_STRUCTURE \ @@ -165,90 +169,91 @@ static _PT_Index_Functions _IndexFuncts[] = { char startUrl[1024] struct _PT_Index__New { - PT_INDEX_COMMON_STRUCTURE; - char path[1024]; /* either empty, or must include ending / */ - int fixedPath; - int safeCache; - unzFile zFile; - PT_Mutex zFileLock; + PT_INDEX_COMMON_STRUCTURE; + char path[1024]; /* either empty, or must include ending / */ + int fixedPath; + int safeCache; + unzFile zFile; + PT_Mutex zFileLock; }; struct _PT_Index__Old { - PT_INDEX_COMMON_STRUCTURE; - char filenameDat[1024]; - char filenameNdx[1024]; - FILE *dat,*ndx; - PT_Mutex fileLock; - int version; - char lastmodified[1024]; - char path[1024]; /* either empty, or must include ending / */ - int fixedPath; - int safeCache; + PT_INDEX_COMMON_STRUCTURE; + char filenameDat[1024]; + char filenameNdx[1024]; + FILE *dat, *ndx; + PT_Mutex fileLock; + int version; + char lastmodified[1024]; + char path[1024]; /* either empty, or must include ending / */ + int fixedPath; + int safeCache; }; struct _PT_Index__Arc { - PT_INDEX_COMMON_STRUCTURE; - FILE *file; - PT_Mutex fileLock; - int version; - char lastmodified[1024]; - char line[2048]; - char filenameIndexBuff[2048]; + PT_INDEX_COMMON_STRUCTURE; + FILE *file; + PT_Mutex fileLock; + int version; + char lastmodified[1024]; + char line[2048]; + char filenameIndexBuff[2048]; }; struct _PT_Index { - int type; - union { - _PT_Index__New formatNew; - _PT_Index__Old formatOld; - _PT_Index__Arc formatArc; - struct { - PT_INDEX_COMMON_STRUCTURE; - } common; - } slots; + int type; + union { + _PT_Index__New formatNew; + _PT_Index__Old formatOld; + _PT_Index__Arc formatArc; + struct { + PT_INDEX_COMMON_STRUCTURE; + } common; + } slots; }; struct _PT_Indexes { - inthash cil; - struct _PT_Index **index; - int index_size; + inthash cil; + struct _PT_Index **index; + int index_size; }; struct _PT_CacheItem { - time_t lastUsed; - size_t size; - void* data; + time_t lastUsed; + size_t size; + void *data; }; struct _PT_Cache { - inthash index; - size_t maxSize; - size_t totalSize; - int count; + inthash index; + size_t maxSize; + size_t totalSize; + int count; }; PT_Indexes PT_New(void) { - PT_Indexes index = (PT_Indexes) calloc(sizeof(_PT_Indexes), 1); - index->cil = inthash_new(127); - index->index_size = 0; - index->index = NULL; - return index; + PT_Indexes index = (PT_Indexes) calloc(sizeof(_PT_Indexes), 1); + + index->cil = inthash_new(127); + index->index_size = 0; + index->index = NULL; + return index; } void PT_Delete(PT_Indexes index) { - if (index != NULL) { - inthash_delete(&index->cil); - free(index); - } + if (index != NULL) { + inthash_delete(&index->cil); + free(index); + } } int PT_RemoveIndex(PT_Indexes index, int indexId) { - return 0; + return 0; } #define assertf(exp) -static int binput(char* buff,char* s,int max) { +static int binput(char *buff, char *s, int max) { int count = 0; int destCount = 0; @@ -257,7 +262,7 @@ static int binput(char* buff,char* s,int max) { if (buff[count] != '\r') { s[destCount++] = buff[count]; } - count++; + count++; } s[destCount] = '\0'; @@ -265,529 +270,573 @@ static int binput(char* buff,char* s,int max) { return count + 1; } -static time_t file_timestamp(const char* file) { +static time_t file_timestamp(const char *file) { struct stat buf; + if (stat(file, &buf) == 0) { time_t tt = buf.st_mtime; - if (tt != (time_t) 0 && tt != (time_t) -1) { - return tt; - } + + if (tt != (time_t) 0 && tt != (time_t) - 1) { + return tt; + } } return (time_t) 0; } -static int PT_Index_Check__(PT_Index index, const char* file, int line) { - if (index == NULL) - return 0; - if (index->type >= PT_CACHE_MIN && index->type <= PT_CACHE_MAX) - return 1; - proxytrack_print_log(CRITICAL, "index corrupted in memory at %s:%d", file, line); - return 0; +static int PT_Index_Check__(PT_Index index, const char *file, int line) { + if (index == NULL) + return 0; + if (index->type >= PT_CACHE_MIN && index->type <= PT_CACHE_MAX) + return 1; + proxytrack_print_log(CRITICAL, "index corrupted in memory at %s:%d", file, + line); + return 0; } -#define SAFE_INDEX(index) PT_Index_Check__(index, __FILE__, __LINE__) +#define SAFE_INDEX(index) PT_Index_Check__(index, __FILE__, __LINE__) /* ------------------------------------------------------------ */ /* Generic cache dispatch */ /* ------------------------------------------------------------ */ -void PT_Index_Delete(PT_Index *pindex) { - if (pindex != NULL && (*pindex) != NULL) { - PT_Index index = *pindex; - if (SAFE_INDEX(index)) { - _IndexFuncts[index->type].PT_Index_Delete(pindex); - } - free(index); - *pindex = NULL; - } -} - -static void PT_Index_Delete__New(PT_Index *pindex) { - if (pindex != NULL && (*pindex) != NULL) { - PT_Index__New index = &(*pindex)->slots.formatNew; - if (index->zFile != NULL) { - unzClose(index->zFile); - index->zFile = NULL; - } - if (index->hash != NULL) { - inthash_delete(&index->hash); - index->hash = NULL; - } - MutexFree(&index->zFileLock); - } -} - -static void PT_Index_Delete__Old(PT_Index *pindex) { - if (pindex != NULL && (*pindex) != NULL) { - PT_Index__Old index = &(*pindex)->slots.formatOld; - if (index->dat != NULL) { - fclose(index->dat); - } - if (index->ndx != NULL) { - fclose(index->ndx); - } - if (index->hash != NULL) { - inthash_delete(&index->hash); - index->hash = NULL; - } - MutexFree(&index->fileLock); - } -} - -static void PT_Index_Delete__Arc(PT_Index *pindex) { - if (pindex != NULL && (*pindex) != NULL) { - PT_Index__Arc index = &(*pindex)->slots.formatArc; - if (index->file != NULL) { - fclose(index->file); - } - MutexFree(&index->fileLock); - } +void PT_Index_Delete(PT_Index * pindex) { + if (pindex != NULL && (*pindex) != NULL) { + PT_Index index = *pindex; + + if (SAFE_INDEX(index)) { + _IndexFuncts[index->type].PT_Index_Delete(pindex); + } + free(index); + *pindex = NULL; + } +} + +static void PT_Index_Delete__New(PT_Index * pindex) { + if (pindex != NULL && (*pindex) != NULL) { + PT_Index__New index = &(*pindex)->slots.formatNew; + + if (index->zFile != NULL) { + unzClose(index->zFile); + index->zFile = NULL; + } + if (index->hash != NULL) { + inthash_delete(&index->hash); + index->hash = NULL; + } + MutexFree(&index->zFileLock); + } +} + +static void PT_Index_Delete__Old(PT_Index * pindex) { + if (pindex != NULL && (*pindex) != NULL) { + PT_Index__Old index = &(*pindex)->slots.formatOld; + + if (index->dat != NULL) { + fclose(index->dat); + } + if (index->ndx != NULL) { + fclose(index->ndx); + } + if (index->hash != NULL) { + inthash_delete(&index->hash); + index->hash = NULL; + } + MutexFree(&index->fileLock); + } +} + +static void PT_Index_Delete__Arc(PT_Index * pindex) { + if (pindex != NULL && (*pindex) != NULL) { + PT_Index__Arc index = &(*pindex)->slots.formatArc; + + if (index->file != NULL) { + fclose(index->file); + } + MutexFree(&index->fileLock); + } } int PT_AddIndex(PT_Indexes indexes, const char *path) { - PT_Index index = PT_LoadCache(path); - if (index != NULL) { - int ret = PT_IndexMerge(indexes, &index); - if (index != NULL) { - PT_Index_Delete(&index); - } - return ret; - } - return -1; + PT_Index index = PT_LoadCache(path); + + if (index != NULL) { + int ret = PT_IndexMerge(indexes, &index); + + if (index != NULL) { + PT_Index_Delete(&index); + } + return ret; + } + return -1; } PT_Element PT_Index_HTML_BuildRootInfo(PT_Indexes indexes) { - if (indexes != NULL) { - PT_Element elt = PT_ElementNew(); - int i; - String html = STRING_EMPTY; - StringClear(html); - StringCat(html, - "<html>" - PROXYTRACK_COMMENT_HEADER - DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES - "<head>\r\n" - "<title>ProxyTrack " PROXYTRACK_VERSION " Catalog</title>" - "</head>\r\n" - "<body>\r\n" - "<h3>Available sites in this cache:</h3><br />" - "<br />" - ); - StringCat(html, "<ul>\r\n"); - for(i = 0 ; i < indexes->index_size ; i++) { - if (indexes->index[i] != NULL - && indexes->index[i]->slots.common.startUrl[0] != '\0') - { - const char * url = indexes->index[i]->slots.common.startUrl; - StringCat(html, "<li>\r\n"); - StringCat(html, "<a href=\""); - StringCat(html, url); - StringCat(html, "\">"); - StringCat(html, url); - StringCat(html, "</a>\r\n"); - StringCat(html, "</li>\r\n"); - } - } - StringCat(html, "</ul>\r\n"); - StringCat(html, "</body></html>\r\n"); - elt->size = StringLength(html); - elt->adr = StringAcquire(&html); - elt->statuscode = HTTP_OK; - strcpy(elt->charset, "iso-8859-1"); - strcpy(elt->contenttype, "text/html"); - strcpy(elt->msg, "OK"); - StringFree(html); - return elt; - } - return NULL; -} - -static char* strchr_stop(char* str, char c, char stop) { - for( ; *str != 0 && *str != stop && *str != c ; str++); - if (*str == c) - return str; - return NULL; -} - -char ** PT_Enumerate(PT_Indexes indexes, const char *url, int subtree) { - // should be cached! - if (indexes != NULL && indexes->cil != NULL) { - unsigned int urlSize; - String list = STRING_EMPTY; - String listindexes = STRING_EMPTY; - String subitem = STRING_EMPTY; - unsigned int listCount = 0; - struct_inthash_enum en = inthash_enum_new(indexes->cil); - inthash_chain* chain; - inthash hdupes = NULL; - if (!subtree) - hdupes= inthash_new(127); - StringClear(list); - StringClear(listindexes); - StringClear(subitem); - if (strncmp(url, "http://", 7) == 0) - url += 7; - urlSize = (unsigned int) strlen(url); - while((chain = inthash_enum_next(&en))) { - long int index = (long int)chain->value.intg; - if (urlSize == 0 || strncmp(chain->name, url, urlSize) == 0) { - if (index >= 0 && index < indexes->index_size) { - char * item = chain->name + urlSize; - if (*item == '/') - item++; - { - char * pos = subtree ? 0 : strchr_stop(item, '/', '?'); - unsigned int len = pos ? (unsigned int)( pos - item ) : (unsigned int)strlen(item); - if (len > 0 /* default document */ || *item == 0) { - int isFolder = ( item[len] == '/' ); - StringClear(subitem); - if (len > 0) - StringMemcat(subitem, item, len); - if (len == 0 || !inthash_exists(hdupes, StringBuff(subitem))) { - char* ptr = NULL; - ptr += StringLength(list); - if (len > 0) - StringCat(list, StringBuff(subitem)); - if (isFolder) - StringCat(list, "/"); - StringMemcat(list, "\0", 1); /* NULL terminated strings */ - StringMemcat(listindexes, &ptr, sizeof(ptr)); - listCount++; - inthash_write(hdupes, StringBuff(subitem), 0); - } - } - } - } else { - proxytrack_print_log(CRITICAL, "PT_Enumerate:Corrupted central index locator"); - } - } - } - StringFree(subitem); - inthash_delete(&hdupes); - if (listCount > 0) { - unsigned int i; - void* blk; - char *nullPointer = NULL; - char* startStrings; - /* NULL terminated index */ - StringMemcat(listindexes, &nullPointer, sizeof(nullPointer)); - /* start of all strings (index) */ - startStrings = nullPointer + StringLength(listindexes); - /* copy list of URLs after indexes */ - StringMemcat(listindexes, StringBuff(list), StringLength(list)); - /* ---- no reallocation beyond this point (fixed addresses) ---- */ - /* start of all strings (pointer) */ - startStrings = (startStrings - nullPointer) + StringBuffRW(listindexes); - /* transform indexes into references */ - for(i = 0 ; i < listCount ; i++) { - char *ptr = NULL; - unsigned int ndx; - memcpy(&ptr, &StringBuff(listindexes)[i*sizeof(char*)], sizeof(char*)); - ndx = (unsigned int) (ptr - nullPointer); - ptr = startStrings + ndx; - memcpy(&StringBuffRW(listindexes)[i*sizeof(char*)], &ptr, sizeof(char*)); - } - blk = StringAcquire(&listindexes); - StringFree(list); - StringFree(listindexes); - return (char **)blk; - } - } - return NULL; + if (indexes != NULL) { + PT_Element elt = PT_ElementNew(); + int i; + String html = STRING_EMPTY; + + StringClear(html); + StringCat(html, + "<html>" PROXYTRACK_COMMENT_HEADER + DISABLE_IE_FRIENDLY_HTTP_ERROR_MESSAGES "<head>\r\n" + "<title>ProxyTrack " PROXYTRACK_VERSION " Catalog</title>" + "</head>\r\n" "<body>\r\n" + "<h3>Available sites in this cache:</h3><br />" "<br />"); + StringCat(html, "<ul>\r\n"); + for(i = 0; i < indexes->index_size; i++) { + if (indexes->index[i] != NULL + && indexes->index[i]->slots.common.startUrl[0] != '\0') { + const char *url = indexes->index[i]->slots.common.startUrl; + + StringCat(html, "<li>\r\n"); + StringCat(html, "<a href=\""); + StringCat(html, url); + StringCat(html, "\">"); + StringCat(html, url); + StringCat(html, "</a>\r\n"); + StringCat(html, "</li>\r\n"); + } + } + StringCat(html, "</ul>\r\n"); + StringCat(html, "</body></html>\r\n"); + elt->size = StringLength(html); + elt->adr = StringAcquire(&html); + elt->statuscode = HTTP_OK; + strcpy(elt->charset, "iso-8859-1"); + strcpy(elt->contenttype, "text/html"); + strcpy(elt->msg, "OK"); + StringFree(html); + return elt; + } + return NULL; +} + +static char *strchr_stop(char *str, char c, char stop) { + for(; *str != 0 && *str != stop && *str != c; str++) ; + if (*str == c) + return str; + return NULL; +} + +char **PT_Enumerate(PT_Indexes indexes, const char *url, int subtree) { + // should be cached! + if (indexes != NULL && indexes->cil != NULL) { + unsigned int urlSize; + String list = STRING_EMPTY; + String listindexes = STRING_EMPTY; + String subitem = STRING_EMPTY; + unsigned int listCount = 0; + struct_inthash_enum en = inthash_enum_new(indexes->cil); + inthash_chain *chain; + inthash hdupes = NULL; + + if (!subtree) + hdupes = inthash_new(127); + StringClear(list); + StringClear(listindexes); + StringClear(subitem); + if (strncmp(url, "http://", 7) == 0) + url += 7; + urlSize = (unsigned int) strlen(url); + while((chain = inthash_enum_next(&en))) { + long int index = (long int) chain->value.intg; + + if (urlSize == 0 || strncmp(chain->name, url, urlSize) == 0) { + if (index >= 0 && index < indexes->index_size) { + char *item = chain->name + urlSize; + + if (*item == '/') + item++; + { + char *pos = subtree ? 0 : strchr_stop(item, '/', '?'); + unsigned int len = + pos ? (unsigned int) (pos - item) : (unsigned int) strlen(item); + if (len > 0 /* default document */ || *item == 0) { + int isFolder = (item[len] == '/'); + + StringClear(subitem); + if (len > 0) + StringMemcat(subitem, item, len); + if (len == 0 || !inthash_exists(hdupes, StringBuff(subitem))) { + char *ptr = NULL; + + ptr += StringLength(list); + if (len > 0) + StringCat(list, StringBuff(subitem)); + if (isFolder) + StringCat(list, "/"); + StringMemcat(list, "\0", 1); /* NULL terminated strings */ + StringMemcat(listindexes, &ptr, sizeof(ptr)); + listCount++; + inthash_write(hdupes, StringBuff(subitem), 0); + } + } + } + } else { + proxytrack_print_log(CRITICAL, + "PT_Enumerate:Corrupted central index locator"); + } + } + } + StringFree(subitem); + inthash_delete(&hdupes); + if (listCount > 0) { + unsigned int i; + void *blk; + char *nullPointer = NULL; + char *startStrings; + + /* NULL terminated index */ + StringMemcat(listindexes, &nullPointer, sizeof(nullPointer)); + /* start of all strings (index) */ + startStrings = nullPointer + StringLength(listindexes); + /* copy list of URLs after indexes */ + StringMemcat(listindexes, StringBuff(list), StringLength(list)); + /* ---- no reallocation beyond this point (fixed addresses) ---- */ + /* start of all strings (pointer) */ + startStrings = (startStrings - nullPointer) + StringBuffRW(listindexes); + /* transform indexes into references */ + for(i = 0; i < listCount; i++) { + char *ptr = NULL; + unsigned int ndx; + + memcpy(&ptr, &StringBuff(listindexes)[i * sizeof(char *)], + sizeof(char *)); + ndx = (unsigned int) (ptr - nullPointer); + ptr = startStrings + ndx; + memcpy(&StringBuffRW(listindexes)[i * sizeof(char *)], &ptr, + sizeof(char *)); + } + blk = StringAcquire(&listindexes); + StringFree(list); + StringFree(listindexes); + return (char **) blk; + } + } + return NULL; } void PT_Enumerate_Delete(char ***plist) { - if (plist != NULL && *plist != NULL) { - free(*plist); - *plist = NULL; - } + if (plist != NULL && *plist != NULL) { + free(*plist); + *plist = NULL; + } } static int PT_GetType(const char *filename) { - char * dot = strrchr(filename, '.'); - if (dot != NULL) { - if (strcasecmp(dot, ".zip") == 0) { - return PT_CACHE__NEW; - } else if (strcasecmp(dot, ".ndx") == 0 || strcasecmp(dot, ".dat") == 0) { - return PT_CACHE__OLD; - } else if (strcasecmp(dot, ".arc") == 0) { - return PT_CACHE__ARC; - } - } - return PT_CACHE_UNDEFINED; + char *dot = strrchr(filename, '.'); + + if (dot != NULL) { + if (strcasecmp(dot, ".zip") == 0) { + return PT_CACHE__NEW; + } else if (strcasecmp(dot, ".ndx") == 0 || strcasecmp(dot, ".dat") == 0) { + return PT_CACHE__OLD; + } else if (strcasecmp(dot, ".arc") == 0) { + return PT_CACHE__ARC; + } + } + return PT_CACHE_UNDEFINED; } PT_Index PT_LoadCache(const char *filename) { - int type = PT_GetType(filename); - if (type != PT_CACHE_UNDEFINED) { - PT_Index index = calloc(sizeof(_PT_Index), 1); - if (index != NULL) { - index->type = type; - index->slots.common.timestamp = (time_t) time(NULL); - index->slots.common.startUrl[0] = '\0'; - index->slots.common.hash = inthash_new(8191); - if (!_IndexFuncts[type].PT_LoadCache(index, filename)) { - proxytrack_print_log(DEBUG, "reading httrack cache (format #%d) %s : error", type, filename ); - free(index); - index = NULL; - return NULL; - } else { - proxytrack_print_log(DEBUG, "reading httrack cache (format #%d) %s : success", type, filename ); - } - /* default starting URL is the first hash entry */ - if (index->slots.common.startUrl[0] == '\0') { - struct_inthash_enum en = inthash_enum_new(index->slots.common.hash); - inthash_chain* chain; - chain = inthash_enum_next(&en); - if (chain != NULL - && strstr(chain->name, "/robots.txt") != NULL) - { - chain = inthash_enum_next(&en); - } - if (chain != NULL) { - if (!link_has_authority(chain->name)) - strcat(index->slots.common.startUrl, "http://"); - strcat(index->slots.common.startUrl, chain->name); - } - } - } - return index; - } - return NULL; -} - - -static long int filesize(const char* filename) { + int type = PT_GetType(filename); + + if (type != PT_CACHE_UNDEFINED) { + PT_Index index = calloc(sizeof(_PT_Index), 1); + + if (index != NULL) { + index->type = type; + index->slots.common.timestamp = (time_t) time(NULL); + index->slots.common.startUrl[0] = '\0'; + index->slots.common.hash = inthash_new(8191); + if (!_IndexFuncts[type].PT_LoadCache(index, filename)) { + proxytrack_print_log(DEBUG, + "reading httrack cache (format #%d) %s : error", + type, filename); + free(index); + index = NULL; + return NULL; + } else { + proxytrack_print_log(DEBUG, + "reading httrack cache (format #%d) %s : success", + type, filename); + } + /* default starting URL is the first hash entry */ + if (index->slots.common.startUrl[0] == '\0') { + struct_inthash_enum en = inthash_enum_new(index->slots.common.hash); + inthash_chain *chain; + + chain = inthash_enum_next(&en); + if (chain != NULL && strstr(chain->name, "/robots.txt") != NULL) { + chain = inthash_enum_next(&en); + } + if (chain != NULL) { + if (!link_has_authority(chain->name)) + strcat(index->slots.common.startUrl, "http://"); + strcat(index->slots.common.startUrl, chain->name); + } + } + } + return index; + } + return NULL; +} + +static long int filesize(const char *filename) { struct stat st; + memset(&st, 0, sizeof(st)); if (stat(filename, &st) == 0) { - return (long int)st.st_size; + return (long int) st.st_size; } return -1; -} +} -int PT_LookupCache(PT_Index index, const char* url) { - if (index != NULL && SAFE_INDEX(index)) { - return _IndexFuncts[index->type].PT_LookupCache(index, url); - } - return 0; +int PT_LookupCache(PT_Index index, const char *url) { + if (index != NULL && SAFE_INDEX(index)) { + return _IndexFuncts[index->type].PT_LookupCache(index, url); + } + return 0; } int PT_SaveCache(PT_Indexes indexes, const char *filename) { - int type = PT_GetType(filename); - if (type != PT_CACHE_UNDEFINED) { - if (_IndexFuncts[type].PT_SaveCache != NULL) { - int ret = _IndexFuncts[type].PT_SaveCache(indexes, filename); - if (ret == 0) { - (void) set_filetime_time_t(filename, PT_GetTimeIndex(indexes)); - return 0; - } - } - } - return -1; -} - -int PT_EnumCache(PT_Indexes indexes, int (*callback)(void *, const char *url, PT_Element), void *arg) { - if (indexes != NULL && indexes->cil != NULL) { - struct_inthash_enum en = inthash_enum_new(indexes->cil); - inthash_chain* chain; - while((chain = inthash_enum_next(&en))) { - const long int index_id = (long int)chain->value.intg; - const char *const url = chain->name; - if (index_id >= 0 && index_id <= indexes->index_size) { - PT_Element item = PT_ReadCache(indexes->index[index_id], url, FETCH_HEADERS | FETCH_BODY); - if (item != NULL) { - int ret = callback(arg, url, item); - PT_Element_Delete(&item); - if (ret != 0) - return ret; - } - } else { - proxytrack_print_log(CRITICAL, "PT_ReadCache:Corrupted central index locator"); - return -1; - } - } - } - return 0; + int type = PT_GetType(filename); + + if (type != PT_CACHE_UNDEFINED) { + if (_IndexFuncts[type].PT_SaveCache != NULL) { + int ret = _IndexFuncts[type].PT_SaveCache(indexes, filename); + + if (ret == 0) { + (void) set_filetime_time_t(filename, PT_GetTimeIndex(indexes)); + return 0; + } + } + } + return -1; +} + +int PT_EnumCache(PT_Indexes indexes, + int (*callback) (void *, const char *url, PT_Element), + void *arg) { + if (indexes != NULL && indexes->cil != NULL) { + struct_inthash_enum en = inthash_enum_new(indexes->cil); + inthash_chain *chain; + + while((chain = inthash_enum_next(&en))) { + const long int index_id = (long int) chain->value.intg; + const char *const url = chain->name; + + if (index_id >= 0 && index_id <= indexes->index_size) { + PT_Element item = + PT_ReadCache(indexes->index[index_id], url, + FETCH_HEADERS | FETCH_BODY); + if (item != NULL) { + int ret = callback(arg, url, item); + + PT_Element_Delete(&item); + if (ret != 0) + return ret; + } + } else { + proxytrack_print_log(CRITICAL, + "PT_ReadCache:Corrupted central index locator"); + return -1; + } + } + } + return 0; } time_t PT_Index_Timestamp(PT_Index index) { - return index->slots.common.timestamp; -} - -static int PT_LookupCache__New(PT_Index index, const char* url) { - int retCode; - MutexLock(&index->slots.formatNew.zFileLock); - { - retCode = PT_LookupCache__New_u(index, url); - } - MutexUnlock(&index->slots.formatNew.zFileLock); - return retCode; -} - -static int PT_LookupCache__New_u(PT_Index index_, const char* url) { - if (index_ != NULL) { - PT_Index__New index = &index_->slots.formatNew; - if (index->hash != NULL && index->zFile != NULL && url != NULL && *url != 0) { - int hash_pos_return; - if (strncmp(url, "http://", 7) == 0) - url += 7; - hash_pos_return = inthash_read(index->hash, url, NULL); - if (hash_pos_return) - return 1; - } - } - return 0; -} - -int PT_IndexMerge(PT_Indexes indexes, PT_Index *pindex) -{ - if (pindex != NULL && *pindex != NULL && (*pindex)->slots.common.hash != NULL - && indexes != NULL) - { - PT_Index index = *pindex; - struct_inthash_enum en = inthash_enum_new(index->slots.common.hash); - inthash_chain* chain; - int index_id = indexes->index_size++; - int nMerged = 0; - if ((indexes->index = realloc(indexes->index, sizeof(struct _PT_Index)*indexes->index_size)) != NULL) { - indexes->index[index_id] = index; - *pindex = NULL; - while((chain = inthash_enum_next(&en)) != NULL) { - const char * url = chain->name; - if (url != NULL && url[0] != '\0') { - intptr_t previous_index_id = 0; - if (inthash_read(indexes->cil, url, &previous_index_id)) { - if (previous_index_id >= 0 && previous_index_id < indexes->index_size) { - if (indexes->index[previous_index_id]->slots.common.timestamp > index->slots.common.timestamp) // existing entry is newer - break; - } else { - proxytrack_print_log(CRITICAL, "PT_IndexMerge:Corrupted central index locator"); - } - } - inthash_write(indexes->cil, chain->name, index_id); - nMerged++; - } - } - } else { - proxytrack_print_log(CRITICAL, "PT_IndexMerge:Memory exhausted"); - } - return nMerged; - } - return -1; -} - -void PT_Element_Delete(PT_Element *pentry) { - if (pentry != NULL) { - PT_Element entry = *pentry; - if (entry != NULL) { - if (entry->adr != NULL) { - free(entry->adr); - entry->adr = NULL; - } - if (entry->headers != NULL) { - free(entry->headers); - entry->headers = NULL; - } - if (entry->location != NULL) { - free(entry->location); - entry->location = NULL; - } - free(entry); - } - *pentry = NULL; - } -} - -PT_Element PT_ReadIndex(PT_Indexes indexes, const char* url, int flags) -{ - if (indexes != NULL) - { - intptr_t index_id; - if (strncmp(url, "http://", 7) == 0) - url += 7; - if (inthash_read(indexes->cil, url, &index_id)) { - if (index_id >= 0 && index_id <= indexes->index_size) { - PT_Element item = PT_ReadCache(indexes->index[index_id], url, flags); - if (item != NULL) { - item->indexId = (int) index_id; - return item; - } - } else { - proxytrack_print_log(CRITICAL, "PT_ReadCache:Corrupted central index locator"); - } - } - } - return NULL; -} - -int PT_LookupIndex(PT_Indexes indexes, const char* url) { - if (indexes != NULL) - { - intptr_t index_id; - if (strncmp(url, "http://", 7) == 0) - url += 7; - if (inthash_read(indexes->cil, url, &index_id)) { - if (index_id >= 0 && index_id <= indexes->index_size) { - return 1; - } else { - proxytrack_print_log(CRITICAL, "PT_ReadCache:Corrupted central index locator"); - } - } - } - return 0; + return index->slots.common.timestamp; +} + +static int PT_LookupCache__New(PT_Index index, const char *url) { + int retCode; + + MutexLock(&index->slots.formatNew.zFileLock); + { + retCode = PT_LookupCache__New_u(index, url); + } + MutexUnlock(&index->slots.formatNew.zFileLock); + return retCode; +} + +static int PT_LookupCache__New_u(PT_Index index_, const char *url) { + if (index_ != NULL) { + PT_Index__New index = &index_->slots.formatNew; + + if (index->hash != NULL && index->zFile != NULL && url != NULL && *url != 0) { + int hash_pos_return; + + if (strncmp(url, "http://", 7) == 0) + url += 7; + hash_pos_return = inthash_read(index->hash, url, NULL); + if (hash_pos_return) + return 1; + } + } + return 0; +} + +int PT_IndexMerge(PT_Indexes indexes, PT_Index * pindex) { + if (pindex != NULL && *pindex != NULL && (*pindex)->slots.common.hash != NULL + && indexes != NULL) { + PT_Index index = *pindex; + struct_inthash_enum en = inthash_enum_new(index->slots.common.hash); + inthash_chain *chain; + int index_id = indexes->index_size++; + int nMerged = 0; + + if ((indexes->index = + realloc(indexes->index, + sizeof(struct _PT_Index) * indexes->index_size)) != NULL) { + indexes->index[index_id] = index; + *pindex = NULL; + while((chain = inthash_enum_next(&en)) != NULL) { + const char *url = chain->name; + + if (url != NULL && url[0] != '\0') { + intptr_t previous_index_id = 0; + + if (inthash_read(indexes->cil, url, &previous_index_id)) { + if (previous_index_id >= 0 + && previous_index_id < indexes->index_size) { + if (indexes->index[previous_index_id]->slots.common.timestamp > index->slots.common.timestamp) // existing entry is newer + break; + } else { + proxytrack_print_log(CRITICAL, + "PT_IndexMerge:Corrupted central index locator"); + } + } + inthash_write(indexes->cil, chain->name, index_id); + nMerged++; + } + } + } else { + proxytrack_print_log(CRITICAL, "PT_IndexMerge:Memory exhausted"); + } + return nMerged; + } + return -1; +} + +void PT_Element_Delete(PT_Element * pentry) { + if (pentry != NULL) { + PT_Element entry = *pentry; + + if (entry != NULL) { + if (entry->adr != NULL) { + free(entry->adr); + entry->adr = NULL; + } + if (entry->headers != NULL) { + free(entry->headers); + entry->headers = NULL; + } + if (entry->location != NULL) { + free(entry->location); + entry->location = NULL; + } + free(entry); + } + *pentry = NULL; + } +} + +PT_Element PT_ReadIndex(PT_Indexes indexes, const char *url, int flags) { + if (indexes != NULL) { + intptr_t index_id; + + if (strncmp(url, "http://", 7) == 0) + url += 7; + if (inthash_read(indexes->cil, url, &index_id)) { + if (index_id >= 0 && index_id <= indexes->index_size) { + PT_Element item = PT_ReadCache(indexes->index[index_id], url, flags); + + if (item != NULL) { + item->indexId = (int) index_id; + return item; + } + } else { + proxytrack_print_log(CRITICAL, + "PT_ReadCache:Corrupted central index locator"); + } + } + } + return NULL; +} + +int PT_LookupIndex(PT_Indexes indexes, const char *url) { + if (indexes != NULL) { + intptr_t index_id; + + if (strncmp(url, "http://", 7) == 0) + url += 7; + if (inthash_read(indexes->cil, url, &index_id)) { + if (index_id >= 0 && index_id <= indexes->index_size) { + return 1; + } else { + proxytrack_print_log(CRITICAL, + "PT_ReadCache:Corrupted central index locator"); + } + } + } + return 0; } time_t PT_GetTimeIndex(PT_Indexes indexes) { - if (indexes != NULL && indexes->index_size > 0) - { - int i; - time_t maxt = indexes->index[0]->slots.common.timestamp; - for(i = 1 ; i < indexes->index_size ; i++) { - const time_t currt = indexes->index[i]->slots.common.timestamp; - if (currt > maxt) { - maxt = currt; - } - } - return maxt; - } - return (time_t) -1; + if (indexes != NULL && indexes->index_size > 0) { + int i; + time_t maxt = indexes->index[0]->slots.common.timestamp; + + for(i = 1; i < indexes->index_size; i++) { + const time_t currt = indexes->index[i]->slots.common.timestamp; + + if (currt > maxt) { + maxt = currt; + } + } + return maxt; + } + return (time_t) - 1; } PT_Index PT_GetIndex(PT_Indexes indexes, int indexId) { - if (indexes != NULL && indexId >= 0 && indexId < indexes->index_size) - { - return indexes->index[indexId]; - } - return NULL; + if (indexes != NULL && indexId >= 0 && indexId < indexes->index_size) { + return indexes->index[indexId]; + } + return NULL; } PT_Element PT_ElementNew(void) { - PT_Element r = NULL; - if ((r = calloc(sizeof(_PT_Element), 1)) == NULL) - return NULL; - r->statuscode=STATUSCODE_INVALID; - r->indexId = -1; - return r; -} + PT_Element r = NULL; -PT_Element PT_ReadCache(PT_Index index, const char* url, int flags) { - if (index != NULL && SAFE_INDEX(index)) { - return _IndexFuncts[index->type].PT_ReadCache(index, url, flags); - } - return NULL; + if ((r = calloc(sizeof(_PT_Element), 1)) == NULL) + return NULL; + r->statuscode = STATUSCODE_INVALID; + r->indexId = -1; + return r; } -static PT_Element PT_ReadCache__New(PT_Index index, const char* url, int flags) { - PT_Element retCode; - MutexLock(&index->slots.formatNew.zFileLock); - { - retCode = PT_ReadCache__New_u(index, url, flags); - } - MutexUnlock(&index->slots.formatNew.zFileLock); - return retCode; +PT_Element PT_ReadCache(PT_Index index, const char *url, int flags) { + if (index != NULL && SAFE_INDEX(index)) { + return _IndexFuncts[index->type].PT_ReadCache(index, url, flags); + } + return NULL; } +static PT_Element PT_ReadCache__New(PT_Index index, const char *url, int flags) { + PT_Element retCode; + + MutexLock(&index->slots.formatNew.zFileLock); + { + retCode = PT_ReadCache__New_u(index, url, flags); + } + MutexUnlock(&index->slots.formatNew.zFileLock); + return retCode; +} /* ------------------------------------------------------------ */ /* New HTTrack cache (new.zip) format */ @@ -825,167 +874,182 @@ static PT_Element PT_ReadCache__New(PT_Index index, const char* url, int flags) } while(0) int PT_LoadCache__New(PT_Index index_, const char *filename) { - if (index_ != NULL && filename != NULL) { - PT_Index__New index = &index_->slots.formatNew; - unzFile zFile = index->zFile = unzOpen(filename); - index->timestamp = file_timestamp(filename); - MutexInit(&index->zFileLock); - - // Opened ? - if (zFile!=NULL) { - const char * abpath; - int slashes; - inthash hashtable = index->hash; - - /* Compute base path for this index - the filename MUST be absolute! */ - for(slashes = 2, abpath = filename + (int)strlen(filename) - 1 - ; abpath > filename && ( ( *abpath != '/'&& *abpath != '\\' ) || --slashes > 0) - ; abpath--); - index->path[0] = '\0'; - if (slashes == 0 && *abpath != 0) { - int i; - strncat(index->path, filename, (int) ( abpath - filename ) + 1 ); - for(i = 0 ; index->path[i] != 0 ; i++) { - if (index->path[i] == '\\') { - index->path[i] = '/'; - } - } - } - - /* Ready directory entries */ - if (unzGoToFirstFile(zFile) == Z_OK) { - char comment[128]; - char filename[HTS_URLMAXSIZE * 4]; - int entries = 0; - int firstSeen = 0; - memset(comment, 0, sizeof(comment)); // for truncated reads - do { - int readSizeHeader = 0; - filename[0] = '\0'; - comment[0] = '\0'; - if (unzOpenCurrentFile(zFile) == Z_OK) { - if ( - (readSizeHeader = unzGetLocalExtrafield(zFile, comment, sizeof(comment) - 2)) > 0 - && - unzGetCurrentFileInfo(zFile, NULL, filename, sizeof(filename) - 2, NULL, 0, NULL, 0) == Z_OK - ) - { - long int pos = (long int) unzGetOffset(zFile); - assertf(readSizeHeader < sizeof(comment)); - comment[readSizeHeader] = '\0'; - entries++; - if (pos > 0) { - int dataincache = 0; // data in cache ? - char* filenameIndex = filename; - if (strncmp(filenameIndex, "http://", 7) == 0) { - filenameIndex += 7; - } - if (comment[0] != '\0') { - int maxLine = 2; - char* a = comment; - while(*a && maxLine-- > 0) { // parse only few first lines - char line[1024]; - line[0] = '\0'; - a+=binput(a, line, sizeof(line) - 2); - if (strncmp(line, "X-In-Cache:", 11) == 0) { - if (strcmp(line, "X-In-Cache: 1") == 0) { - dataincache = 1; - } else { - dataincache = 0; - } - break; - } - } - } - if (dataincache) - inthash_add(hashtable, filenameIndex, pos); - else - inthash_add(hashtable, filenameIndex, -pos); - - /* First link as starting URL */ - if (!firstSeen) { - if (strstr(filenameIndex, "/robots.txt") == NULL) { - firstSeen = 1; - if (!link_has_authority(filenameIndex)) - strcat(index->startUrl, "http://"); - strcat(index->startUrl, filenameIndex); - } - } - } else { - fprintf(stderr, "Corrupted cache meta entry #%d"LF, (int)entries); - } - } else { - fprintf(stderr, "Corrupted cache entry #%d"LF, (int)entries); - } - unzCloseCurrentFile(zFile); - } else { - fprintf(stderr, "Corrupted cache entry #%d"LF, (int)entries); - } - } while( unzGoToNextFile(zFile) == Z_OK ); - return 1; - } else { - inthash_delete(&index->hash); - index = NULL; - } - } else { - index = NULL; - } - } - return 0; -} - -static PT_Element PT_ReadCache__New_u(PT_Index index_, const char* url, int flags) -{ - PT_Index__New index = (PT_Index__New) &index_->slots.formatNew; - char location_default[HTS_URLMAXSIZE*2]; - char previous_save[HTS_URLMAXSIZE*2]; - char previous_save_[HTS_URLMAXSIZE*2]; - char catbuff[CATBUFF_SIZE]; + if (index_ != NULL && filename != NULL) { + PT_Index__New index = &index_->slots.formatNew; + unzFile zFile = index->zFile = unzOpen(filename); + + index->timestamp = file_timestamp(filename); + MutexInit(&index->zFileLock); + + // Opened ? + if (zFile != NULL) { + const char *abpath; + int slashes; + inthash hashtable = index->hash; + + /* Compute base path for this index - the filename MUST be absolute! */ + for(slashes = 2, abpath = filename + (int) strlen(filename) - 1; + abpath > filename && ((*abpath != '/' && *abpath != '\\') + || --slashes > 0); + abpath--) ; + index->path[0] = '\0'; + if (slashes == 0 && *abpath != 0) { + int i; + + strncat(index->path, filename, (int) (abpath - filename) + 1); + for(i = 0; index->path[i] != 0; i++) { + if (index->path[i] == '\\') { + index->path[i] = '/'; + } + } + } + + /* Ready directory entries */ + if (unzGoToFirstFile(zFile) == Z_OK) { + char comment[128]; + char filename[HTS_URLMAXSIZE * 4]; + int entries = 0; + int firstSeen = 0; + + memset(comment, 0, sizeof(comment)); // for truncated reads + do { + int readSizeHeader = 0; + + filename[0] = '\0'; + comment[0] = '\0'; + if (unzOpenCurrentFile(zFile) == Z_OK) { + if ((readSizeHeader = + unzGetLocalExtrafield(zFile, comment, sizeof(comment) - 2)) > 0 + && unzGetCurrentFileInfo(zFile, NULL, filename, + sizeof(filename) - 2, NULL, 0, NULL, + 0) == Z_OK) { + long int pos = (long int) unzGetOffset(zFile); + + assertf(readSizeHeader < sizeof(comment)); + comment[readSizeHeader] = '\0'; + entries++; + if (pos > 0) { + int dataincache = 0; // data in cache ? + char *filenameIndex = filename; + + if (strncmp(filenameIndex, "http://", 7) == 0) { + filenameIndex += 7; + } + if (comment[0] != '\0') { + int maxLine = 2; + char *a = comment; + + while(*a && maxLine-- > 0) { // parse only few first lines + char line[1024]; + + line[0] = '\0'; + a += binput(a, line, sizeof(line) - 2); + if (strncmp(line, "X-In-Cache:", 11) == 0) { + if (strcmp(line, "X-In-Cache: 1") == 0) { + dataincache = 1; + } else { + dataincache = 0; + } + break; + } + } + } + if (dataincache) + inthash_add(hashtable, filenameIndex, pos); + else + inthash_add(hashtable, filenameIndex, -pos); + + /* First link as starting URL */ + if (!firstSeen) { + if (strstr(filenameIndex, "/robots.txt") == NULL) { + firstSeen = 1; + if (!link_has_authority(filenameIndex)) + strcat(index->startUrl, "http://"); + strcat(index->startUrl, filenameIndex); + } + } + } else { + fprintf(stderr, "Corrupted cache meta entry #%d" LF, + (int) entries); + } + } else { + fprintf(stderr, "Corrupted cache entry #%d" LF, (int) entries); + } + unzCloseCurrentFile(zFile); + } else { + fprintf(stderr, "Corrupted cache entry #%d" LF, (int) entries); + } + } while(unzGoToNextFile(zFile) == Z_OK); + return 1; + } else { + inthash_delete(&index->hash); + index = NULL; + } + } else { + index = NULL; + } + } + return 0; +} + +static PT_Element PT_ReadCache__New_u(PT_Index index_, const char *url, + int flags) { + PT_Index__New index = (PT_Index__New) & index_->slots.formatNew; + char location_default[HTS_URLMAXSIZE * 2]; + char previous_save[HTS_URLMAXSIZE * 2]; + char previous_save_[HTS_URLMAXSIZE * 2]; + char catbuff[CATBUFF_SIZE]; intptr_t hash_pos; int hash_pos_return; - PT_Element r = NULL; - if (index == NULL || index->hash == NULL || index->zFile == NULL || url == NULL || *url == 0) - return NULL; - if ((r = PT_ElementNew()) == NULL) - return NULL; - location_default[0] = '\0'; - previous_save[0] = previous_save_[0] = '\0'; + PT_Element r = NULL; + + if (index == NULL || index->hash == NULL || index->zFile == NULL + || url == NULL || *url == 0) + return NULL; + if ((r = PT_ElementNew()) == NULL) + return NULL; + location_default[0] = '\0'; + previous_save[0] = previous_save_[0] = '\0'; memset(r, 0, sizeof(_PT_Element)); r->location = location_default; - strcpy(r->location, ""); - if (strncmp(url, "http://", 7) == 0) - url += 7; + strcpy(r->location, ""); + if (strncmp(url, "http://", 7) == 0) + url += 7; hash_pos_return = inthash_read(index->hash, url, &hash_pos); if (hash_pos_return) { uLong posInZip; + if (hash_pos > 0) { posInZip = (uLong) hash_pos; } else { - posInZip = (uLong) -hash_pos; + posInZip = (uLong) - hash_pos; } - if (unzSetOffset(index->zFile, posInZip) == Z_OK) { + if (unzSetOffset(index->zFile, posInZip) == Z_OK) { /* Read header (Max 8KiB) */ if (unzOpenCurrentFile(index->zFile) == Z_OK) { char headerBuff[8192 + 2]; int readSizeHeader; int totalHeader = 0; int dataincache = 0; - + /* For BIG comments */ - headerBuff[0] - = headerBuff[sizeof(headerBuff) - 1] - = headerBuff[sizeof(headerBuff) - 2] + headerBuff[0] + = headerBuff[sizeof(headerBuff) - 1] + = headerBuff[sizeof(headerBuff) - 2] = headerBuff[sizeof(headerBuff) - 3] = '\0'; - if ( (readSizeHeader = unzGetLocalExtrafield(index->zFile, headerBuff, sizeof(headerBuff) - 2)) > 0) - { + if ((readSizeHeader = + unzGetLocalExtrafield(index->zFile, headerBuff, + sizeof(headerBuff) - 2)) > 0) { int offset = 0; char line[HTS_URLMAXSIZE + 2]; int lineEof = 0; + headerBuff[readSizeHeader] = '\0'; do { - char* value; + char *value; + line[0] = '\0'; offset += binput(headerBuff + offset, line, sizeof(line) - 2); if (line[0] == '\0') { @@ -994,175 +1058,187 @@ static PT_Element PT_ReadCache__New_u(PT_Index index_, const char* url, int flag value = strchr(line, ':'); if (value != NULL) { *value++ = '\0'; - if (*value == ' ' || *value == '\t') value++; + if (*value == ' ' || *value == '\t') + value++; ZIP_READFIELD_INT(line, value, "X-In-Cache", dataincache); ZIP_READFIELD_INT(line, value, "X-Statuscode", r->statuscode); - ZIP_READFIELD_STRING(line, value, "X-StatusMessage", r->msg); // msg - ZIP_READFIELD_INT(line, value, "X-Size", r->size); // size - ZIP_READFIELD_STRING(line, value, "Content-Type", r->contenttype); // contenttype - ZIP_READFIELD_STRING(line, value, "X-Charset", r->charset); // contenttype - ZIP_READFIELD_STRING(line, value, "Last-Modified", r->lastmodified); // last-modified - ZIP_READFIELD_STRING(line, value, "Etag", r->etag); // Etag - ZIP_READFIELD_STRING(line, value, "Location", r->location); // 'location' pour moved - ZIP_READFIELD_STRING(line, value, "Content-Disposition", r->cdispo); // Content-disposition + ZIP_READFIELD_STRING(line, value, "X-StatusMessage", r->msg); // msg + ZIP_READFIELD_INT(line, value, "X-Size", r->size); // size + ZIP_READFIELD_STRING(line, value, "Content-Type", r->contenttype); // contenttype + ZIP_READFIELD_STRING(line, value, "X-Charset", r->charset); // contenttype + ZIP_READFIELD_STRING(line, value, "Last-Modified", r->lastmodified); // last-modified + ZIP_READFIELD_STRING(line, value, "Etag", r->etag); // Etag + ZIP_READFIELD_STRING(line, value, "Location", r->location); // 'location' pour moved + ZIP_READFIELD_STRING(line, value, "Content-Disposition", r->cdispo); // Content-disposition //ZIP_READFIELD_STRING(line, value, "X-Addr", ..); // Original address //ZIP_READFIELD_STRING(line, value, "X-Fil", ..); // Original URI filename - ZIP_READFIELD_STRING(line, value, "X-Save", previous_save_); // Original save filename - if (line[0] != '\0') { - int len = r->headers ? ((int) strlen(r->headers)) : 0; - int nlen = (int) ( strlen(line) + 2 + strlen(value) + sizeof("\r\n") + 1 ); - r->headers = realloc(r->headers, len + nlen); - r->headers[len] = '\0'; - strcat(r->headers, line); - strcat(r->headers, ": "); - strcat(r->headers, value); - strcat(r->headers, "\r\n"); - } + ZIP_READFIELD_STRING(line, value, "X-Save", previous_save_); // Original save filename + if (line[0] != '\0') { + int len = r->headers ? ((int) strlen(r->headers)) : 0; + int nlen = + (int) (strlen(line) + 2 + strlen(value) + sizeof("\r\n") + 1); + r->headers = realloc(r->headers, len + nlen); + r->headers[len] = '\0'; + strcat(r->headers, line); + strcat(r->headers, ": "); + strcat(r->headers, value); + strcat(r->headers, "\r\n"); + } } } while(offset < readSizeHeader && !lineEof); totalHeader = offset; - /* Previous entry */ - if (previous_save_[0] != '\0') { - int pathLen = (int) strlen(index->path); - if (pathLen > 0 && strncmp(previous_save_, index->path, pathLen) == 0) { // old (<3.40) buggy format - strcpy(previous_save, previous_save_); - } - // relative ? (hack) - else if (index->safeCache - || (previous_save_[0] != '/' // /home/foo/bar.gif - && ( !isalpha(previous_save_[0]) || previous_save_[1] != ':' ) ) // c:/home/foo/bar.gif - ) - { - index->safeCache = 1; - sprintf(previous_save, "%s%s", index->path, previous_save_); - } - // bogus format (includes buggy absolute path) - else { - /* guess previous path */ - if (index->fixedPath == 0) { - const char * start = jump_protocol_and_auth(url); - const char * end = start ? strchr(start, '/') : NULL; - int len = (int) (end - start); - if (start != NULL && end != NULL && len > 0 && len < 128) { - char piece[128 + 2]; - const char * where; - piece[0] = '\0'; - strncat(piece, start, len); - if ((where = strstr(previous_save_, piece)) != NULL) { - index->fixedPath = (int) (where - previous_save_); // offset to relative path - } - } - } - if (index->fixedPath > 0) { - int saveLen = (int) strlen(previous_save_); - if (index->fixedPath < saveLen) { - sprintf(previous_save, "%s%s", index->path, previous_save_ + index->fixedPath); - } else { - sprintf(r->msg, "Bogus fixePath prefix for %s (prefixLen=%d)", previous_save_, (int)index->fixedPath); - r->statuscode = STATUSCODE_INVALID; - } - } else { - sprintf(previous_save, "%s%s", index->path, previous_save_); - } - } - } + /* Previous entry */ + if (previous_save_[0] != '\0') { + int pathLen = (int) strlen(index->path); + + if (pathLen > 0 && strncmp(previous_save_, index->path, pathLen) == 0) { // old (<3.40) buggy format + strcpy(previous_save, previous_save_); + } + // relative ? (hack) + else if (index->safeCache || (previous_save_[0] != '/' // /home/foo/bar.gif + && (!isalpha(previous_save_[0]) || previous_save_[1] != ':')) // c:/home/foo/bar.gif + ) { + index->safeCache = 1; + sprintf(previous_save, "%s%s", index->path, previous_save_); + } + // bogus format (includes buggy absolute path) + else { + /* guess previous path */ + if (index->fixedPath == 0) { + const char *start = jump_protocol_and_auth(url); + const char *end = start ? strchr(start, '/') : NULL; + int len = (int) (end - start); + + if (start != NULL && end != NULL && len > 0 && len < 128) { + char piece[128 + 2]; + const char *where; + + piece[0] = '\0'; + strncat(piece, start, len); + if ((where = strstr(previous_save_, piece)) != NULL) { + index->fixedPath = (int) (where - previous_save_); // offset to relative path + } + } + } + if (index->fixedPath > 0) { + int saveLen = (int) strlen(previous_save_); + + if (index->fixedPath < saveLen) { + sprintf(previous_save, "%s%s", index->path, + previous_save_ + index->fixedPath); + } else { + sprintf(r->msg, "Bogus fixePath prefix for %s (prefixLen=%d)", + previous_save_, (int) index->fixedPath); + r->statuscode = STATUSCODE_INVALID; + } + } else { + sprintf(previous_save, "%s%s", index->path, previous_save_); + } + } + } /* Complete fields */ - r->adr=NULL; - if (r->statuscode != STATUSCODE_INVALID) { /* Can continue */ + r->adr = NULL; + if (r->statuscode != STATUSCODE_INVALID) { /* Can continue */ int ok = 0; - + // Court-circuit: // Peut-on stocker le fichier directement sur disque? if (ok) { if (r->msg[0] == '\0') { - strcpy(r->msg,"Cache Read Error : Unexpected error"); + strcpy(r->msg, "Cache Read Error : Unexpected error"); } - } else { // lire en mémoire - + } else { // lire en mémoire + if (!dataincache) { - /* Read in memory from cache */ - if (flags & FETCH_BODY) { - if (strnotempty(previous_save)) { - FILE* fp = fopen(fconv(catbuff,previous_save), "rb"); - if (fp != NULL) { - r->adr = (char*) malloc(r->size + 4); - if (r->adr != NULL) { - if (r->size > 0 && fread(r->adr, 1, r->size, fp) != r->size) { + /* Read in memory from cache */ + if (flags & FETCH_BODY) { + if (strnotempty(previous_save)) { + FILE *fp = fopen(fconv(catbuff, previous_save), "rb"); + + if (fp != NULL) { + r->adr = (char *) malloc(r->size + 4); + if (r->adr != NULL) { + if (r->size > 0 + && fread(r->adr, 1, r->size, fp) != r->size) { int last_errno = errno; - r->statuscode=STATUSCODE_INVALID; - sprintf(r->msg,"Read error in cache disk data: %s", strerror(last_errno)); - } - } else { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"Read error (memory exhausted) from cache"); - } - fclose(fp); - } else { - r->statuscode=STATUSCODE_INVALID; - sprintf(r->msg, "Read error (can't open '%s') from cache", fconv(catbuff,previous_save)); - } - } else { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"Cached file name is invalid"); - } - } + + r->statuscode = STATUSCODE_INVALID; + sprintf(r->msg, "Read error in cache disk data: %s", + strerror(last_errno)); + } + } else { + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, + "Read error (memory exhausted) from cache"); + } + fclose(fp); + } else { + r->statuscode = STATUSCODE_INVALID; + sprintf(r->msg, "Read error (can't open '%s') from cache", + fconv(catbuff, previous_save)); + } + } else { + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Cached file name is invalid"); + } + } } else { - // lire fichier (d'un coup) - if (flags & FETCH_BODY) { - r->adr=(char*) malloc(r->size+1); - if (r->adr!=NULL) { - if (unzReadCurrentFile(index->zFile, r->adr, (unsigned int) r->size) != r->size) { // erreur - free(r->adr); - r->adr=NULL; - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"Cache Read Error : Read Data"); - } else - *(r->adr+r->size)='\0'; - //printf(">%s status %d\n",back[p].r->contenttype,back[p].r->statuscode); - } else { // erreur - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"Cache Memory Error"); - } - } - } + // lire fichier (d'un coup) + if (flags & FETCH_BODY) { + r->adr = (char *) malloc(r->size + 1); + if (r->adr != NULL) { + if (unzReadCurrentFile(index->zFile, r->adr, (unsigned int) r->size) != r->size) { // erreur + free(r->adr); + r->adr = NULL; + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Cache Read Error : Read Data"); + } else + *(r->adr + r->size) = '\0'; + //printf(">%s status %d\n",back[p].r->contenttype,back[p].r->statuscode); + } else { // erreur + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Cache Memory Error"); + } + } + } } - } // si save==null, ne rien charger (juste en tête) + } // si save==null, ne rien charger (juste en tête) } else { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"Cache Read Error : Read Header Data"); + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Cache Read Error : Read Header Data"); } unzCloseCurrentFile(index->zFile); } else { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"Cache Read Error : Open File"); + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Cache Read Error : Open File"); } } else { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"Cache Read Error : Bad Offset"); + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Cache Read Error : Bad Offset"); } } else { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"File Cache Entry Not Found"); - } - if (r->location[0] != '\0') { - r->location = strdup(r->location); - } else { - r->location = NULL; - } + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "File Cache Entry Not Found"); + } + if (r->location[0] != '\0') { + r->location = strdup(r->location); + } else { + r->location = NULL; + } return r; } static int PT_SaveCache__New_Fun(void *arg, const char *url, PT_Element element) { - zipFile zFileOut = (zipFile) arg; - char headers[8192]; + zipFile zFileOut = (zipFile) arg; + char headers[8192]; int headersSize; zip_fileinfo fi; - int zErr; - const char *url_adr = ""; - const char *url_fil = ""; + int zErr; + const char *url_adr = ""; + const char *url_fil = ""; headers[0] = '\0'; headersSize = 0; @@ -1172,14 +1248,16 @@ static int PT_SaveCache__New_Fun(void *arg, const char *url, PT_Element element) headersSize = 0; /* */ { - char* message; + char *message; + if (strlen(element->msg) < 32) { message = element->msg; } else { message = "(See X-StatusMessage)"; } /* 64 characters MAX for first line */ - sprintf(headers + headersSize, "HTTP/1.%c %d %s\r\n", '1', element->statuscode, element->msg); + sprintf(headers + headersSize, "HTTP/1.%c %d %s\r\n", '1', + element->statuscode, element->msg); } headersSize += (int) strlen(headers + headersSize); @@ -1187,22 +1265,23 @@ static int PT_SaveCache__New_Fun(void *arg, const char *url, PT_Element element) ZIP_FIELD_INT_FORCE(headers, headersSize, "X-In-Cache", 1); ZIP_FIELD_INT(headers, headersSize, "X-StatusCode", element->statuscode); ZIP_FIELD_STRING(headers, headersSize, "X-StatusMessage", element->msg); - ZIP_FIELD_INT(headers, headersSize, "X-Size", element->size); // size - ZIP_FIELD_STRING(headers, headersSize, "Content-Type", element->contenttype); // contenttype - ZIP_FIELD_STRING(headers, headersSize, "X-Charset", element->charset); // contenttype - ZIP_FIELD_STRING(headers, headersSize, "Last-Modified", element->lastmodified); // last-modified - ZIP_FIELD_STRING(headers, headersSize, "Etag", element->etag); // Etag - ZIP_FIELD_STRING(headers, headersSize, "Location", element->location); // 'location' pour moved - ZIP_FIELD_STRING(headers, headersSize, "Content-Disposition", element->cdispo); // Content-disposition - ZIP_FIELD_STRING(headers, headersSize, "X-Addr", url_adr); // Original address - ZIP_FIELD_STRING(headers, headersSize, "X-Fil", url_fil); // Original URI filename - ZIP_FIELD_STRING(headers, headersSize, "X-Save", ""); // Original save filename - + ZIP_FIELD_INT(headers, headersSize, "X-Size", element->size); // size + ZIP_FIELD_STRING(headers, headersSize, "Content-Type", element->contenttype); // contenttype + ZIP_FIELD_STRING(headers, headersSize, "X-Charset", element->charset); // contenttype + ZIP_FIELD_STRING(headers, headersSize, "Last-Modified", element->lastmodified); // last-modified + ZIP_FIELD_STRING(headers, headersSize, "Etag", element->etag); // Etag + ZIP_FIELD_STRING(headers, headersSize, "Location", element->location); // 'location' pour moved + ZIP_FIELD_STRING(headers, headersSize, "Content-Disposition", element->cdispo); // Content-disposition + ZIP_FIELD_STRING(headers, headersSize, "X-Addr", url_adr); // Original address + ZIP_FIELD_STRING(headers, headersSize, "X-Fil", url_fil); // Original URI filename + ZIP_FIELD_STRING(headers, headersSize, "X-Save", ""); // Original save filename + /* Time */ memset(&fi, 0, sizeof(fi)); if (element->lastmodified[0] != '\0') { - struct tm buffer; - struct tm* tm_s = convert_time_rfc822(&buffer, element->lastmodified); + struct tm buffer; + struct tm *tm_s = convert_time_rfc822(&buffer, element->lastmodified); + if (tm_s) { fi.tmz_date.tm_sec = (uInt) tm_s->tm_sec; fi.tmz_date.tm_min = (uInt) tm_s->tm_min; @@ -1214,333 +1293,355 @@ static int PT_SaveCache__New_Fun(void *arg, const char *url, PT_Element element) } /* Open file - NOTE: headers in "comment" */ - if ((zErr = zipOpenNewFileInZip(zFileOut, - url, - &fi, - /* - Store headers in realtime in the local file directory as extra field - In case of crash, we'll be able to recover the whole ZIP file by rescanning it - */ - headers, - (uInt) strlen(headers), - NULL, - 0, - NULL, /* comment */ - Z_DEFLATED, - Z_DEFAULT_COMPRESSION)) != Z_OK) - { + if ((zErr = zipOpenNewFileInZip(zFileOut, url, &fi, + /* + Store headers in realtime in the local file directory as extra field + In case of crash, we'll be able to recover the whole ZIP file by rescanning it + */ + headers, (uInt) strlen(headers), NULL, 0, NULL, /* comment */ + Z_DEFLATED, Z_DEFAULT_COMPRESSION)) != Z_OK) { int zip_zipOpenNewFileInZip_failed = 0; + assertf(zip_zipOpenNewFileInZip_failed); } - - /* Write data in cache */ - if (element->size > 0 && element->adr != NULL) { - if ((zErr = zipWriteInFileInZip(zFileOut, element->adr, (int) element->size)) != Z_OK) { - int zip_zipWriteInFileInZip_failed = 0; - assertf(zip_zipWriteInFileInZip_failed); - } - } - - /* Close */ - if ((zErr = zipCloseFileInZip(zFileOut)) != Z_OK) { - int zip_zipCloseFileInZip_failed = 0; + + /* Write data in cache */ + if (element->size > 0 && element->adr != NULL) { + if ((zErr = + zipWriteInFileInZip(zFileOut, element->adr, + (int) element->size)) != Z_OK) { + int zip_zipWriteInFileInZip_failed = 0; + + assertf(zip_zipWriteInFileInZip_failed); + } + } + + /* Close */ + if ((zErr = zipCloseFileInZip(zFileOut)) != Z_OK) { + int zip_zipCloseFileInZip_failed = 0; + assertf(zip_zipCloseFileInZip_failed); } /* Flush */ if ((zErr = zipFlush(zFileOut)) != 0) { int zip_zipFlush_failed = 0; + assertf(zip_zipFlush_failed); } - return 0; + return 0; } static int PT_SaveCache__New(PT_Indexes indexes, const char *filename) { - zipFile zFileOut = zipOpen(filename, 0); - if (zFileOut != NULL) { - int ret = PT_EnumCache(indexes, PT_SaveCache__New_Fun, (void *) zFileOut); - zipClose(zFileOut, "Created by HTTrack Website Copier/ProxyTrack "PROXYTRACK_VERSION); - zFileOut = NULL; - if (ret != 0) - (void) unlink(filename); - return ret; - } - return -1; + zipFile zFileOut = zipOpen(filename, 0); + + if (zFileOut != NULL) { + int ret = PT_EnumCache(indexes, PT_SaveCache__New_Fun, (void *) zFileOut); + + zipClose(zFileOut, + "Created by HTTrack Website Copier/ProxyTrack " + PROXYTRACK_VERSION); + zFileOut = NULL; + if (ret != 0) + (void) unlink(filename); + return ret; + } + return -1; } - - /* ------------------------------------------------------------ */ /* Old HTTrack cache (dat/ndx) format */ /* ------------------------------------------------------------ */ -static int cache_brstr(char* adr,char* s) { +static int cache_brstr(char *adr, char *s) { int i; int off; char buff[256 + 1]; - off=binput(adr,buff,256); - adr+=off; - sscanf(buff,"%d",&i); - if (i>0) - strncpy(s,adr,i); - *(s+i)='\0'; - off+=i; + + off = binput(adr, buff, 256); + adr += off; + sscanf(buff, "%d", &i); + if (i > 0) + strncpy(s, adr, i); + *(s + i) = '\0'; + off += i; return off; } -static void cache_rstr(FILE* fp,char* s) { +static void cache_rstr(FILE * fp, char *s) { INTsys i; - char buff[256+4]; - linput(fp,buff,256); - sscanf(buff,INTsysP,&i); - if (i < 0 || i > 32768) /* error, something nasty happened */ - i=0; - if (i>0) { - if ((int) fread(s,1,i,fp) != i) { + char buff[256 + 4]; + + linput(fp, buff, 256); + sscanf(buff, INTsysP, &i); + if (i < 0 || i > 32768) /* error, something nasty happened */ + i = 0; + if (i > 0) { + if ((int) fread(s, 1, i, fp) != i) { int fread_cache_failed = 0; + assertf(fread_cache_failed); } } - *(s+i)='\0'; + *(s + i) = '\0'; } -static char* cache_rstr_addr(FILE* fp) { +static char *cache_rstr_addr(FILE * fp) { INTsys i; - char* addr = NULL; - char buff[256+4]; - linput(fp,buff,256); - sscanf(buff,"%d",&i); - if (i < 0 || i > 32768) /* error, something nasty happened */ - i=0; + char *addr = NULL; + char buff[256 + 4]; + + linput(fp, buff, 256); + sscanf(buff, "%d", &i); + if (i < 0 || i > 32768) /* error, something nasty happened */ + i = 0; if (i > 0) { addr = malloc(i + 1); if (addr != NULL) { - if ((int) fread(addr,1,i,fp) != i) { + if ((int) fread(addr, 1, i, fp) != i) { int fread_cache_failed = 0; + assertf(fread_cache_failed); } - *(addr+i)='\0'; + *(addr + i) = '\0'; } } return addr; } -static void cache_rint(FILE* fp,int* i) { +static void cache_rint(FILE * fp, int *i) { char s[256]; - cache_rstr(fp,s); - sscanf(s,"%d",i); + + cache_rstr(fp, s); + sscanf(s, "%d", i); } -static void cache_rLLint(FILE* fp,unsigned long* i) { - int l; +static void cache_rLLint(FILE * fp, unsigned long *i) { + int l; char s[256]; - cache_rstr(fp,s); - sscanf(s,"%d",&l); - *i = (unsigned long)l; + + cache_rstr(fp, s); + sscanf(s, "%d", &l); + *i = (unsigned long) l; } static int PT_LoadCache__Old(PT_Index index_, const char *filename) { - if (index_ != NULL && filename != NULL) { - char * pos = strrchr(filename, '.'); - PT_Index__Old cache = &index_->slots.formatOld; - long int ndxSize; - cache->filenameDat[0] = '\0'; - cache->filenameNdx[0] = '\0'; - cache->path[0] = '\0'; - - { - PT_Index__Old index = cache; - const char * abpath; - int slashes; - /* -------------------- COPY OF THE __New() CODE -------------------- */ - /* Compute base path for this index - the filename MUST be absolute! */ - for(slashes = 2, abpath = filename + (int)strlen(filename) - 1 - ; abpath > filename && ( ( *abpath != '/'&& *abpath != '\\' ) || --slashes > 0) - ; abpath--); - index->path[0] = '\0'; - if (slashes == 0 && *abpath != 0) { - int i; - strncat(index->path, filename, (int) ( abpath - filename ) + 1 ); - for(i = 0 ; index->path[i] != 0 ; i++) { - if (index->path[i] == '\\') { - index->path[i] = '/'; - } - } - } - /* -------------------- END OF COPY OF THE __New() CODE -------------------- */ - } - - /* Index/data filenames */ - if (pos != NULL) { - int nLen = (int) (pos - filename); - strncat(cache->filenameDat, filename, nLen); - strncat(cache->filenameNdx, filename, nLen); - strcat(cache->filenameDat, ".dat"); - strcat(cache->filenameNdx, ".ndx"); - } - ndxSize = filesize(cache->filenameNdx); - cache->timestamp = file_timestamp(cache->filenameDat); - cache->dat = fopen(cache->filenameDat, "rb"); - cache->ndx = fopen(cache->filenameNdx, "rb"); - if (cache->dat != NULL && cache->ndx != NULL && ndxSize > 0) { - char * use = malloc(ndxSize + 1); - if (fread(use, 1, ndxSize, cache->ndx) == ndxSize) { - char firstline[256]; - char* a=use; - use[ndxSize] = '\0'; - a += cache_brstr(a, firstline); - if (strncmp(firstline,"CACHE-",6)==0) { // Nouvelle version du cache - if (strncmp(firstline,"CACHE-1.",8)==0) { // Version 1.1x - cache->version=(int)(firstline[8]-'0'); // cache 1.x - if (cache->version <= 5) { - a+=cache_brstr(a,firstline); - strcpy(cache->lastmodified,firstline); - } else { - // fprintf(opt->errlog,"Cache: version 1.%d not supported, ignoring current cache"LF,cache->version); - fclose(cache->dat); - cache->dat=NULL; - free(use); - use=NULL; - } - } else { // non supporté - // fspc(opt->errlog,"error"); fprintf(opt->errlog,"Cache: %s not supported, ignoring current cache"LF,firstline); - fclose(cache->dat); - cache->dat=NULL; - free(use); - use=NULL; - } - /* */ - } else { // Vieille version du cache - /* */ - // hts_log_print(opt, LOG_WARNING, "Cache: importing old cache format"); - cache->version=0; // cache 1.0 - strcpy(cache->lastmodified,firstline); - } - - /* Create hash table for the cache (MUCH FASTER!) */ - if (use) { - char line[HTS_URLMAXSIZE*2]; - char linepos[256]; - int pos; - int firstSeen = 0; - while ( (a!=NULL) && (a < (use + ndxSize) ) ) { - a=strchr(a+1,'\n'); /* start of line */ - if (a) { - a++; - /* read "host/file" */ - a+=binput(a,line,HTS_URLMAXSIZE); - a+=binput(a,line+strlen(line),HTS_URLMAXSIZE); - /* read position */ - a+=binput(a,linepos,200); - sscanf(linepos,"%d",&pos); - - /* Add entry */ - inthash_add(cache->hash,line,pos); - - /* First link as starting URL */ - if (!firstSeen) { - if (strstr(line, "/robots.txt") == NULL) { - PT_Index__Old index = cache; - firstSeen = 1; - if (!link_has_authority(line)) - strcat(index->startUrl, "http://"); - strcat(index->startUrl, line); - } - } - - } - } - /* Not needed anymore! */ - free(use); - use=NULL; - return 1; - } - } - } - } - return 0; -} - -static String DecodeUrl(const char * url) { - int i; - String s = STRING_EMPTY; - StringClear(s); - for(i = 0 ; url[i] != '\0' ; i++) { - if (url[i] == '+') { - StringAddchar(s, ' '); - } else if (url[i] == '%') { - if (url[i + 1] == '%') { - StringAddchar(s, '%'); - i++; - } else if (url[i + 1] != 0 && url[i + 2] != 0) { - char tmp[3]; - int codepoint = 0; - tmp[0] = url[i + 1]; - tmp[1] = url[i + 2]; - tmp[2] = 0; - if (sscanf(tmp, "%x", &codepoint) == 1) { - StringAddchar(s, (char)codepoint); - } - i += 2; - } - } else { - StringAddchar(s, url[i]); - } - } - return s; -} - -static PT_Element PT_ReadCache__Old(PT_Index index, const char* url, int flags) { - PT_Element retCode; - MutexLock(&index->slots.formatOld.fileLock); - { - retCode = PT_ReadCache__Old_u(index, url, flags); - } - MutexUnlock(&index->slots.formatOld.fileLock); - return retCode; -} - -static PT_Element PT_ReadCache__Old_u(PT_Index index_, const char* url, int flags) { - PT_Index__Old cache = (PT_Index__Old) &index_->slots.formatOld; + if (index_ != NULL && filename != NULL) { + char *pos = strrchr(filename, '.'); + PT_Index__Old cache = &index_->slots.formatOld; + long int ndxSize; + + cache->filenameDat[0] = '\0'; + cache->filenameNdx[0] = '\0'; + cache->path[0] = '\0'; + + { + PT_Index__Old index = cache; + const char *abpath; + int slashes; + + /* -------------------- COPY OF THE __New() CODE -------------------- */ + /* Compute base path for this index - the filename MUST be absolute! */ + for(slashes = 2, abpath = filename + (int) strlen(filename) - 1; + abpath > filename && ((*abpath != '/' && *abpath != '\\') + || --slashes > 0); + abpath--) ; + index->path[0] = '\0'; + if (slashes == 0 && *abpath != 0) { + int i; + + strncat(index->path, filename, (int) (abpath - filename) + 1); + for(i = 0; index->path[i] != 0; i++) { + if (index->path[i] == '\\') { + index->path[i] = '/'; + } + } + } + /* -------------------- END OF COPY OF THE __New() CODE -------------------- */ + } + + /* Index/data filenames */ + if (pos != NULL) { + int nLen = (int) (pos - filename); + + strncat(cache->filenameDat, filename, nLen); + strncat(cache->filenameNdx, filename, nLen); + strcat(cache->filenameDat, ".dat"); + strcat(cache->filenameNdx, ".ndx"); + } + ndxSize = filesize(cache->filenameNdx); + cache->timestamp = file_timestamp(cache->filenameDat); + cache->dat = fopen(cache->filenameDat, "rb"); + cache->ndx = fopen(cache->filenameNdx, "rb"); + if (cache->dat != NULL && cache->ndx != NULL && ndxSize > 0) { + char *use = malloc(ndxSize + 1); + + if (fread(use, 1, ndxSize, cache->ndx) == ndxSize) { + char firstline[256]; + char *a = use; + + use[ndxSize] = '\0'; + a += cache_brstr(a, firstline); + if (strncmp(firstline, "CACHE-", 6) == 0) { // Nouvelle version du cache + if (strncmp(firstline, "CACHE-1.", 8) == 0) { // Version 1.1x + cache->version = (int) (firstline[8] - '0'); // cache 1.x + if (cache->version <= 5) { + a += cache_brstr(a, firstline); + strcpy(cache->lastmodified, firstline); + } else { + // fprintf(opt->errlog,"Cache: version 1.%d not supported, ignoring current cache"LF,cache->version); + fclose(cache->dat); + cache->dat = NULL; + free(use); + use = NULL; + } + } else { // non supporté + // fspc(opt->errlog,"error"); fprintf(opt->errlog,"Cache: %s not supported, ignoring current cache"LF,firstline); + fclose(cache->dat); + cache->dat = NULL; + free(use); + use = NULL; + } + /* */ + } else { // Vieille version du cache + /* */ + // hts_log_print(opt, LOG_WARNING, "Cache: importing old cache format"); + cache->version = 0; // cache 1.0 + strcpy(cache->lastmodified, firstline); + } + + /* Create hash table for the cache (MUCH FASTER!) */ + if (use) { + char line[HTS_URLMAXSIZE * 2]; + char linepos[256]; + int pos; + int firstSeen = 0; + + while((a != NULL) && (a < (use + ndxSize))) { + a = strchr(a + 1, '\n'); /* start of line */ + if (a) { + a++; + /* read "host/file" */ + a += binput(a, line, HTS_URLMAXSIZE); + a += binput(a, line + strlen(line), HTS_URLMAXSIZE); + /* read position */ + a += binput(a, linepos, 200); + sscanf(linepos, "%d", &pos); + + /* Add entry */ + inthash_add(cache->hash, line, pos); + + /* First link as starting URL */ + if (!firstSeen) { + if (strstr(line, "/robots.txt") == NULL) { + PT_Index__Old index = cache; + + firstSeen = 1; + if (!link_has_authority(line)) + strcat(index->startUrl, "http://"); + strcat(index->startUrl, line); + } + } + + } + } + /* Not needed anymore! */ + free(use); + use = NULL; + return 1; + } + } + } + } + return 0; +} + +static String DecodeUrl(const char *url) { + int i; + String s = STRING_EMPTY; + + StringClear(s); + for(i = 0; url[i] != '\0'; i++) { + if (url[i] == '+') { + StringAddchar(s, ' '); + } else if (url[i] == '%') { + if (url[i + 1] == '%') { + StringAddchar(s, '%'); + i++; + } else if (url[i + 1] != 0 && url[i + 2] != 0) { + char tmp[3]; + int codepoint = 0; + + tmp[0] = url[i + 1]; + tmp[1] = url[i + 2]; + tmp[2] = 0; + if (sscanf(tmp, "%x", &codepoint) == 1) { + StringAddchar(s, (char) codepoint); + } + i += 2; + } + } else { + StringAddchar(s, url[i]); + } + } + return s; +} + +static PT_Element PT_ReadCache__Old(PT_Index index, const char *url, int flags) { + PT_Element retCode; + + MutexLock(&index->slots.formatOld.fileLock); + { + retCode = PT_ReadCache__Old_u(index, url, flags); + } + MutexUnlock(&index->slots.formatOld.fileLock); + return retCode; +} + +static PT_Element PT_ReadCache__Old_u(PT_Index index_, const char *url, + int flags) { + PT_Index__Old cache = (PT_Index__Old) & index_->slots.formatOld; intptr_t hash_pos; int hash_pos_return; - char location_default[HTS_URLMAXSIZE*2]; - char previous_save[HTS_URLMAXSIZE*2]; - char previous_save_[HTS_URLMAXSIZE*2]; + char location_default[HTS_URLMAXSIZE * 2]; + char previous_save[HTS_URLMAXSIZE * 2]; + char previous_save_[HTS_URLMAXSIZE * 2]; PT_Element r; - int ok=0; - - if (cache == NULL || cache->hash == NULL || url == NULL || *url == 0) - return NULL; - if ((r = PT_ElementNew()) == NULL) - return NULL; - location_default[0] = '\0'; - previous_save[0] = previous_save_[0] = '\0'; + int ok = 0; + + if (cache == NULL || cache->hash == NULL || url == NULL || *url == 0) + return NULL; + if ((r = PT_ElementNew()) == NULL) + return NULL; + location_default[0] = '\0'; + previous_save[0] = previous_save_[0] = '\0'; memset(r, 0, sizeof(_PT_Element)); r->location = location_default; - strcpy(r->location, ""); - if (strncmp(url, "http://", 7) == 0) - url += 7; - hash_pos_return=inthash_read(cache->hash, url, &hash_pos); + strcpy(r->location, ""); + if (strncmp(url, "http://", 7) == 0) + url += 7; + hash_pos_return = inthash_read(cache->hash, url, &hash_pos); if (hash_pos_return) { - int pos = (int) hash_pos; /* simply */ - - if (fseek(cache->dat, (pos>0) ? pos : (-pos), SEEK_SET) == 0) { - /* Importer cache1.0 */ - if (cache->version==0) { - OLD_htsblk old_r; - if (fread((char*) &old_r,1,sizeof(old_r),cache->dat) == sizeof(old_r)) { // lire tout (y compris statuscode etc) - int i; - String urlDecoded; - r->statuscode = old_r.statuscode; - r->size = old_r.size; // taille fichier - strcpy(r->msg, old_r.msg); - strcpy(r->contenttype, old_r.contenttype); - - /* Guess the destination filename.. this sucks, because this method is not reliable. - Yes, the old 1.0 cache format was *that* bogus. /rx */ + int pos = (int) hash_pos; /* simply */ + + if (fseek(cache->dat, (pos > 0) ? pos : (-pos), SEEK_SET) == 0) { + /* Importer cache1.0 */ + if (cache->version == 0) { + OLD_htsblk old_r; + + if (fread((char *) &old_r, 1, sizeof(old_r), cache->dat) == sizeof(old_r)) { // lire tout (y compris statuscode etc) + int i; + String urlDecoded; + + r->statuscode = old_r.statuscode; + r->size = old_r.size; // taille fichier + strcpy(r->msg, old_r.msg); + strcpy(r->contenttype, old_r.contenttype); + + /* Guess the destination filename.. this sucks, because this method is not reliable. + Yes, the old 1.0 cache format was *that* bogus. /rx */ #define FORBIDDEN_CHAR(c) (c == '~' \ || c == '\\' \ || c == ':' \ @@ -1554,203 +1655,211 @@ static PT_Element PT_ReadCache__Old_u(PT_Index index_, const char* url, int flag || ((unsigned char) c ) <= 31 \ || ((unsigned char) c ) == 127 \ ) - urlDecoded = DecodeUrl(jump_protocol_and_auth(url)); - strcpy(previous_save_, StringBuff(urlDecoded)); - StringFree(urlDecoded); - for(i = 0 ; previous_save_[i] != '\0' && previous_save_[i] != '?' ; i++) { - if (FORBIDDEN_CHAR(previous_save_[i])) { - previous_save_[i] = '_'; - } - } - previous_save_[i] = '\0'; + urlDecoded = DecodeUrl(jump_protocol_and_auth(url)); + strcpy(previous_save_, StringBuff(urlDecoded)); + StringFree(urlDecoded); + for(i = 0; previous_save_[i] != '\0' && previous_save_[i] != '?'; i++) { + if (FORBIDDEN_CHAR(previous_save_[i])) { + previous_save_[i] = '_'; + } + } + previous_save_[i] = '\0'; #undef FORBIDDEN_CHAR - ok = 1; /* import ok */ - } - /* */ - /* Cache 1.1 */ + ok = 1; /* import ok */ + } + /* */ + /* Cache 1.1 */ } else { char check[256]; unsigned long size_read; unsigned long int size_; - check[0]='\0'; + + check[0] = '\0'; // - cache_rint(cache->dat,&r->statuscode); - cache_rLLint(cache->dat,&size_); + cache_rint(cache->dat, &r->statuscode); + cache_rLLint(cache->dat, &size_); r->size = (size_t) size_; - cache_rstr(cache->dat,r->msg); - cache_rstr(cache->dat,r->contenttype); + cache_rstr(cache->dat, r->msg); + cache_rstr(cache->dat, r->contenttype); if (cache->version >= 3) - cache_rstr(cache->dat,r->charset); - cache_rstr(cache->dat,r->lastmodified); - cache_rstr(cache->dat,r->etag); - cache_rstr(cache->dat,r->location); + cache_rstr(cache->dat, r->charset); + cache_rstr(cache->dat, r->lastmodified); + cache_rstr(cache->dat, r->etag); + cache_rstr(cache->dat, r->location); if (cache->version >= 2) - cache_rstr(cache->dat,r->cdispo); + cache_rstr(cache->dat, r->cdispo); if (cache->version >= 4) { - cache_rstr(cache->dat, previous_save_); // adr - cache_rstr(cache->dat, previous_save_); // fil + cache_rstr(cache->dat, previous_save_); // adr + cache_rstr(cache->dat, previous_save_); // fil previous_save[0] = '\0'; - cache_rstr(cache->dat, previous_save_); // save + cache_rstr(cache->dat, previous_save_); // save } if (cache->version >= 5) { r->headers = cache_rstr_addr(cache->dat); } // - cache_rstr(cache->dat,check); - if (strcmp(check,"HTS")==0) { /* intégrité OK */ - ok=1; + cache_rstr(cache->dat, check); + if (strcmp(check, "HTS") == 0) { /* intégrité OK */ + ok = 1; } - cache_rLLint(cache->dat, &size_read); /* lire size pour être sûr de la taille déclarée (réécrire) */ - if (size_read > 0) { /* si inscrite ici */ + cache_rLLint(cache->dat, &size_read); /* lire size pour être sûr de la taille déclarée (réécrire) */ + if (size_read > 0) { /* si inscrite ici */ r->size = size_read; - } else { /* pas de données directement dans le cache, fichier présent? */ - r->size = 0; + } else { /* pas de données directement dans le cache, fichier présent? */ + r->size = 0; } } - /* Check destination filename */ - - { - PT_Index__Old index = cache; - /* -------------------- COPY OF THE __New() CODE -------------------- */ - if (previous_save_[0] != '\0') { - int pathLen = (int) strlen(index->path); - if (pathLen > 0 && strncmp(previous_save_, index->path, pathLen) == 0) { // old (<3.40) buggy format - strcpy(previous_save, previous_save_); - } - // relative ? (hack) - else if (index->safeCache - || (previous_save_[0] != '/' // /home/foo/bar.gif - && ( !isalpha(previous_save_[0]) || previous_save_[1] != ':' ) ) // c:/home/foo/bar.gif - ) - { - index->safeCache = 1; - sprintf(previous_save, "%s%s", index->path, previous_save_); - } - // bogus format (includes buggy absolute path) - else { - /* guess previous path */ - if (index->fixedPath == 0) { - const char * start = jump_protocol_and_auth(url); - const char * end = start ? strchr(start, '/') : NULL; - int len = (int) (end - start); - if (start != NULL && end != NULL && len > 0 && len < 128) { - char piece[128 + 2]; - const char * where; - piece[0] = '\0'; - strncat(piece, start, len); - if ((where = strstr(previous_save_, piece)) != NULL) { - index->fixedPath = (int) (where - previous_save_); // offset to relative path - } - } - } - if (index->fixedPath > 0) { - int saveLen = (int) strlen(previous_save_); - if (index->fixedPath < saveLen) { - sprintf(previous_save, "%s%s", index->path, previous_save_ + index->fixedPath); - } else { - sprintf(r->msg, "Bogus fixePath prefix for %s (prefixLen=%d)", previous_save_, (int)index->fixedPath); - r->statuscode = STATUSCODE_INVALID; - } - } else { - sprintf(previous_save, "%s%s", index->path, previous_save_); - } - } - } - /* -------------------- END OF COPY OF THE __New() CODE -------------------- */ - } + /* Check destination filename */ + + { + PT_Index__Old index = cache; + + /* -------------------- COPY OF THE __New() CODE -------------------- */ + if (previous_save_[0] != '\0') { + int pathLen = (int) strlen(index->path); + + if (pathLen > 0 && strncmp(previous_save_, index->path, pathLen) == 0) { // old (<3.40) buggy format + strcpy(previous_save, previous_save_); + } + // relative ? (hack) + else if (index->safeCache || (previous_save_[0] != '/' // /home/foo/bar.gif + && (!isalpha(previous_save_[0]) || previous_save_[1] != ':')) // c:/home/foo/bar.gif + ) { + index->safeCache = 1; + sprintf(previous_save, "%s%s", index->path, previous_save_); + } + // bogus format (includes buggy absolute path) + else { + /* guess previous path */ + if (index->fixedPath == 0) { + const char *start = jump_protocol_and_auth(url); + const char *end = start ? strchr(start, '/') : NULL; + int len = (int) (end - start); + + if (start != NULL && end != NULL && len > 0 && len < 128) { + char piece[128 + 2]; + const char *where; + + piece[0] = '\0'; + strncat(piece, start, len); + if ((where = strstr(previous_save_, piece)) != NULL) { + index->fixedPath = (int) (where - previous_save_); // offset to relative path + } + } + } + if (index->fixedPath > 0) { + int saveLen = (int) strlen(previous_save_); + + if (index->fixedPath < saveLen) { + sprintf(previous_save, "%s%s", index->path, + previous_save_ + index->fixedPath); + } else { + sprintf(r->msg, "Bogus fixePath prefix for %s (prefixLen=%d)", + previous_save_, (int) index->fixedPath); + r->statuscode = STATUSCODE_INVALID; + } + } else { + sprintf(previous_save, "%s%s", index->path, previous_save_); + } + } + } + /* -------------------- END OF COPY OF THE __New() CODE -------------------- */ + } /* Read data */ - if (ok) { - r->adr = NULL; - if ( (r->statuscode>=0) && (r->statuscode<=999)) { - r->adr = NULL; - if (pos<0) { - if (flags & FETCH_BODY) { - FILE* fp = fopen(previous_save, "rb"); - if (fp != NULL) { - r->adr = (char*) malloc(r->size + 1); - if (r->adr != NULL) { - if (r->size > 0 && fread(r->adr, 1, r->size, fp) != r->size) { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"Read error in cache disk data"); - } - r->adr[r->size] = '\0'; - } else { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"Read error (memory exhausted) from cache"); - } - fclose(fp); - } else { - r->statuscode = STATUSCODE_INVALID; - strcpy(r->msg, "Previous cache file not found (2)"); - } - } - } else { - // lire fichier (d'un coup) - if (flags & FETCH_BODY) { - r->adr=(char*) malloc(r->size + 1); - if (r->adr!=NULL) { - if (fread(r->adr, 1, r->size,cache->dat) != r->size) { // erreur - free(r->adr); - r->adr=NULL; - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"Cache Read Error : Read Data"); - } else - r->adr[r->size] = '\0'; - } else { // erreur - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"Cache Memory Error"); - } - } - } - } else { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"Cache Read Error : Bad Data"); + if (ok) { + r->adr = NULL; + if ((r->statuscode >= 0) && (r->statuscode <= 999)) { + r->adr = NULL; + if (pos < 0) { + if (flags & FETCH_BODY) { + FILE *fp = fopen(previous_save, "rb"); + + if (fp != NULL) { + r->adr = (char *) malloc(r->size + 1); + if (r->adr != NULL) { + if (r->size > 0 && fread(r->adr, 1, r->size, fp) != r->size) { + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Read error in cache disk data"); + } + r->adr[r->size] = '\0'; + } else { + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Read error (memory exhausted) from cache"); + } + fclose(fp); + } else { + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Previous cache file not found (2)"); + } + } + } else { + // lire fichier (d'un coup) + if (flags & FETCH_BODY) { + r->adr = (char *) malloc(r->size + 1); + if (r->adr != NULL) { + if (fread(r->adr, 1, r->size, cache->dat) != r->size) { // erreur + free(r->adr); + r->adr = NULL; + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Cache Read Error : Read Data"); + } else + r->adr[r->size] = '\0'; + } else { // erreur + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Cache Memory Error"); + } + } + } + } else { + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Cache Read Error : Bad Data"); } - } else { // erreur - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"Cache Read Error : Read Header"); + } else { // erreur + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Cache Read Error : Read Header"); } } else { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"Cache Read Error : Seek Failed"); + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Cache Read Error : Seek Failed"); } } else { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"File Cache Entry Not Found"); - } - if (r->location[0] != '\0') { - r->location = strdup(r->location); - } else { - r->location = NULL; - } + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "File Cache Entry Not Found"); + } + if (r->location[0] != '\0') { + r->location = strdup(r->location); + } else { + r->location = NULL; + } return r; } -static int PT_LookupCache__Old(PT_Index index, const char* url) { - int retCode; - MutexLock(&index->slots.formatOld.fileLock); - { - retCode = PT_LookupCache__Old_u(index, url); - } - MutexUnlock(&index->slots.formatOld.fileLock); - return retCode; -} +static int PT_LookupCache__Old(PT_Index index, const char *url) { + int retCode; -static int PT_LookupCache__Old_u(PT_Index index_, const char* url) { - if (index_ != NULL) { - PT_Index__New cache = (PT_Index__New) &index_->slots.formatNew; - if (cache == NULL || cache->hash == NULL || url == NULL || *url == 0) - return 0; - if (strncmp(url, "http://", 7) == 0) - url += 7; - if (inthash_read(cache->hash, url, NULL)) - return 1; - } - return 0; + MutexLock(&index->slots.formatOld.fileLock); + { + retCode = PT_LookupCache__Old_u(index, url); + } + MutexUnlock(&index->slots.formatOld.fileLock); + return retCode; } +static int PT_LookupCache__Old_u(PT_Index index_, const char *url) { + if (index_ != NULL) { + PT_Index__New cache = (PT_Index__New) & index_->slots.formatNew; + + if (cache == NULL || cache->hash == NULL || url == NULL || *url == 0) + return 0; + if (strncmp(url, "http://", 7) == 0) + url += 7; + if (inthash_read(cache->hash, url, NULL)) + return 1; + } + return 0; +} /* ------------------------------------------------------------ */ /* Internet Archive Arc 1.0 (arc) format */ @@ -1760,199 +1869,221 @@ static int PT_LookupCache__Old_u(PT_Index index_, const char* url) { #define ARC_SP ' ' -static const char* getArcField(const char *line, int pos) { - int i; - for(i = 0 ; line[i] != '\0' && pos > 0 ; i++) { - if (line[i] == ARC_SP) - pos--; - } - if (pos == 0) - return &line[i]; - return NULL; -} - -static char* copyArcField(const char *line, int npos, char *dest, int destMax) { - const char *pos; - if ((pos = getArcField(line, npos)) != NULL) { - int i; - for(i = 0 ; pos[i] != '\0' && pos[i] != ARC_SP && ( --destMax ) > 0; i++) { - dest[i] = pos[i]; - } - dest[i] = 0; - return dest; - } - dest[0] = 0; - return NULL; +static const char *getArcField(const char *line, int pos) { + int i; + + for(i = 0; line[i] != '\0' && pos > 0; i++) { + if (line[i] == ARC_SP) + pos--; + } + if (pos == 0) + return &line[i]; + return NULL; +} + +static char *copyArcField(const char *line, int npos, char *dest, int destMax) { + const char *pos; + + if ((pos = getArcField(line, npos)) != NULL) { + int i; + + for(i = 0; pos[i] != '\0' && pos[i] != ARC_SP && (--destMax) > 0; i++) { + dest[i] = pos[i]; + } + dest[i] = 0; + return dest; + } + dest[0] = 0; + return NULL; } static int getArcLength(const char *line) { - const char *pos; - if ((pos = getArcField(line, 9)) != NULL - || (pos = getArcField(line, 4)) != NULL - || (pos = getArcField(line, 2)) != NULL - ) { - int length; - if (sscanf(pos, "%d", &length) == 1) { - return length; - } - } - return -1; -} - -static int skipArcNl(FILE* file) { - if (fgetc(file) == 0x0a) { - return 0; - } - return -1; -} - -static int skipArcData(FILE* file, const char *line) { - int jump = getArcLength(line); - if (jump != -1) { - if (fseek(file, jump, SEEK_CUR) == 0 /* && skipArcNl(file) == 0 */) { - return 0; - } - } - return -1; + const char *pos; + + if ((pos = getArcField(line, 9)) != NULL + || (pos = getArcField(line, 4)) != NULL + || (pos = getArcField(line, 2)) != NULL) { + int length; + + if (sscanf(pos, "%d", &length) == 1) { + return length; + } + } + return -1; +} + +static int skipArcNl(FILE * file) { + if (fgetc(file) == 0x0a) { + return 0; + } + return -1; +} + +static int skipArcData(FILE * file, const char *line) { + int jump = getArcLength(line); + + if (jump != -1) { + if (fseek(file, jump, SEEK_CUR) == 0 /* && skipArcNl(file) == 0 */ ) { + return 0; + } + } + return -1; } static int getDigit(const char digit) { - return (int) ( digit - '0' ); + return (int) (digit - '0'); } -static int getDigit2(const char * const pos) { - return getDigit(pos[0])*10 + getDigit(pos[1]); +static int getDigit2(const char *const pos) { + return getDigit(pos[0]) * 10 + getDigit(pos[1]); } -static int getDigit4(const char * const pos) { - return getDigit(pos[0])*1000 + getDigit(pos[1])*100 + getDigit(pos[2])*10 + getDigit(pos[3]); +static int getDigit4(const char *const pos) { + return getDigit(pos[0]) * 1000 + getDigit(pos[1]) * 100 + + getDigit(pos[2]) * 10 + getDigit(pos[3]); } -static time_t getGMT(struct tm *tm) { /* hey, time_t is local! */ - time_t t = mktime(tm); - if (t != (time_t) -1 && t != (time_t) 0) { +static time_t getGMT(struct tm *tm) { /* hey, time_t is local! */ + time_t t = mktime(tm); + + if (t != (time_t) - 1 && t != (time_t) 0) { /* BSD does not have static "timezone" declared */ #if (defined(BSD) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD_kernel__)) - time_t now = time(NULL); - time_t timezone = - localtime(&now)->tm_gmtoff; + time_t now = time(NULL); + time_t timezone = -localtime(&now)->tm_gmtoff; #endif - return (time_t) (t - timezone); - } - return (time_t) -1; -} - -static time_t getArcTimestamp(const char * const line) { - const char *pos; - if ((pos = getArcField(line, 2)) != NULL) { - int i; - /* date == YYYYMMDDhhmmss (Greenwich Mean Time) */ - /* example: 20050405154029 */ - for(i = 0 ; pos[i] >= '0' && pos[i] <= '9' ; i++); - if (i == 14) { - struct tm tm; - memset(&tm, 0, sizeof(tm)); - tm.tm_year = getDigit4(pos + 0) - 1900; /* current year minus 1900 */ - tm.tm_mon = getDigit2(pos + 4) - 1; /* 0 – 11 */ - tm.tm_mday = getDigit2(pos + 6); /* 1 – 31 */ - tm.tm_hour = getDigit2(pos + 8); /* 0 – 23 */ - tm.tm_min = getDigit2(pos + 10); /* 0 – 59 */ - tm.tm_sec = getDigit2(pos + 12); /* 0 – 59 */ - tm.tm_isdst = 0; - return getGMT(&tm); - } - } - return (time_t) -1; + return (time_t) (t - timezone); + } + return (time_t) - 1; +} + +static time_t getArcTimestamp(const char *const line) { + const char *pos; + + if ((pos = getArcField(line, 2)) != NULL) { + int i; + + /* date == YYYYMMDDhhmmss (Greenwich Mean Time) */ + /* example: 20050405154029 */ + for(i = 0; pos[i] >= '0' && pos[i] <= '9'; i++) ; + if (i == 14) { + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + tm.tm_year = getDigit4(pos + 0) - 1900; /* current year minus 1900 */ + tm.tm_mon = getDigit2(pos + 4) - 1; /* 0 – 11 */ + tm.tm_mday = getDigit2(pos + 6); /* 1 – 31 */ + tm.tm_hour = getDigit2(pos + 8); /* 0 – 23 */ + tm.tm_min = getDigit2(pos + 10); /* 0 – 59 */ + tm.tm_sec = getDigit2(pos + 12); /* 0 – 59 */ + tm.tm_isdst = 0; + return getGMT(&tm); + } + } + return (time_t) - 1; } static int readArcURLRecord(PT_Index__Arc index) { - index->line[0] = '\0'; - if (linput(index->file, index->line, sizeof(index->line) - 1)) { - return 0; - } - return -1; + index->line[0] = '\0'; + if (linput(index->file, index->line, sizeof(index->line) - 1)) { + return 0; + } + return -1; } #define str_begins(str, sstr) ( strncmp(str, sstr, sizeof(sstr) - 1) == 0 ) static int PT_CompatibleScheme(const char *url) { - return (str_begins(url, "http:") - || str_begins(url, "https:") - || str_begins(url, "ftp:") - || str_begins(url, "file:")); + return (str_begins(url, "http:") + || str_begins(url, "https:") + || str_begins(url, "ftp:") + || str_begins(url, "file:")); } int PT_LoadCache__Arc(PT_Index index_, const char *filename) { - if (index_ != NULL && filename != NULL) { - PT_Index__Arc index = &index_->slots.formatArc; - index->timestamp = file_timestamp(filename); - MutexInit(&index->fileLock); - index->file = fopen(filename, "rb"); - - // Opened ? - if (index->file != NULL) { - inthash hashtable = index->hash; - if (readArcURLRecord(index) == 0) { - int entries = 0; - /* Read first line */ - if (strncmp(index->line, "filedesc://", sizeof("filedesc://") - 1) != 0) { - fprintf(stderr, "Unexpected bad signature #%s"LF, index->line); - fclose(index->file); - index->file = NULL; - return 0; - } - /* Timestamp */ - index->timestamp = getArcTimestamp(index->line); - /* Skip first entry */ - if (skipArcData(index->file, index->line) != 0 || skipArcNl(index->file) != 0) { - fprintf(stderr, "Unexpected bad data offset size first entry"LF); - fclose(index->file); - index->file = NULL; - return 0; - } - /* Read all meta-entries (not data) */ - while(!feof(index->file)) { - unsigned long int fpos = ftell(index->file); - if (skipArcNl(index->file) == 0 && readArcURLRecord(index) == 0) { - int length = getArcLength(index->line); - if (length >= 0) { - const char * filenameIndex = copyArcField(index->line, 0, - index->filenameIndexBuff, sizeof(index->filenameIndexBuff) - 1); /* can not be NULL */ - if (strncmp(filenameIndex, "http://", 7) == 0) { - filenameIndex += 7; - } - if (*filenameIndex != 0) { - if (skipArcData(index->file, index->line) != 0) { - fprintf(stderr, "Corrupted cache data entry #%d (truncated file?), aborting read"LF, (int)entries); - } - /*fprintf(stdout, "adding %s [%d]\n", filenameIndex, (int)fpos);*/ - if (PT_CompatibleScheme(index->filenameIndexBuff)) { - inthash_add(hashtable, filenameIndex, fpos); /* position of meta-data */ - entries++; - } - } else { - fprintf(stderr, "Corrupted cache meta entry #%d"LF, (int)entries); - } - } else { - fprintf(stderr, "Corrupted cache meta entry #%d, aborting read"LF, (int)entries); - break ; - } - } else { - break ; - } - } - - /* OK */ - return 1; - } else { - fprintf(stderr, "Bad file (empty ?)"LF); - } - } else { - fprintf(stderr, "Unable to open file"LF); - index = NULL; - } - } else { - fprintf(stderr, "Bad arguments"LF); - } - return 0; + if (index_ != NULL && filename != NULL) { + PT_Index__Arc index = &index_->slots.formatArc; + + index->timestamp = file_timestamp(filename); + MutexInit(&index->fileLock); + index->file = fopen(filename, "rb"); + + // Opened ? + if (index->file != NULL) { + inthash hashtable = index->hash; + + if (readArcURLRecord(index) == 0) { + int entries = 0; + + /* Read first line */ + if (strncmp(index->line, "filedesc://", sizeof("filedesc://") - 1) != 0) { + fprintf(stderr, "Unexpected bad signature #%s" LF, index->line); + fclose(index->file); + index->file = NULL; + return 0; + } + /* Timestamp */ + index->timestamp = getArcTimestamp(index->line); + /* Skip first entry */ + if (skipArcData(index->file, index->line) != 0 + || skipArcNl(index->file) != 0) { + fprintf(stderr, "Unexpected bad data offset size first entry" LF); + fclose(index->file); + index->file = NULL; + return 0; + } + /* Read all meta-entries (not data) */ + while(!feof(index->file)) { + unsigned long int fpos = ftell(index->file); + + if (skipArcNl(index->file) == 0 && readArcURLRecord(index) == 0) { + int length = getArcLength(index->line); + + if (length >= 0) { + const char *filenameIndex = copyArcField(index->line, 0, + index->filenameIndexBuff, sizeof(index->filenameIndexBuff) - 1); /* can not be NULL */ + + if (strncmp(filenameIndex, "http://", 7) == 0) { + filenameIndex += 7; + } + if (*filenameIndex != 0) { + if (skipArcData(index->file, index->line) != 0) { + fprintf(stderr, + "Corrupted cache data entry #%d (truncated file?), aborting read" + LF, (int) entries); + } + /*fprintf(stdout, "adding %s [%d]\n", filenameIndex, (int)fpos); */ + if (PT_CompatibleScheme(index->filenameIndexBuff)) { + inthash_add(hashtable, filenameIndex, fpos); /* position of meta-data */ + entries++; + } + } else { + fprintf(stderr, "Corrupted cache meta entry #%d" LF, + (int) entries); + } + } else { + fprintf(stderr, + "Corrupted cache meta entry #%d, aborting read" LF, + (int) entries); + break; + } + } else { + break; + } + } + + /* OK */ + return 1; + } else { + fprintf(stderr, "Bad file (empty ?)" LF); + } + } else { + fprintf(stderr, "Unable to open file" LF); + index = NULL; + } + } else { + fprintf(stderr, "Bad arguments" LF); + } + return 0; } #define HTTP_READFIELD_STRING(line, value, refline, refvalue) do { \ @@ -1970,278 +2101,287 @@ int PT_LoadCache__Arc(PT_Index index_, const char *filename) { } \ } while(0) -static PT_Element PT_ReadCache__Arc(PT_Index index, const char* url, int flags) { - PT_Element retCode; - MutexLock(&index->slots.formatArc.fileLock); - { - retCode = PT_ReadCache__Arc_u(index, url, flags); - } - MutexUnlock(&index->slots.formatArc.fileLock); - return retCode; +static PT_Element PT_ReadCache__Arc(PT_Index index, const char *url, int flags) { + PT_Element retCode; + + MutexLock(&index->slots.formatArc.fileLock); + { + retCode = PT_ReadCache__Arc_u(index, url, flags); + } + MutexUnlock(&index->slots.formatArc.fileLock); + return retCode; } -static PT_Element PT_ReadCache__Arc_u(PT_Index index_, const char* url, int flags) -{ - PT_Index__Arc index = (PT_Index__Arc) &index_->slots.formatArc; - char location_default[HTS_URLMAXSIZE*2]; +static PT_Element PT_ReadCache__Arc_u(PT_Index index_, const char *url, + int flags) { + PT_Index__Arc index = (PT_Index__Arc) & index_->slots.formatArc; + char location_default[HTS_URLMAXSIZE * 2]; intptr_t hash_pos; int hash_pos_return; - PT_Element r = NULL; - if (index == NULL || index->hash == NULL || url == NULL || *url == 0) - return NULL; - if ((r = PT_ElementNew()) == NULL) - return NULL; - location_default[0] = '\0'; + PT_Element r = NULL; + + if (index == NULL || index->hash == NULL || url == NULL || *url == 0) + return NULL; + if ((r = PT_ElementNew()) == NULL) + return NULL; + location_default[0] = '\0'; memset(r, 0, sizeof(_PT_Element)); r->location = location_default; - strcpy(r->location, ""); - if (strncmp(url, "http://", 7) == 0) - url += 7; + strcpy(r->location, ""); + if (strncmp(url, "http://", 7) == 0) + url += 7; hash_pos_return = inthash_read(index->hash, url, &hash_pos); - if (hash_pos_return) { - if (fseek(index->file, (long)hash_pos, SEEK_SET) == 0) { - if (skipArcNl(index->file) == 0 && readArcURLRecord(index) == 0) { - long int fposMeta = ftell(index->file); - int dataLength = getArcLength(index->line); - const char *pos; - - /* Read HTTP headers */ - /* HTTP/1.1 404 Not Found */ - if (linput(index->file, index->line, sizeof(index->line) - 1)) { - if ((pos = getArcField(index->line, 1)) != NULL) { - if (sscanf(pos, "%d", &r->statuscode) != 1) { - r->statuscode = STATUSCODE_INVALID; - } - } - if ((pos = getArcField(index->line, 2)) != NULL) { - r->msg[0] = '\0'; - strncat(r->msg, pos, sizeof(pos) - 1); - } - while (linput(index->file, index->line, sizeof(index->line) - 1) && index->line[0] != '\0') { - char* const line = index->line; - char* value = strchr(line, ':'); - if (value != NULL) { - *value = '\0'; - for( value++ ; *value == ' ' || *value == '\t' ; value++); - HTTP_READFIELD_INT(line, value, "Content-Length", r->size); // size - HTTP_READFIELD_STRING(line, value, "Content-Type", r->contenttype); // contenttype - HTTP_READFIELD_STRING(line, value, "Last-Modified", r->lastmodified); // last-modified - HTTP_READFIELD_STRING(line, value, "Etag", r->etag); // Etag - HTTP_READFIELD_STRING(line, value, "Location", r->location); // 'location' pour moved - HTTP_READFIELD_STRING(line, value, "Content-Disposition", r->cdispo); // Content-disposition - if (line[0] != '\0') { - int len = r->headers ? ((int) strlen(r->headers)) : 0; - int nlen = (int) ( strlen(line) + 2 + strlen(value) + sizeof("\r\n") + 1 ); - r->headers = realloc(r->headers, len + nlen); - r->headers[len] = '\0'; - strcat(r->headers, line); - strcat(r->headers, ": "); - strcat(r->headers, value); - strcat(r->headers, "\r\n"); - } - } - } - - /* FIXME charset */ - if (r->contenttype[0] != '\0') { - char *pos = strchr(r->contenttype, ';'); - if (pos != NULL) { - /*char *chs = strchr(pos, "charset=");*/ - /*HTTP_READFIELD_STRING(line, value, "X-Charset", r->charset);*/ - *pos = 0; - if ((pos = strchr(r->contenttype, ' ')) != NULL) { - *pos = 0; - } - } - } - - /* Read data */ - if (r->statuscode != STATUSCODE_INVALID) { /* Can continue */ - if (flags & FETCH_BODY) { - long int fposCurrent = ftell(index->file); - long int metaSize = fposCurrent - fposMeta; - long int fetchSize = (long int) r->size; - if (fetchSize <= 0) { - fetchSize = dataLength - metaSize; - } else if (fetchSize > dataLength - metaSize) { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg, "Cache Read Error : Truncated Data"); - } - r->size = 0; - if (r->statuscode != STATUSCODE_INVALID) { - r->adr = (char*) malloc(fetchSize); - if (r->adr != NULL) { - if (fetchSize > 0 && ( r->size = (int) fread(r->adr, 1, fetchSize, index->file) ) != fetchSize) { + if (hash_pos_return) { + if (fseek(index->file, (long) hash_pos, SEEK_SET) == 0) { + if (skipArcNl(index->file) == 0 && readArcURLRecord(index) == 0) { + long int fposMeta = ftell(index->file); + int dataLength = getArcLength(index->line); + const char *pos; + + /* Read HTTP headers */ + /* HTTP/1.1 404 Not Found */ + if (linput(index->file, index->line, sizeof(index->line) - 1)) { + if ((pos = getArcField(index->line, 1)) != NULL) { + if (sscanf(pos, "%d", &r->statuscode) != 1) { + r->statuscode = STATUSCODE_INVALID; + } + } + if ((pos = getArcField(index->line, 2)) != NULL) { + r->msg[0] = '\0'; + strncat(r->msg, pos, sizeof(pos) - 1); + } + while(linput(index->file, index->line, sizeof(index->line) - 1) + && index->line[0] != '\0') { + char *const line = index->line; + char *value = strchr(line, ':'); + + if (value != NULL) { + *value = '\0'; + for(value++; *value == ' ' || *value == '\t'; value++) ; + HTTP_READFIELD_INT(line, value, "Content-Length", r->size); // size + HTTP_READFIELD_STRING(line, value, "Content-Type", r->contenttype); // contenttype + HTTP_READFIELD_STRING(line, value, "Last-Modified", r->lastmodified); // last-modified + HTTP_READFIELD_STRING(line, value, "Etag", r->etag); // Etag + HTTP_READFIELD_STRING(line, value, "Location", r->location); // 'location' pour moved + HTTP_READFIELD_STRING(line, value, "Content-Disposition", r->cdispo); // Content-disposition + if (line[0] != '\0') { + int len = r->headers ? ((int) strlen(r->headers)) : 0; + int nlen = + (int) (strlen(line) + 2 + strlen(value) + sizeof("\r\n") + 1); + r->headers = realloc(r->headers, len + nlen); + r->headers[len] = '\0'; + strcat(r->headers, line); + strcat(r->headers, ": "); + strcat(r->headers, value); + strcat(r->headers, "\r\n"); + } + } + } + + /* FIXME charset */ + if (r->contenttype[0] != '\0') { + char *pos = strchr(r->contenttype, ';'); + + if (pos != NULL) { + /*char *chs = strchr(pos, "charset="); */ + /*HTTP_READFIELD_STRING(line, value, "X-Charset", r->charset); */ + *pos = 0; + if ((pos = strchr(r->contenttype, ' ')) != NULL) { + *pos = 0; + } + } + } + + /* Read data */ + if (r->statuscode != STATUSCODE_INVALID) { /* Can continue */ + if (flags & FETCH_BODY) { + long int fposCurrent = ftell(index->file); + long int metaSize = fposCurrent - fposMeta; + long int fetchSize = (long int) r->size; + + if (fetchSize <= 0) { + fetchSize = dataLength - metaSize; + } else if (fetchSize > dataLength - metaSize) { + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Cache Read Error : Truncated Data"); + } + r->size = 0; + if (r->statuscode != STATUSCODE_INVALID) { + r->adr = (char *) malloc(fetchSize); + if (r->adr != NULL) { + if (fetchSize > 0 + && (r->size = + (int) fread(r->adr, 1, fetchSize, + index->file)) != fetchSize) { int last_errno = errno; - r->statuscode=STATUSCODE_INVALID; - sprintf(r->msg,"Read error in cache disk data: %s", strerror(last_errno)); - } - } else { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"Read error (memory exhausted) from cache"); - } - } - } - } - - } else { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg, "Cache Read Error : Read Header Error"); - } - - } else { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg, "Cache Read Error : Read Header Error"); - } - } else { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg, "Cache Read Error : Seek Error"); - } - - } else { - r->statuscode=STATUSCODE_INVALID; - strcpy(r->msg,"File Cache Entry Not Found"); - } - if (r->location[0] != '\0') { - r->location = strdup(r->location); - } else { - r->location = NULL; - } + + r->statuscode = STATUSCODE_INVALID; + sprintf(r->msg, "Read error in cache disk data: %s", + strerror(last_errno)); + } + } else { + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Read error (memory exhausted) from cache"); + } + } + } + } + + } else { + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Cache Read Error : Read Header Error"); + } + + } else { + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Cache Read Error : Read Header Error"); + } + } else { + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "Cache Read Error : Seek Error"); + } + + } else { + r->statuscode = STATUSCODE_INVALID; + strcpy(r->msg, "File Cache Entry Not Found"); + } + if (r->location[0] != '\0') { + r->location = strdup(r->location); + } else { + r->location = NULL; + } return r; } -static int PT_LookupCache__Arc(PT_Index index, const char* url) { - int retCode; - MutexLock(&index->slots.formatArc.fileLock); - { - retCode = PT_LookupCache__Arc_u(index, url); - } - MutexUnlock(&index->slots.formatArc.fileLock); - return retCode; +static int PT_LookupCache__Arc(PT_Index index, const char *url) { + int retCode; + + MutexLock(&index->slots.formatArc.fileLock); + { + retCode = PT_LookupCache__Arc_u(index, url); + } + MutexUnlock(&index->slots.formatArc.fileLock); + return retCode; } -static int PT_LookupCache__Arc_u(PT_Index index_, const char* url) { - if (index_ != NULL) { - PT_Index__New cache = (PT_Index__New) &index_->slots.formatNew; - if (cache == NULL || cache->hash == NULL || url == NULL || *url == 0) - return 0; - if (strncmp(url, "http://", 7) == 0) - url += 7; - if (inthash_read(cache->hash, url, NULL)) - return 1; - } - return 0; +static int PT_LookupCache__Arc_u(PT_Index index_, const char *url) { + if (index_ != NULL) { + PT_Index__New cache = (PT_Index__New) & index_->slots.formatNew; + + if (cache == NULL || cache->hash == NULL || url == NULL || *url == 0) + return 0; + if (strncmp(url, "http://", 7) == 0) + url += 7; + if (inthash_read(cache->hash, url, NULL)) + return 1; + } + return 0; } typedef struct PT_SaveCache__Arc_t { - PT_Indexes indexes; - FILE *fp; - time_t t; - char filename[64]; - struct tm buff; - char headers[8192]; + PT_Indexes indexes; + FILE *fp; + time_t t; + char filename[64]; + struct tm buff; + char headers[8192]; char md5[32 + 2]; } PT_SaveCache__Arc_t; static int PT_SaveCache__Arc_Fun(void *arg, const char *url, PT_Element element) { - PT_SaveCache__Arc_t *st = (PT_SaveCache__Arc_t*) arg; - FILE * const fp = st->fp; - struct tm* tm = convert_time_rfc822(&st->buff, element->lastmodified); - int size_headers; - - sprintf(st->headers, - "HTTP/1.0 %d %s" "\r\n" - "X-Server: ProxyTrack " PROXYTRACK_VERSION "\r\n" - "Content-type: %s%s%s%s" "\r\n" - "Last-modified: %s" "\r\n" - "Content-length: %d" "\r\n" - , - element->statuscode, element->msg, - /**/ - element->contenttype, - (element->charset[0] ? "; charset=\"" : ""), - (element->charset[0] ? element->charset : ""), - (element->charset[0] ? "\"" : ""), - /**/ - element->lastmodified, - (int) element->size - ); - if (element->location != NULL && element->location[0] != '\0') { - sprintf(st->headers + strlen(st->headers), "Location: %s" "\r\n", element->location); - } - if (element->headers != NULL) { - if ( strlen(element->headers) < sizeof(st->headers) - strlen(element->headers) - 1 ) { - strcat(st->headers, element->headers); - } - } - strcat(st->headers, "\r\n"); - size_headers = (int) strlen(st->headers); - - /* doc == <nl><URL-record><nl><network_doc> */ + PT_SaveCache__Arc_t *st = (PT_SaveCache__Arc_t *) arg; + FILE *const fp = st->fp; + struct tm *tm = convert_time_rfc822(&st->buff, element->lastmodified); + int size_headers; + + sprintf(st->headers, + "HTTP/1.0 %d %s" "\r\n" "X-Server: ProxyTrack " PROXYTRACK_VERSION + "\r\n" "Content-type: %s%s%s%s" "\r\n" "Last-modified: %s" "\r\n" + "Content-length: %d" "\r\n", element->statuscode, element->msg, + /**/ element->contenttype, + (element->charset[0] ? "; charset=\"" : ""), + (element->charset[0] ? element->charset : ""), + (element->charset[0] ? "\"" : ""), /**/ element->lastmodified, + (int) element->size); + if (element->location != NULL && element->location[0] != '\0') { + sprintf(st->headers + strlen(st->headers), "Location: %s" "\r\n", + element->location); + } + if (element->headers != NULL) { + if (strlen(element->headers) < + sizeof(st->headers) - strlen(element->headers) - 1) { + strcat(st->headers, element->headers); + } + } + strcat(st->headers, "\r\n"); + size_headers = (int) strlen(st->headers); + + /* doc == <nl><URL-record><nl><network_doc> */ /* Format: URL IP date mime result checksum location offset filename length */ - if (element->adr != NULL) { - domd5mem(element->adr, element->size, st->md5, 1); - } else { - strcpy(st->md5, "-"); - } - fprintf(fp, - /* nl */ - "\n" - /* URL-record */ - "%s%s %s %04d%02d%02d%02d%02d%02d %s %d %s %s %ld %s %ld" - /* nl */ - "\n", - /* args */ - ( link_has_authority(url) ? "" : "http://" ), url, - "0.0.0.0", - tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, - element->contenttype, - element->statuscode, - st->md5, ( element->location ? element->location : "-" ), - (long int)ftell(fp), st->filename, - (long int)( size_headers + element->size )); - /* network_doc */ - if (fwrite(st->headers, 1, size_headers, fp) != size_headers - || ( element->size > 0 && fwrite(element->adr, 1, element->size, fp) != element->size ) - ) { - return 1; /* Error */ - } - - return 0; + if (element->adr != NULL) { + domd5mem(element->adr, element->size, st->md5, 1); + } else { + strcpy(st->md5, "-"); + } + fprintf(fp, + /* nl */ + "\n" + /* URL-record */ + "%s%s %s %04d%02d%02d%02d%02d%02d %s %d %s %s %ld %s %ld" + /* nl */ + "\n", + /* args */ + (link_has_authority(url) ? "" : "http://"), url, "0.0.0.0", + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, + tm->tm_min, tm->tm_sec, element->contenttype, element->statuscode, + st->md5, (element->location ? element->location : "-"), + (long int) ftell(fp), st->filename, + (long int) (size_headers + element->size)); + /* network_doc */ + if (fwrite(st->headers, 1, size_headers, fp) != size_headers + || (element->size > 0 + && fwrite(element->adr, 1, element->size, fp) != element->size) + ) { + return 1; /* Error */ + } + + return 0; } static int PT_SaveCache__Arc(PT_Indexes indexes, const char *filename) { - FILE *fp = fopen(filename, "wb"); - if (fp != NULL) { - PT_SaveCache__Arc_t st; - int ret; - time_t t = PT_GetTimeIndex(indexes); - struct tm tm = PT_GetTime(t); - - /* version-2-block == - filedesc://<path><sp><ip_address><sp><date><sp>text/plain<sp>200<sp>-<sp>-<sp>0<sp><filename><sp><length><nl> - 2<sp><reserved><sp><origin-code><nl> - URL<sp>IP-address<sp>Archive-date<sp>Content-type<sp>Result-code<sp>Checksum<sp>Location<sp> Offset<sp>Filename<sp>Archive-length<nl> - <nl> */ - const char* prefix = - "2 0 HTTrack Website Copier" "\n" - "URL IP-address Archive-Date Content-Type Result-code Checksum Location Offset Filename Archive-length" "\n" "\n"; - sprintf(st.filename, "httrack_%d.arc", (int) t); - fprintf(fp, "filedesc://%s 0.0.0.0 %04d%02d%02d%02d%02d%02d text/plain 200 - - 0 %s %d" "\n" - "%s", - st.filename, - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, - st.filename, (int)strlen(prefix), prefix); - st.fp = fp; - st.indexes = indexes; - st.t = t; - ret = PT_EnumCache(indexes, PT_SaveCache__Arc_Fun, (void *)&st); - fclose(fp); - if (ret != 0) - (void) unlink(filename); - return ret; - } - return -1; + FILE *fp = fopen(filename, "wb"); + + if (fp != NULL) { + PT_SaveCache__Arc_t st; + int ret; + time_t t = PT_GetTimeIndex(indexes); + struct tm tm = PT_GetTime(t); + + /* version-2-block == + filedesc://<path><sp><ip_address><sp><date><sp>text/plain<sp>200<sp>-<sp>-<sp>0<sp><filename><sp><length><nl> + 2<sp><reserved><sp><origin-code><nl> + URL<sp>IP-address<sp>Archive-date<sp>Content-type<sp>Result-code<sp>Checksum<sp>Location<sp> Offset<sp>Filename<sp>Archive-length<nl> + <nl> */ + const char *prefix = + "2 0 HTTrack Website Copier" "\n" + "URL IP-address Archive-Date Content-Type Result-code Checksum Location Offset Filename Archive-length" + "\n" "\n"; + sprintf(st.filename, "httrack_%d.arc", (int) t); + fprintf(fp, + "filedesc://%s 0.0.0.0 %04d%02d%02d%02d%02d%02d text/plain 200 - - 0 %s %d" + "\n" "%s", st.filename, tm.tm_year + 1900, tm.tm_mon + 1, + tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, st.filename, + (int) strlen(prefix), prefix); + st.fp = fp; + st.indexes = indexes; + st.t = t; + ret = PT_EnumCache(indexes, PT_SaveCache__Arc_Fun, (void *) &st); + fclose(fp); + if (ret != 0) + (void) unlink(filename); + return ret; + } + return -1; } diff --git a/src/proxy/store.h b/src/proxy/store.h index b8fd4db..97d0e0c 100644 --- a/src/proxy/store.h +++ b/src/proxy/store.h @@ -50,66 +50,68 @@ typedef struct _PT_CacheItem _PT_CacheItem; typedef struct _PT_CacheItem *PT_CacheItem; typedef struct _PT_Element { - int indexId; // index identifier, if suitable (!= -1) - // - int statuscode; // status-code, -1=erreur, 200=OK,201=..etc (cf RFC1945) - char* adr; // adresse du bloc de mémoire, NULL=vide - char* headers; // adresse des en têtes si présents (RFC822 format) - size_t size; // taille fichier - char msg[1024]; // error message ("\0"=undefined) - char contenttype[64]; // content-type ("text/html" par exemple) - char charset[64]; // charset ("iso-8859-1" par exemple) - char* location; // on copie dedans éventuellement la véritable 'location' - char lastmodified[64]; // Last-Modified - char etag[64]; // Etag - char cdispo[256]; // Content-Disposition coupé + int indexId; // index identifier, if suitable (!= -1) + // + int statuscode; // status-code, -1=erreur, 200=OK,201=..etc (cf RFC1945) + char *adr; // adresse du bloc de mémoire, NULL=vide + char *headers; // adresse des en têtes si présents (RFC822 format) + size_t size; // taille fichier + char msg[1024]; // error message ("\0"=undefined) + char contenttype[64]; // content-type ("text/html" par exemple) + char charset[64]; // charset ("iso-8859-1" par exemple) + char *location; // on copie dedans éventuellement la véritable 'location' + char lastmodified[64]; // Last-Modified + char etag[64]; // Etag + char cdispo[256]; // Content-Disposition coupé } _PT_Element; typedef struct _PT_Element *PT_Element; typedef enum PT_Fetch_Flags { - FETCH_HEADERS, // fetch headers - FETCH_BODY // fetch body + FETCH_HEADERS, // fetch headers + FETCH_BODY // fetch body } PT_Fetch_Flags; /* Locking */ #ifdef _WIN32 -typedef void* PT_Mutex; +typedef void *PT_Mutex; #else typedef pthread_mutex_t PT_Mutex; #endif -void MutexInit(PT_Mutex *pMutex); -void MutexLock(PT_Mutex *pMutex); -void MutexUnlock(PT_Mutex *pMutex); -void MutexFree(PT_Mutex *pMutex); +void MutexInit(PT_Mutex * pMutex); +void MutexLock(PT_Mutex * pMutex); +void MutexUnlock(PT_Mutex * pMutex); +void MutexFree(PT_Mutex * pMutex); /* Indexes */ PT_Indexes PT_New(void); void PT_Delete(PT_Indexes index); -PT_Element PT_ReadIndex(PT_Indexes indexes, const char* url, int flags); -int PT_LookupIndex(PT_Indexes indexes, const char* url); +PT_Element PT_ReadIndex(PT_Indexes indexes, const char *url, int flags); +int PT_LookupIndex(PT_Indexes indexes, const char *url); int PT_AddIndex(PT_Indexes index, const char *path); int PT_RemoveIndex(PT_Indexes index, int indexId); -int PT_IndexMerge(PT_Indexes indexes, PT_Index *pindex); +int PT_IndexMerge(PT_Indexes indexes, PT_Index * pindex); PT_Index PT_GetIndex(PT_Indexes indexes, int indexId); time_t PT_GetTimeIndex(PT_Indexes indexes); /* Indexes list */ PT_Element PT_Index_HTML_BuildRootInfo(PT_Indexes indexes); -char ** PT_Enumerate(PT_Indexes indexes, const char *url, int subtree); +char **PT_Enumerate(PT_Indexes indexes, const char *url, int subtree); void PT_Enumerate_Delete(char ***plist); -int PT_EnumCache(PT_Indexes indexes, int (*callback)(void *, const char *url, PT_Element), void *arg); +int PT_EnumCache(PT_Indexes indexes, + int (*callback) (void *, const char *url, PT_Element), + void *arg); int PT_SaveCache(PT_Indexes indexes, const char *filename); /* Index */ PT_Index PT_LoadCache(const char *filename); -void PT_Index_Delete(PT_Index *pindex); -PT_Element PT_ReadCache(PT_Index index, const char* url, int flags); -int PT_LookupCache(PT_Index index, const char* url); +void PT_Index_Delete(PT_Index * pindex); +PT_Element PT_ReadCache(PT_Index index, const char *url, int flags); +int PT_LookupCache(PT_Index index, const char *url); time_t PT_Index_Timestamp(PT_Index index); /* Elements*/ PT_Element PT_ElementNew(void); -void PT_Element_Delete(PT_Element *pentry); +void PT_Element_Delete(PT_Element * pentry); #endif |