]> git.ipfire.org Git - thirdparty/squid.git/blame - src/main.cc
update
[thirdparty/squid.git] / src / main.cc
CommitLineData
30a4f2a8 1/*
6355abef 2 * $Id: main.cc,v 1.105 1996/10/25 16:43:25 wessels Exp $
30a4f2a8 3 *
4 * DEBUG: section 1 Startup and Main Loop
5 * AUTHOR: Harvest Derived
6 *
7 * SQUID Internet Object Cache http://www.nlanr.net/Squid/
8 * --------------------------------------------------------
9 *
10 * Squid is the result of efforts by numerous individuals from the
11 * Internet community. Development is led by Duane Wessels of the
12 * National Laboratory for Applied Network Research and funded by
13 * the National Science Foundation.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 *
29 */
30
31/*
32 * Copyright (c) 1994, 1995. All rights reserved.
33 *
34 * The Harvest software was developed by the Internet Research Task
35 * Force Research Group on Resource Discovery (IRTF-RD):
36 *
37 * Mic Bowman of Transarc Corporation.
38 * Peter Danzig of the University of Southern California.
39 * Darren R. Hardy of the University of Colorado at Boulder.
40 * Udi Manber of the University of Arizona.
41 * Michael F. Schwartz of the University of Colorado at Boulder.
42 * Duane Wessels of the University of Colorado at Boulder.
43 *
44 * This copyright notice applies to software in the Harvest
45 * ``src/'' directory only. Users should consult the individual
46 * copyright notices in the ``components/'' subdirectories for
47 * copyright information about other software bundled with the
48 * Harvest source code distribution.
49 *
50 * TERMS OF USE
51 *
52 * The Harvest software may be used and re-distributed without
53 * charge, provided that the software origin and research team are
54 * cited in any use of the system. Most commonly this is
55 * accomplished by including a link to the Harvest Home Page
56 * (http://harvest.cs.colorado.edu/) from the query page of any
57 * Broker you deploy, as well as in the query result pages. These
58 * links are generated automatically by the standard Broker
59 * software distribution.
60 *
61 * The Harvest software is provided ``as is'', without express or
62 * implied warranty, and with no support nor obligation to assist
63 * in its use, correction, modification or enhancement. We assume
64 * no liability with respect to the infringement of copyrights,
65 * trade secrets, or any patents, and are not responsible for
66 * consequential damages. Proper use of the Harvest software is
67 * entirely the responsibility of the user.
68 *
69 * DERIVATIVE WORKS
70 *
71 * Users may make derivative works from the Harvest software, subject
72 * to the following constraints:
73 *
74 * - You must include the above copyright notice and these
75 * accompanying paragraphs in all forms of derivative works,
76 * and any documentation and other materials related to such
77 * distribution and use acknowledge that the software was
78 * developed at the above institutions.
79 *
80 * - You must notify IRTF-RD regarding your distribution of
81 * the derivative work.
82 *
83 * - You must clearly notify users that your are distributing
84 * a modified version and not the original Harvest software.
85 *
86 * - Any derivative product is also subject to these copyright
87 * and use restrictions.
88 *
89 * Note that the Harvest software is NOT in the public domain. We
90 * retain copyright, as specified above.
91 *
92 * HISTORY OF FREE SOFTWARE STATUS
93 *
94 * Originally we required sites to license the software in cases
95 * where they were going to build commercial products/services
96 * around Harvest. In June 1995 we changed this policy. We now
97 * allow people to use the core Harvest software (the code found in
98 * the Harvest ``src/'' directory) for free. We made this change
99 * in the interest of encouraging the widest possible deployment of
100 * the technology. The Harvest software is really a reference
101 * implementation of a set of protocols and formats, some of which
102 * we intend to standardize. We encourage commercial
103 * re-implementations of code complying to this set of standards.
104 */
44a47c6e 105
106#include "squid.h"
107
b8de7ebe 108time_t squid_starttime = 0;
30a4f2a8 109int theHttpConnection = -1;
110int theInIcpConnection = -1;
111int theOutIcpConnection = -1;
090089c4 112int do_reuse = 1;
d68adf86 113int opt_unlink_on_reload = 0;
30a4f2a8 114int opt_reload_hit_only = 0; /* only UDP_HIT during store relaod */
1758c627 115int opt_catch_signals = 1;
30a4f2a8 116int opt_dns_tests = 1;
117int opt_foreground_rebuild = 0;
b6f794d6 118int opt_zap_disk_store = 0;
6e40f263 119int opt_syslog_enable = 0; /* disabled by default */
1758c627 120int opt_no_ipcache = 0; /* use ipcache by default */
fedac7e5 121static int opt_send_signal = -1; /* no signal to send */
caebbe00 122int opt_udp_hit_obj = 1;
123int opt_mem_pools = 1;
124int opt_forwarded_for = 1;
090089c4 125int vhost_mode = 0;
235c7b49 126volatile int unbuffered_logs = 1; /* debug and hierarchy unbuffered by default */
127volatile int shutdown_pending = 0; /* set by SIGTERM handler (shut_down()) */
128volatile int reread_pending = 0; /* set by SIGHUP handler */
30a4f2a8 129char version_string[] = SQUID_VERSION;
130char appname[] = "squid";
131char localhost[] = "127.0.0.1";
132struct in_addr local_addr;
56082504 133char dash_str[] = "-";
134char null_string[] = "";
30a4f2a8 135
136/* for error reporting from xmalloc and friends */
67508012 137extern void (*failure_notify) _PARAMS((char *));
30a4f2a8 138
67508012 139static volatile int rotate_pending = 0; /* set by SIGUSR1 handler */
30a4f2a8 140static int httpPortNumOverride = 1;
141static int icpPortNumOverride = 1; /* Want to detect "-u 0" */
142#if MALLOC_DBG
4d64d74a 143static int malloc_debug_level = 0;
30a4f2a8 144#endif
4d7add01 145
146static time_t next_cleaning;
147static time_t next_maintain;
148static time_t next_dirclean;
149static time_t next_announce;
150static time_t next_ip_purge;
151
24382924 152static time_t mainMaintenance _PARAMS((void));
67508012 153static void rotate_logs _PARAMS((int));
154static void reconfigure _PARAMS((int));
155static void mainInitialize _PARAMS((void));
156static void mainReinitialize _PARAMS((void));
67508012 157static void usage _PARAMS((void));
158static void mainParseOptions _PARAMS((int, char **));
159static void sendSignal _PARAMS((void));
24382924 160static void serverConnectionsOpen _PARAMS((void));
b8d8561b 161
66cedb85 162extern int store_maintain_rate;
163
b8d8561b 164static void
0673c0ba 165usage(void)
ccff9601 166{
77ffc99f 167 fprintf(stderr, "\
7690e8eb 168Usage: %s [-hsvzCDFRUVY] [-f config-file] [-[au] port] [-k signal]\n\
30a4f2a8 169 -a port Specify ASCII port number (default: %d).\n\
170 -f file Use given config-file instead of\n\
171 %s\n\
ccff9601 172 -h Print help message.\n\
7690e8eb 173 -i Disable IP caching.\n\
f3753518 174 -k reconfigure|rotate|shutdown|interrupt|kill|debug|check\n\
7690e8eb 175 Send signal to running copy and exit.\n\
ccff9601 176 -s Enable logging to syslog.\n\
6e40f263 177 -u port Specify ICP port number (default: %d), disable with 0.\n\
ccff9601 178 -v Print version.\n\
179 -z Zap disk storage -- deletes all objects in disk cache.\n\
180 -C Do not catch fatal signals.\n\
181 -D Disable initial DNS tests.\n\
30a4f2a8 182 -F Foreground fast store rebuild.\n\
ccff9601 183 -R Do not set REUSEADDR on port.\n\
d68adf86 184 -U Unlink expired objects on reload.\n\
30a4f2a8 185 -V Virtual host httpd-accelerator.\n\
1061b406 186 -Y Only return UDP_HIT or UDP_RELOADING during fast reload.\n",
30a4f2a8 187 appname, CACHE_HTTP_PORT, DefaultConfigFile, CACHE_ICP_PORT);
77ffc99f 188 exit(1);
ccff9601 189}
190
b8d8561b 191static void
192mainParseOptions(int argc, char *argv[])
090089c4 193{
090089c4 194 extern char *optarg;
4d64d74a 195 int c;
090089c4 196
7690e8eb 197 while ((c = getopt(argc, argv, "CDFRUVYa:bf:hik:m:su:vz?")) != -1) {
090089c4 198 switch (c) {
090089c4 199 case 'C':
1758c627 200 opt_catch_signals = 0;
090089c4 201 break;
202 case 'D':
30a4f2a8 203 opt_dns_tests = 0;
090089c4 204 break;
30a4f2a8 205 case 'F':
206 opt_foreground_rebuild = 1;
090089c4 207 break;
090089c4 208 case 'R':
209 do_reuse = 0;
210 break;
d68adf86 211 case 'U':
212 opt_unlink_on_reload = 1;
213 break;
30a4f2a8 214 case 'V':
215 vhost_mode = 1;
216 break;
217 case 'Y':
218 opt_reload_hit_only = 1;
219 break;
220 case 'a':
221 httpPortNumOverride = atoi(optarg);
222 break;
223 case 'b':
224 unbuffered_logs = 0;
225 break;
090089c4 226 case 'f':
00fac1f8 227 xfree(ConfigFile);
228 ConfigFile = xstrdup(optarg);
090089c4 229 break;
30a4f2a8 230 case 'h':
231 usage();
090089c4 232 break;
1758c627 233 case 'i':
234 opt_no_ipcache = 1;
235 break;
7690e8eb 236 case 'k':
24382924 237 if ((int) strlen(optarg) < 1)
7690e8eb 238 usage();
239 if (!strncmp(optarg, "reconfigure", strlen(optarg)))
240 opt_send_signal = SIGHUP;
241 else if (!strncmp(optarg, "rotate", strlen(optarg)))
242 opt_send_signal = SIGUSR1;
243 else if (!strncmp(optarg, "debug", strlen(optarg)))
244 opt_send_signal = SIGUSR2;
245 else if (!strncmp(optarg, "shutdown", strlen(optarg)))
246 opt_send_signal = SIGTERM;
6759a5fb 247 else if (!strncmp(optarg, "interrupt", strlen(optarg)))
248 opt_send_signal = SIGINT;
7690e8eb 249 else if (!strncmp(optarg, "kill", strlen(optarg)))
250 opt_send_signal = SIGKILL;
251 else if (!strncmp(optarg, "check", strlen(optarg)))
fedac7e5 252 opt_send_signal = 0; /* SIGNULL */
7690e8eb 253 else
254 usage();
255 break;
090089c4 256 case 'm':
30a4f2a8 257#if MALLOC_DBG
090089c4 258 malloc_debug_level = atoi(optarg);
34c54bb6 259 /* NOTREACHED */
090089c4 260 break;
30a4f2a8 261#else
262 fatal("Need to add -DMALLOC_DBG when compiling to use -m option");
24382924 263 /* NOTREACHED */
30a4f2a8 264#endif
265 case 's':
6e40f263 266 opt_syslog_enable = 1;
30a4f2a8 267 break;
268 case 'u':
269 icpPortNumOverride = atoi(optarg);
270 if (icpPortNumOverride < 0)
271 icpPortNumOverride = 0;
272 break;
273 case 'v':
274 printf("Squid Cache: Version %s\n", version_string);
275 exit(0);
276 /* NOTREACHED */
090089c4 277 case 'z':
b6f794d6 278 opt_zap_disk_store = 1;
090089c4 279 break;
280 case '?':
090089c4 281 default:
ccff9601 282 usage();
090089c4 283 break;
284 }
090089c4 285 }
4d64d74a 286}
090089c4 287
b8d8561b 288static void
289rotate_logs(int sig)
30a4f2a8 290{
291 debug(21, 1, "rotate_logs: SIGUSR1 received.\n");
292 rotate_pending = 1;
293#if !HAVE_SIGACTION
294 signal(sig, rotate_logs);
295#endif
296}
297
b8d8561b 298static void
299reconfigure(int sig)
30a4f2a8 300{
301 debug(21, 1, "reconfigure: SIGHUP received\n");
302 debug(21, 1, "Waiting %d seconds for active connections to finish\n",
b6f794d6 303 Config.lifetimeShutdown);
30a4f2a8 304 reread_pending = 1;
305#if !HAVE_SIGACTION
306 signal(sig, reconfigure);
307#endif
308}
309
b8d8561b 310void
311shut_down(int sig)
30a4f2a8 312{
f3753518 313 shutdown_pending = sig == SIGINT ? -1 : 1;
30a4f2a8 314 debug(21, 1, "Preparing for shutdown after %d connections\n",
315 ntcpconn + nudpconn);
316 debug(21, 1, "Waiting %d seconds for active connections to finish\n",
f3753518 317 shutdown_pending > 0 ? Config.lifetimeShutdown : 0);
6e40f263 318#if SA_RESETHAND == 0
319 signal(SIGTERM, SIG_DFL);
320 signal(SIGINT, SIG_DFL);
321#endif
30a4f2a8 322}
323
24382924 324static void
0673c0ba 325serverConnectionsOpen(void)
4d64d74a 326{
30a4f2a8 327 struct in_addr addr;
328 u_short port;
30a4f2a8 329 enter_suid();
16b204c4 330 theHttpConnection = comm_open(SOCK_STREAM,
331 0,
b6f794d6 332 Config.Addrs.tcp_incoming,
333 Config.Port.http,
16b204c4 334 COMM_NONBLOCKING,
30a4f2a8 335 "HTTP Port");
336 leave_suid();
337 if (theHttpConnection < 0) {
338 fatal("Cannot open HTTP Port");
090089c4 339 }
30a4f2a8 340 fd_note(theHttpConnection, "HTTP socket");
341 comm_listen(theHttpConnection);
b177367b 342 commSetSelect(theHttpConnection,
090089c4 343 COMM_SELECT_READ,
344 asciiHandleConn,
b177367b 345 NULL, 0);
30a4f2a8 346 debug(1, 1, "Accepting HTTP connections on FD %d.\n",
347 theHttpConnection);
090089c4 348
b6f794d6 349 if (!httpd_accel_mode || Config.Accel.withProxy) {
7690e8eb 350 if ((port = Config.Port.icp) > (u_short) 0) {
328d1c43 351 enter_suid();
16b204c4 352 theInIcpConnection = comm_open(SOCK_DGRAM,
353 0,
b6f794d6 354 Config.Addrs.udp_incoming,
30a4f2a8 355 port,
16b204c4 356 COMM_NONBLOCKING,
30a4f2a8 357 "ICP Port");
328d1c43 358 leave_suid();
30a4f2a8 359 if (theInIcpConnection < 0)
360 fatal("Cannot open ICP Port");
361 fd_note(theInIcpConnection, "ICP socket");
b177367b 362 commSetSelect(theInIcpConnection,
090089c4 363 COMM_SELECT_READ,
364 icpHandleUdp,
b177367b 365 NULL, 0);
e90100aa 366 comm_join_mcast_groups(theInIcpConnection);
30a4f2a8 367 debug(1, 1, "Accepting ICP connections on FD %d.\n",
368 theInIcpConnection);
369
b6f794d6 370 if ((addr = Config.Addrs.udp_outgoing).s_addr != INADDR_NONE) {
328d1c43 371 enter_suid();
16b204c4 372 theOutIcpConnection = comm_open(SOCK_DGRAM,
cc6a9d2e 373 0,
30a4f2a8 374 addr,
375 port,
cc6a9d2e 376 COMM_NONBLOCKING,
30a4f2a8 377 "ICP Port");
9d90e665 378 leave_suid();
30a4f2a8 379 if (theOutIcpConnection < 0)
380 fatal("Cannot open Outgoing ICP Port");
b177367b 381 commSetSelect(theOutIcpConnection,
30a4f2a8 382 COMM_SELECT_READ,
383 icpHandleUdp,
b177367b 384 NULL, 0);
30a4f2a8 385 debug(1, 1, "Accepting ICP connections on FD %d.\n",
386 theOutIcpConnection);
387 fd_note(theOutIcpConnection, "Outgoing ICP socket");
388 fd_note(theInIcpConnection, "Incoming ICP socket");
389 } else {
390 theOutIcpConnection = theInIcpConnection;
391 }
090089c4 392 }
393 }
5ecceaa4 394 clientdbInit();
16b204c4 395 icmpOpen();
67508012 396 netdbInit();
5f3f8d0e 397}
398
b8d8561b 399void
0673c0ba 400serverConnectionsClose(void)
5f3f8d0e 401{
30a4f2a8 402 /* NOTE, this function will be called repeatedly while shutdown
403 * is pending */
404 if (theHttpConnection >= 0) {
405 debug(21, 1, "FD %d Closing HTTP connection\n",
406 theHttpConnection);
407 comm_close(theHttpConnection);
b177367b 408 commSetSelect(theHttpConnection,
5f3f8d0e 409 COMM_SELECT_READ,
410 NULL,
b177367b 411 NULL, 0);
30a4f2a8 412 theHttpConnection = -1;
090089c4 413 }
30a4f2a8 414 if (theInIcpConnection >= 0) {
415 /* NOTE, don't close outgoing ICP connection, we need to write to
416 * it during shutdown */
417 debug(21, 1, "FD %d Closing ICP connection\n",
418 theInIcpConnection);
419 if (theInIcpConnection != theOutIcpConnection)
420 comm_close(theInIcpConnection);
b177367b 421 commSetSelect(theInIcpConnection,
5f3f8d0e 422 COMM_SELECT_READ,
423 NULL,
b177367b 424 NULL, 0);
30a4f2a8 425 if (theInIcpConnection != theOutIcpConnection)
b177367b 426 commSetSelect(theOutIcpConnection,
30a4f2a8 427 COMM_SELECT_READ,
428 NULL,
b177367b 429 NULL, 0);
30a4f2a8 430 theInIcpConnection = -1;
5f3f8d0e 431 }
c7433536 432 if (icmp_sock > -1)
f6610c4e 433 icmpClose();
5f3f8d0e 434}
435
b8d8561b 436static void
0673c0ba 437mainReinitialize(void)
5f3f8d0e 438{
ad6272a1 439 debug(1, 0, "Restarting Squid Cache (version %s)...\n", version_string);
0ffd22bc 440 /* Already called serverConnectionsClose and ipcacheShutdownServers() */
5f3f8d0e 441 neighborsDestroy();
00fac1f8 442 parseConfigFile(ConfigFile);
b6f794d6 443 _db_init(Config.Log.log, Config.debugOptions);
0ffd22bc 444 neighbors_init();
f88bb09c 445 dnsOpenServers();
d2af9477 446 redirectOpenServers();
0ffd22bc 447 serverConnectionsOpen();
234967c9 448 (void) ftpInitialize();
b6f794d6 449 if (theOutIcpConnection >= 0 && (!httpd_accel_mode || Config.Accel.withProxy))
30a4f2a8 450 neighbors_open(theOutIcpConnection);
0ffd22bc 451 debug(1, 0, "Ready to serve requests.\n");
5f3f8d0e 452}
453
b8d8561b 454static void
0673c0ba 455mainInitialize(void)
5f3f8d0e 456{
457 static int first_time = 1;
1758c627 458 if (opt_catch_signals) {
30a4f2a8 459 squid_signal(SIGSEGV, death, SA_NODEFER | SA_RESETHAND);
460 squid_signal(SIGBUS, death, SA_NODEFER | SA_RESETHAND);
44f99671 461 }
30a4f2a8 462 squid_signal(SIGPIPE, SIG_IGN, SA_RESTART);
463 squid_signal(SIGCHLD, sig_child, SA_NODEFER | SA_RESTART);
44f99671 464
00fac1f8 465 if (ConfigFile == NULL)
466 ConfigFile = xstrdup(DefaultConfigFile);
467 parseConfigFile(ConfigFile);
5f3f8d0e 468
30a4f2a8 469 leave_suid(); /* Run as non privilegied user */
5f3f8d0e 470
34c54bb6 471#if USE_ASYNC_IO
472#if HAVE_AIO_INIT
473 if (first_time)
474 aio_init();
475#endif
476 squid_signal(SIGIO, aioSigHandler, SA_RESTART);
477#endif
478
30a4f2a8 479 if (httpPortNumOverride != 1)
480 setHttpPortNum((u_short) httpPortNumOverride);
481 if (icpPortNumOverride != 1)
482 setIcpPortNum((u_short) icpPortNumOverride);
483
b6f794d6 484 _db_init(Config.Log.log, Config.debugOptions);
30a4f2a8 485 fdstat_open(fileno(debug_log), FD_LOG);
b6f794d6 486 fd_note(fileno(debug_log), Config.Log.log);
5f3f8d0e 487
30a4f2a8 488 debug(1, 0, "Starting Squid Cache version %s for %s...\n",
489 version_string,
490 CONFIG_HOST_TYPE);
491 debug(1, 1, "With %d file descriptors available\n", FD_SETSIZE);
5f3f8d0e 492
850c4ead 493 if (first_time) {
94e891ea 494 stmemInit(); /* stmem must go before at least redirect */
234967c9 495 disk_init(); /* disk_init must go before ipcache_init() */
850c4ead 496 }
5f3f8d0e 497 ipcache_init();
f88bb09c 498 fqdncache_init();
499 dnsOpenServers();
d2af9477 500 redirectOpenServers();
5f3f8d0e 501 neighbors_init();
234967c9 502 (void) ftpInitialize();
5f3f8d0e 503
30a4f2a8 504#if MALLOC_DBG
5f3f8d0e 505 malloc_debug(0, malloc_debug_level);
506#endif
507
a26bdc75 508 if (first_time) {
5f3f8d0e 509 /* module initialization */
7111c86a 510 urlInitialize();
a528eb87 511 stat_init(&HTTPCacheInfo, Config.Log.access);
512 stat_init(&ICPCacheInfo, NULL);
5f3f8d0e 513 storeInit();
090089c4 514
b6f794d6 515 if (Config.effectiveUser) {
234967c9 516 /* we were probably started as root, so cd to a swap
517 * directory in case we dump core */
518 if (chdir(swappath(0)) < 0) {
519 debug(1, 0, "%s: %s\n", swappath(0), xstrerror());
520 fatal_dump("Cannot cd to swap directory?");
521 }
522 }
5f3f8d0e 523 /* after this point we want to see the mallinfo() output */
524 do_mallinfo = 1;
525 }
2285407f 526 serverConnectionsOpen();
b6f794d6 527 if (theOutIcpConnection >= 0 && (!httpd_accel_mode || Config.Accel.withProxy))
30a4f2a8 528 neighbors_open(theOutIcpConnection);
529
0a5b9b32 530 if (first_time)
531 writePidFile(); /* write PID file */
532
30a4f2a8 533 squid_signal(SIGUSR1, rotate_logs, SA_RESTART);
534 squid_signal(SIGUSR2, sigusr2_handle, SA_RESTART);
535 squid_signal(SIGHUP, reconfigure, SA_RESTART);
536 squid_signal(SIGTERM, shut_down, SA_NODEFER | SA_RESETHAND | SA_RESTART);
537 squid_signal(SIGINT, shut_down, SA_NODEFER | SA_RESETHAND | SA_RESTART);
5f3f8d0e 538 debug(1, 0, "Ready to serve requests.\n");
4d7add01 539
540 if (first_time) {
541 next_cleaning = squid_curtime + Config.cleanRate;
542 next_maintain = squid_curtime + 0;
543 next_dirclean = squid_curtime + 15;
cb0486c3 544 next_announce = squid_curtime + 3600;
4d7add01 545 next_ip_purge = squid_curtime + 10;
546 }
0a5b9b32 547 first_time = 0;
4d64d74a 548}
549
b8d8561b 550static time_t
0673c0ba 551mainMaintenance(void)
9ca89c5a 552{
4d7add01 553 time_t next;
4d7add01 554 if (squid_curtime >= next_maintain) {
28b2f45f 555 storeMaintainSwapSpace();
556 next_maintain = squid_curtime + 1;
9ca89c5a 557 }
86ee2017 558 if (store_rebuilding == STORE_NOT_REBUILDING) {
559 if (squid_curtime >= next_ip_purge) {
560 ipcache_purgelru();
561 next_ip_purge = squid_curtime + 10;
562 } else if (squid_curtime >= next_dirclean) {
563 /* clean a cache directory every 15 seconds */
564 /* 15 * 16 * 256 = 17 hrs */
565 storeDirClean();
566 next_dirclean = squid_curtime + 15;
567 } else if (squid_curtime >= next_cleaning) {
568 storePurgeOld();
569 next_cleaning = squid_curtime + Config.cleanRate;
570 } else if (squid_curtime >= next_announce) {
1d73e33a 571 if (Config.Announce.on)
ceb8994e 572 send_announce();
86ee2017 573 next_announce = squid_curtime + Config.Announce.rate;
574 }
9ca89c5a 575 }
4d7add01 576 next = next_ip_purge;
577 if (next_dirclean < next)
578 next = next_dirclean;
579 if (next_cleaning < next)
580 next = next_cleaning;
581 if (next_announce < next)
582 next = next_announce;
583 return next - squid_curtime;
9ca89c5a 584}
585
b8d8561b 586int
587main(int argc, char **argv)
4d64d74a 588{
589 int errcount = 0;
4d64d74a 590 int n; /* # of GC'd objects */
bc528c78 591 time_t loop_delay;
4d64d74a 592
7328e889 593 /* call mallopt() before anything else */
594#if HAVE_MALLOPT
595#ifdef M_GRAIN
596 /* Round up all sizes to a multiple of this */
597 mallopt(M_GRAIN, 16);
598#endif
599#ifdef M_MXFAST
600 /* biggest size that is considered a small block */
601 mallopt(M_MXFAST, 256);
602#endif
603#ifdef M_NBLKS
604 /* allocate this many small blocks at once */
605 mallopt(M_NLBLKS, 32);
606#endif
607#endif /* HAVE_MALLOPT */
608
30a4f2a8 609 memset(&local_addr, '\0', sizeof(struct in_addr));
610 local_addr.s_addr = inet_addr(localhost);
611
4d64d74a 612 errorInitialize();
613
b8de7ebe 614 squid_starttime = getCurrentTime();
4d64d74a 615 failure_notify = fatal_dump;
616
617 mainParseOptions(argc, argv);
618
7690e8eb 619 /* send signal to running copy and exit */
620 if (opt_send_signal != -1) {
621 sendSignal();
622 /* NOTREACHED */
623 }
4d64d74a 624 setMaxFD();
625
1758c627 626 if (opt_catch_signals)
30a4f2a8 627 for (n = FD_SETSIZE; n > 2; n--)
628 close(n);
4d64d74a 629
4d64d74a 630 /*init comm module */
631 comm_init();
632
633 /* we have to init fdstat here. */
634 fdstat_init(PREOPEN_FD);
30a4f2a8 635 fdstat_open(0, FD_LOG);
636 fdstat_open(1, FD_LOG);
637 fdstat_open(2, FD_LOG);
4d64d74a 638 fd_note(0, "STDIN");
639 fd_note(1, "STDOUT");
640 fd_note(2, "STDERR");
641
4d64d74a 642 /* preinit for debug module */
643 debug_log = stderr;
644 hash_init(0);
645
4d64d74a 646 mainInitialize();
647
090089c4 648 /* main loop */
983061ed 649 for (;;) {
30a4f2a8 650 if (rotate_pending) {
651 ftpServerClose();
e97f40f4 652 icmpClose();
30a4f2a8 653 _db_rotate_log(); /* cache.log */
654 storeWriteCleanLog();
655 storeRotateLog(); /* store.log */
30a4f2a8 656 stat_rotate_log(); /* access.log */
657 (void) ftpInitialize();
e97f40f4 658 icmpOpen();
30a4f2a8 659 rotate_pending = 0;
660 }
4d7add01 661 if ((loop_delay = mainMaintenance()) < 0)
662 loop_delay = 0;
66cedb85 663 else if (loop_delay > store_maintain_rate)
664 loop_delay = store_maintain_rate;
bc528c78 665 if (doBackgroundProcessing())
4d7add01 666 loop_delay = 0;
9ca89c5a 667 switch (comm_select(loop_delay)) {
090089c4 668 case COMM_OK:
234967c9 669 errcount = 0; /* reset if successful */
090089c4 670 break;
671 case COMM_ERROR:
672 errcount++;
234967c9 673 debug(1, 0, "Select loop Error. Retry %d\n", errcount);
090089c4 674 if (errcount == 10)
4d64d74a 675 fatal_dump("Select Loop failed!");
090089c4 676 break;
4d64d74a 677 case COMM_SHUTDOWN:
43030d00 678 /* delayed close so we can transmit while shutdown pending */
30a4f2a8 679 if (theOutIcpConnection > 0) {
680 comm_close(theOutIcpConnection);
681 theOutIcpConnection = -1;
43030d00 682 }
5f3f8d0e 683 if (shutdown_pending) {
684 normal_shutdown();
685 exit(0);
686 } else if (reread_pending) {
0ffd22bc 687 mainReinitialize();
5f3f8d0e 688 reread_pending = 0; /* reset */
689 } else {
690 fatal_dump("MAIN: SHUTDOWN from comm_select, but nothing pending.");
691 }
0ffd22bc 692 break;
9ca89c5a 693 case COMM_TIMEOUT:
6c93e119 694 break;
090089c4 695 default:
6eb42cae 696 fatal_dump("MAIN: Internal error -- this should never happen.");
090089c4 697 break;
698 }
699 }
700 /* NOTREACHED */
983061ed 701 return 0;
090089c4 702}
7690e8eb 703
b8d8561b 704static void
0673c0ba 705sendSignal(void)
7690e8eb 706{
ff8d0ea6 707 pid_t pid;
fedac7e5 708 debug_log = stderr;
709 if (ConfigFile == NULL)
710 ConfigFile = xstrdup(DefaultConfigFile);
711 parseConfigFile(ConfigFile);
712 pid = readPidFile();
713 if (pid > 1) {
714 if (kill(pid, opt_send_signal) &&
715 /* ignore permissions if just running check */
716 !(opt_send_signal == 0 && errno == EPERM)) {
717 fprintf(stderr, "%s: ERROR: Could not send ", appname);
718 fprintf(stderr, "signal %d to process %d: %s\n",
41d30aa8 719 opt_send_signal, (int) pid, xstrerror());
7690e8eb 720 exit(1);
721 }
fedac7e5 722 } else {
723 fprintf(stderr, "%s: ERROR: No running copy\n", appname);
724 exit(1);
7690e8eb 725 }
fedac7e5 726 /* signal successfully sent */
727 exit(0);
728}