--------------------- PatchSet 2126 Date: 2001/04/27 17:06:45 Author: serassio Branch: cygwin Tag: (none) Log: Added Windows NT Service Support - First round Members: src/debug.c:1.3.26.3->1.3.26.4 src/defines.h:1.3.22.6->1.3.22.7 src/dns_internal.c:1.5.26.6->1.5.26.7 src/globals.h:1.5.12.4->1.5.12.5 src/main.c:1.12.2.6->1.12.2.7 src/protos.h:1.9.2.4->1.9.2.5 src/tools.c:1.7.2.5->1.7.2.6 src/win32.c:1.1.50.1->1.1.50.2 Index: squid/src/debug.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/debug.c,v retrieving revision 1.3.26.3 retrieving revision 1.3.26.4 diff -u -r1.3.26.3 -r1.3.26.4 --- squid/src/debug.c 25 Apr 2001 11:38:30 -0000 1.3.26.3 +++ squid/src/debug.c 27 Apr 2001 17:06:45 -0000 1.3.26.4 @@ -1,416 +1,414 @@ - -/* - * $Id: debug.c,v 1.3.26.3 2001/04/25 11:38:30 serassio Exp $ - * - * DEBUG: section 0 Debug Routines - * AUTHOR: Harvest Derived - * - * SQUID Web Proxy Cache http://www.squid-cache.org/ - * ---------------------------------------------------------- - * - * Squid is the result of efforts by numerous individuals from - * the Internet community; see the CONTRIBUTORS file for full - * details. Many organizations have provided support for Squid's - * development; see the SPONSORS file for full details. Squid is - * Copyrighted (C) 2001 by the Regents of the University of - * California; see the COPYRIGHT file for full details. Squid - * incorporates software developed and/or copyrighted by other - * sources; see the CREDITS file for full details. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. - * - */ - -#include "squid.h" - -static char *debug_log_file = NULL; -static int Ctx_Lock = 0; -static const char *debugLogTime(time_t); -static void ctx_print(void); - -#if STDC_HEADERS -void -_db_print(const char *format,...) -{ -#if defined(__QNX__) - va_list eargs; -#endif - va_list args; -#else -void -_db_print(va_alist) - va_dcl -{ - va_list args; - const char *format = NULL; -#endif - LOCAL_ARRAY(char, f, BUFSIZ); -#if HAVE_SYSLOG - LOCAL_ARRAY(char, tmpbuf, BUFSIZ); -#endif - -#if STDC_HEADERS - va_start(args, format); -#if defined(__QNX__) - va_start(eargs, format); -#endif -#else - va_start(args); - format = va_arg(args, const char *); -#endif - - if (debug_log == NULL) - return; - /* give a chance to context-based debugging to print current context */ - if (!Ctx_Lock) - ctx_print(); - snprintf(f, BUFSIZ, "%s| %s", - debugLogTime(squid_curtime), - format); -#if HAVE_SYSLOG - /* level 0,1 go to syslog */ - if (_db_level <= 1 && opt_syslog_enable) { - tmpbuf[0] = '\0'; - vsnprintf(tmpbuf, BUFSIZ, format, args); - tmpbuf[BUFSIZ - 1] = '\0'; - syslog(_db_level == 0 ? LOG_WARNING : LOG_NOTICE, "%s", tmpbuf); - } -#endif /* HAVE_SYSLOG */ - /* write to log file */ -#if defined(__QNX__) - vfprintf(debug_log, f, eargs); -#else - vfprintf(debug_log, f, args); -#endif - if (!Config.onoff.buffered_logs) - fflush(debug_log); - if (opt_debug_stderr >= _db_level && debug_log != stderr) { -#if defined(__QNX__) - vfprintf(stderr, f, eargs); -#else - vfprintf(stderr, f, args); -#endif - } -#if defined(__QNX__) - va_end(eargs); -#endif - va_end(args); -} - -static void -debugArg(const char *arg) -{ - int s = 0; - int l = 0; - int i; - if (!strncasecmp(arg, "ALL", 3)) { - s = -1; - arg += 4; - } else { - s = atoi(arg); - while (*arg && *arg++ != ','); - } - l = atoi(arg); - assert(s >= -1); - assert(s < MAX_DEBUG_SECTIONS); - if (l < 0) - l = 0; - if (l > 10) - l = 10; - if (s >= 0) { - debugLevels[s] = l; - return; - } - for (i = 0; i < MAX_DEBUG_SECTIONS; i++) - debugLevels[i] = l; -} - -static void -debugOpenLog(const char *logfile) -{ - if (logfile == NULL) { - debug_log = stderr; - return; - } - if (debug_log_file) - xfree(debug_log_file); - debug_log_file = xstrdup(logfile); /* keep a static copy */ - if (debug_log && debug_log != stderr) - fclose(debug_log); - debug_log = fopen(logfile, "a+"); - if (!debug_log) { - fprintf(stderr, "WARNING: Cannot write log file: %s\n", logfile); - perror(logfile); - fprintf(stderr, " messages will be sent to 'stderr'.\n"); - fflush(stderr); - debug_log = stderr; - } -#if defined(_SQUID_CYGWIN_) - setmode(fileno(debug_log), O_TEXT); -#endif -} - -void -_db_init(const char *logfile, const char *options) -{ - int i; - char *p = NULL; - char *s = NULL; - - for (i = 0; i < MAX_DEBUG_SECTIONS; i++) - debugLevels[i] = -1; - - if (options) { - p = xstrdup(options); - for (s = strtok(p, w_space); s; s = strtok(NULL, w_space)) - debugArg(s); - xfree(p); - } - debugOpenLog(logfile); - -#if HAVE_SYSLOG && defined(LOG_LOCAL4) - if (opt_syslog_enable) - openlog(appname, LOG_PID | LOG_NDELAY | LOG_CONS, LOG_LOCAL4); -#endif /* HAVE_SYSLOG */ - -} - -void -_db_rotate_log(void) -{ - int i; - LOCAL_ARRAY(char, from, MAXPATHLEN); - LOCAL_ARRAY(char, to, MAXPATHLEN); -#ifdef S_ISREG - struct stat sb; -#endif - - if (debug_log_file == NULL) - return; -#ifdef S_ISREG - if (stat(debug_log_file, &sb) == 0) - if (S_ISREG(sb.st_mode) == 0) - return; -#endif - - /* - * NOTE: we cannot use xrename here without having it in a - * separate file -- tools.c has too many dependencies to be - * used everywhere debug.c is used. - */ - /* Rotate numbers 0 through N up one */ - for (i = Config.Log.rotateNumber; i > 1;) { - i--; - snprintf(from, MAXPATHLEN, "%s.%d", debug_log_file, i - 1); - snprintf(to, MAXPATHLEN, "%s.%d", debug_log_file, i); - rename(from, to); - } - /* - * You can't rename open files on Microsoft "operating systems" - * so we close before renaming. - */ -#ifdef _SQUID_MSWIN_ - if (debug_log != stderr) - fclose(debug_log); -#endif - /* Rotate the current log to .0 */ - if (Config.Log.rotateNumber > 0) { - snprintf(to, MAXPATHLEN, "%s.%d", debug_log_file, 0); - xrename(debug_log_file, to); - } - /* Close and reopen the log. It may have been renamed "manually" - * before HUP'ing us. */ - if (debug_log != stderr) - debugOpenLog(Config.Log.log); -} - -static const char * -debugLogTime(time_t t) -{ - struct tm *tm; - static char buf[128]; - static time_t last_t = 0; - if (t != last_t) { - tm = localtime(&t); - strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm); - last_t = t; - } - return buf; -} - -void -xassert(const char *msg, const char *file, int line) -{ - debug(0, 0) ("assertion failed: %s:%d: \"%s\"\n", file, line, msg); - if (!shutting_down) - abort(); -} - -/* - * Context-based Debugging - * - * Rationale - * --------- - * - * When you have a long nested processing sequence, it is often impossible - * for low level routines to know in what larger context they operate. If a - * routine coredumps, one can restore the context using debugger trace. - * However, in many case you do not want to coredump, but just want to report - * a potential problem. A report maybe useless out of problem context. - * - * To solve this potential problem, use the following approach: - * - * int - * top_level_foo(const char *url) - * { - * // define current context - * // note: we stack but do not dup ctx descriptions! - * Ctx ctx = ctx_enter(url); - * ... - * // go down; middle_level_bar will eventually call bottom_level_boo - * middle_level_bar(method, protocol); - * ... - * // exit, clean after yourself - * ctx_exit(ctx); - * } - * - * void - * bottom_level_boo(int status, void *data) - * { - * // detect exceptional condition, and simply report it, the context - * // information will be available somewhere close in the log file - * if (status == STRANGE_STATUS) - * debug(13, 6) ("DOS attack detected, data: %p\n", data); - * ... - * } - * - * Current implementation is extremely simple but still very handy. It has a - * negligible overhead (descriptions are not duplicated). - * - * When the _first_ debug message for a given context is printed, it is - * prepended with the current context description. Context is printed with - * the same debugging level as the original message. - * - * Note that we do not print context every type you do ctx_enter(). This - * approach would produce too many useless messages. For the same reason, a - * context description is printed at most _once_ even if you have 10 - * debugging messages within one context. - * - * Contexts can be nested, of course. You must use ctx_enter() to enter a - * context (push it onto stack). It is probably safe to exit several nested - * contexts at _once_ by calling ctx_exit() at the top level (this will pop - * all context till current one). However, as in any stack, you cannot start - * in the middle. - * - * Analysis: - * i) locate debugging message, - * ii) locate current context by going _upstream_ in your log file, - * iii) hack away. - * - * - * To-Do: - * ----- - * - * decide if we want to dup() descriptions (adds overhead) but allows to - * add printf()-style interface - * - * implementation: - * --------------- - * - * descriptions for contexts over CTX_MAX_LEVEL limit are ignored, you probably - * have a bug if your nesting goes that deep. - */ - -#define CTX_MAX_LEVEL 255 - -/* - * produce a warning when nesting reaches this level and then double - * the level - */ -static int Ctx_Warn_Level = 32; -/* all descriptions has been printed up to this level */ -static int Ctx_Reported_Level = -1; -/* descriptions are still valid or active up to this level */ -static int Ctx_Valid_Level = -1; -/* current level, the number of nested ctx_enter() calls */ -static int Ctx_Current_Level = -1; -/* saved descriptions (stack) */ -static const char *Ctx_Descrs[CTX_MAX_LEVEL + 1]; -/* "safe" get secription */ -static const char *ctx_get_descr(Ctx ctx); - - -Ctx -ctx_enter(const char *descr) -{ - Ctx_Current_Level++; - - if (Ctx_Current_Level <= CTX_MAX_LEVEL) - Ctx_Descrs[Ctx_Current_Level] = descr; - - if (Ctx_Current_Level == Ctx_Warn_Level) { - debug(0, 0) ("# ctx: suspiciously deep (%d) nesting:\n", Ctx_Warn_Level); - Ctx_Warn_Level *= 2; - } - return Ctx_Current_Level; -} - -void -ctx_exit(Ctx ctx) -{ - assert(ctx >= 0); - Ctx_Current_Level = (ctx >= 0) ? ctx - 1 : -1; - if (Ctx_Valid_Level > Ctx_Current_Level) - Ctx_Valid_Level = Ctx_Current_Level; -} - -/* - * the idea id to print each context description at most once but provide enough - * info for deducing the current execution stack - */ -static void -ctx_print(void) -{ - /* lock so _db_print will not call us recursively */ - Ctx_Lock++; - /* ok, user saw [0,Ctx_Reported_Level] descriptions */ - /* first inform about entries popped since user saw them */ - if (Ctx_Valid_Level < Ctx_Reported_Level) { - if (Ctx_Reported_Level != Ctx_Valid_Level + 1) - _db_print("ctx: exit levels from %2d down to %2d\n", - Ctx_Reported_Level, Ctx_Valid_Level + 1); - else - _db_print("ctx: exit level %2d\n", Ctx_Reported_Level); - Ctx_Reported_Level = Ctx_Valid_Level; - } - /* report new contexts that were pushed since last report */ - while (Ctx_Reported_Level < Ctx_Current_Level) { - Ctx_Reported_Level++; - Ctx_Valid_Level++; - _db_print("ctx: enter level %2d: '%s'\n", Ctx_Reported_Level, - ctx_get_descr(Ctx_Reported_Level)); - } - /* unlock */ - Ctx_Lock--; -} - -/* checks for nulls and overflows */ -static const char * -ctx_get_descr(Ctx ctx) -{ - if (ctx < 0 || ctx > CTX_MAX_LEVEL) - return ""; - return Ctx_Descrs[ctx] ? Ctx_Descrs[ctx] : ""; -} + +/* + * $Id: debug.c,v 1.3.26.4 2001/04/27 17:06:45 serassio Exp $ + * + * DEBUG: section 0 Debug Routines + * AUTHOR: Harvest Derived + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include "squid.h" + +static char *debug_log_file = NULL; +static int Ctx_Lock = 0; +static const char *debugLogTime(time_t); +static void ctx_print(void); + +#if STDC_HEADERS +void +_db_print(const char *format, ...) +{ +#if defined(__QNX__) + va_list eargs; +#endif + va_list args; +#else +void +_db_print(va_alist) + va_dcl +{ + va_list args; + const char *format = NULL; +#endif + LOCAL_ARRAY(char, f, BUFSIZ); +#if HAVE_SYSLOG + LOCAL_ARRAY(char, tmpbuf, BUFSIZ); +#endif + +#if STDC_HEADERS + va_start(args, format); +#if defined(__QNX__) + va_start(eargs, format); +#endif +#else + va_start(args); + format = va_arg(args, const char *); +#endif + + if (debug_log == NULL) + return; + /* give a chance to context-based debugging to print current context */ + if (!Ctx_Lock) + ctx_print(); + snprintf(f, BUFSIZ, "%s| %s", debugLogTime(squid_curtime), format); +#if HAVE_SYSLOG + /* level 0,1 go to syslog */ + if (_db_level <= 1 && opt_syslog_enable) { + tmpbuf[0] = '\0'; + vsnprintf(tmpbuf, BUFSIZ, format, args); + tmpbuf[BUFSIZ - 1] = '\0'; + syslog(_db_level == 0 ? LOG_WARNING : LOG_NOTICE, "%s", tmpbuf); + } +#endif /* HAVE_SYSLOG */ + /* write to log file */ +#if defined(__QNX__) + vfprintf(debug_log, f, eargs); +#else + vfprintf(debug_log, f, args); +#endif + if (!Config.onoff.buffered_logs) + fflush(debug_log); + if (opt_debug_stderr >= _db_level && debug_log != stderr) { +#if defined(__QNX__) + vfprintf(stderr, f, eargs); +#else + vfprintf(stderr, f, args); +#endif + } +#if defined(__QNX__) + va_end(eargs); +#endif + va_end(args); +} + +static void +debugArg(const char *arg) +{ + int s = 0; + int l = 0; + int i; + if (!strncasecmp(arg, "ALL", 3)) { + s = -1; + arg += 4; + } else { + s = atoi(arg); + while (*arg && *arg++ != ','); + } + l = atoi(arg); + assert(s >= -1); + assert(s < MAX_DEBUG_SECTIONS); + if (l < 0) + l = 0; + if (l > 10) + l = 10; + if (s >= 0) { + debugLevels[s] = l; + return; + } + for (i = 0; i < MAX_DEBUG_SECTIONS; i++) + debugLevels[i] = l; +} + +static void +debugOpenLog(const char *logfile) +{ + if (logfile == NULL) { + debug_log = stderr; + return; + } + if (debug_log_file) + xfree(debug_log_file); + debug_log_file = xstrdup(logfile); /* keep a static copy */ + if (debug_log && debug_log != stderr) + fclose(debug_log); + debug_log = fopen(logfile, "a+"); + if (!debug_log) { + fprintf(stderr, "WARNING: Cannot write log file: %s\n", logfile); + perror(logfile); + fprintf(stderr, " messages will be sent to 'stderr'.\n"); + fflush(stderr); + debug_log = stderr; + } +#if defined(_SQUID_CYGWIN_) + setmode(fileno(debug_log), O_TEXT); +#endif +} + +void +_db_init(const char *logfile, const char *options) +{ + int i; + char *p = NULL; + char *s = NULL; + + for (i = 0; i < MAX_DEBUG_SECTIONS; i++) + debugLevels[i] = -1; + + if (options) { + p = xstrdup(options); + for (s = strtok(p, w_space); s; s = strtok(NULL, w_space)) + debugArg(s); + xfree(p); + } + debugOpenLog(logfile); + +#if HAVE_SYSLOG && defined(LOG_LOCAL4) + if (opt_syslog_enable) + openlog(appname, LOG_PID | LOG_NDELAY | LOG_CONS, LOG_LOCAL4); +#endif /* HAVE_SYSLOG */ + +} + +void +_db_rotate_log(void) +{ + int i; + LOCAL_ARRAY(char, from, MAXPATHLEN); + LOCAL_ARRAY(char, to, MAXPATHLEN); +#ifdef S_ISREG + struct stat sb; +#endif + + if (debug_log_file == NULL) + return; +#ifdef S_ISREG + if (stat(debug_log_file, &sb) == 0) + if (S_ISREG(sb.st_mode) == 0) + return; +#endif + + /* + * NOTE: we cannot use xrename here without having it in a + * separate file -- tools.c has too many dependencies to be + * used everywhere debug.c is used. + */ + /* Rotate numbers 0 through N up one */ + for (i = Config.Log.rotateNumber; i > 1;) { + i--; + snprintf(from, MAXPATHLEN, "%s.%d", debug_log_file, i - 1); + snprintf(to, MAXPATHLEN, "%s.%d", debug_log_file, i); + rename(from, to); + } + /* + * You can't rename open files on Microsoft "operating systems" + * so we close before renaming. + */ +#ifdef _SQUID_MSWIN_ + if (debug_log != stderr) + fclose(debug_log); +#endif + /* Rotate the current log to .0 */ + if (Config.Log.rotateNumber > 0) { + snprintf(to, MAXPATHLEN, "%s.%d", debug_log_file, 0); + xrename(debug_log_file, to); + } + /* Close and reopen the log. It may have been renamed "manually" + * before HUP'ing us. */ + if (debug_log != stderr) + debugOpenLog(Config.Log.log); +} + +static const char * +debugLogTime(time_t t) +{ + struct tm *tm; + static char buf[128]; + static time_t last_t = 0; + if (t != last_t) { + tm = localtime(&t); + strftime(buf, 127, "%Y/%m/%d %H:%M:%S", tm); + last_t = t; + } + return buf; +} + +void +xassert(const char *msg, const char *file, int line) +{ + debug(0, 0) ("assertion failed: %s:%d: \"%s\"\n", file, line, msg); + if (!shutting_down) + abort(); +} + +/* + * Context-based Debugging + * + * Rationale + * --------- + * + * When you have a long nested processing sequence, it is often impossible + * for low level routines to know in what larger context they operate. If a + * routine coredumps, one can restore the context using debugger trace. + * However, in many case you do not want to coredump, but just want to report + * a potential problem. A report maybe useless out of problem context. + * + * To solve this potential problem, use the following approach: + * + * int + * top_level_foo(const char *url) + * { + * // define current context + * // note: we stack but do not dup ctx descriptions! + * Ctx ctx = ctx_enter(url); + * ... + * // go down; middle_level_bar will eventually call bottom_level_boo + * middle_level_bar(method, protocol); + * ... + * // exit, clean after yourself + * ctx_exit(ctx); + * } + * + * void + * bottom_level_boo(int status, void *data) + * { + * // detect exceptional condition, and simply report it, the context + * // information will be available somewhere close in the log file + * if (status == STRANGE_STATUS) + * debug(13, 6) ("DOS attack detected, data: %p\n", data); + * ... + * } + * + * Current implementation is extremely simple but still very handy. It has a + * negligible overhead (descriptions are not duplicated). + * + * When the _first_ debug message for a given context is printed, it is + * prepended with the current context description. Context is printed with + * the same debugging level as the original message. + * + * Note that we do not print context every type you do ctx_enter(). This + * approach would produce too many useless messages. For the same reason, a + * context description is printed at most _once_ even if you have 10 + * debugging messages within one context. + * + * Contexts can be nested, of course. You must use ctx_enter() to enter a + * context (push it onto stack). It is probably safe to exit several nested + * contexts at _once_ by calling ctx_exit() at the top level (this will pop + * all context till current one). However, as in any stack, you cannot start + * in the middle. + * + * Analysis: + * i) locate debugging message, + * ii) locate current context by going _upstream_ in your log file, + * iii) hack away. + * + * + * To-Do: + * ----- + * + * decide if we want to dup() descriptions (adds overhead) but allows to + * add printf()-style interface + * + * implementation: + * --------------- + * + * descriptions for contexts over CTX_MAX_LEVEL limit are ignored, you probably + * have a bug if your nesting goes that deep. + */ + +#define CTX_MAX_LEVEL 255 + +/* + * produce a warning when nesting reaches this level and then double + * the level + */ +static int Ctx_Warn_Level = 32; +/* all descriptions has been printed up to this level */ +static int Ctx_Reported_Level = -1; +/* descriptions are still valid or active up to this level */ +static int Ctx_Valid_Level = -1; +/* current level, the number of nested ctx_enter() calls */ +static int Ctx_Current_Level = -1; +/* saved descriptions (stack) */ +static const char *Ctx_Descrs[CTX_MAX_LEVEL + 1]; +/* "safe" get secription */ +static const char *ctx_get_descr(Ctx ctx); + + +Ctx ctx_enter(const char *descr) +{ + Ctx_Current_Level++; + + if (Ctx_Current_Level <= CTX_MAX_LEVEL) + Ctx_Descrs[Ctx_Current_Level] = descr; + + if (Ctx_Current_Level == Ctx_Warn_Level) { + debug(0, 0) ("# ctx: suspiciously deep (%d) nesting:\n", + Ctx_Warn_Level); + Ctx_Warn_Level *= 2; + } + return Ctx_Current_Level; +} + +void +ctx_exit(Ctx ctx) +{ + assert(ctx >= 0); + Ctx_Current_Level = (ctx >= 0) ? ctx - 1 : -1; + if (Ctx_Valid_Level > Ctx_Current_Level) + Ctx_Valid_Level = Ctx_Current_Level; +} + +/* + * the idea id to print each context description at most once but provide enough + * info for deducing the current execution stack + */ +static void +ctx_print(void) +{ + /* lock so _db_print will not call us recursively */ + Ctx_Lock++; + /* ok, user saw [0,Ctx_Reported_Level] descriptions */ + /* first inform about entries popped since user saw them */ + if (Ctx_Valid_Level < Ctx_Reported_Level) { + if (Ctx_Reported_Level != Ctx_Valid_Level + 1) + _db_print("ctx: exit levels from %2d down to %2d\n", + Ctx_Reported_Level, Ctx_Valid_Level + 1); + else + _db_print("ctx: exit level %2d\n", Ctx_Reported_Level); + Ctx_Reported_Level = Ctx_Valid_Level; + } + /* report new contexts that were pushed since last report */ + while (Ctx_Reported_Level < Ctx_Current_Level) { + Ctx_Reported_Level++; + Ctx_Valid_Level++; + _db_print("ctx: enter level %2d: '%s'\n", Ctx_Reported_Level, + ctx_get_descr(Ctx_Reported_Level)); + } + /* unlock */ + Ctx_Lock--; +} + +/* checks for nulls and overflows */ +static const char * +ctx_get_descr(Ctx ctx) +{ + if (ctx < 0 || ctx > CTX_MAX_LEVEL) + return ""; + return Ctx_Descrs[ctx] ? Ctx_Descrs[ctx] : ""; +} Index: squid/src/defines.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/defines.h,v retrieving revision 1.3.22.6 retrieving revision 1.3.22.7 diff -u -r1.3.22.6 -r1.3.22.7 --- squid/src/defines.h 25 Apr 2001 11:53:00 -0000 1.3.22.6 +++ squid/src/defines.h 27 Apr 2001 17:06:45 -0000 1.3.22.7 @@ -1,6 +1,6 @@ /* - * $Id: defines.h,v 1.3.22.6 2001/04/25 11:53:00 serassio Exp $ + * $Id: defines.h,v 1.3.22.7 2001/04/27 17:06:45 serassio Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -299,9 +299,14 @@ #define _WIN_OS_WIN9X 1 #define _WIN_OS_WINNT 2 #define _WIN_OS_WIN2K 3 +#define _WIN_SQUID_SERVICE_CONTROL_STOP SERVICE_CONTROL_STOP +#define _WIN_SQUID_SERVICE_CONTROL_SHUTDOWN SERVICE_CONTROL_SHUTDOWN +#define _WIN_SQUID_SERVICE_CONTROL_INTERROGATE SERVICE_CONTROL_INTERROGATE #define _WIN_SQUID_SERVICE_CONTROL_ROTATE 128 #define _WIN_SQUID_SERVICE_CONTROL_RECONFIGURE 129 #define _WIN_SQUID_SERVICE_CONTROL_DEBUG 130 #define _WIN_SQUID_SERVICE_CONTROL_INTERRUPT 131 #define _WIN_SQUID_SERVICE_NAME "SquidNT" +#define _WIN_SQUID_RUN_MODE_INTERACTIVE 0 +#define _WIN_SQUID_RUN_MODE_SERVICE 1 #endif Index: squid/src/dns_internal.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/dns_internal.c,v retrieving revision 1.5.26.6 retrieving revision 1.5.26.7 diff -u -r1.5.26.6 -r1.5.26.7 --- squid/src/dns_internal.c 27 Apr 2001 09:58:04 -0000 1.5.26.6 +++ squid/src/dns_internal.c 27 Apr 2001 17:06:45 -0000 1.5.26.7 @@ -1,6 +1,6 @@ /* - * $Id: dns_internal.c,v 1.5.26.6 2001/04/27 09:58:04 serassio Exp $ + * $Id: dns_internal.c,v 1.5.26.7 2001/04/27 17:06:45 serassio Exp $ * * DEBUG: section 78 DNS lookups; interacts with lib/rfc1035.c * AUTHOR: Duane Wessels @@ -35,7 +35,7 @@ #include "squid.h" -#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) +#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) #include #endif #ifndef _PATH_RESOLV_CONF @@ -53,7 +53,8 @@ typedef struct _idns_query idns_query; typedef struct _ns ns; -struct _idns_query { +struct _idns_query +{ char buf[512]; size_t sz; unsigned short id; @@ -66,7 +67,8 @@ int attempt; }; -struct _ns { +struct _ns +{ struct sockaddr_in S; int nqueries; int nreplies; @@ -101,12 +103,19 @@ { struct in_addr A; if (!safe_inet_addr(buf, &A)) { - debug(78, 0) ("WARNING: rejecting '%s' as a name server, because it is not a numeric IP address\n", buf); + debug(78, + 0) + ("WARNING: rejecting '%s' as a name server, because it is not a numeric IP address\n", + buf); return; } if (A.s_addr == 0) { - debug(78, 0) ("WARNING: Squid does not accept 0.0.0.0 in DNS server specifications.\n"); - debug(78, 0) ("Will be using 127.0.0.1 instead, assuming you meant that DNS is running on the same machine\n"); + debug(78, + 0) + ("WARNING: Squid does not accept 0.0.0.0 in DNS server specifications.\n"); + debug(78, + 0) + ("Will be using 127.0.0.1 instead, assuming you meant that DNS is running on the same machine\n"); safe_inet_addr("127.0.0.1", &A); } if (nns == nns_alloc) { @@ -162,7 +171,7 @@ } #if defined(_SQUID_CYGWIN_) setmode(fileno(fp), O_TEXT); -#endif +#endif while (fgets(buf, 512, fp)) { t = strtok(buf, w_space); if (NULL == t) @@ -178,121 +187,150 @@ fclose(fp); } -#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) +#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) static void idnsParseWIN32Registry(void) { char *t; char *token; - HKEY hndKey,hndKey2; - - idnsFreeNameservers(); - - switch (WIN32_OS_version) - { - case _WIN_OS_WINNT: - /* get nameservers from the Windows NT registry */ - if (RegOpenKey(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",&hndKey) == ERROR_SUCCESS) { - DWORD Type = 0; - DWORD Size = 0; - LONG Result; - Result = RegQueryValueEx(hndKey,"DhcpNameServer",NULL,&Type,NULL,&Size); + HKEY hndKey, hndKey2; + + idnsFreeNameservers(); + + switch (WIN32_OS_version) { + case _WIN_OS_WINNT: + /* get nameservers from the Windows NT registry */ + if (RegOpenKey(HKEY_LOCAL_MACHINE, + "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", + &hndKey) == ERROR_SUCCESS) { + DWORD Type = 0; + DWORD Size = 0; + LONG Result; + Result = + RegQueryValueEx(hndKey, "DhcpNameServer", NULL, &Type, NULL, + &Size); + if (Result == ERROR_SUCCESS && Size) { + t = (unsigned char *) xmalloc(Size); + RegQueryValueEx(hndKey, "DhcpNameServer", NULL, &Type, t, + &Size); + token = strtok((char *) t, ", "); + while (token) { + idnsAddNameserver(token); + debug(78, 1) ("Adding DHCP nameserver %s from Registry\n", + token); + token = strtok(NULL, ", "); + } + } + Result = + RegQueryValueEx(hndKey, "NameServer", NULL, &Type, NULL, &Size); + if (Result == ERROR_SUCCESS && Size) { + t = (unsigned char *) xmalloc(Size); + RegQueryValueEx(hndKey, "NameServer", NULL, &Type, t, &Size); + token = strtok((char *) t, ", "); + while (token) { + debug(78, 1) ("Adding nameserver %s from Registry\n", + token); + idnsAddNameserver(token); + token = strtok(NULL, ", "); + } + } + RegCloseKey(hndKey); + } + break; + case _WIN_OS_WIN2K: + /* get nameservers from the Windows 2000 registry */ + /* search all interfaces for DNS server addresses */ + if (RegOpenKey(HKEY_LOCAL_MACHINE, + "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces", + &hndKey) == ERROR_SUCCESS) { + int i; + char keyname[255]; + + for (i = 0; i < 10; i++) { + if (RegEnumKey(hndKey, i, (char *) &keyname, + 255) == ERROR_SUCCESS) { + char newkeyname[255]; + + strcpy(newkeyname, + "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\"); + strcat(newkeyname, keyname); + if (RegOpenKey(HKEY_LOCAL_MACHINE, newkeyname, + &hndKey2) == ERROR_SUCCESS) { + DWORD Type = 0; + DWORD Size = 0; + LONG Result; + Result = + RegQueryValueEx(hndKey2, "DhcpNameServer", NULL, + &Type, NULL, &Size); if (Result == ERROR_SUCCESS && Size) { - t = (unsigned char*) xmalloc(Size); - RegQueryValueEx(hndKey,"DhcpNameServer",NULL,&Type,t,&Size); - token = strtok((char*)t,", "); - while (token) { - idnsAddNameserver(token); - debug(78, 1) ("Adding DHCP nameserver %s from Registry\n", token); - token = strtok(NULL,", "); - } - } - Result = RegQueryValueEx(hndKey,"NameServer",NULL,&Type,NULL,&Size); + t = (unsigned char *) xmalloc(Size); + RegQueryValueEx(hndKey2, "DhcpNameServer", NULL, + &Type, t, &Size); + token = strtok((char *) t, ", "); + while (token) { + debug(78, + 1) + ("Adding DHCP nameserver %s from Registry\n", + token); + idnsAddNameserver(token); + token = strtok(NULL, ", "); + } + } + Result = + RegQueryValueEx(hndKey2, "NameServer", NULL, &Type, + NULL, &Size); if (Result == ERROR_SUCCESS && Size) { - t = (unsigned char*)xmalloc(Size); - RegQueryValueEx(hndKey,"NameServer",NULL,&Type,t,&Size); - token = strtok((char*)t,", "); - while (token) { - debug(78, 1) ("Adding nameserver %s from Registry\n", token); - idnsAddNameserver(token); - token = strtok(NULL,", "); - } - } - RegCloseKey(hndKey); - } - break; - case _WIN_OS_WIN2K: - /* get nameservers from the Windows 2000 registry */ - /* search all interfaces for DNS server addresses */ - if (RegOpenKey(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces",&hndKey) == ERROR_SUCCESS) { - int i; - char keyname[255]; - - for (i=0;i < 10; i++) { - if (RegEnumKey(hndKey,i,(char *)&keyname,255) == ERROR_SUCCESS) { - char newkeyname[255]; - - strcpy(newkeyname,"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\"); - strcat(newkeyname,keyname); - if (RegOpenKey(HKEY_LOCAL_MACHINE,newkeyname,&hndKey2) == ERROR_SUCCESS) { - DWORD Type = 0; - DWORD Size = 0; - LONG Result; - Result = RegQueryValueEx(hndKey2,"DhcpNameServer",NULL,&Type,NULL,&Size); - if (Result == ERROR_SUCCESS && Size) { - t =(unsigned char*) xmalloc(Size); - RegQueryValueEx(hndKey2,"DhcpNameServer",NULL,&Type,t,&Size); - token = strtok((char*)t,", "); - while (token) { - debug(78, 1) ("Adding DHCP nameserver %s from Registry\n", token); - idnsAddNameserver(token); - token = strtok(NULL,", "); - } - } - Result = RegQueryValueEx(hndKey2,"NameServer",NULL,&Type,NULL,&Size); - if (Result == ERROR_SUCCESS && Size) { - t =(unsigned char*) xmalloc(Size); - RegQueryValueEx(hndKey2,"NameServer",NULL,&Type,t,&Size); - token = strtok((char*)t,", "); - while (token) { - debug(78, 1) ("Adding nameserver %s from Registry\n", token); - idnsAddNameserver(token); - token = strtok(NULL,", "); - } - } - RegCloseKey(hndKey2); - } - } + t = (unsigned char *) xmalloc(Size); + RegQueryValueEx(hndKey2, "NameServer", NULL, &Type, + t, &Size); + token = strtok((char *) t, ", "); + while (token) { + debug(78, + 1) ("Adding nameserver %s from Registry\n", + token); + idnsAddNameserver(token); + token = strtok(NULL, ", "); + } } - RegCloseKey(hndKey); + RegCloseKey(hndKey2); + } } - break; - case _WIN_OS_WIN9X: - /* get nameservers from the Windows 9X registry */ - if (RegOpenKey(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP",&hndKey) == ERROR_SUCCESS) { - DWORD Type = 0; - DWORD Size = 0; - LONG Result; - Result = RegQueryValueEx(hndKey,"NameServer",NULL,&Type,NULL,&Size); - if (Result == ERROR_SUCCESS && Size) { - t = (unsigned char*)xmalloc(Size); - RegQueryValueEx(hndKey,"NameServer",NULL,&Type,t,&Size); - token = strtok((char*)t,", "); - while (token) { - debug(78, 1) ("Adding nameserver %s from Registry\n", token); - idnsAddNameserver(token); - token = strtok(NULL,", "); - } - } - RegCloseKey(hndKey); + } + RegCloseKey(hndKey); + } + break; + case _WIN_OS_WIN9X: + /* get nameservers from the Windows 9X registry */ + if (RegOpenKey(HKEY_LOCAL_MACHINE, + "SYSTEM\\CurrentControlSet\\Services\\VxD\\MSTCP", + &hndKey) == ERROR_SUCCESS) { + DWORD Type = 0; + DWORD Size = 0; + LONG Result; + Result = + RegQueryValueEx(hndKey, "NameServer", NULL, &Type, NULL, &Size); + if (Result == ERROR_SUCCESS && Size) { + t = (unsigned char *) xmalloc(Size); + RegQueryValueEx(hndKey, "NameServer", NULL, &Type, t, &Size); + token = strtok((char *) t, ", "); + while (token) { + debug(78, 1) ("Adding nameserver %s from Registry\n", + token); + idnsAddNameserver(token); + token = strtok(NULL, ", "); } - break; - default: - debug(78, 1) ("Failed to read nameserver from Registry: Unknown System Type.\n"); - return; + } + RegCloseKey(hndKey); } + break; + default: + debug(78, + 1) + ("Failed to read nameserver from Registry: Unknown System Type.\n"); + return; + } } -#endif +#endif static void idnsStats(StoreEntry * sentry) @@ -319,8 +357,7 @@ for (i = 0; i < nns; i++) { storeAppendPrintf(sentry, "%-15s %9d %9d\n", inet_ntoa(nameservers[i].S.sin_addr), - nameservers[i].nqueries, - nameservers[i].nreplies); + nameservers[i].nqueries, nameservers[i].nreplies); } storeAppendPrintf(sentry, "\nRcode Matrix:\n"); storeAppendPrintf(sentry, "RCODE"); @@ -362,10 +399,7 @@ try_again: ns = q->nsends % nns; x = comm_udp_sendto(DnsSocket, - &nameservers[ns].S, - sizeof(nameservers[ns].S), - q->buf, - q->sz); + &nameservers[ns].S, sizeof(nameservers[ns].S), q->buf, q->sz); q->nsends++; q->sent_t = current_time; if (x < 0) { @@ -417,10 +451,7 @@ rfc1035_rr *answers = NULL; unsigned short rid = 0xFFFF; idns_query *q; - n = rfc1035AnswersUnpack(buf, - sz, - &answers, - &rid); + n = rfc1035AnswersUnpack(buf, sz, &answers, &rid); debug(78, 3) ("idnsGrokReply: ID %#hx, %d answers\n", rid, n); if (rid == 0xFFFF) { debug(78, 1) ("idnsGrokReply: Unknown error\n"); @@ -493,9 +524,7 @@ assert(N); (*N)++; debug(78, 3) ("idnsRead: FD %d: received %d bytes from %s.\n", - fd, - len, - inet_ntoa(from.sin_addr)); + fd, len, inet_ntoa(from.sin_addr)); ns = idnsFromKnownNameserver(&from); if (ns >= 0) { nameservers[ns].nreplies++; @@ -543,19 +572,21 @@ /* name servers went away; reconfiguring or shutting down */ break; q = n->data; - if (tvSubDsec(q->sent_t, current_time) < Config.Timeout.idns_retransmit * (1 << q->nsends % nns)) + if (tvSubDsec(q->sent_t, + current_time) < + Config.Timeout.idns_retransmit * (1 << q->nsends % nns)) break; - debug(78, 3) ("idnsCheckQueue: ID %#04x timeout\n", - q->id); + debug(78, 3) ("idnsCheckQueue: ID %#04x timeout\n", q->id); p = n->prev; dlinkDelete(&q->lru, &lru_list); if (tvSubDsec(q->start_t, current_time) < Config.Timeout.idns_query) { idnsSendQuery(q); } else { int v = cbdataValid(q->callback_data); - debug(78, 1) ("idnsCheckQueue: ID %x: giving up after %d tries and %5.1f seconds\n", - (int) q->id, q->nsends, - tvSubDsec(q->start_t, current_time)); + debug(78, + 1) + ("idnsCheckQueue: ID %x: giving up after %d tries and %5.1f seconds\n", + (int) q->id, q->nsends, tvSubDsec(q->start_t, current_time)); cbdataUnlock(q->callback_data); if (v) q->callback(q->callback_data, NULL, 0); @@ -588,34 +619,32 @@ static int init = 0; if (DnsSocket < 0) { DnsSocket = comm_open(SOCK_DGRAM, - 0, - Config.Addrs.udp_outgoing, - 0, - COMM_NONBLOCKING, - "DNS Socket"); + 0, Config.Addrs.udp_outgoing, 0, COMM_NONBLOCKING, "DNS Socket"); if (DnsSocket < 0) fatal("Could not create a DNS socket"); debug(78, 1) ("DNS Socket created on FD %d\n", DnsSocket); } assert(0 == nns); idnsParseNameservers(); -#ifndef _SQUID_MSWIN_ +#ifndef _SQUID_MSWIN_ if (0 == nns) idnsParseResolvConf(); #endif -#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) +#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) if (0 == nns) - idnsParseWIN32Registry(); + idnsParseWIN32Registry(); #endif if (0 == nns) fatal("Could not find any nameservers.\n" +#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) + " Please check your TCP-IP settings or /etc/resolv.conf file\n" +#else " Please check your /etc/resolv.conf file\n" +#endif " or use the 'dns_nameservers' option in squid.conf."); if (!init) { memDataInit(MEM_IDNS_QUERY, "idns_query", sizeof(idns_query), 0); - cachemgrRegister("idns", - "Internal DNS Statistics", - idnsStats, 0, 1); + cachemgrRegister("idns", "Internal DNS Statistics", idnsStats, 0, 1); memset(RcodeMatrix, '\0', sizeof(RcodeMatrix)); init++; } @@ -676,7 +705,8 @@ { int i, n = 0; variable_list *Answer = NULL; - debug(49, 5) ("snmp_netDnsFn: Processing request:\n", Var->name[LEN_SQ_NET + 1]); + debug(49, 5) ("snmp_netDnsFn: Processing request:\n", + Var->name[LEN_SQ_NET + 1]); snmpDebugOid(5, Var->name, Var->name_length); *ErrP = SNMP_ERR_NOERROR; switch (Var->name[LEN_SQ_NET + 1]) { @@ -684,20 +714,17 @@ for (i = 0; i < nns; i++) n += nameservers[i].nqueries; Answer = snmp_var_new_integer(Var->name, Var->name_length, - n, - SMI_COUNTER32); + n, SMI_COUNTER32); break; case DNS_REP: for (i = 0; i < nns; i++) n += nameservers[i].nreplies; Answer = snmp_var_new_integer(Var->name, Var->name_length, - n, - SMI_COUNTER32); + n, SMI_COUNTER32); break; case DNS_SERVERS: Answer = snmp_var_new_integer(Var->name, Var->name_length, - 0, - SMI_COUNTER32); + 0, SMI_COUNTER32); break; default: *ErrP = SNMP_ERR_NOSUCHNAME; Index: squid/src/globals.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/globals.h,v retrieving revision 1.5.12.4 retrieving revision 1.5.12.5 diff -u -r1.5.12.4 -r1.5.12.5 --- squid/src/globals.h 25 Apr 2001 11:53:00 -0000 1.5.12.4 +++ squid/src/globals.h 27 Apr 2001 17:06:45 -0000 1.5.12.5 @@ -1,6 +1,6 @@ /* - * $Id: globals.h,v 1.5.12.4 2001/04/25 11:53:00 serassio Exp $ + * $Id: globals.h,v 1.5.12.5 2001/04/27 17:06:45 serassio Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -131,7 +131,7 @@ extern int _db_level; extern const int CacheDigestHashFuncCount; /* 4 */ extern CacheDigest *store_digest; /* NULL */ -extern const char *StoreDigestFileName; /* "store_digest" */ +extern const char *StoreDigestFileName; /* "store_digest" */ extern const char *StoreDigestMimeStr; /* "application/cache-digest" */ #if USE_CACHE_DIGESTS extern const Version CacheDigestVer; /* { 5, 3 } */ @@ -155,4 +155,5 @@ extern hash_table *proxy_auth_username_cache; /* NULL */ #if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) extern unsigned int WIN32_OS_version; /* 0 */ +extern unsigned int WIN32_run_mode; /* _WIN_SQUID_RUN_MODE_INTERACTIVE */ #endif Index: squid/src/main.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/main.c,v retrieving revision 1.12.2.6 retrieving revision 1.12.2.7 diff -u -r1.12.2.6 -r1.12.2.7 --- squid/src/main.c 24 Apr 2001 16:02:43 -0000 1.12.2.6 +++ squid/src/main.c 27 Apr 2001 17:06:45 -0000 1.12.2.7 @@ -1,6 +1,6 @@ /* - * $Id: main.c,v 1.12.2.6 2001/04/24 16:02:43 serassio Exp $ + * $Id: main.c,v 1.12.2.7 2001/04/27 17:06:45 serassio Exp $ * * DEBUG: section 1 Startup and Main Loop * AUTHOR: Harvest Derived @@ -35,11 +35,26 @@ #include "squid.h" +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) +#include +#include +static int opt_install_service = FALSE; +static int opt_remove_service = FALSE; +static int opt_config_file = FALSE; +extern void WIN32_svcstatusupdate(DWORD); +void WINAPI WIN32_svcHandler(DWORD); +extern int WIN32_StoreKey(const char *, DWORD, unsigned char *, int); +#endif + /* for error reporting from xmalloc and friends */ extern void (*failure_notify) (const char *); static int opt_send_signal = -1; +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) +static int opt_no_daemon = 1; +#else static int opt_no_daemon = 0; +#endif static int opt_parse_cfg_only = 0; static int httpPortNumOverride = 1; static int icpPortNumOverride = 1; /* Want to detect "-u 0" */ @@ -53,8 +68,8 @@ static void mainRotate(void); static void mainReconfigure(void); -static SIGHDLR rotate_logs; -static SIGHDLR reconfigure; +/* static SIGHDLR rotate_logs; +static SIGHDLR reconfigure; */ #if ALARM_UPDATES_TIME static SIGHDLR time_tick; #endif @@ -83,15 +98,28 @@ usage(void) { fprintf(stderr, +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + "Usage: %s [-dhirsvzCDFRVYX] [-f config-file] [-[au] port] [-k signal]\n" +#else "Usage: %s [-dhsvzCDFNRVYX] [-f config-file] [-[au] port] [-k signal]\n" +#endif " -a port Specify HTTP port number (default: %d).\n" " -d level Write debugging to stderr also.\n" +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + " -f file Set Windows NT Registry to use given config-file instead of\n" +#else " -f file Use given config-file instead of\n" - " %s\n" - " -h Print help message.\n" +#endif + " %s\n" " -h Print help message.\n" +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + " -i Installs the " _WIN_SQUID_SERVICE_NAME " service.\n" +#endif " -k reconfigure|rotate|shutdown|interrupt|kill|debug|check|parse\n" " Parse configuration file, then send signal to \n" " running copy (except -k parse) and exit.\n" +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + " -r Removes the " _WIN_SQUID_SERVICE_NAME " service.\n" +#endif " -s Enable logging to syslog.\n" " -u port Specify ICP port number (default: %d), disable with 0.\n" " -v Print version.\n" @@ -99,7 +127,9 @@ " -C Do not catch fatal signals.\n" " -D Disable initial DNS tests.\n" " -F Don't serve any requests until store is rebuilt.\n" +#if !(defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))) " -N No daemon mode.\n" +#endif " -R Do not set REUSEADDR on port.\n" " -S Double-check swap during rebuild.\n" " -V Virtual host httpd-accelerator.\n" @@ -115,7 +145,11 @@ extern char *optarg; int c; +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + while ((c = getopt(argc, argv, "CDFRSVYXa:d:f:hik:m::rsu:vz?")) != -1) { +#else while ((c = getopt(argc, argv, "CDFNRSVYXa:d:f:hk:m::su:vz?")) != -1) { +#endif switch (c) { case 'C': opt_catch_signals = 0; @@ -126,9 +160,11 @@ case 'F': opt_foreground_rebuild = 1; break; +#if !(defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))) case 'N': opt_no_daemon = 1; break; +#endif case 'R': opt_reuseaddr = 0; break; @@ -152,12 +188,20 @@ opt_debug_stderr = atoi(optarg); break; case 'f': +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + opt_config_file = TRUE; +#endif xfree(ConfigFile); ConfigFile = xstrdup(optarg); break; case 'h': usage(); break; +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + case 'i': + opt_install_service = TRUE; + break; +#endif case 'k': if ((int) strlen(optarg) < 1) usage(); @@ -184,7 +228,7 @@ else if (!strncmp(optarg, "check", strlen(optarg))) opt_send_signal = 0; /* SIGNULL */ else if (!strncmp(optarg, "parse", strlen(optarg))) - opt_parse_cfg_only = 1; /* parse cfg file only */ + opt_parse_cfg_only = 1; /* parse cfg file only */ else usage(); break; @@ -195,16 +239,23 @@ /* NOTREACHED */ break; #else - fatal("Need to add -DMALLOC_DBG when compiling to use -mX option"); + fatal + ("Need to add -DMALLOC_DBG when compiling to use -mX option"); /* NOTREACHED */ #endif } else { #if XMALLOC_TRACE xmalloc_trace = !xmalloc_trace; #else - fatal("Need to configure --enable-xmalloc-debug-trace to use -m option"); + fatal + ("Need to configure --enable-xmalloc-debug-trace to use -m option"); #endif } +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + case 'r': + opt_remove_service = TRUE; + break; +#endif case 's': opt_syslog_enable = 1; break; @@ -215,6 +266,9 @@ break; case 'v': printf("Squid Cache: Version %s\n", version_string); +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + printf("Compiled as Windows System Service.\n"); +#endif exit(0); /* NOTREACHED */ case 'z': @@ -229,7 +283,7 @@ } /* ARGSUSED */ -static void +void rotate_logs(int sig) { do_rotate = 1; @@ -252,7 +306,7 @@ #endif /* ARGSUSED */ -static void +void reconfigure(int sig) { do_reconfigure = 1; @@ -406,6 +460,7 @@ static void setEffectiveUser(void) { +#if !(defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_))) leave_suid(); /* Run as non privilegied user */ #ifdef _SQUID_OS2_ return; @@ -417,6 +472,7 @@ debug(0, 0) ("'cache_effective_user' option in the config file.\n"); fatal("Don't run Squid as root, set 'cache_effective_user'!"); } +#endif } static void @@ -464,8 +520,11 @@ log_trace_init("/tmp/squid.alloc"); #endif debug(1, 0) ("Starting Squid Cache version %s for %s...\n", - version_string, - CONFIG_HOST_TYPE); + version_string, CONFIG_HOST_TYPE); +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) + debug(1, 0) ("Running as Windows System Service\n"); +#endif debug(1, 1) ("Process ID %d\n", (int) getpid()); debug(1, 1) ("With %d file descriptors available\n", Squid_MaxFD); @@ -561,20 +620,36 @@ configured_once = 1; } +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) +void WINAPI +SquidMain(DWORD argc, char **argv) +#else int main(int argc, char **argv) +#endif { int errcount = 0; int n; /* # of GC'd objects */ time_t loop_delay; mode_t oldmask; +#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) + int WIN32_init_err; +#endif debug_log = stderr; if (FD_SETSIZE < Squid_MaxFD) Squid_MaxFD = FD_SETSIZE; #if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) - WIN32_Subsystem_Init(); +#ifdef USE_WIN32_SERVICE + WIN32_run_mode = + (argc == 1 ? _WIN_SQUID_RUN_MODE_SERVICE : _WIN_SQUID_RUN_MODE_INTERACTIVE); + if (WIN32_Subsystem_Init()) + return; +#else + if (WIN32_init_err = WIN32_Subsystem_Init()) + return WIN32_init_err; +#endif #endif /* call mallopt() before anything else */ @@ -615,8 +690,29 @@ squid_start = current_time; failure_notify = fatal_dump; +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + WIN32_svcstatusupdate(SERVICE_START_PENDING); +#endif + mainParseOptions(argc, argv); +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + if (opt_install_service) { + WIN32_InstallService(); + if (!opt_config_file) + return; + } + if (opt_config_file) { + WIN32_StoreKey("ConfigFile", REG_SZ, (unsigned char *) ConfigFile, + strlen(ConfigFile) + 1); + return; + } + if (opt_remove_service) { + WIN32_RemoveService(); + return; + } +#endif + /* parse configuration file * note: in "normal" case this used to be called from mainInitialize() */ { @@ -635,7 +731,11 @@ parse_err = parseConfigFile(ConfigFile); if (opt_parse_cfg_only) +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + return; +#else return parse_err; +#endif } if (-1 == opt_send_signal) if (checkRunningPid()) @@ -666,7 +766,11 @@ setEffectiveUser(); debug(0, 0) ("Creating Swap Directories\n"); storeCreateSwapDirectories(); +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + return; +#else return 0; +#endif } if (!opt_no_daemon) watch_child(argv); @@ -686,8 +790,15 @@ fd_open(1, FD_LOG, "stdout"); fd_open(2, FD_LOG, "stderr"); } +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + WIN32_svcstatusupdate(SERVICE_START_PENDING); +#endif mainInitialize(); +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + WIN32_svcstatusupdate(SERVICE_RUNNING); +#endif + /* main loop */ for (;;) { if (do_reconfigure) { @@ -700,18 +811,23 @@ time_t wait = do_shutdown > 0 ? (int) Config.shutdownLifetime : 0; debug(1, 1) ("Preparing for shutdown after %d requests\n", statCounter.client_http.requests); - debug(1, 1) ("Waiting %d seconds for active connections to finish\n", + debug(1, + 1) ("Waiting %d seconds for active connections to finish\n", wait); do_shutdown = 0; shutting_down = 1; serverConnectionsClose(); +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + WIN32_svcstatusupdate(SERVICE_STOP_PENDING); +#endif #if USE_DNSSERVERS dnsShutdown(); #else idnsShutdown(); #endif redirectShutdown(); - eventAdd("SquidShutdown", SquidShutdown, NULL, (double) (wait + 1), 1); + eventAdd("SquidShutdown", SquidShutdown, NULL, (double) (wait + 1), + 1); } eventRun(); if ((loop_delay = eventNextTime()) < 0) @@ -741,7 +857,11 @@ } } /* NOTREACHED */ +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + return; +#else return 0; +#endif } static void @@ -751,14 +871,18 @@ debug_log = stderr; pid = readPidFile(); if (pid > 1) { +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) + WIN32_sendSignal(opt_send_signal); +#else if (kill(pid, opt_send_signal) && - /* ignore permissions if just running check */ + /* ignore permissions if just running check */ !(opt_send_signal == 0 && errno == EPERM)) { fprintf(stderr, "%s: ERROR: Could not send ", appname); fprintf(stderr, "signal %d to process %d: %s\n", opt_send_signal, (int) pid, xstrerror()); exit(1); } +#endif } else { fprintf(stderr, "%s: ERROR: No running copy\n", appname); exit(1); @@ -998,7 +1122,28 @@ if (debug_log) fclose(debug_log); #if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) - WIN32_Subsystem_Shutdown(); -#endif + WIN32_Exit(0); +#else exit(0); +#endif + } + +#if defined(USE_WIN32_SERVICE) && (defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_)) +int +main(int argc, char **argv) +{ + SERVICE_TABLE_ENTRY DispatchTable[] = { + {_WIN_SQUID_SERVICE_NAME, SquidMain}, + {NULL, NULL} + }; + if (argc > 1) + SquidMain(argc, argv); + else if (!StartServiceCtrlDispatcher(DispatchTable)) { + fprintf(stderr, "StartServiceCtrlDispatcher error = %ld\n", + GetLastError()); + return 1; + } + return 0; +} +#endif Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.9.2.4 retrieving revision 1.9.2.5 diff -u -r1.9.2.4 -r1.9.2.5 --- squid/src/protos.h 25 Apr 2001 11:38:30 -0000 1.9.2.4 +++ squid/src/protos.h 27 Apr 2001 17:06:45 -0000 1.9.2.5 @@ -1,1318 +1,1362 @@ - -/* - * $Id: protos.h,v 1.9.2.4 2001/04/25 11:38:30 serassio Exp $ - * - * - * SQUID Web Proxy Cache http://www.squid-cache.org/ - * ---------------------------------------------------------- - * - * Squid is the result of efforts by numerous individuals from - * the Internet community; see the CONTRIBUTORS file for full - * details. Many organizations have provided support for Squid's - * development; see the SPONSORS file for full details. Squid is - * Copyrighted (C) 2001 by the Regents of the University of - * California; see the COPYRIGHT file for full details. Squid - * incorporates software developed and/or copyrighted by other - * sources; see the CREDITS file for full details. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. - * - */ - -extern void accessLogLog(AccessLogEntry *); -extern void accessLogRotate(void); -extern void accessLogClose(void); -extern void accessLogInit(void); -extern const char *accessLogTime(time_t); -extern void hierarchyNote(HierarchyLogEntry *, hier_code, const char *); -#if FORW_VIA_DB -extern void fvdbCountVia(const char *key); -extern void fvdbCountForw(const char *key); -#endif -#if HEADERS_LOG -extern void headersLog(int cs, int pq, method_t m, void *data); -#endif -char *log_quote(const char *header); - -/* acl.c */ -extern aclCheck_t *aclChecklistCreate(const struct _acl_access *, - request_t *, - const char *ident); -extern void aclNBCheck(aclCheck_t *, PF *, void *); -extern int aclCheckFast(const struct _acl_access *A, aclCheck_t *); -extern void aclChecklistFree(aclCheck_t *); -extern int aclMatchAclList(const acl_list * list, aclCheck_t * checklist); -extern void aclDestroyAccessList(struct _acl_access **list); -extern void aclDestroyAcls(acl **); -extern void aclParseAccessLine(struct _acl_access **); -extern void aclParseAclLine(acl **); -extern int aclIsProxyAuth(const char *name); -extern err_type aclGetDenyInfoPage(acl_deny_info_list ** head, const char *name); -extern void aclParseDenyInfoLine(struct _acl_deny_info_list **); -extern void aclDestroyDenyInfoList(struct _acl_deny_info_list **); -extern void aclDestroyRegexList(struct _relist *data); -extern int aclMatchRegex(relist * data, const char *word); -extern void aclParseRegexList(void *curlist); -extern const char *aclTypeToStr(squid_acl); -extern wordlist *aclDumpGeneric(const acl *); -extern int aclPurgeMethodInUse(acl_access *); -extern void aclCacheMatchFlush(dlink_list * cache); - -/* - * cache_cf.c - */ -extern int parseConfigFile(const char *file_name); -extern void intlistDestroy(intlist **); -extern int intlistFind(intlist * list, int i); -extern const char *wordlistAdd(wordlist **, const char *); -extern void wordlistAddWl(wordlist **, wordlist *); -extern void wordlistJoin(wordlist **, wordlist **); -extern wordlist *wordlistDup(const wordlist *); -extern void wordlistDestroy(wordlist **); -extern void configFreeMemory(void); -extern void wordlistCat(const wordlist *, MemBuf * mb); -extern void allocate_new_swapdir(cacheSwap *); -extern void self_destruct(void); -extern int GetInteger(void); - -/* extra functions from cache_cf.c useful for lib modules */ -extern void parse_int(int *var); -extern void parse_eol(char *volatile *var); -extern void parse_wordlist(wordlist ** list); -extern void requirePathnameExists(const char *name, const char *path); -extern void parse_time_t(time_t * var); -extern void parse_cachedir_options(SwapDir * sd, struct cache_dir_option *options, int reconfiguring); - - -/* - * cbdata.c - */ -extern void cbdataInit(void); -#if CBDATA_DEBUG -extern void *cbdataInternalAllocDbg(cbdata_type type, int, const char *); -extern void cbdataLockDbg(const void *p, const char *, int); -extern void cbdataUnlockDbg(const void *p, const char *, int); -#else -extern void *cbdataInternalAlloc(cbdata_type type); -extern void cbdataLock(const void *p); -extern void cbdataUnlock(const void *p); -#endif -/* Note: Allocations is done using the cbdataAlloc macro */ -extern void *cbdataInternalFree(void *p); -extern int cbdataValid(const void *p); -extern void cbdataInitType(cbdata_type type, char *label, int size, FREE * free_func); -extern cbdata_type cbdataAddType(cbdata_type type, char *label, int size, FREE * free_func); -extern int cbdataLocked(const void *p); - -extern void clientdbInit(void); -extern void clientdbUpdate(struct in_addr, log_type, protocol_t, size_t); -extern int clientdbCutoffDenied(struct in_addr); -extern void clientdbDump(StoreEntry *); -extern void clientdbFreeMemory(void); -extern int clientdbEstablished(struct in_addr, int); - -extern void clientAccessCheck(void *); -extern void clientAccessCheckDone(int, void *); -extern int modifiedSince(StoreEntry *, request_t *); -extern char *clientConstructTraceEcho(clientHttpRequest *); -extern void clientPurgeRequest(clientHttpRequest *); -extern int checkNegativeHit(StoreEntry *); -extern void clientHttpConnectionsOpen(void); -extern void clientHttpConnectionsClose(void); -extern StoreEntry *clientCreateStoreEntry(clientHttpRequest *, method_t, request_flags); -extern int isTcpHit(log_type); -extern void clientReadBody(request_t * req, char *buf, size_t size, CBCB * callback, void *data); -extern int clientAbortBody(request_t * req); - -extern int commSetNonBlocking(int fd); -extern int commUnsetNonBlocking(int fd); -extern void commSetCloseOnExec(int fd); -extern int comm_accept(int fd, struct sockaddr_in *, struct sockaddr_in *); -extern void comm_close(int fd); -#if LINGERING_CLOSE -extern void comm_lingering_close(int fd); -#endif -extern void commConnectStart(int fd, const char *, u_short, CNCB *, void *); -extern int comm_connect_addr(int sock, const struct sockaddr_in *); -extern void comm_init(void); -extern int comm_listen(int sock); -extern int comm_open(int, int, struct in_addr, u_short port, int, const char *note); -extern u_short comm_local_port(int fd); - -extern void commSetSelect(int, unsigned int, PF *, void *, time_t); -extern void comm_add_close_handler(int fd, PF *, void *); -extern void comm_remove_close_handler(int fd, PF *, void *); -extern int comm_udp_sendto(int, const struct sockaddr_in *, int, const void *, int); -extern void comm_write(int fd, - char *buf, - int size, - CWCB * handler, - void *handler_data, - FREE *); -extern void comm_write_mbuf(int fd, MemBuf mb, CWCB * handler, void *handler_data); -extern void commCallCloseHandlers(int fd); -extern int commSetTimeout(int fd, int, PF *, void *); -extern void commSetDefer(int fd, DEFER * func, void *); -extern int ignoreErrno(int); -extern void commCloseAllSockets(void); - - -/* - * comm_select.c - */ -extern void comm_select_init(void); -#if HAVE_POLL -extern int comm_poll(int); -#else -extern int comm_select(int); -#endif -extern void commUpdateReadBits(int, PF *); -extern void commUpdateWriteBits(int, PF *); -extern void comm_quick_poll_required(void); - -extern void packerToStoreInit(Packer * p, StoreEntry * e); -extern void packerToMemInit(Packer * p, MemBuf * mb); -extern void packerClean(Packer * p); -extern void packerAppend(Packer * p, const char *buf, int size); -#if STDC_HEADERS -extern void packerPrintf(Packer * p, const char *fmt,...); -#else -extern void packerPrintf(); -#endif - - -/* see debug.c for info on context-based debugging */ -extern Ctx ctx_enter(const char *descr); -extern void ctx_exit(Ctx ctx); - -extern void _db_init(const char *logfile, const char *options); -extern void _db_rotate_log(void); - -#if STDC_HEADERS -extern void _db_print(const char *,...); -#else -extern void _db_print(); -#endif -extern void xassert(const char *, const char *, int); - -/* packs, then prints an object using debug() */ -extern void debugObj(int section, int level, const char *label, void *obj, ObjPackMethod pm); - -/* disk.c */ -extern int file_open(const char *path, int mode); -extern void file_close(int fd); -extern void file_write(int, off_t, void *, int len, DWCB *, void *, FREE *); -extern void file_write_mbuf(int fd, off_t, MemBuf mb, DWCB * handler, void *handler_data); -extern void file_read(int, char *, int, off_t, DRCB *, void *); -extern void disk_init(void); - -/* diskd.c */ -extern diskd_queue *afile_create_queue(void); -extern void afile_destroy_queue(diskd_queue *); -extern void afile_sync_queue(diskd_queue *); -extern void afile_sync(void); -extern void afile_open(const char *path, int mode, DOCB *, void *); -extern void afile_close(int fd, DCCB * callback, void *data); -extern void afile_write(int, off_t, void *, int len, DWCB *, void *, FREE *); -extern void afile_write_mbuf(int fd, off_t, MemBuf, DWCB *, void *); -extern void afile_read(int, char *, int, off_t, DRCB *, void *); -extern void afile_unlink(const char *path, DUCB *, void *); -extern void afile_truncate(const char *path, DTCB *, void *); - -extern void dnsShutdown(void); -extern void dnsInit(void); -extern void dnsSubmit(const char *lookup, HLPCB * callback, void *data); - -/* dns_internal.c */ -extern void idnsInit(void); -extern void idnsShutdown(void); -extern void idnsALookup(const char *, IDNSCB *, void *); -extern void idnsPTRLookup(const struct in_addr, IDNSCB *, void *); - -extern void eventAdd(const char *name, EVH * func, void *arg, double when, int); -extern void eventAddIsh(const char *name, EVH * func, void *arg, double delta_ish, int); -extern void eventRun(void); -extern time_t eventNextTime(void); -extern void eventDelete(EVH * func, void *arg); -extern void eventInit(void); -extern void eventFreeMemory(void); -extern int eventFind(EVH *, void *); - -extern void fd_close(int fd); -extern void fd_open(int fd, unsigned int type, const char *); -extern void fd_note(int fd, const char *); -extern void fd_bytes(int fd, int len, unsigned int type); -extern void fdFreeMemory(void); -extern void fdDumpOpen(void); -extern int fdNFree(void); -extern void fdAdjustReserved(void); - -extern fileMap *file_map_create(void); -extern int file_map_allocate(fileMap *, int); -extern int file_map_bit_set(fileMap *, int); -extern int file_map_bit_test(fileMap *, int); -extern void file_map_bit_reset(fileMap *, int); -extern void filemapFreeMemory(fileMap *); - - -extern void fqdncache_nbgethostbyaddr(struct in_addr, FQDNH *, void *); -extern const char *fqdncache_gethostbyaddr(struct in_addr, int flags); -extern void fqdncache_init(void); -extern void fqdnStats(StoreEntry *); -extern void fqdncacheReleaseInvalid(const char *); -extern const char *fqdnFromAddr(struct in_addr); -extern int fqdncacheQueueDrain(void); -extern void fqdncacheFreeMemory(void); -extern void fqdncache_restart(void); -extern EVH fqdncache_purgelru; -extern void fqdncacheAddEntryFromHosts(char *addr, wordlist * hostnames); - -extern void ftpStart(FwdState *); -extern char *ftpUrlWith2f(const request_t *); - -extern void gopherStart(FwdState *); -extern int gopherCachable(const char *); - - -extern void whoisStart(FwdState *); - -/* http.c */ -extern int httpCachable(method_t); -extern void httpStart(FwdState *); -extern void httpParseReplyHeaders(const char *, http_reply *); -extern void httpProcessReplyHeader(HttpStateData *, const char *, int); -extern mb_size_t httpBuildRequestPrefix(request_t * request, - request_t * orig_request, - StoreEntry * entry, - MemBuf * mb, - int cfd, - http_state_flags); -extern void httpAnonInitModule(void); -extern int httpAnonHdrAllowed(http_hdr_type hdr_id); -extern int httpAnonHdrDenied(http_hdr_type hdr_id); -extern void httpBuildRequestHeader(request_t *, request_t *, StoreEntry *, HttpHeader *, int, http_state_flags); -extern void httpBuildVersion(http_version_t * version, unsigned int major, unsigned int minor); -extern const char *httpMakeVaryMark(request_t * request, HttpReply * reply); - -/* ETag */ -extern int etagParseInit(ETag * etag, const char *str); -extern int etagIsEqual(const ETag * tag1, const ETag * tag2); - -/* Http Status Line */ -/* init/clean */ -extern void httpStatusLineInit(HttpStatusLine * sline); -extern void httpStatusLineClean(HttpStatusLine * sline); -/* set/get values */ -extern void httpStatusLineSet(HttpStatusLine * sline, http_version_t version, - http_status status, const char *reason); -extern const char *httpStatusLineReason(const HttpStatusLine * sline); -/* parse/pack */ -/* parse a 0-terminating buffer and fill internal structires; returns true on success */ -extern int httpStatusLineParse(HttpStatusLine * sline, const char *start, - const char *end); -/* pack fields using Packer */ -extern void httpStatusLinePackInto(const HttpStatusLine * sline, Packer * p); -extern const char *httpStatusString(http_status status); - -/* Http Body */ -/* init/clean */ -extern void httpBodyInit(HttpBody * body); -extern void httpBodyClean(HttpBody * body); -/* get body ptr (always use this) */ -extern const char *httpBodyPtr(const HttpBody * body); -/* set body, does not clone mb so you should not reuse it */ -extern void httpBodySet(HttpBody * body, MemBuf * mb); - -/* pack */ -extern void httpBodyPackInto(const HttpBody * body, Packer * p); - -/* Http Cache Control Header Field */ -extern void httpHdrCcInitModule(void); -extern void httpHdrCcCleanModule(void); -extern HttpHdrCc *httpHdrCcCreate(void); -extern HttpHdrCc *httpHdrCcParseCreate(const String * str); -extern void httpHdrCcDestroy(HttpHdrCc * cc); -extern HttpHdrCc *httpHdrCcDup(const HttpHdrCc * cc); -extern void httpHdrCcPackInto(const HttpHdrCc * cc, Packer * p); -extern void httpHdrCcJoinWith(HttpHdrCc * cc, const HttpHdrCc * new_cc); -extern void httpHdrCcSetMaxAge(HttpHdrCc * cc, int max_age); -extern void httpHdrCcSetSMaxAge(HttpHdrCc * cc, int s_maxage); -extern void httpHdrCcUpdateStats(const HttpHdrCc * cc, StatHist * hist); -extern void httpHdrCcStatDumper(StoreEntry * sentry, int idx, double val, double size, int count); - -/* Http Range Header Field */ -extern HttpHdrRange *httpHdrRangeParseCreate(const String * range_spec); -/* returns true if ranges are valid; inits HttpHdrRange */ -extern int httpHdrRangeParseInit(HttpHdrRange * range, const String * range_spec); -extern void httpHdrRangeDestroy(HttpHdrRange * range); -extern HttpHdrRange *httpHdrRangeDup(const HttpHdrRange * range); -extern void httpHdrRangePackInto(const HttpHdrRange * range, Packer * p); -/* iterate through specs */ -extern HttpHdrRangeSpec *httpHdrRangeGetSpec(const HttpHdrRange * range, HttpHdrRangePos * pos); -/* adjust specs after the length is known */ -extern int httpHdrRangeCanonize(HttpHdrRange *, ssize_t); -/* other */ -extern String httpHdrRangeBoundaryStr(clientHttpRequest * http); -extern int httpHdrRangeIsComplex(const HttpHdrRange * range); -extern int httpHdrRangeWillBeComplex(const HttpHdrRange * range); -extern ssize_t httpHdrRangeFirstOffset(const HttpHdrRange * range); -extern ssize_t httpHdrRangeLowestOffset(const HttpHdrRange * range, ssize_t); -extern int httpHdrRangeOffsetLimit(HttpHdrRange *); - - -/* Http Content Range Header Field */ -extern HttpHdrContRange *httpHdrContRangeCreate(void); -extern HttpHdrContRange *httpHdrContRangeParseCreate(const char *crange_spec); -/* returns true if range is valid; inits HttpHdrContRange */ -extern int httpHdrContRangeParseInit(HttpHdrContRange * crange, const char *crange_spec); -extern void httpHdrContRangeDestroy(HttpHdrContRange * crange); -extern HttpHdrContRange *httpHdrContRangeDup(const HttpHdrContRange * crange); -extern void httpHdrContRangePackInto(const HttpHdrContRange * crange, Packer * p); -/* inits with given spec */ -extern void httpHdrContRangeSet(HttpHdrContRange *, HttpHdrRangeSpec, ssize_t); - -/* Http Header Tools */ -extern HttpHeaderFieldInfo *httpHeaderBuildFieldsInfo(const HttpHeaderFieldAttrs * attrs, int count); -extern void httpHeaderDestroyFieldsInfo(HttpHeaderFieldInfo * info, int count); -extern int httpHeaderIdByName(const char *name, int name_len, const HttpHeaderFieldInfo * attrs, int end); -extern int httpHeaderIdByNameDef(const char *name, int name_len); -extern const char *httpHeaderNameById(int id); -extern void httpHeaderMaskInit(HttpHeaderMask * mask, int value); -extern void httpHeaderCalcMask(HttpHeaderMask * mask, const int *enums, int count); -extern int httpHeaderHasConnDir(const HttpHeader * hdr, const char *directive); -extern void httpHeaderAddContRange(HttpHeader *, HttpHdrRangeSpec, ssize_t); -extern void strListAdd(String * str, const char *item, char del); -extern int strListIsMember(const String * str, const char *item, char del); -extern int strListIsSubstr(const String * list, const char *s, char del); -extern int strListGetItem(const String * str, char del, const char **item, int *ilen, const char **pos); -extern const char *getStringPrefix(const char *str, const char *end); -extern int httpHeaderParseInt(const char *start, int *val); -extern int httpHeaderParseSize(const char *start, ssize_t * sz); -extern int httpHeaderReset(HttpHeader * hdr); -#if STDC_HEADERS -extern void httpHeaderPutStrf(HttpHeader * hdr, http_hdr_type id, const char *fmt,...); -#else -extern void httpHeaderPutStrf(); -#endif - - -/* Http Header */ -extern void httpHeaderInitModule(void); -extern void httpHeaderCleanModule(void); -/* init/clean */ -extern void httpHeaderInit(HttpHeader * hdr, http_hdr_owner_type owner); -extern void httpHeaderClean(HttpHeader * hdr); -/* append/update */ -extern void httpHeaderAppend(HttpHeader * dest, const HttpHeader * src); -extern void httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh, const HttpHeaderMask * denied_mask); -/* parse/pack */ -extern int httpHeaderParse(HttpHeader * hdr, const char *header_start, const char *header_end); -extern void httpHeaderPackInto(const HttpHeader * hdr, Packer * p); -/* field manipulation */ -extern int httpHeaderHas(const HttpHeader * hdr, http_hdr_type type); -extern void httpHeaderPutInt(HttpHeader * hdr, http_hdr_type type, int number); -extern void httpHeaderPutTime(HttpHeader * hdr, http_hdr_type type, time_t time); -extern void httpHeaderPutStr(HttpHeader * hdr, http_hdr_type type, const char *str); -extern void httpHeaderPutAuth(HttpHeader * hdr, const char *authScheme, const char *realm); -extern void httpHeaderPutCc(HttpHeader * hdr, const HttpHdrCc * cc); -extern void httpHeaderPutContRange(HttpHeader * hdr, const HttpHdrContRange * cr); -extern void httpHeaderPutRange(HttpHeader * hdr, const HttpHdrRange * range); -extern void httpHeaderPutExt(HttpHeader * hdr, const char *name, const char *value); -extern int httpHeaderGetInt(const HttpHeader * hdr, http_hdr_type id); -extern time_t httpHeaderGetTime(const HttpHeader * hdr, http_hdr_type id); -extern TimeOrTag httpHeaderGetTimeOrTag(const HttpHeader * hdr, http_hdr_type id); -extern HttpHdrCc *httpHeaderGetCc(const HttpHeader * hdr); -extern ETag httpHeaderGetETag(const HttpHeader * hdr, http_hdr_type id); -extern HttpHdrRange *httpHeaderGetRange(const HttpHeader * hdr); -extern HttpHdrContRange *httpHeaderGetContRange(const HttpHeader * hdr); -extern const char *httpHeaderGetStr(const HttpHeader * hdr, http_hdr_type id); -extern const char *httpHeaderGetLastStr(const HttpHeader * hdr, http_hdr_type id); -extern const char *httpHeaderGetAuth(const HttpHeader * hdr, http_hdr_type id, const char *authScheme); -extern String httpHeaderGetList(const HttpHeader * hdr, http_hdr_type id); -extern String httpHeaderGetStrOrList(const HttpHeader * hdr, http_hdr_type id); -extern String httpHeaderGetByName(const HttpHeader * hdr, const char *name); -extern int httpHeaderDelByName(HttpHeader * hdr, const char *name); -extern int httpHeaderDelById(HttpHeader * hdr, http_hdr_type id); -extern void httpHeaderDelAt(HttpHeader * hdr, HttpHeaderPos pos); -/* avoid using these low level routines */ -extern HttpHeaderEntry *httpHeaderGetEntry(const HttpHeader * hdr, HttpHeaderPos * pos); -extern HttpHeaderEntry *httpHeaderFindEntry(const HttpHeader * hdr, http_hdr_type id); -extern void httpHeaderAddEntry(HttpHeader * hdr, HttpHeaderEntry * e); -extern HttpHeaderEntry *httpHeaderEntryClone(const HttpHeaderEntry * e); -extern void httpHeaderEntryPackInto(const HttpHeaderEntry * e, Packer * p); -/* store report about current header usage and other stats */ -extern void httpHeaderStoreReport(StoreEntry * e); -extern void httpHdrMangleList(HttpHeader *, request_t *); - -/* Http Msg (currently in HttpReply.c @?@ ) */ -extern int httpMsgIsPersistent(http_version_t http_ver, const HttpHeader * hdr); -extern int httpMsgIsolateHeaders(const char **parse_start, const char **blk_start, const char **blk_end); - -/* Http Reply */ -extern void httpReplyInitModule(void); -/* create/destroy */ -extern HttpReply *httpReplyCreate(void); -extern void httpReplyDestroy(HttpReply * rep); -/* reset: clean, then init */ -extern void httpReplyReset(HttpReply * rep); -/* absorb: copy the contents of a new reply to the old one, destroy new one */ -extern void httpReplyAbsorb(HttpReply * rep, HttpReply * new_rep); -/* parse returns -1,0,+1 on error,need-more-data,success */ -extern int httpReplyParse(HttpReply * rep, const char *buf, ssize_t); -extern void httpReplyPackInto(const HttpReply * rep, Packer * p); -/* ez-routines */ -/* mem-pack: returns a ready to use mem buffer with a packed reply */ -extern MemBuf httpReplyPack(const HttpReply * rep); -/* swap: create swap-based packer, pack, destroy packer */ -extern void httpReplySwapOut(const HttpReply * rep, StoreEntry * e); -/* set commonly used info with one call */ -extern void httpReplySetHeaders(HttpReply * rep, http_version_t ver, http_status status, - const char *reason, const char *ctype, int clen, time_t lmt, time_t expires); -/* do everything in one call: init, set, pack, clean, return MemBuf */ -extern MemBuf httpPackedReply(http_version_t ver, http_status status, const char *ctype, - int clen, time_t lmt, time_t expires); -/* construct 304 reply and pack it into MemBuf, return MemBuf */ -extern MemBuf httpPacked304Reply(const HttpReply * rep); -/* update when 304 reply is received for a cached object */ -extern void httpReplyUpdateOnNotModified(HttpReply * rep, HttpReply * freshRep); -/* header manipulation */ -extern int httpReplyContentLen(const HttpReply * rep); -extern const char *httpReplyContentType(const HttpReply * rep); -extern time_t httpReplyExpires(const HttpReply * rep); -extern int httpReplyHasCc(const HttpReply * rep, http_hdr_cc_type type); -extern void httpRedirectReply(HttpReply *, http_status, const char *); -extern int httpReplyBodySize(method_t, HttpReply *); - -/* Http Request */ -extern request_t *requestCreate(method_t, protocol_t, const char *urlpath); -extern void requestDestroy(request_t *); -extern request_t *requestLink(request_t *); -extern void requestUnlink(request_t *); -extern int httpRequestParseHeader(request_t * req, const char *parse_start); -extern void httpRequestSwapOut(const request_t * req, StoreEntry * e); -extern void httpRequestPack(const request_t * req, Packer * p); -extern int httpRequestPrefixLen(const request_t * req); -extern int httpRequestHdrAllowed(const HttpHeaderEntry * e, String * strConnection); -extern int httpRequestHdrAllowedByName(http_hdr_type id); - -extern void icmpOpen(void); -extern void icmpClose(void); -extern void icmpPing(struct in_addr to); -extern void icmpSourcePing(struct in_addr to, const icp_common_t *, const char *url); -extern void icmpDomainPing(struct in_addr to, const char *domain); - -extern void *icpCreateMessage(icp_opcode opcode, - int flags, - const char *url, - int reqnum, - int pad); -extern int icpUdpSend(int, const struct sockaddr_in *, icp_common_t *, log_type, int); -extern PF icpHandleUdp; -extern PF icpUdpSendQueue; -extern PF httpAccept; - -#ifdef SQUID_SNMP -extern PF snmpHandleUdp; -extern void snmpInit(void); -extern void snmpConnectionOpen(void); -extern void snmpConnectionShutdown(void); -extern void snmpConnectionClose(void); -extern void snmpDebugOid(int lvl, oid * Name, snint Len); -extern void addr2oid(struct in_addr addr, oid * Dest); -extern struct in_addr *oid2addr(oid * id); -extern struct in_addr *client_entry(struct in_addr *current); -extern variable_list *snmp_basicFn(variable_list *, snint *); -extern variable_list *snmp_confFn(variable_list *, snint *); -extern variable_list *snmp_sysFn(variable_list *, snint *); -extern variable_list *snmp_prfSysFn(variable_list *, snint *); -extern variable_list *snmp_prfProtoFn(variable_list *, snint *); -extern variable_list *snmp_prfPeerFn(variable_list *, snint *); -extern variable_list *snmp_netIpFn(variable_list *, snint *); -extern variable_list *snmp_netFqdnFn(variable_list *, snint *); -#if USE_DNSSERVERS -extern variable_list *snmp_netDnsFn(variable_list *, snint *); -#else -extern variable_list *snmp_netIdnsFn(variable_list *, snint *); -#endif -extern variable_list *snmp_meshPtblFn(variable_list *, snint *); -extern variable_list *snmp_meshCtblFn(variable_list *, snint *); -#endif /* SQUID_SNMP */ - -#if USE_WCCP -extern void wccpInit(void); -extern void wccpConnectionOpen(void); -extern void wccpConnectionShutdown(void); -extern void wccpConnectionClose(void); -#endif /* USE_WCCP */ - -extern void icpHandleIcpV3(int, struct sockaddr_in, char *, int); -extern int icpCheckUdpHit(StoreEntry *, request_t * request); -extern void icpConnectionsOpen(void); -extern void icpConnectionShutdown(void); -extern void icpConnectionClose(void); -extern int icpSetCacheKey(const cache_key * key); -extern const cache_key *icpGetCacheKey(const char *url, int reqnum); - -extern void ipcache_nbgethostbyname(const char *name, - IPH * handler, - void *handlerData); -extern EVH ipcache_purgelru; -extern const ipcache_addrs *ipcache_gethostbyname(const char *, int flags); -extern void ipcacheInvalidate(const char *); -extern void ipcacheReleaseInvalid(const char *); -extern void ipcache_init(void); -extern void stat_ipcache_get(StoreEntry *); -extern int ipcacheQueueDrain(void); -extern void ipcacheCycleAddr(const char *name, ipcache_addrs *); -extern void ipcacheMarkBadAddr(const char *name, struct in_addr); -extern void ipcacheMarkGoodAddr(const char *name, struct in_addr); -extern void ipcacheFreeMemory(void); -extern ipcache_addrs *ipcacheCheckNumeric(const char *name); -extern void ipcache_restart(void); -extern int ipcacheAddEntryFromHosts(const char *name, const char *ipaddr); - -/* MemBuf */ -/* init with specific sizes */ -extern void memBufInit(MemBuf * mb, mb_size_t szInit, mb_size_t szMax); -/* init with defaults */ -extern void memBufDefInit(MemBuf * mb); -/* cleans mb; last function to call if you do not give .buf away */ -extern void memBufClean(MemBuf * mb); -/* resets mb preserving (or initializing if needed) memory buffer */ -extern void memBufReset(MemBuf * mb); -/* unfirtunate hack to test if the buffer has been Init()ialized */ -extern int memBufIsNull(MemBuf * mb); -/* calls memcpy, appends exactly size bytes, extends buffer if needed */ -extern void memBufAppend(MemBuf * mb, const char *buf, mb_size_t size); -/* calls snprintf, extends buffer if needed */ -#if STDC_HEADERS -extern void memBufPrintf(MemBuf * mb, const char *fmt,...); -#else -extern void memBufPrintf(); -#endif -/* vprintf for other printf()'s to use */ -extern void memBufVPrintf(MemBuf * mb, const char *fmt, va_list ap); -/* returns free() function to be used, _freezes_ the object! */ -extern FREE *memBufFreeFunc(MemBuf * mb); -/* puts report on MemBuf _module_ usage into mb */ -extern void memBufReport(MemBuf * mb); - -extern char *mime_get_header(const char *mime, const char *header); -extern char *mime_get_header_field(const char *mime, const char *name, const char *prefix); -extern size_t headersEnd(const char *, size_t); -extern const char *mime_get_auth(const char *hdr, const char *auth_scheme, const char **auth_field); - -extern void mimeInit(char *filename); -extern void mimeFreeMemory(void); -extern char *mimeGetContentEncoding(const char *fn); -extern char *mimeGetContentType(const char *fn); -extern char *mimeGetIcon(const char *fn); -extern const char *mimeGetIconURL(const char *fn); -extern char mimeGetTransferMode(const char *fn); -extern int mimeGetDownloadOption(const char *fn); -extern int mimeGetViewOption(const char *fn); - -extern int mcastSetTtl(int, int); -extern IPH mcastJoinGroups; - -/* Labels for hierachical log file */ -/* put them all here for easier reference when writing a logfile analyzer */ - - -extern peer *getFirstPeer(void); -extern peer *getFirstUpParent(request_t *); -extern peer *getNextPeer(peer *); -extern peer *getSingleParent(request_t *); -extern int neighborsCount(request_t *); -extern int neighborsUdpPing(request_t *, - StoreEntry *, - IRCB * callback, - void *data, - int *exprep, - int *timeout); -extern void neighborAddAcl(const char *, const char *); -extern void neighborsUdpAck(const cache_key *, icp_common_t *, const struct sockaddr_in *); -extern void neighborAdd(const char *, const char *, int, int, int, int, int); -extern void neighbors_open(int); -extern peer *peerFindByName(const char *); -extern peer *peerFindByNameAndPort(const char *, unsigned short); -extern peer *getDefaultParent(request_t * request); -extern peer *getRoundRobinParent(request_t * request); -EVH peerClearRR; -extern peer *getAnyParent(request_t * request); -extern lookup_t peerDigestLookup(peer * p, request_t * request); -extern peer *neighborsDigestSelect(request_t * request); -extern void peerNoteDigestLookup(request_t * request, peer * p, lookup_t lookup); -extern void peerNoteDigestGone(peer * p); -extern int neighborUp(const peer * e); -extern CBDUNL peerDestroy; -extern char *neighborTypeStr(const peer * e); -extern peer_t neighborType(const peer *, const request_t *); -extern void peerConnectFailed(peer *); -extern void peerConnectSucceded(peer *); -extern void dump_peer_options(StoreEntry *, peer *); -extern int peerHTTPOkay(const peer *, request_t *); -extern peer *whichPeer(const struct sockaddr_in *from); -#if USE_HTCP -extern void neighborsHtcpReply(const cache_key *, htcpReplyData *, const struct sockaddr_in *); -#endif - -extern void netdbInit(void); -extern void netdbHandlePingReply(const struct sockaddr_in *from, int hops, int rtt); -extern void netdbPingSite(const char *hostname); -extern void netdbInit(void); -extern void netdbDump(StoreEntry *); -extern int netdbHops(struct in_addr); -extern void netdbFreeMemory(void); -extern int netdbHostHops(const char *host); -extern int netdbHostRtt(const char *host); -extern int netdbHostPeerRtt(const char *host, peer * peer); -extern void netdbUpdatePeer(request_t *, peer * e, int rtt, int hops); -extern void netdbDeleteAddrNetwork(struct in_addr addr); -extern int netdbHostPeerRtt(const char *host, peer * peer); -extern void netdbBinaryExchange(StoreEntry *); -extern EVH netdbExchangeStart; -extern void netdbExchangeUpdatePeer(struct in_addr, peer *, double, double); -extern peer *netdbClosestParent(request_t *); -extern void netdbHostData(const char *host, int *samp, int *rtt, int *hops); - -extern void cachemgrStart(int fd, request_t * request, StoreEntry * entry); -extern void cachemgrRegister(const char *, const char *, OBJH *, int, int); -extern void cachemgrInit(void); - -extern void peerSelect(request_t *, StoreEntry *, PSC *, void *data); -extern void peerSelectInit(void); - -/* peer_digest.c */ -extern PeerDigest *peerDigestCreate(peer * p); -extern void peerDigestNeeded(PeerDigest * pd); -extern void peerDigestNotePeerGone(PeerDigest * pd); -extern void peerDigestStatsReport(const PeerDigest * pd, StoreEntry * e); - -/* forward.c */ -extern void fwdStart(int, StoreEntry *, request_t *); -extern DEFER fwdCheckDeferRead; -extern void fwdFail(FwdState *, ErrorState *); -extern void fwdUnregister(int fd, FwdState *); -extern void fwdComplete(FwdState * fwdState); -extern void fwdInit(void); -extern int fwdReforwardableStatus(http_status s); -extern void fwdServersFree(FwdServer ** FS); -#if WIP_FWD_LOG -extern void fwdUninit(void); -extern void fwdLogRotate(void); -extern void fwdStatus(FwdState *, http_status); -#endif - -extern void urnStart(request_t *, StoreEntry *); - -extern void redirectStart(clientHttpRequest *, RH *, void *); -extern void redirectInit(void); -extern void redirectShutdown(void); - -/* auth_modules.c */ -extern void authSchemeSetup(void); - -/* authenticate.c */ -extern void authenticateAuthUserMerge(auth_user_t *, auth_user_t *); -extern auth_user_t *authenticateAuthUserNew(const char *); -extern int authenticateAuthSchemeId(const char *typestr); -extern void authenticateStart(auth_user_request_t *, RH *, void *); -extern void authenticateSchemeInit(void); -extern void authenticateInit(authConfig *); -extern void authenticateShutdown(void); -extern void authenticateFixHeader(HttpReply *, auth_user_request_t *, request_t *, int); -extern void authenticateAddTrailer(HttpReply *, auth_user_request_t *, request_t *, int); -extern auth_user_request_t *authenticateGetAuthUser(const char *proxy_auth); -extern void authenticateAuthenticateUser(auth_user_request_t *, request_t *, ConnStateData *, http_hdr_type); -extern void authenticateAuthUserUnlock(auth_user_t * auth_user); -extern void authenticateAuthUserLock(auth_user_t * auth_user); -extern void authenticateAuthUserRequestUnlock(auth_user_request_t *); -extern void authenticateAuthUserRequestLock(auth_user_request_t *); -extern char *authenticateAuthUserRequestMessage(auth_user_request_t *); -extern int authenticateAuthUserInuse(auth_user_t * auth_user); -extern void authenticateAuthUserRequestSetIp(auth_user_request_t *, struct in_addr); -extern int authenticateDirection(auth_user_request_t *); -extern FREE authenticateFreeProxyAuthUser; -extern void authenticateFreeProxyAuthUserACLResults(void *data); -extern void authenticateProxyUserCacheCleanup(void *); -extern void authenticateInitUserCache(void); -extern int authenticateActiveSchemeCount(void); -extern int authenticateSchemeCount(void); -extern void authenticateUserNameCacheAdd(auth_user_t * auth_user); -extern int authenticateCheckAuthUserIP(struct in_addr request_src_addr, auth_user_request_t * auth_user); -extern int authenticateUserAuthenticated(auth_user_request_t *); -extern void authenticateUserCacheRestart(void); -extern char *authenticateUserUsername(auth_user_t *); -extern char *authenticateUserRequestUsername(auth_user_request_t *); -extern int authenticateValidateUser(auth_user_request_t *); -extern void authenticateOnCloseConnection(ConnStateData * conn); -extern void authSchemeAdd(char *type, AUTHSSETUP * setup); - -extern void refreshAddToList(const char *, int, time_t, int, time_t); -extern int refreshIsCachable(const StoreEntry *); -extern int refreshCheckHTTP(const StoreEntry *, request_t *); -extern int refreshCheckICP(const StoreEntry *, request_t *); -extern int refreshCheckHTCP(const StoreEntry *, request_t *); -extern int refreshCheckDigest(const StoreEntry *, time_t delta); -extern time_t getMaxAge(const char *url); -extern void refreshInit(void); - -extern void serverConnectionsClose(void); -extern void shut_down(int); - - -extern void start_announce(void *unused); -extern void sslStart(int fd, const char *, request_t *, size_t *, int *); -extern void waisStart(FwdState *); - -/* ident.c */ -#if USE_IDENT -extern void identStart(struct sockaddr_in *me, struct sockaddr_in *peer, IDCB * callback, void *cbdata); -extern void identInit(void); -#endif - -extern void statInit(void); -extern void statFreeMemory(void); -extern double median_svc_get(int, int); -extern void pconnHistCount(int, int); -extern int stat5minClientRequests(void); -extern double stat5minCPUUsage(void); -extern const char *storeEntryFlags(const StoreEntry *); -extern double statRequestHitRatio(int minutes); -extern double statRequestHitMemoryRatio(int minutes); -extern double statRequestHitDiskRatio(int minutes); -extern double statByteHitRatio(int minutes); -extern int storeEntryLocked(const StoreEntry *); - - -/* StatHist */ -extern void statHistClean(StatHist * H); -extern void statHistCount(StatHist * H, double val); -extern void statHistCopy(StatHist * Dest, const StatHist * Orig); -extern void statHistSafeCopy(StatHist * Dest, const StatHist * Orig); -extern double statHistDeltaMedian(const StatHist * A, const StatHist * B); -extern void statHistDump(const StatHist * H, StoreEntry * sentry, StatHistBinDumper bd); -extern void statHistLogInit(StatHist * H, int capacity, double min, double max); -extern void statHistEnumInit(StatHist * H, int last_enum); -extern void statHistIntInit(StatHist * H, int n); -extern StatHistBinDumper statHistEnumDumper; -extern StatHistBinDumper statHistIntDumper; - - -/* MemMeter */ -extern void memMeterSyncHWater(MemMeter * m); -#define memMeterCheckHWater(m) { if ((m).hwater_level < (m).level) memMeterSyncHWater(&(m)); } -#define memMeterInc(m) { (m).level++; memMeterCheckHWater(m); } -#define memMeterDec(m) { (m).level--; } -#define memMeterAdd(m, sz) { (m).level += (sz); memMeterCheckHWater(m); } -#define memMeterDel(m, sz) { (m).level -= (sz); } - -/* mem */ -extern void memInit(void); -extern void memClean(void); -extern void memInitModule(void); -extern void memCleanModule(void); -extern void memConfigure(void); -extern void *memAllocate(mem_type); -extern void *memAllocBuf(size_t net_size, size_t * gross_size); -extern void memFree(void *, int type); -extern void memFreeBuf(size_t size, void *); -extern void memFree2K(void *); -extern void memFree4K(void *); -extern void memFree8K(void *); -extern void memFree16K(void *); -extern void memFree32K(void *); -extern void memFree64K(void *); -extern int memInUse(mem_type); -extern size_t memTotalAllocated(void); -extern void memDataInit(mem_type, const char *, size_t, int); -extern void memCheckInit(void); - -/* MemPool */ -extern MemPool *memPoolCreate(const char *label, size_t obj_size); -extern void memPoolDestroy(MemPool * pool); -extern void *memPoolAlloc(MemPool * pool); -extern void memPoolFree(MemPool * pool, void *obj); -extern int memPoolWasUsed(const MemPool * pool); -extern int memPoolInUseCount(const MemPool * pool); -extern size_t memPoolInUseSize(const MemPool * pool); -extern int memPoolUsedCount(const MemPool * pool); -extern void memPoolReport(const MemPool * pool, StoreEntry * e); - -/* Mem */ -extern void memReport(StoreEntry * e); - -extern int stmemFreeDataUpto(mem_hdr *, int); -extern void stmemAppend(mem_hdr *, const char *, int); -extern ssize_t stmemCopy(const mem_hdr *, off_t, char *, size_t); -extern void stmemFree(mem_hdr *); -extern void stmemFreeData(mem_hdr *); - -/* ----------------------------------------------------------------- */ - -/* - * store.c - */ -extern StoreEntry *new_StoreEntry(int, const char *, const char *); -extern StoreEntry *storeGet(const cache_key *); -extern StoreEntry *storeGetPublic(const char *uri, const method_t method); -extern StoreEntry *storeGetPublicByRequest(request_t * request); -extern StoreEntry *storeGetPublicByRequestMethod(request_t * request, const method_t method); -extern StoreEntry *storeCreateEntry(const char *, const char *, request_flags, method_t); -extern void storeSetPublicKey(StoreEntry *); -extern void storeComplete(StoreEntry *); -extern void storeInit(void); -extern int storeClientWaiting(const StoreEntry *); -extern void storeAbort(StoreEntry *); -extern void storeAppend(StoreEntry *, const char *, int); -extern void storeLockObject(StoreEntry *); -extern void storeRelease(StoreEntry *); -extern int storeUnlockObject(StoreEntry *); -extern int storePendingNClients(const StoreEntry *); -extern EVH storeMaintainSwapSpace; -extern void storeExpireNow(StoreEntry *); -extern void storeReleaseRequest(StoreEntry *); -extern off_t storeLowestMemReaderOffset(const StoreEntry *); -extern void storeConfigure(void); -extern void storeNegativeCache(StoreEntry *); -extern void storeFreeMemory(void); -extern int expiresMoreThan(time_t, time_t); -extern void InvokeHandlers(StoreEntry *); -extern int storeEntryValidToSend(StoreEntry *); -extern void storeTimestampsSet(StoreEntry *); -extern void storeRegisterAbort(StoreEntry * e, STABH * cb, void *); -extern void storeUnregisterAbort(StoreEntry * e); -extern void storeMemObjectDump(MemObject * mem); -extern void storeEntryDump(const StoreEntry * e, int debug_lvl); -extern const char *storeUrl(const StoreEntry *); -extern void storeCreateMemObject(StoreEntry *, const char *, const char *); -extern void storeCopyNotModifiedReplyHeaders(MemObject * O, MemObject * N); -extern void storeBuffer(StoreEntry *); -extern void storeBufferFlush(StoreEntry *); -extern void storeHashInsert(StoreEntry * e, const cache_key *); -extern void storeSetMemStatus(StoreEntry * e, int); -#if STDC_HEADERS -extern void storeAppendPrintf(StoreEntry *, const char *,...); -#else -extern void storeAppendPrintf(); -#endif -extern void storeAppendVPrintf(StoreEntry *, const char *, va_list ap); -extern int storeCheckCachable(StoreEntry * e); -extern void storeSetPrivateKey(StoreEntry *); -extern int objectLen(const StoreEntry * e); -extern int contentLen(const StoreEntry * e); -extern HttpReply *storeEntryReply(StoreEntry *); -extern int storeTooManyDiskFilesOpen(void); -extern void storeEntryReset(StoreEntry *); -extern void storeHeapPositionUpdate(StoreEntry *, SwapDir *); -extern void storeSwapFileNumberSet(StoreEntry * e, sfileno filn); -extern void storeFsInit(void); -extern void storeFsDone(void); -extern void storeFsAdd(char *, STSETUP *); -extern void storeReplAdd(char *, REMOVALPOLICYCREATE *); - -/* store_modules.c */ -extern void storeFsSetup(void); - -/* repl_modules.c */ -extern void storeReplSetup(void); - -/* store_io.c */ -extern storeIOState *storeCreate(StoreEntry *, STFNCB *, STIOCB *, void *); -extern storeIOState *storeOpen(StoreEntry *, STFNCB *, STIOCB *, void *); -extern void storeClose(storeIOState *); -extern void storeRead(storeIOState *, char *, size_t, off_t, STRCB *, void *); -extern void storeWrite(storeIOState *, char *, size_t, off_t, FREE *); -extern void storeUnlink(StoreEntry *); -extern off_t storeOffset(storeIOState *); - -/* - * store_log.c - */ -extern void storeLog(int tag, const StoreEntry * e); -extern void storeLogRotate(void); -extern void storeLogClose(void); -extern void storeLogOpen(void); - - -/* - * store_key_*.c - */ -extern cache_key *storeKeyDup(const cache_key *); -extern cache_key *storeKeyCopy(cache_key *, const cache_key *); -extern void storeKeyFree(const cache_key *); -extern const cache_key *storeKeyScan(const char *); -extern const char *storeKeyText(const cache_key *); -extern const cache_key *storeKeyPublic(const char *, const method_t); -extern const cache_key *storeKeyPublicByRequest(request_t *); -extern const cache_key *storeKeyPublicByRequestMethod(request_t *, const method_t); -extern const cache_key *storeKeyPrivate(const char *, method_t, int); -extern int storeKeyHashBuckets(int); -extern int storeKeyNull(const cache_key *); -extern void storeKeyInit(void); -extern HASHHASH storeKeyHashHash; -extern HASHCMP storeKeyHashCmp; - -/* - * store_digest.c - */ -extern void storeDigestInit(void); -extern void storeDigestNoteStoreReady(void); -extern void storeDigestScheduleRebuild(void); -extern void storeDigestDel(const StoreEntry * entry); -extern void storeDigestReport(StoreEntry *); - -/* - * store_dir.c - */ -extern OBJH storeDirStats; -extern char *storeDirSwapLogFile(int, const char *); -extern char *storeSwapDir(int); -extern char *storeSwapFullPath(int, char *); -extern char *storeSwapSubSubDir(int, char *); -extern const char *storeSwapPath(int); -extern int storeDirWriteCleanLogs(int reopen); -extern STDIRSELECT *storeDirSelectSwapDir; -extern int storeVerifySwapDirs(void); -extern void storeCreateSwapDirectories(void); -extern void storeDirCloseSwapLogs(void); -extern void storeDirCloseTmpSwapLog(int dirn); -extern void storeDirConfigure(void); -extern void storeDirDiskFull(sdirno); -extern void storeDirInit(void); -extern void storeDirOpenSwapLogs(void); -extern void storeDirSwapLog(const StoreEntry *, int op); -extern void storeDirUpdateSwapSize(SwapDir *, size_t size, int sign); -extern void storeDirSync(void); -extern void storeDirCallback(void); -extern void storeDirLRUDelete(StoreEntry *); -extern void storeDirLRUAdd(StoreEntry *); -extern int storeDirGetBlkSize(const char *path, int *blksize); -extern int storeDirGetUFSStats(const char *, int *, int *, int *, int *); - -/* - * store_swapmeta.c - */ -extern char *storeSwapMetaPack(tlv * tlv_list, int *length); -extern tlv *storeSwapMetaBuild(StoreEntry * e); -extern tlv *storeSwapMetaUnpack(const char *buf, int *hdrlen); -extern void storeSwapTLVFree(tlv * n); - -/* - * store_rebuild.c - */ -extern void storeRebuildStart(void); -extern void storeRebuildComplete(struct _store_rebuild_data *); -extern void storeRebuildProgress(int index, int total, int sofar); - -/* - * store_swapin.c - */ -extern void storeSwapInStart(store_client *); - -/* - * store_swapout.c - */ -extern void storeSwapOut(StoreEntry * e); -extern void storeSwapOutFileClose(StoreEntry * e); -extern int storeSwapOutAble(const StoreEntry * e); - -/* - * store_client.c - */ -#if STORE_CLIENT_LIST_DEBUG -extern store_client *storeClientListSearch(const MemObject * mem, void *data); -#endif -extern store_client *storeClientListAdd(StoreEntry * e, void *data); -extern void storeClientCopy(store_client *, StoreEntry *, off_t, off_t, size_t, char *, STCB *, void *); -extern int storeClientCopyPending(store_client *, StoreEntry * e, void *data); -extern int storeUnregister(store_client * sc, StoreEntry * e, void *data); -extern off_t storeLowestMemReaderOffset(const StoreEntry * entry); -extern void InvokeHandlers(StoreEntry * e); -extern int storePendingNClients(const StoreEntry * e); - - -extern const char *getMyHostname(void); -extern const char *uniqueHostname(void); -extern void safeunlink(const char *path, int quiet); -extern void death(int sig); -extern void fatal(const char *message); -#if STDC_HEADERS -extern void fatalf(const char *fmt,...); -#else -extern void fatalf(); -#endif -extern void fatal_dump(const char *message); -extern void sigusr2_handle(int sig); -extern void sig_child(int sig); -extern void leave_suid(void); -extern void enter_suid(void); -extern void no_suid(void); -extern void writePidFile(void); -extern void setSocketShutdownLifetimes(int); -extern void setMaxFD(void); -extern time_t getCurrentTime(void); -extern int percent(int, int); -extern double dpercent(double, double); -extern void squid_signal(int sig, SIGHDLR *, int flags); -extern pid_t readPidFile(void); -extern struct in_addr inaddrFromHostent(const struct hostent *hp); -extern int intAverage(int, int, int, int); -extern double doubleAverage(double, double, int, int); -extern void debug_trap(const char *); -extern void logsFlush(void); -extern char *checkNullString(char *p); -extern void squid_getrusage(struct rusage *r); -extern double rusage_cputime(struct rusage *r); -extern int rusage_maxrss(struct rusage *r); -extern int rusage_pagefaults(struct rusage *r); -extern void releaseServerSockets(void); -extern void PrintRusage(void); -extern void dumpMallocStats(void); - -#if USE_UNLINKD -extern void unlinkdInit(void); -extern void unlinkdClose(void); -extern void unlinkdUnlink(const char *); -#endif - -extern char *url_convert_hex(char *org_url, int allocate); -extern char *url_escape(const char *url); -extern protocol_t urlParseProtocol(const char *); -extern method_t urlParseMethod(const char *); -extern void urlInitialize(void); -extern request_t *urlParse(method_t, char *); -extern const char *urlCanonical(request_t *); -extern char *urlRInternal(const char *host, u_short port, const char *dir, const char *name); -extern char *urlInternal(const char *dir, const char *name); -extern int matchDomainName(const char *host, const char *domain); -extern int urlCheckRequest(const request_t *); -extern int urlDefaultPort(protocol_t p); -extern char *urlCanonicalClean(const request_t *); -extern char *urlHostname(const char *url); -extern void urlExtMethodConfigure(void); - -extern void useragentOpenLog(void); -extern void useragentRotateLog(void); -extern void logUserAgent(const char *, const char *); -extern void refererOpenLog(void); -extern void refererRotateLog(void); -extern void logReferer(const char *, const char *, const char *); -extern peer_t parseNeighborType(const char *s); - -extern void errorInitialize(void); -extern void errorClean(void); -extern HttpReply *errorBuildReply(ErrorState * err); -extern void errorSend(int fd, ErrorState *); -extern void errorAppendEntry(StoreEntry *, ErrorState *); -extern void errorStateFree(ErrorState * err); -extern int errorReservePageId(const char *page_name); -extern ErrorState *errorCon(err_type type, http_status); - -extern void pconnPush(int, const char *host, u_short port); -extern int pconnPop(const char *host, u_short port); -extern void pconnInit(void); - -extern int asnMatchIp(void *, struct in_addr); -extern void asnInit(void); -extern void asnFreeMemory(void); - -/* tools.c */ -extern void dlinkAdd(void *data, dlink_node *, dlink_list *); -extern void dlinkAddTail(void *data, dlink_node *, dlink_list *); -extern void dlinkDelete(dlink_node * m, dlink_list * list); -extern void dlinkNodeDelete(dlink_node * m); -extern dlink_node *dlinkNodeNew(void); - -extern void kb_incr(kb_t *, size_t); -extern double gb_to_double(const gb_t *); -extern const char *gb_to_str(const gb_t *); -extern void gb_flush(gb_t *); /* internal, do not use this */ -extern int stringHasWhitespace(const char *); -extern int stringHasCntl(const char *); -extern void linklistPush(link_list **, void *); -extern void *linklistShift(link_list **); -extern int xrename(const char *from, const char *to); -extern int isPowTen(int); -extern void parseEtcHosts(void); - -#if USE_HTCP -extern void htcpInit(void); -extern void htcpQuery(StoreEntry * e, request_t * req, peer * p); -extern void htcpSocketShutdown(void); -extern void htcpSocketClose(void); -#endif - -/* String */ -#define strLen(s) ((/* const */ int)(s).len) -#define strBuf(s) ((const char*)(s).buf) -#define strChr(s,ch) ((const char*)strchr(strBuf(s), (ch))) -#define strRChr(s,ch) ((const char*)strrchr(strBuf(s), (ch))) -#define strStr(s,str) ((const char*)strstr(strBuf(s), (str))) -#define strCmp(s,str) strcmp(strBuf(s), (str)) -#define strNCmp(s,str,n) strncmp(strBuf(s), (str), (n)) -#define strCaseCmp(s,str) strcasecmp(strBuf(s), (str)) -#define strNCaseCmp(s,str,n) strncasecmp(strBuf(s), (str), (n)) -#define strSet(s,ptr,ch) (s).buf[ptr-(s).buf] = (ch) -#define strCut(s,pos) (((s).len = pos) , ((s).buf[pos] = '\0')) -#define strCutPtr(s,ptr) (((s).len = (ptr)-(s).buf) , ((s).buf[(s).len] = '\0')) -/* #define strCat(s,str) stringAppend(&(s), (str), strlen(str)+1) */ -extern void stringInit(String * s, const char *str); -extern void stringLimitInit(String * s, const char *str, int len); -extern String stringDup(const String * s); -extern void stringClean(String * s); -extern void stringReset(String * s, const char *str); -extern void stringAppend(String * s, const char *buf, int len); -/* extern void stringAppendf(String *s, const char *fmt, ...); */ - -/* - * ipc.c - */ -extern int ipcCreate(int type, - const char *prog, - char *const args[], - const char *name, - int *rfd, - int *wfd); - -/* CacheDigest */ -extern CacheDigest *cacheDigestCreate(int capacity, int bpe); -extern void cacheDigestDestroy(CacheDigest * cd); -extern CacheDigest *cacheDigestClone(const CacheDigest * cd); -extern void cacheDigestClear(CacheDigest * cd); -extern void cacheDigestChangeCap(CacheDigest * cd, int new_cap); -extern int cacheDigestTest(const CacheDigest * cd, const cache_key * key); -extern void cacheDigestAdd(CacheDigest * cd, const cache_key * key); -extern void cacheDigestDel(CacheDigest * cd, const cache_key * key); -extern size_t cacheDigestCalcMaskSize(int cap, int bpe); -extern int cacheDigestBitUtil(const CacheDigest * cd); -extern void cacheDigestGuessStatsUpdate(cd_guess_stats * stats, int real_hit, int guess_hit); -extern void cacheDigestGuessStatsReport(const cd_guess_stats * stats, StoreEntry * sentry, const char *label); -extern void cacheDigestReport(CacheDigest * cd, const char *label, StoreEntry * e); - -extern void internalStart(request_t *, StoreEntry *); -extern int internalCheck(const char *urlpath); -extern int internalStaticCheck(const char *urlpath); -extern char *internalLocalUri(const char *dir, const char *name); -extern char *internalRemoteUri(const char *, u_short, const char *, const char *); -extern const char *internalHostname(void); -extern int internalHostnameIs(const char *); - -#if USE_CARP -extern void carpInit(void); -extern peer *carpSelectParent(request_t *); -#endif - -#if DELAY_POOLS -extern void delayPoolsInit(void); -extern void delayInitDelayData(unsigned short pools); -extern void delayFreeDelayData(void); -extern void delayCreateDelayPool(unsigned short pool, u_char class); -extern void delayInitDelayPool(unsigned short pool, u_char class, delaySpecSet * rates); -extern void delayFreeDelayPool(unsigned short pool); -extern void delayPoolsReconfigure(void); -extern void delaySetNoDelay(int fd); -extern void delayClearNoDelay(int fd); -extern int delayIsNoDelay(int fd); -extern delay_id delayClient(request_t *); -extern EVH delayPoolsUpdate; -extern int delayBytesWanted(delay_id d, int min, int max); -extern void delayBytesIn(delay_id, int qty); -extern int delayMostBytesWanted(const MemObject * mem, int max); -extern delay_id delayMostBytesAllowed(const MemObject * mem); -extern void delaySetStoreClient(store_client * sc, delay_id delay_id); -extern void delayRegisterDelayIdPtr(delay_id * loc); -extern void delayUnregisterDelayIdPtr(delay_id * loc); -#endif - -/* helper.c */ -extern void helperOpenServers(helper * hlp); -extern void helperStatefulOpenServers(statefulhelper * hlp); -extern void helperSubmit(helper * hlp, const char *buf, HLPCB * callback, void *data); -extern void helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPSCB * callback, void *data, helper_stateful_server * lastserver); -extern void helperStats(StoreEntry * sentry, helper * hlp); -extern void helperStatefulStats(StoreEntry * sentry, statefulhelper * hlp); -extern void helperShutdown(helper * hlp); -extern void helperStatefulShutdown(statefulhelper * hlp); -extern helper *helperCreate(const char *); -extern statefulhelper *helperStatefulCreate(const char *); -extern void helperFree(helper *); -extern void helperStatefulFree(statefulhelper *); -extern void helperStatefulReset(helper_stateful_server * srv); -extern void helperStatefulReleaseServer(helper_stateful_server * srv); -extern void *helperStatefulServerGetData(helper_stateful_server * srv); -extern helper_stateful_server *helperStatefulDefer(statefulhelper *); - - - -#if USE_LEAKFINDER -extern void leakInit(void); -extern void *leakAddFL(void *, const char *, int); -extern void *leakTouchFL(void *, const char *, int); -extern void *leakFreeFL(void *, const char *, int); -#endif - -/* logfile.c */ -extern Logfile *logfileOpen(const char *path, size_t bufsz, int); -extern void logfileClose(Logfile * lf); -extern void logfileRotate(Logfile * lf); -extern void logfileWrite(Logfile * lf, void *buf, size_t len); -extern void logfileFlush(Logfile * lf); -#if STDC_HEADERS -extern void logfilePrintf(Logfile * lf, const char *fmt,...); -#else -extern void logfilePrintf(va_alist); -#endif - -/* - * Removal Policies - */ -extern RemovalPolicy *createRemovalPolicy(RemovalPolicySettings * settings); - -/* - * prototypes for system functions missing from system includes - */ - -#ifdef _SQUID_SOLARIS_ -extern int getrusage(int, struct rusage *); -extern int getpagesize(void); -extern int gethostname(char *, int); -#endif - -#if URL_CHECKSUM_DEBUG -extern unsigned int url_checksum(const char *url); -#endif - -/* - * hack to allow snmp access to the statistics counters - */ -extern StatCounters *snmpStatGet(int); - -/* Vary support functions */ -int varyEvaluateMatch(StoreEntry * entry, request_t * req); - -/* CygWin & Windows NT Port */ -/* win32.c */ -#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) -extern void WIN32_Subsystem_Shutdown(); -extern void WIN32_Subsystem_Init(); -/*VOID ServiceExit(int); -void InstallService(void); -void RemoveService(void); -extern int store_key(const char *, DWORD, unsigned char *, int);*/ - - -#endif + +/* + * $Id: protos.h,v 1.9.2.5 2001/04/27 17:06:45 serassio Exp $ + * + * + * SQUID Web Proxy Cache http://www.squid-cache.org/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from + * the Internet community; see the CONTRIBUTORS file for full + * details. Many organizations have provided support for Squid's + * development; see the SPONSORS file for full details. Squid is + * Copyrighted (C) 2001 by the Regents of the University of + * California; see the COPYRIGHT file for full details. Squid + * incorporates software developed and/or copyrighted by other + * sources; see the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +extern void accessLogLog(AccessLogEntry *); +extern void accessLogRotate(void); +extern void accessLogClose(void); +extern void accessLogInit(void); +extern const char *accessLogTime(time_t); +extern void hierarchyNote(HierarchyLogEntry *, hier_code, const char *); +#if FORW_VIA_DB +extern void fvdbCountVia(const char *key); +extern void fvdbCountForw(const char *key); +#endif +#if HEADERS_LOG +extern void headersLog(int cs, int pq, method_t m, void *data); +#endif +char *log_quote(const char *header); + +/* acl.c */ +extern aclCheck_t *aclChecklistCreate(const struct _acl_access *, + request_t *, const char *ident); +extern void aclNBCheck(aclCheck_t *, PF *, void *); +extern int aclCheckFast(const struct _acl_access *A, aclCheck_t *); +extern void aclChecklistFree(aclCheck_t *); +extern int aclMatchAclList(const acl_list * list, aclCheck_t * checklist); +extern void aclDestroyAccessList(struct _acl_access **list); +extern void aclDestroyAcls(acl **); +extern void aclParseAccessLine(struct _acl_access **); +extern void aclParseAclLine(acl **); +extern int aclIsProxyAuth(const char *name); +extern err_type aclGetDenyInfoPage(acl_deny_info_list ** head, + const char *name); +extern void aclParseDenyInfoLine(struct _acl_deny_info_list **); +extern void aclDestroyDenyInfoList(struct _acl_deny_info_list **); +extern void aclDestroyRegexList(struct _relist *data); +extern int aclMatchRegex(relist * data, const char *word); +extern void aclParseRegexList(void *curlist); +extern const char *aclTypeToStr(squid_acl); +extern wordlist *aclDumpGeneric(const acl *); +extern int aclPurgeMethodInUse(acl_access *); +extern void aclCacheMatchFlush(dlink_list * cache); + +/* + * cache_cf.c + */ +extern int parseConfigFile(const char *file_name); +extern void intlistDestroy(intlist **); +extern int intlistFind(intlist * list, int i); +extern const char *wordlistAdd(wordlist **, const char *); +extern void wordlistAddWl(wordlist **, wordlist *); +extern void wordlistJoin(wordlist **, wordlist **); +extern wordlist *wordlistDup(const wordlist *); +extern void wordlistDestroy(wordlist **); +extern void configFreeMemory(void); +extern void wordlistCat(const wordlist *, MemBuf * mb); +extern void allocate_new_swapdir(cacheSwap *); +extern void self_destruct(void); +extern int GetInteger(void); + +/* extra functions from cache_cf.c useful for lib modules */ +extern void parse_int(int *var); +extern void parse_eol(char *volatile *var); +extern void parse_wordlist(wordlist ** list); +extern void requirePathnameExists(const char *name, const char *path); +extern void parse_time_t(time_t * var); +extern void parse_cachedir_options(SwapDir * sd, + struct cache_dir_option *options, int reconfiguring); + + +/* + * cbdata.c + */ +extern void cbdataInit(void); +#if CBDATA_DEBUG +extern void *cbdataInternalAllocDbg(cbdata_type type, int, const char *); +extern void cbdataLockDbg(const void *p, const char *, int); +extern void cbdataUnlockDbg(const void *p, const char *, int); +#else +extern void *cbdataInternalAlloc(cbdata_type type); +extern void cbdataLock(const void *p); +extern void cbdataUnlock(const void *p); +#endif +/* Note: Allocations is done using the cbdataAlloc macro */ +extern void *cbdataInternalFree(void *p); +extern int cbdataValid(const void *p); +extern void cbdataInitType(cbdata_type type, char *label, int size, + FREE * free_func); +extern cbdata_type cbdataAddType(cbdata_type type, char *label, int size, + FREE * free_func); +extern int cbdataLocked(const void *p); + +extern void clientdbInit(void); +extern void clientdbUpdate(struct in_addr, log_type, protocol_t, size_t); +extern int clientdbCutoffDenied(struct in_addr); +extern void clientdbDump(StoreEntry *); +extern void clientdbFreeMemory(void); +extern int clientdbEstablished(struct in_addr, int); + +extern void clientAccessCheck(void *); +extern void clientAccessCheckDone(int, void *); +extern int modifiedSince(StoreEntry *, request_t *); +extern char *clientConstructTraceEcho(clientHttpRequest *); +extern void clientPurgeRequest(clientHttpRequest *); +extern int checkNegativeHit(StoreEntry *); +extern void clientHttpConnectionsOpen(void); +extern void clientHttpConnectionsClose(void); +extern StoreEntry *clientCreateStoreEntry(clientHttpRequest *, method_t, + request_flags); +extern int isTcpHit(log_type); +extern void clientReadBody(request_t * req, char *buf, size_t size, + CBCB * callback, void *data); +extern int clientAbortBody(request_t * req); + +extern int commSetNonBlocking(int fd); +extern int commUnsetNonBlocking(int fd); +extern void commSetCloseOnExec(int fd); +extern int comm_accept(int fd, struct sockaddr_in *, struct sockaddr_in *); +extern void comm_close(int fd); +#if LINGERING_CLOSE +extern void comm_lingering_close(int fd); +#endif +extern void commConnectStart(int fd, const char *, u_short, CNCB *, void *); +extern int comm_connect_addr(int sock, const struct sockaddr_in *); +extern void comm_init(void); +extern int comm_listen(int sock); +extern int comm_open(int, int, struct in_addr, u_short port, int, + const char *note); +extern u_short comm_local_port(int fd); + +extern void commSetSelect(int, unsigned int, PF *, void *, time_t); +extern void comm_add_close_handler(int fd, PF *, void *); +extern void comm_remove_close_handler(int fd, PF *, void *); +extern int comm_udp_sendto(int, const struct sockaddr_in *, int, const void *, + int); +extern void comm_write(int fd, char *buf, int size, CWCB * handler, + void *handler_data, FREE *); +extern void comm_write_mbuf(int fd, MemBuf mb, CWCB * handler, + void *handler_data); +extern void commCallCloseHandlers(int fd); +extern int commSetTimeout(int fd, int, PF *, void *); +extern void commSetDefer(int fd, DEFER * func, void *); +extern int ignoreErrno(int); +extern void commCloseAllSockets(void); + + +/* + * comm_select.c + */ +extern void comm_select_init(void); +#if HAVE_POLL +extern int comm_poll(int); +#else +extern int comm_select(int); +#endif +extern void commUpdateReadBits(int, PF *); +extern void commUpdateWriteBits(int, PF *); +extern void comm_quick_poll_required(void); + +extern void packerToStoreInit(Packer * p, StoreEntry * e); +extern void packerToMemInit(Packer * p, MemBuf * mb); +extern void packerClean(Packer * p); +extern void packerAppend(Packer * p, const char *buf, int size); +#if STDC_HEADERS +extern void packerPrintf(Packer * p, const char *fmt, ...); +#else +extern void packerPrintf(); +#endif + + +/* see debug.c for info on context-based debugging */ +extern Ctx ctx_enter(const char *descr); +extern void ctx_exit(Ctx ctx); + +extern void _db_init(const char *logfile, const char *options); +extern void _db_rotate_log(void); + +#if STDC_HEADERS +extern void _db_print(const char *, ...); +#else +extern void _db_print(); +#endif +extern void xassert(const char *, const char *, int); + +/* packs, then prints an object using debug() */ +extern void debugObj(int section, int level, const char *label, void *obj, + ObjPackMethod pm); + +/* disk.c */ +extern int file_open(const char *path, int mode); +extern void file_close(int fd); +extern void file_write(int, off_t, void *, int len, DWCB *, void *, FREE *); +extern void file_write_mbuf(int fd, off_t, MemBuf mb, DWCB * handler, + void *handler_data); +extern void file_read(int, char *, int, off_t, DRCB *, void *); +extern void disk_init(void); + +/* diskd.c */ +extern diskd_queue *afile_create_queue(void); +extern void afile_destroy_queue(diskd_queue *); +extern void afile_sync_queue(diskd_queue *); +extern void afile_sync(void); +extern void afile_open(const char *path, int mode, DOCB *, void *); +extern void afile_close(int fd, DCCB * callback, void *data); +extern void afile_write(int, off_t, void *, int len, DWCB *, void *, FREE *); +extern void afile_write_mbuf(int fd, off_t, MemBuf, DWCB *, void *); +extern void afile_read(int, char *, int, off_t, DRCB *, void *); +extern void afile_unlink(const char *path, DUCB *, void *); +extern void afile_truncate(const char *path, DTCB *, void *); + +extern void dnsShutdown(void); +extern void dnsInit(void); +extern void dnsSubmit(const char *lookup, HLPCB * callback, void *data); + +/* dns_internal.c */ +extern void idnsInit(void); +extern void idnsShutdown(void); +extern void idnsALookup(const char *, IDNSCB *, void *); +extern void idnsPTRLookup(const struct in_addr, IDNSCB *, void *); + +extern void eventAdd(const char *name, EVH * func, void *arg, double when, int); +extern void eventAddIsh(const char *name, EVH * func, void *arg, + double delta_ish, int); +extern void eventRun(void); +extern time_t eventNextTime(void); +extern void eventDelete(EVH * func, void *arg); +extern void eventInit(void); +extern void eventFreeMemory(void); +extern int eventFind(EVH *, void *); + +extern void fd_close(int fd); +extern void fd_open(int fd, unsigned int type, const char *); +extern void fd_note(int fd, const char *); +extern void fd_bytes(int fd, int len, unsigned int type); +extern void fdFreeMemory(void); +extern void fdDumpOpen(void); +extern int fdNFree(void); +extern void fdAdjustReserved(void); + +extern fileMap *file_map_create(void); +extern int file_map_allocate(fileMap *, int); +extern int file_map_bit_set(fileMap *, int); +extern int file_map_bit_test(fileMap *, int); +extern void file_map_bit_reset(fileMap *, int); +extern void filemapFreeMemory(fileMap *); + + +extern void fqdncache_nbgethostbyaddr(struct in_addr, FQDNH *, void *); +extern const char *fqdncache_gethostbyaddr(struct in_addr, int flags); +extern void fqdncache_init(void); +extern void fqdnStats(StoreEntry *); +extern void fqdncacheReleaseInvalid(const char *); +extern const char *fqdnFromAddr(struct in_addr); +extern int fqdncacheQueueDrain(void); +extern void fqdncacheFreeMemory(void); +extern void fqdncache_restart(void); +extern EVH fqdncache_purgelru; +extern void fqdncacheAddEntryFromHosts(char *addr, wordlist * hostnames); + +extern void ftpStart(FwdState *); +extern char *ftpUrlWith2f(const request_t *); + +extern void gopherStart(FwdState *); +extern int gopherCachable(const char *); + + +extern void whoisStart(FwdState *); + +/* http.c */ +extern int httpCachable(method_t); +extern void httpStart(FwdState *); +extern void httpParseReplyHeaders(const char *, http_reply *); +extern void httpProcessReplyHeader(HttpStateData *, const char *, int); +extern mb_size_t httpBuildRequestPrefix(request_t * request, + request_t * orig_request, + StoreEntry * entry, MemBuf * mb, int cfd, http_state_flags); +extern void httpAnonInitModule(void); +extern int httpAnonHdrAllowed(http_hdr_type hdr_id); +extern int httpAnonHdrDenied(http_hdr_type hdr_id); +extern void httpBuildRequestHeader(request_t *, request_t *, StoreEntry *, + HttpHeader *, int, http_state_flags); +extern void httpBuildVersion(http_version_t * version, unsigned int major, + unsigned int minor); +extern const char *httpMakeVaryMark(request_t * request, HttpReply * reply); + +/* ETag */ +extern int etagParseInit(ETag * etag, const char *str); +extern int etagIsEqual(const ETag * tag1, const ETag * tag2); + +/* Http Status Line */ +/* init/clean */ +extern void httpStatusLineInit(HttpStatusLine * sline); +extern void httpStatusLineClean(HttpStatusLine * sline); +/* set/get values */ +extern void httpStatusLineSet(HttpStatusLine * sline, http_version_t version, + http_status status, const char *reason); +extern const char *httpStatusLineReason(const HttpStatusLine * sline); +/* parse/pack */ +/* parse a 0-terminating buffer and fill internal structires; returns true on success */ +extern int httpStatusLineParse(HttpStatusLine * sline, const char *start, + const char *end); +/* pack fields using Packer */ +extern void httpStatusLinePackInto(const HttpStatusLine * sline, Packer * p); +extern const char *httpStatusString(http_status status); + +/* Http Body */ +/* init/clean */ +extern void httpBodyInit(HttpBody * body); +extern void httpBodyClean(HttpBody * body); +/* get body ptr (always use this) */ +extern const char *httpBodyPtr(const HttpBody * body); +/* set body, does not clone mb so you should not reuse it */ +extern void httpBodySet(HttpBody * body, MemBuf * mb); + +/* pack */ +extern void httpBodyPackInto(const HttpBody * body, Packer * p); + +/* Http Cache Control Header Field */ +extern void httpHdrCcInitModule(void); +extern void httpHdrCcCleanModule(void); +extern HttpHdrCc *httpHdrCcCreate(void); +extern HttpHdrCc *httpHdrCcParseCreate(const String * str); +extern void httpHdrCcDestroy(HttpHdrCc * cc); +extern HttpHdrCc *httpHdrCcDup(const HttpHdrCc * cc); +extern void httpHdrCcPackInto(const HttpHdrCc * cc, Packer * p); +extern void httpHdrCcJoinWith(HttpHdrCc * cc, const HttpHdrCc * new_cc); +extern void httpHdrCcSetMaxAge(HttpHdrCc * cc, int max_age); +extern void httpHdrCcSetSMaxAge(HttpHdrCc * cc, int s_maxage); +extern void httpHdrCcUpdateStats(const HttpHdrCc * cc, StatHist * hist); +extern void httpHdrCcStatDumper(StoreEntry * sentry, int idx, double val, + double size, int count); + +/* Http Range Header Field */ +extern HttpHdrRange *httpHdrRangeParseCreate(const String * range_spec); +/* returns true if ranges are valid; inits HttpHdrRange */ +extern int httpHdrRangeParseInit(HttpHdrRange * range, + const String * range_spec); +extern void httpHdrRangeDestroy(HttpHdrRange * range); +extern HttpHdrRange *httpHdrRangeDup(const HttpHdrRange * range); +extern void httpHdrRangePackInto(const HttpHdrRange * range, Packer * p); +/* iterate through specs */ +extern HttpHdrRangeSpec *httpHdrRangeGetSpec(const HttpHdrRange * range, + HttpHdrRangePos * pos); +/* adjust specs after the length is known */ +extern int httpHdrRangeCanonize(HttpHdrRange *, ssize_t); +/* other */ +extern String httpHdrRangeBoundaryStr(clientHttpRequest * http); +extern int httpHdrRangeIsComplex(const HttpHdrRange * range); +extern int httpHdrRangeWillBeComplex(const HttpHdrRange * range); +extern ssize_t httpHdrRangeFirstOffset(const HttpHdrRange * range); +extern ssize_t httpHdrRangeLowestOffset(const HttpHdrRange * range, ssize_t); +extern int httpHdrRangeOffsetLimit(HttpHdrRange *); + + +/* Http Content Range Header Field */ +extern HttpHdrContRange *httpHdrContRangeCreate(void); +extern HttpHdrContRange *httpHdrContRangeParseCreate(const char *crange_spec); +/* returns true if range is valid; inits HttpHdrContRange */ +extern int httpHdrContRangeParseInit(HttpHdrContRange * crange, + const char *crange_spec); +extern void httpHdrContRangeDestroy(HttpHdrContRange * crange); +extern HttpHdrContRange *httpHdrContRangeDup(const HttpHdrContRange * crange); +extern void httpHdrContRangePackInto(const HttpHdrContRange * crange, + Packer * p); +/* inits with given spec */ +extern void httpHdrContRangeSet(HttpHdrContRange *, HttpHdrRangeSpec, ssize_t); + +/* Http Header Tools */ +extern HttpHeaderFieldInfo *httpHeaderBuildFieldsInfo(const HttpHeaderFieldAttrs + * attrs, int count); +extern void httpHeaderDestroyFieldsInfo(HttpHeaderFieldInfo * info, int count); +extern int httpHeaderIdByName(const char *name, int name_len, + const HttpHeaderFieldInfo * attrs, int end); +extern int httpHeaderIdByNameDef(const char *name, int name_len); +extern const char *httpHeaderNameById(int id); +extern void httpHeaderMaskInit(HttpHeaderMask * mask, int value); +extern void httpHeaderCalcMask(HttpHeaderMask * mask, const int *enums, + int count); +extern int httpHeaderHasConnDir(const HttpHeader * hdr, const char *directive); +extern void httpHeaderAddContRange(HttpHeader *, HttpHdrRangeSpec, ssize_t); +extern void strListAdd(String * str, const char *item, char del); +extern int strListIsMember(const String * str, const char *item, char del); +extern int strListIsSubstr(const String * list, const char *s, char del); +extern int strListGetItem(const String * str, char del, const char **item, + int *ilen, const char **pos); +extern const char *getStringPrefix(const char *str, const char *end); +extern int httpHeaderParseInt(const char *start, int *val); +extern int httpHeaderParseSize(const char *start, ssize_t * sz); +extern int httpHeaderReset(HttpHeader * hdr); +#if STDC_HEADERS +extern void httpHeaderPutStrf(HttpHeader * hdr, http_hdr_type id, + const char *fmt, ...); +#else +extern void httpHeaderPutStrf(); +#endif + + +/* Http Header */ +extern void httpHeaderInitModule(void); +extern void httpHeaderCleanModule(void); +/* init/clean */ +extern void httpHeaderInit(HttpHeader * hdr, http_hdr_owner_type owner); +extern void httpHeaderClean(HttpHeader * hdr); +/* append/update */ +extern void httpHeaderAppend(HttpHeader * dest, const HttpHeader * src); +extern void httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh, + const HttpHeaderMask * denied_mask); +/* parse/pack */ +extern int httpHeaderParse(HttpHeader * hdr, const char *header_start, + const char *header_end); +extern void httpHeaderPackInto(const HttpHeader * hdr, Packer * p); +/* field manipulation */ +extern int httpHeaderHas(const HttpHeader * hdr, http_hdr_type type); +extern void httpHeaderPutInt(HttpHeader * hdr, http_hdr_type type, int number); +extern void httpHeaderPutTime(HttpHeader * hdr, http_hdr_type type, + time_t time); +extern void httpHeaderPutStr(HttpHeader * hdr, http_hdr_type type, + const char *str); +extern void httpHeaderPutAuth(HttpHeader * hdr, const char *authScheme, + const char *realm); +extern void httpHeaderPutCc(HttpHeader * hdr, const HttpHdrCc * cc); +extern void httpHeaderPutContRange(HttpHeader * hdr, + const HttpHdrContRange * cr); +extern void httpHeaderPutRange(HttpHeader * hdr, const HttpHdrRange * range); +extern void httpHeaderPutExt(HttpHeader * hdr, const char *name, + const char *value); +extern int httpHeaderGetInt(const HttpHeader * hdr, http_hdr_type id); +extern time_t httpHeaderGetTime(const HttpHeader * hdr, http_hdr_type id); +extern TimeOrTag httpHeaderGetTimeOrTag(const HttpHeader * hdr, + http_hdr_type id); +extern HttpHdrCc *httpHeaderGetCc(const HttpHeader * hdr); +extern ETag httpHeaderGetETag(const HttpHeader * hdr, http_hdr_type id); +extern HttpHdrRange *httpHeaderGetRange(const HttpHeader * hdr); +extern HttpHdrContRange *httpHeaderGetContRange(const HttpHeader * hdr); +extern const char *httpHeaderGetStr(const HttpHeader * hdr, http_hdr_type id); +extern const char *httpHeaderGetLastStr(const HttpHeader * hdr, + http_hdr_type id); +extern const char *httpHeaderGetAuth(const HttpHeader * hdr, http_hdr_type id, + const char *authScheme); +extern String httpHeaderGetList(const HttpHeader * hdr, http_hdr_type id); +extern String httpHeaderGetStrOrList(const HttpHeader * hdr, http_hdr_type id); +extern String httpHeaderGetByName(const HttpHeader * hdr, const char *name); +extern int httpHeaderDelByName(HttpHeader * hdr, const char *name); +extern int httpHeaderDelById(HttpHeader * hdr, http_hdr_type id); +extern void httpHeaderDelAt(HttpHeader * hdr, HttpHeaderPos pos); +/* avoid using these low level routines */ +extern HttpHeaderEntry *httpHeaderGetEntry(const HttpHeader * hdr, + HttpHeaderPos * pos); +extern HttpHeaderEntry *httpHeaderFindEntry(const HttpHeader * hdr, + http_hdr_type id); +extern void httpHeaderAddEntry(HttpHeader * hdr, HttpHeaderEntry * e); +extern HttpHeaderEntry *httpHeaderEntryClone(const HttpHeaderEntry * e); +extern void httpHeaderEntryPackInto(const HttpHeaderEntry * e, Packer * p); +/* store report about current header usage and other stats */ +extern void httpHeaderStoreReport(StoreEntry * e); +extern void httpHdrMangleList(HttpHeader *, request_t *); + +/* Http Msg (currently in HttpReply.c @?@ ) */ +extern int httpMsgIsPersistent(http_version_t http_ver, const HttpHeader * hdr); +extern int httpMsgIsolateHeaders(const char **parse_start, + const char **blk_start, const char **blk_end); + +/* Http Reply */ +extern void httpReplyInitModule(void); +/* create/destroy */ +extern HttpReply *httpReplyCreate(void); +extern void httpReplyDestroy(HttpReply * rep); +/* reset: clean, then init */ +extern void httpReplyReset(HttpReply * rep); +/* absorb: copy the contents of a new reply to the old one, destroy new one */ +extern void httpReplyAbsorb(HttpReply * rep, HttpReply * new_rep); +/* parse returns -1,0,+1 on error,need-more-data,success */ +extern int httpReplyParse(HttpReply * rep, const char *buf, ssize_t); +extern void httpReplyPackInto(const HttpReply * rep, Packer * p); +/* ez-routines */ +/* mem-pack: returns a ready to use mem buffer with a packed reply */ +extern MemBuf httpReplyPack(const HttpReply * rep); +/* swap: create swap-based packer, pack, destroy packer */ +extern void httpReplySwapOut(const HttpReply * rep, StoreEntry * e); +/* set commonly used info with one call */ +extern void httpReplySetHeaders(HttpReply * rep, http_version_t ver, + http_status status, const char *reason, const char *ctype, int clen, + time_t lmt, time_t expires); +/* do everything in one call: init, set, pack, clean, return MemBuf */ +extern MemBuf httpPackedReply(http_version_t ver, http_status status, + const char *ctype, int clen, time_t lmt, time_t expires); +/* construct 304 reply and pack it into MemBuf, return MemBuf */ +extern MemBuf httpPacked304Reply(const HttpReply * rep); +/* update when 304 reply is received for a cached object */ +extern void httpReplyUpdateOnNotModified(HttpReply * rep, HttpReply * freshRep); +/* header manipulation */ +extern int httpReplyContentLen(const HttpReply * rep); +extern const char *httpReplyContentType(const HttpReply * rep); +extern time_t httpReplyExpires(const HttpReply * rep); +extern int httpReplyHasCc(const HttpReply * rep, http_hdr_cc_type type); +extern void httpRedirectReply(HttpReply *, http_status, const char *); +extern int httpReplyBodySize(method_t, HttpReply *); + +/* Http Request */ +extern request_t *requestCreate(method_t, protocol_t, const char *urlpath); +extern void requestDestroy(request_t *); +extern request_t *requestLink(request_t *); +extern void requestUnlink(request_t *); +extern int httpRequestParseHeader(request_t * req, const char *parse_start); +extern void httpRequestSwapOut(const request_t * req, StoreEntry * e); +extern void httpRequestPack(const request_t * req, Packer * p); +extern int httpRequestPrefixLen(const request_t * req); +extern int httpRequestHdrAllowed(const HttpHeaderEntry * e, + String * strConnection); +extern int httpRequestHdrAllowedByName(http_hdr_type id); + +extern void icmpOpen(void); +extern void icmpClose(void); +extern void icmpPing(struct in_addr to); +extern void icmpSourcePing(struct in_addr to, const icp_common_t *, + const char *url); +extern void icmpDomainPing(struct in_addr to, const char *domain); + +extern void *icpCreateMessage(icp_opcode opcode, + int flags, const char *url, int reqnum, int pad); +extern int icpUdpSend(int, const struct sockaddr_in *, icp_common_t *, log_type, + int); +extern PF icpHandleUdp; +extern PF icpUdpSendQueue; +extern PF httpAccept; + +#ifdef SQUID_SNMP +extern PF snmpHandleUdp; +extern void snmpInit(void); +extern void snmpConnectionOpen(void); +extern void snmpConnectionShutdown(void); +extern void snmpConnectionClose(void); +extern void snmpDebugOid(int lvl, oid * Name, snint Len); +extern void addr2oid(struct in_addr addr, oid * Dest); +extern struct in_addr *oid2addr(oid * id); +extern struct in_addr *client_entry(struct in_addr *current); +extern variable_list *snmp_basicFn(variable_list *, snint *); +extern variable_list *snmp_confFn(variable_list *, snint *); +extern variable_list *snmp_sysFn(variable_list *, snint *); +extern variable_list *snmp_prfSysFn(variable_list *, snint *); +extern variable_list *snmp_prfProtoFn(variable_list *, snint *); +extern variable_list *snmp_prfPeerFn(variable_list *, snint *); +extern variable_list *snmp_netIpFn(variable_list *, snint *); +extern variable_list *snmp_netFqdnFn(variable_list *, snint *); +#if USE_DNSSERVERS +extern variable_list *snmp_netDnsFn(variable_list *, snint *); +#else +extern variable_list *snmp_netIdnsFn(variable_list *, snint *); +#endif +extern variable_list *snmp_meshPtblFn(variable_list *, snint *); +extern variable_list *snmp_meshCtblFn(variable_list *, snint *); +#endif /* SQUID_SNMP */ + +#if USE_WCCP +extern void wccpInit(void); +extern void wccpConnectionOpen(void); +extern void wccpConnectionShutdown(void); +extern void wccpConnectionClose(void); +#endif /* USE_WCCP */ + +extern void icpHandleIcpV3(int, struct sockaddr_in, char *, int); +extern int icpCheckUdpHit(StoreEntry *, request_t * request); +extern void icpConnectionsOpen(void); +extern void icpConnectionShutdown(void); +extern void icpConnectionClose(void); +extern int icpSetCacheKey(const cache_key * key); +extern const cache_key *icpGetCacheKey(const char *url, int reqnum); + +extern void ipcache_nbgethostbyname(const char *name, + IPH * handler, void *handlerData); +extern EVH ipcache_purgelru; +extern const ipcache_addrs *ipcache_gethostbyname(const char *, int flags); +extern void ipcacheInvalidate(const char *); +extern void ipcacheReleaseInvalid(const char *); +extern void ipcache_init(void); +extern void stat_ipcache_get(StoreEntry *); +extern int ipcacheQueueDrain(void); +extern void ipcacheCycleAddr(const char *name, ipcache_addrs *); +extern void ipcacheMarkBadAddr(const char *name, struct in_addr); +extern void ipcacheMarkGoodAddr(const char *name, struct in_addr); +extern void ipcacheFreeMemory(void); +extern ipcache_addrs *ipcacheCheckNumeric(const char *name); +extern void ipcache_restart(void); +extern int ipcacheAddEntryFromHosts(const char *name, const char *ipaddr); + +/* MemBuf */ +/* init with specific sizes */ +extern void memBufInit(MemBuf * mb, mb_size_t szInit, mb_size_t szMax); +/* init with defaults */ +extern void memBufDefInit(MemBuf * mb); +/* cleans mb; last function to call if you do not give .buf away */ +extern void memBufClean(MemBuf * mb); +/* resets mb preserving (or initializing if needed) memory buffer */ +extern void memBufReset(MemBuf * mb); +/* unfirtunate hack to test if the buffer has been Init()ialized */ +extern int memBufIsNull(MemBuf * mb); +/* calls memcpy, appends exactly size bytes, extends buffer if needed */ +extern void memBufAppend(MemBuf * mb, const char *buf, mb_size_t size); +/* calls snprintf, extends buffer if needed */ +#if STDC_HEADERS +extern void memBufPrintf(MemBuf * mb, const char *fmt, ...); +#else +extern void memBufPrintf(); +#endif +/* vprintf for other printf()'s to use */ +extern void memBufVPrintf(MemBuf * mb, const char *fmt, va_list ap); +/* returns free() function to be used, _freezes_ the object! */ +extern FREE *memBufFreeFunc(MemBuf * mb); +/* puts report on MemBuf _module_ usage into mb */ +extern void memBufReport(MemBuf * mb); + +extern char *mime_get_header(const char *mime, const char *header); +extern char *mime_get_header_field(const char *mime, const char *name, + const char *prefix); +extern size_t headersEnd(const char *, size_t); +extern const char *mime_get_auth(const char *hdr, const char *auth_scheme, + const char **auth_field); + +extern void mimeInit(char *filename); +extern void mimeFreeMemory(void); +extern char *mimeGetContentEncoding(const char *fn); +extern char *mimeGetContentType(const char *fn); +extern char *mimeGetIcon(const char *fn); +extern const char *mimeGetIconURL(const char *fn); +extern char mimeGetTransferMode(const char *fn); +extern int mimeGetDownloadOption(const char *fn); +extern int mimeGetViewOption(const char *fn); + +extern int mcastSetTtl(int, int); +extern IPH mcastJoinGroups; + +/* Labels for hierachical log file */ +/* put them all here for easier reference when writing a logfile analyzer */ + + +extern peer *getFirstPeer(void); +extern peer *getFirstUpParent(request_t *); +extern peer *getNextPeer(peer *); +extern peer *getSingleParent(request_t *); +extern int neighborsCount(request_t *); +extern int neighborsUdpPing(request_t *, + StoreEntry *, IRCB * callback, void *data, int *exprep, int *timeout); +extern void neighborAddAcl(const char *, const char *); +extern void neighborsUdpAck(const cache_key *, icp_common_t *, + const struct sockaddr_in *); +extern void neighborAdd(const char *, const char *, int, int, int, int, int); +extern void neighbors_open(int); +extern peer *peerFindByName(const char *); +extern peer *peerFindByNameAndPort(const char *, unsigned short); +extern peer *getDefaultParent(request_t * request); +extern peer *getRoundRobinParent(request_t * request); +EVH peerClearRR; +extern peer *getAnyParent(request_t * request); +extern lookup_t peerDigestLookup(peer * p, request_t * request); +extern peer *neighborsDigestSelect(request_t * request); +extern void peerNoteDigestLookup(request_t * request, peer * p, + lookup_t lookup); +extern void peerNoteDigestGone(peer * p); +extern int neighborUp(const peer * e); +extern CBDUNL peerDestroy; +extern char *neighborTypeStr(const peer * e); +extern peer_t neighborType(const peer *, const request_t *); +extern void peerConnectFailed(peer *); +extern void peerConnectSucceded(peer *); +extern void dump_peer_options(StoreEntry *, peer *); +extern int peerHTTPOkay(const peer *, request_t *); +extern peer *whichPeer(const struct sockaddr_in *from); +#if USE_HTCP +extern void neighborsHtcpReply(const cache_key *, htcpReplyData *, + const struct sockaddr_in *); +#endif + +extern void netdbInit(void); +extern void netdbHandlePingReply(const struct sockaddr_in *from, int hops, + int rtt); +extern void netdbPingSite(const char *hostname); +extern void netdbInit(void); +extern void netdbDump(StoreEntry *); +extern int netdbHops(struct in_addr); +extern void netdbFreeMemory(void); +extern int netdbHostHops(const char *host); +extern int netdbHostRtt(const char *host); +extern int netdbHostPeerRtt(const char *host, peer * peer); +extern void netdbUpdatePeer(request_t *, peer * e, int rtt, int hops); +extern void netdbDeleteAddrNetwork(struct in_addr addr); +extern int netdbHostPeerRtt(const char *host, peer * peer); +extern void netdbBinaryExchange(StoreEntry *); +extern EVH netdbExchangeStart; +extern void netdbExchangeUpdatePeer(struct in_addr, peer *, double, double); +extern peer *netdbClosestParent(request_t *); +extern void netdbHostData(const char *host, int *samp, int *rtt, int *hops); + +extern void cachemgrStart(int fd, request_t * request, StoreEntry * entry); +extern void cachemgrRegister(const char *, const char *, OBJH *, int, int); +extern void cachemgrInit(void); + +extern void peerSelect(request_t *, StoreEntry *, PSC *, void *data); +extern void peerSelectInit(void); + +/* peer_digest.c */ +extern PeerDigest *peerDigestCreate(peer * p); +extern void peerDigestNeeded(PeerDigest * pd); +extern void peerDigestNotePeerGone(PeerDigest * pd); +extern void peerDigestStatsReport(const PeerDigest * pd, StoreEntry * e); + +/* forward.c */ +extern void fwdStart(int, StoreEntry *, request_t *); +extern DEFER fwdCheckDeferRead; +extern void fwdFail(FwdState *, ErrorState *); +extern void fwdUnregister(int fd, FwdState *); +extern void fwdComplete(FwdState * fwdState); +extern void fwdInit(void); +extern int fwdReforwardableStatus(http_status s); +extern void fwdServersFree(FwdServer ** FS); +#if WIP_FWD_LOG +extern void fwdUninit(void); +extern void fwdLogRotate(void); +extern void fwdStatus(FwdState *, http_status); +#endif + +extern void urnStart(request_t *, StoreEntry *); + +extern void redirectStart(clientHttpRequest *, RH *, void *); +extern void redirectInit(void); +extern void redirectShutdown(void); + +/* auth_modules.c */ +extern void authSchemeSetup(void); + +/* authenticate.c */ +extern void authenticateAuthUserMerge(auth_user_t *, auth_user_t *); +extern auth_user_t *authenticateAuthUserNew(const char *); +extern int authenticateAuthSchemeId(const char *typestr); +extern void authenticateStart(auth_user_request_t *, RH *, void *); +extern void authenticateSchemeInit(void); +extern void authenticateInit(authConfig *); +extern void authenticateShutdown(void); +extern void authenticateFixHeader(HttpReply *, auth_user_request_t *, + request_t *, int); +extern void authenticateAddTrailer(HttpReply *, auth_user_request_t *, + request_t *, int); +extern auth_user_request_t *authenticateGetAuthUser(const char *proxy_auth); +extern void authenticateAuthenticateUser(auth_user_request_t *, request_t *, + ConnStateData *, http_hdr_type); +extern void authenticateAuthUserUnlock(auth_user_t * auth_user); +extern void authenticateAuthUserLock(auth_user_t * auth_user); +extern void authenticateAuthUserRequestUnlock(auth_user_request_t *); +extern void authenticateAuthUserRequestLock(auth_user_request_t *); +extern char *authenticateAuthUserRequestMessage(auth_user_request_t *); +extern int authenticateAuthUserInuse(auth_user_t * auth_user); +extern void authenticateAuthUserRequestSetIp(auth_user_request_t *, + struct in_addr); +extern int authenticateDirection(auth_user_request_t *); +extern FREE authenticateFreeProxyAuthUser; +extern void authenticateFreeProxyAuthUserACLResults(void *data); +extern void authenticateProxyUserCacheCleanup(void *); +extern void authenticateInitUserCache(void); +extern int authenticateActiveSchemeCount(void); +extern int authenticateSchemeCount(void); +extern void authenticateUserNameCacheAdd(auth_user_t * auth_user); +extern int authenticateCheckAuthUserIP(struct in_addr request_src_addr, + auth_user_request_t * auth_user); +extern int authenticateUserAuthenticated(auth_user_request_t *); +extern void authenticateUserCacheRestart(void); +extern char *authenticateUserUsername(auth_user_t *); +extern char *authenticateUserRequestUsername(auth_user_request_t *); +extern int authenticateValidateUser(auth_user_request_t *); +extern void authenticateOnCloseConnection(ConnStateData * conn); +extern void authSchemeAdd(char *type, AUTHSSETUP * setup); + +extern void refreshAddToList(const char *, int, time_t, int, time_t); +extern int refreshIsCachable(const StoreEntry *); +extern int refreshCheckHTTP(const StoreEntry *, request_t *); +extern int refreshCheckICP(const StoreEntry *, request_t *); +extern int refreshCheckHTCP(const StoreEntry *, request_t *); +extern int refreshCheckDigest(const StoreEntry *, time_t delta); +extern time_t getMaxAge(const char *url); +extern void refreshInit(void); + +extern void serverConnectionsClose(void); +extern void shut_down(int); +extern void reconfigure(int); +extern void rotate_logs(int); + +extern void start_announce(void *unused); +extern void sslStart(int fd, const char *, request_t *, size_t *, int *); +extern void waisStart(FwdState *); + +/* ident.c */ +#if USE_IDENT +extern void identStart(struct sockaddr_in *me, struct sockaddr_in *peer, + IDCB * callback, void *cbdata); +extern void identInit(void); +#endif + +extern void statInit(void); +extern void statFreeMemory(void); +extern double median_svc_get(int, int); +extern void pconnHistCount(int, int); +extern int stat5minClientRequests(void); +extern double stat5minCPUUsage(void); +extern const char *storeEntryFlags(const StoreEntry *); +extern double statRequestHitRatio(int minutes); +extern double statRequestHitMemoryRatio(int minutes); +extern double statRequestHitDiskRatio(int minutes); +extern double statByteHitRatio(int minutes); +extern int storeEntryLocked(const StoreEntry *); + + +/* StatHist */ +extern void statHistClean(StatHist * H); +extern void statHistCount(StatHist * H, double val); +extern void statHistCopy(StatHist * Dest, const StatHist * Orig); +extern void statHistSafeCopy(StatHist * Dest, const StatHist * Orig); +extern double statHistDeltaMedian(const StatHist * A, const StatHist * B); +extern void statHistDump(const StatHist * H, StoreEntry * sentry, + StatHistBinDumper bd); +extern void statHistLogInit(StatHist * H, int capacity, double min, double max); +extern void statHistEnumInit(StatHist * H, int last_enum); +extern void statHistIntInit(StatHist * H, int n); +extern StatHistBinDumper statHistEnumDumper; +extern StatHistBinDumper statHistIntDumper; + + +/* MemMeter */ +extern void memMeterSyncHWater(MemMeter * m); +#define memMeterCheckHWater(m) { if ((m).hwater_level < (m).level) memMeterSyncHWater(&(m)); } +#define memMeterInc(m) { (m).level++; memMeterCheckHWater(m); } +#define memMeterDec(m) { (m).level--; } +#define memMeterAdd(m, sz) { (m).level += (sz); memMeterCheckHWater(m); } +#define memMeterDel(m, sz) { (m).level -= (sz); } + +/* mem */ +extern void memInit(void); +extern void memClean(void); +extern void memInitModule(void); +extern void memCleanModule(void); +extern void memConfigure(void); +extern void *memAllocate(mem_type); +extern void *memAllocBuf(size_t net_size, size_t * gross_size); +extern void memFree(void *, int type); +extern void memFreeBuf(size_t size, void *); +extern void memFree2K(void *); +extern void memFree4K(void *); +extern void memFree8K(void *); +extern void memFree16K(void *); +extern void memFree32K(void *); +extern void memFree64K(void *); +extern int memInUse(mem_type); +extern size_t memTotalAllocated(void); +extern void memDataInit(mem_type, const char *, size_t, int); +extern void memCheckInit(void); + +/* MemPool */ +extern MemPool *memPoolCreate(const char *label, size_t obj_size); +extern void memPoolDestroy(MemPool * pool); +extern void *memPoolAlloc(MemPool * pool); +extern void memPoolFree(MemPool * pool, void *obj); +extern int memPoolWasUsed(const MemPool * pool); +extern int memPoolInUseCount(const MemPool * pool); +extern size_t memPoolInUseSize(const MemPool * pool); +extern int memPoolUsedCount(const MemPool * pool); +extern void memPoolReport(const MemPool * pool, StoreEntry * e); + +/* Mem */ +extern void memReport(StoreEntry * e); + +extern int stmemFreeDataUpto(mem_hdr *, int); +extern void stmemAppend(mem_hdr *, const char *, int); +extern ssize_t stmemCopy(const mem_hdr *, off_t, char *, size_t); +extern void stmemFree(mem_hdr *); +extern void stmemFreeData(mem_hdr *); + +/* ----------------------------------------------------------------- */ + +/* + * store.c + */ +extern StoreEntry *new_StoreEntry(int, const char *, const char *); +extern StoreEntry *storeGet(const cache_key *); +extern StoreEntry *storeGetPublic(const char *uri, const method_t method); +extern StoreEntry *storeGetPublicByRequest(request_t * request); +extern StoreEntry *storeGetPublicByRequestMethod(request_t * request, + const method_t method); +extern StoreEntry *storeCreateEntry(const char *, const char *, request_flags, + method_t); +extern void storeSetPublicKey(StoreEntry *); +extern void storeComplete(StoreEntry *); +extern void storeInit(void); +extern int storeClientWaiting(const StoreEntry *); +extern void storeAbort(StoreEntry *); +extern void storeAppend(StoreEntry *, const char *, int); +extern void storeLockObject(StoreEntry *); +extern void storeRelease(StoreEntry *); +extern int storeUnlockObject(StoreEntry *); +extern int storePendingNClients(const StoreEntry *); +extern EVH storeMaintainSwapSpace; +extern void storeExpireNow(StoreEntry *); +extern void storeReleaseRequest(StoreEntry *); +extern off_t storeLowestMemReaderOffset(const StoreEntry *); +extern void storeConfigure(void); +extern void storeNegativeCache(StoreEntry *); +extern void storeFreeMemory(void); +extern int expiresMoreThan(time_t, time_t); +extern void InvokeHandlers(StoreEntry *); +extern int storeEntryValidToSend(StoreEntry *); +extern void storeTimestampsSet(StoreEntry *); +extern void storeRegisterAbort(StoreEntry * e, STABH * cb, void *); +extern void storeUnregisterAbort(StoreEntry * e); +extern void storeMemObjectDump(MemObject * mem); +extern void storeEntryDump(const StoreEntry * e, int debug_lvl); +extern const char *storeUrl(const StoreEntry *); +extern void storeCreateMemObject(StoreEntry *, const char *, const char *); +extern void storeCopyNotModifiedReplyHeaders(MemObject * O, MemObject * N); +extern void storeBuffer(StoreEntry *); +extern void storeBufferFlush(StoreEntry *); +extern void storeHashInsert(StoreEntry * e, const cache_key *); +extern void storeSetMemStatus(StoreEntry * e, int); +#if STDC_HEADERS +extern void storeAppendPrintf(StoreEntry *, const char *, ...); +#else +extern void storeAppendPrintf(); +#endif +extern void storeAppendVPrintf(StoreEntry *, const char *, va_list ap); +extern int storeCheckCachable(StoreEntry * e); +extern void storeSetPrivateKey(StoreEntry *); +extern int objectLen(const StoreEntry * e); +extern int contentLen(const StoreEntry * e); +extern HttpReply *storeEntryReply(StoreEntry *); +extern int storeTooManyDiskFilesOpen(void); +extern void storeEntryReset(StoreEntry *); +extern void storeHeapPositionUpdate(StoreEntry *, SwapDir *); +extern void storeSwapFileNumberSet(StoreEntry * e, sfileno filn); +extern void storeFsInit(void); +extern void storeFsDone(void); +extern void storeFsAdd(char *, STSETUP *); +extern void storeReplAdd(char *, REMOVALPOLICYCREATE *); + +/* store_modules.c */ +extern void storeFsSetup(void); + +/* repl_modules.c */ +extern void storeReplSetup(void); + +/* store_io.c */ +extern storeIOState *storeCreate(StoreEntry *, STFNCB *, STIOCB *, void *); +extern storeIOState *storeOpen(StoreEntry *, STFNCB *, STIOCB *, void *); +extern void storeClose(storeIOState *); +extern void storeRead(storeIOState *, char *, size_t, off_t, STRCB *, void *); +extern void storeWrite(storeIOState *, char *, size_t, off_t, FREE *); +extern void storeUnlink(StoreEntry *); +extern off_t storeOffset(storeIOState *); + +/* + * store_log.c + */ +extern void storeLog(int tag, const StoreEntry * e); +extern void storeLogRotate(void); +extern void storeLogClose(void); +extern void storeLogOpen(void); + + +/* + * store_key_*.c + */ +extern cache_key *storeKeyDup(const cache_key *); +extern cache_key *storeKeyCopy(cache_key *, const cache_key *); +extern void storeKeyFree(const cache_key *); +extern const cache_key *storeKeyScan(const char *); +extern const char *storeKeyText(const cache_key *); +extern const cache_key *storeKeyPublic(const char *, const method_t); +extern const cache_key *storeKeyPublicByRequest(request_t *); +extern const cache_key *storeKeyPublicByRequestMethod(request_t *, + const method_t); +extern const cache_key *storeKeyPrivate(const char *, method_t, int); +extern int storeKeyHashBuckets(int); +extern int storeKeyNull(const cache_key *); +extern void storeKeyInit(void); +extern HASHHASH storeKeyHashHash; +extern HASHCMP storeKeyHashCmp; + +/* + * store_digest.c + */ +extern void storeDigestInit(void); +extern void storeDigestNoteStoreReady(void); +extern void storeDigestScheduleRebuild(void); +extern void storeDigestDel(const StoreEntry * entry); +extern void storeDigestReport(StoreEntry *); + +/* + * store_dir.c + */ +extern OBJH storeDirStats; +extern char *storeDirSwapLogFile(int, const char *); +extern char *storeSwapDir(int); +extern char *storeSwapFullPath(int, char *); +extern char *storeSwapSubSubDir(int, char *); +extern const char *storeSwapPath(int); +extern int storeDirWriteCleanLogs(int reopen); +extern STDIRSELECT *storeDirSelectSwapDir; +extern int storeVerifySwapDirs(void); +extern void storeCreateSwapDirectories(void); +extern void storeDirCloseSwapLogs(void); +extern void storeDirCloseTmpSwapLog(int dirn); +extern void storeDirConfigure(void); +extern void storeDirDiskFull(sdirno); +extern void storeDirInit(void); +extern void storeDirOpenSwapLogs(void); +extern void storeDirSwapLog(const StoreEntry *, int op); +extern void storeDirUpdateSwapSize(SwapDir *, size_t size, int sign); +extern void storeDirSync(void); +extern void storeDirCallback(void); +extern void storeDirLRUDelete(StoreEntry *); +extern void storeDirLRUAdd(StoreEntry *); +extern int storeDirGetBlkSize(const char *path, int *blksize); +extern int storeDirGetUFSStats(const char *, int *, int *, int *, int *); + +/* + * store_swapmeta.c + */ +extern char *storeSwapMetaPack(tlv * tlv_list, int *length); +extern tlv *storeSwapMetaBuild(StoreEntry * e); +extern tlv *storeSwapMetaUnpack(const char *buf, int *hdrlen); +extern void storeSwapTLVFree(tlv * n); + +/* + * store_rebuild.c + */ +extern void storeRebuildStart(void); +extern void storeRebuildComplete(struct _store_rebuild_data *); +extern void storeRebuildProgress(int index, int total, int sofar); + +/* + * store_swapin.c + */ +extern void storeSwapInStart(store_client *); + +/* + * store_swapout.c + */ +extern void storeSwapOut(StoreEntry * e); +extern void storeSwapOutFileClose(StoreEntry * e); +extern int storeSwapOutAble(const StoreEntry * e); + +/* + * store_client.c + */ +#if STORE_CLIENT_LIST_DEBUG +extern store_client *storeClientListSearch(const MemObject * mem, void *data); +#endif +extern store_client *storeClientListAdd(StoreEntry * e, void *data); +extern void storeClientCopy(store_client *, StoreEntry *, off_t, off_t, size_t, + char *, STCB *, void *); +extern int storeClientCopyPending(store_client *, StoreEntry * e, void *data); +extern int storeUnregister(store_client * sc, StoreEntry * e, void *data); +extern off_t storeLowestMemReaderOffset(const StoreEntry * entry); +extern void InvokeHandlers(StoreEntry * e); +extern int storePendingNClients(const StoreEntry * e); + + +extern const char *getMyHostname(void); +extern const char *uniqueHostname(void); +extern void safeunlink(const char *path, int quiet); +extern void death(int sig); +extern void fatal(const char *message); +#if STDC_HEADERS +extern void fatalf(const char *fmt, ...); +#else +extern void fatalf(); +#endif +extern void fatal_dump(const char *message); +extern void sigusr2_handle(int sig); +extern void sig_child(int sig); +extern void leave_suid(void); +extern void enter_suid(void); +extern void no_suid(void); +extern void writePidFile(void); +extern void setSocketShutdownLifetimes(int); +extern void setMaxFD(void); +extern time_t getCurrentTime(void); +extern int percent(int, int); +extern double dpercent(double, double); +extern void squid_signal(int sig, SIGHDLR *, int flags); +extern pid_t readPidFile(void); +extern struct in_addr inaddrFromHostent(const struct hostent *hp); +extern int intAverage(int, int, int, int); +extern double doubleAverage(double, double, int, int); +extern void debug_trap(const char *); +extern void logsFlush(void); +extern char *checkNullString(char *p); +extern void squid_getrusage(struct rusage *r); +extern double rusage_cputime(struct rusage *r); +extern int rusage_maxrss(struct rusage *r); +extern int rusage_pagefaults(struct rusage *r); +extern void releaseServerSockets(void); +extern void PrintRusage(void); +extern void dumpMallocStats(void); + +#if USE_UNLINKD +extern void unlinkdInit(void); +extern void unlinkdClose(void); +extern void unlinkdUnlink(const char *); +#endif + +extern char *url_convert_hex(char *org_url, int allocate); +extern char *url_escape(const char *url); +extern protocol_t urlParseProtocol(const char *); +extern method_t urlParseMethod(const char *); +extern void urlInitialize(void); +extern request_t *urlParse(method_t, char *); +extern const char *urlCanonical(request_t *); +extern char *urlRInternal(const char *host, u_short port, const char *dir, + const char *name); +extern char *urlInternal(const char *dir, const char *name); +extern int matchDomainName(const char *host, const char *domain); +extern int urlCheckRequest(const request_t *); +extern int urlDefaultPort(protocol_t p); +extern char *urlCanonicalClean(const request_t *); +extern char *urlHostname(const char *url); +extern void urlExtMethodConfigure(void); + +extern void useragentOpenLog(void); +extern void useragentRotateLog(void); +extern void logUserAgent(const char *, const char *); +extern void refererOpenLog(void); +extern void refererRotateLog(void); +extern void logReferer(const char *, const char *, const char *); +extern peer_t parseNeighborType(const char *s); + +extern void errorInitialize(void); +extern void errorClean(void); +extern HttpReply *errorBuildReply(ErrorState * err); +extern void errorSend(int fd, ErrorState *); +extern void errorAppendEntry(StoreEntry *, ErrorState *); +extern void errorStateFree(ErrorState * err); +extern int errorReservePageId(const char *page_name); +extern ErrorState *errorCon(err_type type, http_status); + +extern void pconnPush(int, const char *host, u_short port); +extern int pconnPop(const char *host, u_short port); +extern void pconnInit(void); + +extern int asnMatchIp(void *, struct in_addr); +extern void asnInit(void); +extern void asnFreeMemory(void); + +/* tools.c */ +extern void dlinkAdd(void *data, dlink_node *, dlink_list *); +extern void dlinkAddTail(void *data, dlink_node *, dlink_list *); +extern void dlinkDelete(dlink_node * m, dlink_list * list); +extern void dlinkNodeDelete(dlink_node * m); +extern dlink_node *dlinkNodeNew(void); + +extern void kb_incr(kb_t *, size_t); +extern double gb_to_double(const gb_t *); +extern const char *gb_to_str(const gb_t *); +extern void gb_flush(gb_t *); /* internal, do not use this */ +extern int stringHasWhitespace(const char *); +extern int stringHasCntl(const char *); +extern void linklistPush(link_list **, void *); +extern void *linklistShift(link_list **); +extern int xrename(const char *from, const char *to); +extern int isPowTen(int); +extern void parseEtcHosts(void); + +#if USE_HTCP +extern void htcpInit(void); +extern void htcpQuery(StoreEntry * e, request_t * req, peer * p); +extern void htcpSocketShutdown(void); +extern void htcpSocketClose(void); +#endif + +/* String */ +#define strLen(s) ((/* const */ int)(s).len) +#define strBuf(s) ((const char*)(s).buf) +#define strChr(s,ch) ((const char*)strchr(strBuf(s), (ch))) +#define strRChr(s,ch) ((const char*)strrchr(strBuf(s), (ch))) +#define strStr(s,str) ((const char*)strstr(strBuf(s), (str))) +#define strCmp(s,str) strcmp(strBuf(s), (str)) +#define strNCmp(s,str,n) strncmp(strBuf(s), (str), (n)) +#define strCaseCmp(s,str) strcasecmp(strBuf(s), (str)) +#define strNCaseCmp(s,str,n) strncasecmp(strBuf(s), (str), (n)) +#define strSet(s,ptr,ch) (s).buf[ptr-(s).buf] = (ch) +#define strCut(s,pos) (((s).len = pos) , ((s).buf[pos] = '\0')) +#define strCutPtr(s,ptr) (((s).len = (ptr)-(s).buf) , ((s).buf[(s).len] = '\0')) +/* #define strCat(s,str) stringAppend(&(s), (str), strlen(str)+1) */ +extern void stringInit(String * s, const char *str); +extern void stringLimitInit(String * s, const char *str, int len); +extern String stringDup(const String * s); +extern void stringClean(String * s); +extern void stringReset(String * s, const char *str); +extern void stringAppend(String * s, const char *buf, int len); +/* extern void stringAppendf(String *s, const char *fmt, ...); */ + +/* + * ipc.c + */ +extern int ipcCreate(int type, + const char *prog, char *const args[], const char *name, int *rfd, int *wfd); + +/* CacheDigest */ +extern CacheDigest *cacheDigestCreate(int capacity, int bpe); +extern void cacheDigestDestroy(CacheDigest * cd); +extern CacheDigest *cacheDigestClone(const CacheDigest * cd); +extern void cacheDigestClear(CacheDigest * cd); +extern void cacheDigestChangeCap(CacheDigest * cd, int new_cap); +extern int cacheDigestTest(const CacheDigest * cd, const cache_key * key); +extern void cacheDigestAdd(CacheDigest * cd, const cache_key * key); +extern void cacheDigestDel(CacheDigest * cd, const cache_key * key); +extern size_t cacheDigestCalcMaskSize(int cap, int bpe); +extern int cacheDigestBitUtil(const CacheDigest * cd); +extern void cacheDigestGuessStatsUpdate(cd_guess_stats * stats, int real_hit, + int guess_hit); +extern void cacheDigestGuessStatsReport(const cd_guess_stats * stats, + StoreEntry * sentry, const char *label); +extern void cacheDigestReport(CacheDigest * cd, const char *label, + StoreEntry * e); + +extern void internalStart(request_t *, StoreEntry *); +extern int internalCheck(const char *urlpath); +extern int internalStaticCheck(const char *urlpath); +extern char *internalLocalUri(const char *dir, const char *name); +extern char *internalRemoteUri(const char *, u_short, const char *, + const char *); +extern const char *internalHostname(void); +extern int internalHostnameIs(const char *); + +#if USE_CARP +extern void carpInit(void); +extern peer *carpSelectParent(request_t *); +#endif + +#if DELAY_POOLS +extern void delayPoolsInit(void); +extern void delayInitDelayData(unsigned short pools); +extern void delayFreeDelayData(void); +extern void delayCreateDelayPool(unsigned short pool, u_char class); +extern void delayInitDelayPool(unsigned short pool, u_char class, + delaySpecSet * rates); +extern void delayFreeDelayPool(unsigned short pool); +extern void delayPoolsReconfigure(void); +extern void delaySetNoDelay(int fd); +extern void delayClearNoDelay(int fd); +extern int delayIsNoDelay(int fd); +extern delay_id delayClient(request_t *); +extern EVH delayPoolsUpdate; +extern int delayBytesWanted(delay_id d, int min, int max); +extern void delayBytesIn(delay_id, int qty); +extern int delayMostBytesWanted(const MemObject * mem, int max); +extern delay_id delayMostBytesAllowed(const MemObject * mem); +extern void delaySetStoreClient(store_client * sc, delay_id delay_id); +extern void delayRegisterDelayIdPtr(delay_id * loc); +extern void delayUnregisterDelayIdPtr(delay_id * loc); +#endif + +/* helper.c */ +extern void helperOpenServers(helper * hlp); +extern void helperStatefulOpenServers(statefulhelper * hlp); +extern void helperSubmit(helper * hlp, const char *buf, HLPCB * callback, + void *data); +extern void helperStatefulSubmit(statefulhelper * hlp, const char *buf, + HLPSCB * callback, void *data, helper_stateful_server * lastserver); +extern void helperStats(StoreEntry * sentry, helper * hlp); +extern void helperStatefulStats(StoreEntry * sentry, statefulhelper * hlp); +extern void helperShutdown(helper * hlp); +extern void helperStatefulShutdown(statefulhelper * hlp); +extern helper *helperCreate(const char *); +extern statefulhelper *helperStatefulCreate(const char *); +extern void helperFree(helper *); +extern void helperStatefulFree(statefulhelper *); +extern void helperStatefulReset(helper_stateful_server * srv); +extern void helperStatefulReleaseServer(helper_stateful_server * srv); +extern void *helperStatefulServerGetData(helper_stateful_server * srv); +extern helper_stateful_server *helperStatefulDefer(statefulhelper *); + + + +#if USE_LEAKFINDER +extern void leakInit(void); +extern void *leakAddFL(void *, const char *, int); +extern void *leakTouchFL(void *, const char *, int); +extern void *leakFreeFL(void *, const char *, int); +#endif + +/* logfile.c */ +extern Logfile *logfileOpen(const char *path, size_t bufsz, int); +extern void logfileClose(Logfile * lf); +extern void logfileRotate(Logfile * lf); +extern void logfileWrite(Logfile * lf, void *buf, size_t len); +extern void logfileFlush(Logfile * lf); +#if STDC_HEADERS +extern void logfilePrintf(Logfile * lf, const char *fmt, ...); +#else +extern void logfilePrintf(va_alist); +#endif + +/* + * Removal Policies + */ +extern RemovalPolicy *createRemovalPolicy(RemovalPolicySettings * settings); + +/* + * prototypes for system functions missing from system includes + */ + +#ifdef _SQUID_SOLARIS_ +extern int getrusage(int, struct rusage *); +extern int getpagesize(void); +extern int gethostname(char *, int); +#endif + +#if URL_CHECKSUM_DEBUG +extern unsigned int url_checksum(const char *url); +#endif + +/* + * hack to allow snmp access to the statistics counters + */ +extern StatCounters *snmpStatGet(int); + +/* Vary support functions */ +int varyEvaluateMatch(StoreEntry * entry, request_t * req); + +/* CygWin & Windows NT Port */ +/* win32.c */ +#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) +extern int WIN32_Subsystem_Init(); +extern void WIN32_sendSignal(int); +extern void WIN32_Exit(int); +extern void WIN32_InstallService(void); +extern void WIN32_RemoveService(void); +#endif Index: squid/src/tools.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/tools.c,v retrieving revision 1.7.2.5 retrieving revision 1.7.2.6 diff -u -r1.7.2.5 -r1.7.2.6 --- squid/src/tools.c 25 Apr 2001 11:38:30 -0000 1.7.2.5 +++ squid/src/tools.c 27 Apr 2001 17:06:45 -0000 1.7.2.6 @@ -1,6 +1,6 @@ /* - * $Id: tools.c,v 1.7.2.5 2001/04/25 11:38:30 serassio Exp $ + * $Id: tools.c,v 1.7.2.6 2001/04/27 17:06:45 serassio Exp $ * * DEBUG: section 21 Misc Functions * AUTHOR: Harvest Derived @@ -123,8 +123,7 @@ fprintf(debug_log, "\ttotal space in arena: %6d KB\n", (int) (ms.bytes_total >> 10)); fprintf(debug_log, "\tTotal free: %6d KB %d%%\n", - (int) (ms.bytes_free >> 10), - percent(ms.bytes_free, ms.bytes_total)); + (int) (ms.bytes_free >> 10), percent(ms.bytes_free, ms.bytes_total)); #elif HAVE_MALLINFO && HAVE_STRUCT_MALLINFO struct mallinfo mp; int t; @@ -132,18 +131,15 @@ return; mp = mallinfo(); fprintf(debug_log, "Memory usage for %s via mallinfo():\n", appname); - fprintf(debug_log, "\ttotal space in arena: %6d KB\n", - mp.arena >> 10); + fprintf(debug_log, "\ttotal space in arena: %6d KB\n", mp.arena >> 10); fprintf(debug_log, "\tOrdinary blocks: %6d KB %6d blks\n", mp.uordblks >> 10, mp.ordblks); fprintf(debug_log, "\tSmall blocks: %6d KB %6d blks\n", mp.usmblks >> 10, mp.smblks); fprintf(debug_log, "\tHolding blocks: %6d KB %6d blks\n", mp.hblkhd >> 10, mp.hblks); - fprintf(debug_log, "\tFree Small blocks: %6d KB\n", - mp.fsmblks >> 10); - fprintf(debug_log, "\tFree Ordinary blocks: %6d KB\n", - mp.fordblks >> 10); + fprintf(debug_log, "\tFree Small blocks: %6d KB\n", mp.fsmblks >> 10); + fprintf(debug_log, "\tFree Ordinary blocks: %6d KB\n", mp.fordblks >> 10); t = mp.uordblks + mp.usmblks + mp.hblkhd; fprintf(debug_log, "\tTotal in use: %6d KB %d%%\n", t >> 10, percent(t, mp.arena)); @@ -151,13 +147,12 @@ fprintf(debug_log, "\tTotal free: %6d KB %d%%\n", t >> 10, percent(t, mp.arena)); #if HAVE_EXT_MALLINFO - fprintf(debug_log, "\tmax size of small blocks:\t%d\n", - mp.mxfast); + fprintf(debug_log, "\tmax size of small blocks:\t%d\n", mp.mxfast); fprintf(debug_log, "\tnumber of small blocks in a holding block:\t%d\n", mp.nlblks); - fprintf(debug_log, "\tsmall block rounding factor:\t%d\n", - mp.grain); - fprintf(debug_log, "\tspace (including overhead) allocated in ord. blks:\t%d\n", + fprintf(debug_log, "\tsmall block rounding factor:\t%d\n", mp.grain); + fprintf(debug_log, + "\tspace (including overhead) allocated in ord. blks:\t%d\n", mp.uordbytes); fprintf(debug_log, "\tnumber of ordinary blocks allocated:\t%d\n", mp.allocated); @@ -236,7 +231,8 @@ fprintf(debug_log, "CPU Usage: %.3f seconds = %.3f user + %.3f sys\n", rusage_cputime(&rusage), rusage.ru_utime.tv_sec + ((double) rusage.ru_utime.tv_usec / 1000000.0), - rusage.ru_stime.tv_sec + ((double) rusage.ru_stime.tv_usec / 1000000.0)); + rusage.ru_stime.tv_sec + + ((double) rusage.ru_stime.tv_usec / 1000000.0)); fprintf(debug_log, "Maximum Resident Size: %d KB\n", rusage_maxrss(&rusage)); fprintf(debug_log, "Page faults with physical i/o: %d\n", @@ -354,13 +350,17 @@ if (0 == store_dirs_rebuilding) storeDirWriteCleanLogs(0); fatal_common(message); +#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) + WIN32_Exit(shutting_down ? 0 : 1); +#else exit(shutting_down ? 0 : 1); +#endif } /* printf-style interface for fatal */ #if STDC_HEADERS void -fatalf(const char *fmt,...) +fatalf(const char *fmt, ...) { va_list args; va_start(args, fmt); @@ -457,14 +457,14 @@ /* use the official name from DNS lookup */ xstrncpy(host, h->h_name, SQUIDHOSTNAMELEN); debug(50, 4) ("getMyHostname: resolved %s to '%s'\n", - inet_ntoa(Config.Sockaddr.http->s.sin_addr), - host); + inet_ntoa(Config.Sockaddr.http->s.sin_addr), host); present = 1; if (strchr(host, '.')) return host; } - debug(50, 1) ("WARNING: failed to resolve %s to a fully qualified hostname\n", + debug(50, + 1) ("WARNING: failed to resolve %s to a fully qualified hostname\n", inet_ntoa(Config.Sockaddr.http->s.sin_addr)); } /* @@ -484,7 +484,8 @@ if (strchr(host, '.')) return host; } - fatal("Could not determine fully qualified hostname. Please set 'visible_hostname'\n"); + fatal + ("Could not determine fully qualified hostname. Please set 'visible_hostname'\n"); return NULL; /* keep compiler happy */ } @@ -556,7 +557,8 @@ uid_t uid; leave_suid(); uid = geteuid(); - debug(21, 3) ("leave_suid: PID %d giving up root priveleges forever\n", getpid()); + debug(21, 3) ("leave_suid: PID %d giving up root priveleges forever\n", + getpid()); #if HAVE_SETRESUID if (setresuid(uid, uid, uid) < 0) debug(50, 1) ("no_suid: setresuid: %s\n", xstrerror()); @@ -594,8 +596,7 @@ } -pid_t -readPidFile(void) +pid_t readPidFile(void) { FILE *pid_fp = NULL; const char *f = Config.pidFilename; @@ -658,7 +659,9 @@ } #endif #else /* HAVE_SETRLIMIT */ - debug(21, 1) ("setMaxFD: Cannot increase: setrlimit() not supported on this system\n"); + debug(21, + 1) + ("setMaxFD: Cannot increase: setrlimit() not supported on this system\n"); #endif /* HAVE_SETRLIMIT */ #if HAVE_SETRLIMIT && defined(RLIMIT_DATA) @@ -687,8 +690,7 @@ #endif /* RLIMIT_VMEM */ } -time_t -getCurrentTime(void) +time_t getCurrentTime(void) { #if GETTIMEOFDAY_NO_TZP gettimeofday(¤t_time); @@ -721,7 +723,8 @@ sa.sa_flags = flags; sigemptyset(&sa.sa_mask); if (sigaction(sig, &sa, NULL) < 0) - debug(50, 0) ("sigaction: sig=%d func=%p: %s\n", sig, func, xstrerror()); + debug(50, 0) ("sigaction: sig=%d func=%p: %s\n", sig, func, + xstrerror()); #else signal(sig, func); #endif @@ -922,7 +925,7 @@ { debug(21, 2) ("xrename: renaming %s to %s\n", from, to); #ifdef _SQUID_MSWIN_ - remove(to); + remove(to); #endif if (0 == rename(from, to)) return 0; Index: squid/src/win32.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/win32.c,v retrieving revision 1.1.50.1 retrieving revision 1.1.50.2 diff -u -r1.1.50.1 -r1.1.50.2 --- squid/src/win32.c 24 Apr 2001 16:02:43 -0000 1.1.50.1 +++ squid/src/win32.c 27 Apr 2001 17:06:45 -0000 1.1.50.2 @@ -1,366 +1,515 @@ -/* - * $Id$ - * - * * * * * * * * Legal stuff * * * * * * * - * - * (C) 2001 Guido Serassio , - * inspired by previous work by Romeo Anghelache & Eric Stern. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. - * - */ - -#include "squid.h" - -/* CygWin & Windows NT Port */ -#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) -#include - -static unsigned int GetOSVersion(); - -#define SKIP_WIN32 -#ifndef SKIP_WIN32 - -static int s_iInitCount = 0; -#define VENDOR "GNU" -#define SOFTWARE "Squid" -#define VERSION "2.5" -#define REGKEY "SOFTWARE\\" VENDOR "\\" SOFTWARE "\\" VERSION -TCHAR servname[512]=_WIN_SQUID_SERVICE_NAME; - -SERVICE_STATUS svcStatus; - -/* ====================================================================== */ -/* LOCAL FUNCTIONS */ -/* ====================================================================== */ - -int create_key(void) -{ - static char *keys[] = - { "SOFTWARE", - VENDOR, - SOFTWARE, - VERSION, - NULL - }; - int index; - HKEY hKey; - HKEY hKeyNext; - int retval; - int rv; - - hKey = HKEY_LOCAL_MACHINE; - index = 0; - retval = 0; - - /* Walk the tree, creating at each stage if necessary */ - while (keys[index]) { - unsigned long result; - - rv = RegCreateKeyEx(hKey, - keys[index], /* subkey */ - 0, /* reserved */ - NULL, /* class */ - REG_OPTION_NON_VOLATILE, - KEY_WRITE, - NULL, - &hKeyNext, - &result); - if (rv != ERROR_SUCCESS) { - debug(1,1)("RegCreateKeyEx(%s),%d\n", keys[index],rv); - retval = -4; - } - - /* Close the old key */ - rv = RegCloseKey(hKey); - if (rv != ERROR_SUCCESS) { - debug(1,1)("RegCloseKey %d\n", rv); - if (retval == 0) { - /* Keep error status from RegCreateKeyEx, if any */ - retval = -4; - } - } - - if (retval) { - break; - } - - hKey = hKeyNext; - index++; - } - - if (keys[index] == NULL) { - /* Close the final key we opened, if we walked the entire - * tree - */ - rv = RegCloseKey(hKey); - if (rv != ERROR_SUCCESS) { - debug(1,1)("RegCloseKey %d\n", rv); - if (retval == 0) { - /* Keep error status from RegCreateKeyEx, if any */ - retval = -4; - } - } - } - - return retval; -} - -int store_key(const char *key, DWORD type, unsigned char *value, int value_size) -{ - long rv; - HKEY hKey; - int retval; - - rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - REGKEY, - 0, - KEY_WRITE, - &hKey); - - if (rv == ERROR_FILE_NOT_FOUND) { - /* Key could not be opened -- try to create it - */ - if (create_key() < 0) { - /* Creation failed (error already reported) */ - return -4; - } - - /* Now it has been created we should be able to open it - */ - rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - REGKEY, - 0, - KEY_WRITE, - &hKey); - - if (rv == ERROR_FILE_NOT_FOUND) { - debug(1,1)("Registry does not contain key %s after creation",REGKEY ); - return -1; - } - } - - if (rv != ERROR_SUCCESS) { - debug(1,1)("RegOpenKeyEx HKLM\\%s, %d\n", REGKEY,rv); - return -4; - } - - /* Now set the value and data */ - rv = RegSetValueEx(hKey, - key, /* value key name */ - 0, /* reserved */ - type, /* type */ - value, /* value data */ - (DWORD)value_size); /* for size of "value" */ - - retval = 0; /* Return value */ - - if (rv != ERROR_SUCCESS) { - debug(1,1)("RegQueryValueEx(key %s),%d\n",key,rv); - retval = -4; - } - else { - debug(1,1)("Registry stored HKLM\\%s\\%s value %s\n", - REGKEY, - key, - type == REG_SZ ? value : (unsigned char*)"(not displayable)"); - } - - /* Make sure we close the key even if there was an error storing - * the data - */ - rv = RegCloseKey(hKey); - if (rv != ERROR_SUCCESS) { - debug(1,1)("RegCloseKey HKLM\\%s, %d\n", REGKEY,rv); - if (retval == 0) { - /* Keep error status from RegQueryValueEx, if any */ - retval = -4; - } - } - - return retval; -} - -void RemoveService() -{ - SC_HANDLE schService; - SC_HANDLE schSCManager; - schSCManager = OpenSCManager( - NULL, // machine (NULL == local) - NULL, // database (NULL == default) - SC_MANAGER_ALL_ACCESS // access required - ); - if (!schSCManager) debug(1,1)("OpenSCManager failed"); - else { - schService = OpenService(schSCManager, servname, SERVICE_ALL_ACCESS); - - if (schService == NULL) debug(1,1)("OpenService failed"); - /* Could not open the service */ - else { - /* try to stop the service */ - if (ControlService(schService, SERVICE_CONTROL_STOP, &svcStatus)) { - Sleep(1000); - while(QueryServiceStatus(schService, &svcStatus)) { - if(svcStatus.dwCurrentState == SERVICE_STOP_PENDING) - Sleep(1000); - else - break; - } - } - - // now remove the service - if (DeleteService(schService) == 0) debug(1,1)("DeleteService failed"); - else printf("Service %s deleted successfuly, see ya'round :)\n", _WIN_SQUID_SERVICE_NAME); - - CloseServiceHandle(schService); - } - - CloseServiceHandle(schSCManager); - } - -} - -void InstallService() -{ - SC_HANDLE schService; - SC_HANDLE schSCManager; - - TCHAR szPath[512]; - int lenpath; - if ((lenpath=GetModuleFileName( NULL, szPath, 512 )) == 0) - { - exit(1); - return; - } - - schSCManager = OpenSCManager( - NULL, // machine (NULL == local) - NULL, // database (NULL == default) - SC_MANAGER_ALL_ACCESS // access required - ); - if (!schSCManager) debug(1,1)("OpenSCManager failed"); - else { - schService = CreateService( - schSCManager, // SCManager database - servname, // name of service - servname, // name to display - SERVICE_ALL_ACCESS, // desired access - SERVICE_WIN32_OWN_PROCESS, // service type - SERVICE_AUTO_START, // start type - SERVICE_ERROR_NORMAL, // error control type - (const char*)szPath, // service's binary - NULL, // no load ordering group - NULL, // no tag identifier - NULL, // dependencies - NULL, // LocalSystem account - NULL); // no password - - if (schService) { - CloseServiceHandle(schService); - - /* Now store the server_root in the registry */ - store_key("ServerRoot", REG_SZ,(unsigned char*) szPath, lenpath+1); - printf("Service %s installed successfuly, enjoy :)\n", _WIN_SQUID_SERVICE_NAME); - printf("that is, u may start it from the Services applet of control panel\n"); - printf("Don't forget to edit squid.conf before starting it\n\n"); - printf("Romeo Anghelache, http://www.andrew.cmu.edu/~romeo/ \n"); - printf("Guido Serassio, http://serassio.interfree.it \n"); - printf("No warranties of any kind, no time for support!\n"); - printf("This work derived from GNU Squid2.3 stable 4\n"); - } - else debug(1,1)("CreateService failed"); - - CloseServiceHandle(schSCManager); - } -} - -int Win32SockInit(void) -{ - int iVersionRequested; - WSADATA wsaData; - int err; - - if (s_iInitCount > 0) { - s_iInitCount++; - return (0); - } - else if (s_iInitCount < 0) - return (s_iInitCount); - - /* s_iInitCount == 0. Do the initailization */ - iVersionRequested = MAKEWORD(2, 0); - err = WSAStartup((WORD) iVersionRequested, &wsaData); - if (err) { - s_iInitCount = -1; - return (s_iInitCount); - } - if (LOBYTE(wsaData.wVersion) != 2 || - HIBYTE(wsaData.wVersion) != 0) { - s_iInitCount = -2; - WSACleanup(); - return (s_iInitCount); - } - debug(1,1)("Windows sockets initialised"); - s_iInitCount++; - return (s_iInitCount); - -} - - -void Win32SockCleanup(void) -{ - if (--s_iInitCount == 0) - WSACleanup(); - return; -} - -#endif - - -static unsigned int GetOSVersion() - -{ -DWORD dwVersion; - dwVersion = GetVersion(); - if (dwVersion < 0x80000000) - { - if ((DWORD)(LOBYTE(LOWORD(dwVersion))) > 4) - return _WIN_OS_WIN2K; - return(_WIN_OS_WINNT); - } - else - if (LOBYTE(LOWORD(dwVersion))<4) - return(_WIN_OS_WIN32S); - else - return(_WIN_OS_WIN9X); -} - -/* ====================================================================== */ -/* PUBLIC FUNCTIONS */ -/* ====================================================================== */ - -void WIN32_Subsystem_Shutdown() - -{ - return; -} - - -void WIN32_Subsystem_Init() - -{ - WIN32_OS_version=GetOSVersion(); - return; -} -#endif +/* + * $Id$ + * + * * * * * * * * Legal stuff * * * * * * * + * + * (C) 2001 Guido Serassio , + * inspired by previous work by Romeo Anghelache & Eric Stern. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include "squid.h" + +/* This code compiles only CygWin & Windows NT Port */ +#if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) +#include + +static unsigned int GetOSVersion(); +void WIN32_svcstatusupdate(DWORD); +void WINAPI WIN32_svcHandler(DWORD); +int WIN32_StoreKey(const char *, DWORD, unsigned char *, int); +static int WIN32_create_key(void); + +static SERVICE_STATUS svcStatus; +static SERVICE_STATUS_HANDLE svcHandle; + +#define VENDOR "GNU" +#define SOFTWARE "Squid" +#define VERSION "2.5" +#define REGKEY "SOFTWARE\\" VENDOR "\\" SOFTWARE "\\" VERSION +TCHAR servname[512] = _WIN_SQUID_SERVICE_NAME; + +/* ====================================================================== */ +/* LOCAL FUNCTIONS */ +/* ====================================================================== */ + +static int +WIN32_create_key(void) +{ + static char *keys[] = { "SOFTWARE", + VENDOR, + SOFTWARE, + VERSION, + NULL + }; + int index; + HKEY hKey; + HKEY hKeyNext; + int retval; + int rv; + + hKey = HKEY_LOCAL_MACHINE; + index = 0; + retval = 0; + + /* Walk the tree, creating at each stage if necessary */ + while (keys[index]) { + unsigned long result; + + rv = RegCreateKeyEx(hKey, keys[index], /* subkey */ + 0, /* reserved */ + NULL, /* class */ + REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKeyNext, &result); + if (rv != ERROR_SUCCESS) { + debug(1, 1) ("RegCreateKeyEx(%s),%d\n", keys[index], rv); + retval = -4; + } + + /* Close the old key */ + rv = RegCloseKey(hKey); + if (rv != ERROR_SUCCESS) { + debug(1, 1) ("RegCloseKey %d\n", rv); + if (retval == 0) { + /* Keep error status from RegCreateKeyEx, if any */ + retval = -4; + } + } + + if (retval) { + break; + } + + hKey = hKeyNext; + index++; + } + + if (keys[index] == NULL) { + /* Close the final key we opened, if we walked the entire + * tree + */ + rv = RegCloseKey(hKey); + if (rv != ERROR_SUCCESS) { + debug(1, 1) ("RegCloseKey %d\n", rv); + if (retval == 0) { + /* Keep error status from RegCreateKeyEx, if any */ + retval = -4; + } + } + } + + return retval; +} + +int +WIN32_StoreKey(const char *key, DWORD type, unsigned char *value, + int value_size) +{ + long rv; + HKEY hKey; + int retval; + + rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY, 0, KEY_WRITE, &hKey); + + if (rv == ERROR_FILE_NOT_FOUND) { + /* Key could not be opened -- try to create it + */ + if (WIN32_create_key() < 0) { + /* Creation failed (error already reported) */ + return -4; + } + + /* Now it has been created we should be able to open it + */ + rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY, 0, KEY_WRITE, &hKey); + + if (rv == ERROR_FILE_NOT_FOUND) { + debug(1, 1) ("Registry does not contain key %s after creation", + REGKEY); + return -1; + } + } + + if (rv != ERROR_SUCCESS) { + debug(1, 1) ("RegOpenKeyEx HKLM\\%s, %d\n", REGKEY, rv); + return -4; + } + + /* Now set the value and data */ + rv = RegSetValueEx(hKey, key, /* value key name */ + 0, /* reserved */ + type, /* type */ + value, /* value data */ + (DWORD) value_size); /* for size of "value" */ + + retval = 0; /* Return value */ + + if (rv != ERROR_SUCCESS) { + debug(1, 1) ("RegQueryValueEx(key %s),%d\n", key, rv); + retval = -4; + } else { + debug(1, 1) ("Registry stored HKLM\\%s\\%s value %s\n", + REGKEY, + key, + type == REG_SZ ? value : (unsigned char *) "(not displayable)"); + } + + /* Make sure we close the key even if there was an error storing + * the data + */ + rv = RegCloseKey(hKey); + if (rv != ERROR_SUCCESS) { + debug(1, 1) ("RegCloseKey HKLM\\%s, %d\n", REGKEY, rv); + if (retval == 0) { + /* Keep error status from RegQueryValueEx, if any */ + retval = -4; + } + } + return retval; +} + +static unsigned int +GetOSVersion() + { + DWORD dwVersion; + dwVersion = GetVersion(); + if (dwVersion < 0x80000000) { + if ((DWORD) (LOBYTE(LOWORD(dwVersion))) > 4) + return _WIN_OS_WIN2K; + return (_WIN_OS_WINNT); + } else if (LOBYTE(LOWORD(dwVersion)) < 4) + return (_WIN_OS_WIN32S); + else + return (_WIN_OS_WIN9X); +} + +/* ====================================================================== */ +/* PUBLIC FUNCTIONS */ +/* ====================================================================== */ + +VOID +WIN32_Exit(int ExitStatus) +{ +#ifdef USE_WIN32_SERVICE + if (ExitStatus) { + svcStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; + svcStatus.dwServiceSpecificExitCode = 1; + } + svcStatus.dwCurrentState = SERVICE_STOPPED; + SetServiceStatus(svcHandle, &svcStatus); +#endif + exit(0); +} + +int +WIN32_Subsystem_Init() + { + WIN32_OS_version = GetOSVersion(); +#ifdef USE_WIN32_SERVICE + if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) { + char path[512]; + HKEY hndKey; + /* Register the service Handler function */ + svcHandle = + RegisterServiceCtrlHandler(_WIN_SQUID_SERVICE_NAME, + WIN32_svcHandler); + if (svcHandle == 0) + return 1; + /* Set Process work dir to directory cointaining squid.exe */ + GetModuleFileName(NULL, path, 512); + path[strlen(path) - 10] = '\0'; + if (SetCurrentDirectory(path) == 0) + return 1; + xfree(ConfigFile); + /* get config file from Windows Registry */ + if (RegOpenKey(HKEY_LOCAL_MACHINE, REGKEY, &hndKey) == ERROR_SUCCESS) { + DWORD Type = 0; + DWORD Size = 0; + LONG Result; + Result = + RegQueryValueEx(hndKey, "ConfigFile", NULL, &Type, NULL, &Size); + if (Result == ERROR_SUCCESS && Size) { + ConfigFile = xmalloc(Size); + RegQueryValueEx(hndKey, "ConfigFile", NULL, &Type, ConfigFile, + &Size); + } else + ConfigFile = xstrdup(DefaultConfigFile); + RegCloseKey(hndKey); + } else { + ConfigFile = xstrdup(DefaultConfigFile); + } + /* Set Service Staus to SERVICE_START_PENDING */ + svcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + svcStatus.dwCurrentState = SERVICE_START_PENDING; + svcStatus.dwControlsAccepted = + SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; + svcStatus.dwWin32ExitCode = 0; + svcStatus.dwServiceSpecificExitCode = 0; + svcStatus.dwCheckPoint = 0; + svcStatus.dwWaitHint = 10000; + SetServiceStatus(svcHandle, &svcStatus); + } +#endif + return 0; +} + +#ifdef USE_WIN32_SERVICE +void +WIN32_svcstatusupdate(DWORD svcstate) + { + if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) { + svcStatus.dwCheckPoint++; + svcStatus.dwCurrentState = svcstate; + SetServiceStatus(svcHandle, &svcStatus); + } +} + +VOID WINAPI +WIN32_svcHandler(DWORD Opcode) +{ + DWORD status; + + switch (Opcode) { + case _WIN_SQUID_SERVICE_CONTROL_STOP: + case _WIN_SQUID_SERVICE_CONTROL_SHUTDOWN: +/* Do whatever it takes to stop here. */ + svcStatus.dwWin32ExitCode = 0; + svcStatus.dwCurrentState = SERVICE_STOP_PENDING; + svcStatus.dwCheckPoint = 0; + svcStatus.dwWaitHint = 10000; + shut_down(SIGTERM); + if (!SetServiceStatus(svcHandle, &svcStatus)) { + status = GetLastError(); + debug(1, 1) (" SetServiceStatus error %ld\n", status); + } + debug(1, 1) ("Leaving Squid service \n"); + return; + case _WIN_SQUID_SERVICE_CONTROL_INTERROGATE: +/* Fall through to send current status. */ + if (!SetServiceStatus(svcHandle, &svcStatus)) { + status = GetLastError(); + debug(1, 1) (" SetServiceStatus error %ld\n", status); + } + break; + case _WIN_SQUID_SERVICE_CONTROL_ROTATE: + rotate_logs(SIGUSR1); + break; + case _WIN_SQUID_SERVICE_CONTROL_RECONFIGURE: + reconfigure(SIGHUP); + break; + case _WIN_SQUID_SERVICE_CONTROL_DEBUG: + sigusr2_handle(SIGUSR2); + break; + case _WIN_SQUID_SERVICE_CONTROL_INTERRUPT: +/* Do whatever it takes to stop here. */ + svcStatus.dwWin32ExitCode = 0; + svcStatus.dwCurrentState = SERVICE_STOP_PENDING; + svcStatus.dwCheckPoint = 0; + svcStatus.dwWaitHint = 10000; + shut_down(SIGINT); + if (!SetServiceStatus(svcHandle, &svcStatus)) { + status = GetLastError(); + debug(1, 1) (" SetServiceStatus error %ld\n", status); + } + debug(1, 1) ("Leaving Squid service \n"); + break; + + default: + debug(1, 1) ("Unrecognized opcode %ld\n", Opcode); + } + return; +} + +void +WIN32_RemoveService() +{ + SC_HANDLE schService; + SC_HANDLE schSCManager; + schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */ + NULL, /* database (NULL == default) */ + SC_MANAGER_ALL_ACCESS /* access required */ + ); + if (!schSCManager) + debug(1, 1) ("OpenSCManager failed"); + else { + schService = OpenService(schSCManager, servname, SERVICE_ALL_ACCESS); + + if (schService == NULL) + debug(1, 1) ("OpenService failed"); + /* Could not open the service */ + else { + /* try to stop the service */ + if (ControlService(schService, _WIN_SQUID_SERVICE_CONTROL_STOP, + &svcStatus)) { + Sleep(1000); + while (QueryServiceStatus(schService, &svcStatus)) { + if (svcStatus.dwCurrentState == SERVICE_STOP_PENDING) + Sleep(1000); + else + break; + } + } + /* now remove the service */ + if (DeleteService(schService) == 0) + debug(1, 1) ("DeleteService failed"); + else + printf("Service %s deleted successfully.\n", + _WIN_SQUID_SERVICE_NAME); + CloseServiceHandle(schService); + } + CloseServiceHandle(schSCManager); + } +} + +void +WIN32_InstallService() +{ + SC_HANDLE schService; + SC_HANDLE schSCManager; + + TCHAR szPath[512]; + int lenpath; + if ((lenpath = GetModuleFileName(NULL, szPath, 512)) == 0) { + exit(1); + return; + } + + schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */ + NULL, /* database (NULL == default) */ + SC_MANAGER_ALL_ACCESS /* access required */ + ); + if (!schSCManager) + debug(1, 1) ("OpenSCManager failed"); + else { + schService = CreateService(schSCManager, /* SCManager database */ + servname, /* name of service */ + servname, /* name to display */ + SERVICE_ALL_ACCESS, /* desired access */ + SERVICE_WIN32_OWN_PROCESS, /* service type */ + SERVICE_AUTO_START, /* start type */ + SERVICE_ERROR_NORMAL, /* error control type */ + (const char *) szPath, /* service's binary */ + NULL, /* no load ordering group */ + NULL, /* no tag identifier */ + NULL, /* dependencies */ + NULL, /* LocalSystem account */ + NULL); /* no password */ + + if (schService) { + CloseServiceHandle(schService); + + /* Now store the server_root in the registry */ + WIN32_StoreKey("ServerRoot", REG_SZ, (unsigned char *) szPath, + lenpath + 1); + printf("Squid Cache version %s for %s\n", version_string, + CONFIG_HOST_TYPE); + printf("installed successfully as %s Windows System Service.\n", + _WIN_SQUID_SERVICE_NAME); + printf + ("To run, start it from the Services Applet of Control Panel.\n"); + printf("Don't forget to edit squid.conf before starting it.\n\n"); + } else + debug(1, 1) ("CreateService failed"); + CloseServiceHandle(schSCManager); + } +} + +void +WIN32_sendSignal(int WIN32_signal) +{ + SERVICE_STATUS ssStatus; + DWORD fdwAccess, fdwControl; + SC_HANDLE schService; + SC_HANDLE schSCManager; + + schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */ + NULL, /* database (NULL == default) */ + SC_MANAGER_ALL_ACCESS /* access required */ + ); + if (!schSCManager) { + debug(1, 1) ("OpenSCManager failed"); + exit(1); + } + /* The required service object access depends on the control. */ + switch (WIN32_signal) { + case 0: /* SIGNULL */ + fdwAccess = SERVICE_INTERROGATE; + fdwControl = _WIN_SQUID_SERVICE_CONTROL_INTERROGATE; + break; + case SIGUSR1: + fdwAccess = SERVICE_USER_DEFINED_CONTROL; + fdwControl = _WIN_SQUID_SERVICE_CONTROL_ROTATE; + break; + case SIGUSR2: + fdwAccess = SERVICE_USER_DEFINED_CONTROL; + fdwControl = _WIN_SQUID_SERVICE_CONTROL_DEBUG; + break; + case SIGHUP: + fdwAccess = SERVICE_USER_DEFINED_CONTROL; + fdwControl = _WIN_SQUID_SERVICE_CONTROL_RECONFIGURE; + break; + case SIGTERM: + fdwAccess = SERVICE_STOP; + fdwControl = _WIN_SQUID_SERVICE_CONTROL_STOP; + break; + case SIGINT: + case SIGKILL: + fdwAccess = SERVICE_USER_DEFINED_CONTROL; + fdwControl = _WIN_SQUID_SERVICE_CONTROL_INTERRUPT; + break; + default: + exit(1); + } + /* Open a handle to the service. */ + schService = OpenService( + schSCManager, /* SCManager database */ + _WIN_SQUID_SERVICE_NAME, /* name of service */ + fdwAccess); /* specify access */ + if (schService == NULL) + { + fprintf(stderr, "%s: ERROR: Could not open Service %s\n", appname, _WIN_SQUID_SERVICE_NAME); + exit(1); + } + else + { + /* Send a control value to the service. */ + if (! ControlService( + schService, /* handle of service */ + fdwControl, /* control value to send */ + &ssStatus) ) /* address of status info */ + { + fprintf(stderr, "%s: ERROR: Could not Control Service %s\n", appname, _WIN_SQUID_SERVICE_NAME); + exit(1); + } + else + { + /* Print the service status. */ + printf("\nStatus of %s Service:\n", _WIN_SQUID_SERVICE_NAME); + printf(" Service Type: 0x%lx\n", ssStatus.dwServiceType); + printf(" Current State: 0x%lx\n", ssStatus.dwCurrentState); + printf(" Controls Accepted: 0x%lx\n", ssStatus.dwControlsAccepted); + printf(" Exit Code: %ld\n", ssStatus.dwWin32ExitCode); + printf(" Service Specific Exit Code: %ld\n", ssStatus.dwServiceSpecificExitCode); + printf(" Check Point: %ld\n", ssStatus.dwCheckPoint); + printf(" Wait Hint: %ld\n", ssStatus.dwWaitHint); + } + CloseServiceHandle(schService); + } + CloseServiceHandle(schSCManager); +} +#endif +#endif + + \ No newline at end of file