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