-/* $Id: cache_cf.cc,v 1.21 1996/04/08 16:01:05 wessels Exp $ */
+/* $Id: cache_cf.cc,v 1.22 1996/04/08 17:07:59 wessels Exp $ */
/* DEBUG: Section 3 cache_cf: Configuration file parsing */
localhost.s_addr = inet_addr("127.0.0.1");
init = 1;
}
-
naddr.s_addr = address.s_addr;
if (naddr.s_addr == localhost.s_addr)
return IP_ALLOW;
-/* $Id: comm.cc,v 1.16 1996/04/05 17:48:27 wessels Exp $ */
+/* $Id: comm.cc,v 1.17 1996/04/08 17:08:00 wessels Exp $ */
/* DEBUG: Section 5 comm: socket level functions */
/* STATIC */
static int *fd_lifetime = NULL;
+#ifdef UNUSED_CODE
static fd_set send_sockets;
static fd_set receive_sockets;
+#endif
static int (*app_handler) ();
static void checkTimeouts();
static void checkLifetimes();
static int examine_select _PARAMS((fd_set *, fd_set *, fd_set *));
static int commSetNoLinger _PARAMS((int));
-/* EXTERN */
-extern int errno;
-extern int do_reuse;
-extern int getMaxFD();
-extern int theAsciiConnection;
-extern int theUdpConnection;
-extern int getConnectTimeout();
-
-extern int fd_of_first_client _PARAMS((StoreEntry *));
-
void comm_handler()
{
/* Call application installed handler. */
int sock;
{
int x;
+#ifdef UNUSED_CODE
FD_SET(sock, &receive_sockets);
+#endif
if ((x = listen(sock, 50)) < 0) {
debug(5, 0, "comm_listen: listen(%d, 50): %s\n",
sock, xstrerror());
sock, lft);
}
/* Add new socket to list of open sockets. */
+#ifdef UNUSED_CODE
FD_SET(sock, &send_sockets);
+#endif
conn->sender = 1;
return status;
}
conn->comm_type = listener->comm_type;
strcpy(conn->ipaddr, inet_ntoa(P.sin_addr));
+#ifdef UNUSED_CODE
FD_SET(sock, &receive_sockets);
+#endif
commSetNonBlocking(sock);
return sock;
}
conn = &fd_table[fd];
+#ifdef UNUSED_SOCKETS
FD_CLR(fd, &receive_sockets);
FD_CLR(fd, &send_sockets);
+#endif
comm_set_fd_lifetime(fd, -1); /* invalidate the lifetime */
debug(5, 10, "comm_close: FD %d\n", fd);
struct timeval poll_time;
struct timeval zero_tv;
int sel_fd_width;
+ int nfds;
+
+ fd_set read_mask, write_mask;
+ int (*tmp) () = NULL;
+ int maxfd;
/* assume all process are very fast (less than 1 second). Call
* time() only once */
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);
- for (i = 0; i < fdstat_biggest_fd() + 1; i++) {
+ nfds = 0;
+ maxfd = fdstat_biggest_fd() + 1;
+ for (i = 0; i < maxfd; i++) {
/* Check each open socket for a handler. */
- if (fd_table[i].read_handler && fd_table[i].stall_until <= cached_curtime)
+ if (fd_table[i].read_handler && fd_table[i].stall_until <= cached_curtime) {
+ nfds++;
FD_SET(i, &readfds);
- if (fd_table[i].write_handler)
+ }
+ if (fd_table[i].write_handler) {
+ nfds++;
FD_SET(i, &writefds);
- if (fd_table[i].except_handler)
+ }
+ if (fd_table[i].except_handler) {
+ nfds++;
FD_SET(i, &exceptfds);
+ }
}
if (!fdstat_are_n_free_fd(RESERVED_FD)) {
FD_CLR(theAsciiConnection, &readfds);
}
+ debug(5, 1, "comm_select: nfds = %d\n", nfds);
+ if (nfds == 0)
+ return COMM_SHUTDOWN;
while (1) {
poll_time.tv_sec = 1;
poll_time.tv_usec = 0;
num = select(fdstat_biggest_fd() + 1,
&readfds, &writefds, &exceptfds, &poll_time);
+ debug(0, 0, "num=%d errno=%d\n", num, errno);
if (num >= 0)
break;
+ if (errno == EINTR)
+ break;
if (errno != EINTR) {
debug(5, 0, "comm_select: select failure: %s (errno %d).\n",
xstrerror(), errno);
}
/* if select interrupted, try again */
}
+ if (num < 0)
+ continue;
debug(5, num ? 5 : 8, "comm_select: %d sockets ready at %d\n",
num, cached_curtime);
* limit in SunOS */
if (num) {
- for (fd = 0; (fd < (fdstat_biggest_fd() + 1)) && (num > 0); fd++) {
+ maxfd = fdstat_biggest_fd() + 1;
+ for (fd = 0; fd < maxfd && num > 0; fd++) {
if (!(FD_ISSET(fd, &readfds) || FD_ISSET(fd, &writefds) ||
FD_ISSET(fd, &exceptfds)))
* Don't forget to keep the UDP acks coming and going.
*/
{
- fd_set read_mask, write_mask;
- int (*tmp) () = NULL;
FD_ZERO(&read_mask);
FD_ZERO(&write_mask);
- if ((fdstat_are_n_free_fd(RESERVED_FD)) && (fd_table[theAsciiConnection].read_handler))
+ if (theAsciiConnection >= 0) {
+ if ((fdstat_are_n_free_fd(RESERVED_FD))
+ && (fd_table[theAsciiConnection].read_handler))
FD_SET(theAsciiConnection, &read_mask);
else
FD_CLR(theAsciiConnection, &read_mask);
+ }
if (theUdpConnection >= 0) {
if (fd_table[theUdpConnection].read_handler)
FD_SET(theUdpConnection, &read_mask);
}
}
}
+
if ((fd == theUdpConnection) || (fd == theAsciiConnection))
continue;
if (FD_ISSET(fd, &readfds)) {
debug(5, 6, "comm_select: FD %d ready for reading\n", fd);
if (fd_table[fd].read_handler) {
- int (*tmp) () = fd_table[fd].read_handler;
+ tmp = fd_table[fd].read_handler;
fd_table[fd].read_handler = 0;
debug(5, 10, "calling read handler %p(%d,%p)\n",
tmp, fd, fd_table[fd].read_data);
if (FD_ISSET(fd, &writefds)) {
debug(5, 5, "comm_select: FD %d ready for writing\n", fd);
if (fd_table[fd].write_handler) {
- int (*tmp) () = fd_table[fd].write_handler;
+ tmp = fd_table[fd].write_handler;
fd_table[fd].write_handler = 0;
debug(5, 10, "calling write handler %p(%d,%p)\n",
tmp, fd, fd_table[fd].write_data);
if (FD_ISSET(fd, &exceptfds)) {
debug(5, 5, "comm_select: FD %d has an exception\n", fd);
if (fd_table[fd].except_handler) {
- int (*tmp) () = fd_table[fd].except_handler;
+ tmp = fd_table[fd].except_handler;
fd_table[fd].except_handler = 0;
debug(5, 10, "calling except handler %p(%d,%p)\n",
tmp, fd, fd_table[fd].except_data);
static void checkTimeouts()
{
int fd;
+ int (*tmp) () = NULL;
+ FD_ENTRY *f = NULL;
+ int maxfd = fdstat_biggest_fd() + 1;
+
/* scan for timeout */
- for (fd = 0; fd < (fdstat_biggest_fd() + 1); ++fd) {
- if ((fd_table[fd].timeout_handler) &&
- (fd_table[fd].timeout_time <= cached_curtime)) {
- int (*tmp) () = fd_table[fd].timeout_handler;
+ for (fd = 0; fd < maxfd; ++fd) {
+ f = &fd_table[fd];
+ if ((f->timeout_handler) &&
+ (f->timeout_time <= cached_curtime)) {
+ tmp = f->timeout_handler;
debug(5, 5, "comm_select: timeout on socket %d at %d\n",
fd, cached_curtime);
- fd_table[fd].timeout_handler = 0;
- tmp(fd, fd_table[fd].timeout_data);
+ f->timeout_handler = 0;
+ tmp(fd, f->timeout_data);
}
}
}
-/* $Id: ipcache.cc,v 1.15 1996/04/05 21:51:46 wessels Exp $ */
+/* $Id: ipcache.cc,v 1.16 1996/04/08 17:08:01 wessels Exp $ */
/*
* DEBUG: Section 14 ipcache: IP Cache
return local_ip_count;
}
+
+void ipcacheShutdownServers()
+{
+ dnsserver_entry *dns = NULL;
+ int i;
+ static char *shutdown = "$shutdown\n";
+
+ debug(14, 1, "ipcacheShutdownServers:\n");
+
+ for (i = 0; i < getDnsChildren(); i++) {
+ dns = *(dns_child_table + i);
+ debug(14, 1, "ipcacheShutdownServers: sending '$shutdown' to dnsserver #%d\n", i);
+ debug(14, 1, "ipcacheShutdownServers: --> FD %d\n", dns->outpipe);
+ file_write(dns->outpipe,
+ shutdown,
+ strlen(shutdown),
+ 0, /* Lock */
+ 0, /* Handler */
+ 0); /* Handler-data */
+ }
+}
-/* $Id: main.cc,v 1.20 1996/04/05 23:21:12 wessels Exp $ */
+/* $Id: main.cc,v 1.21 1996/04/08 17:08:02 wessels Exp $ */
/* DEBUG: Section 1 main: startup and main loop */
static int asciiPortNumOverride = 0;
static int udpPortNumOverride = 0;
-
+static int malloc_debug_level = 0;
static void usage()
{
exit(1);
}
-int main(argc, argv)
+static void mainParseOptions(argc, argv)
int argc;
- char **argv;
+ char *argv[];
{
- int c;
- int malloc_debug_level = 0;
extern char *optarg;
- int errcount = 0;
- static int neighbors = 0;
- char *s = NULL;
- int n; /* # of GC'd objects */
- time_t last_maintain = 0;
-
- errorInitialize();
-
- cached_starttime = getCurrentTime();
- failure_notify = fatal_dump;
-
- setMaxFD();
-
- for (n = getMaxFD(); n > 2; n--)
- close(n);
-
-#if HAVE_MALLOPT
- /* set malloc option */
- /* use small block algorithm for faster allocation */
- /* grain of small block */
- mallopt(M_GRAIN, 16);
- /* biggest size that is considered a small block */
- mallopt(M_MXFAST, 4096);
- /* number of holding small block */
- mallopt(M_NLBLKS, 100);
-#endif
-
- /*init comm module */
- comm_init();
-
- /* we have to init fdstat here. */
- fdstat_init(PREOPEN_FD);
- fdstat_open(0, LOG);
- fdstat_open(1, LOG);
- fdstat_open(2, LOG);
- fd_note(0, "STDIN");
- fd_note(1, "STDOUT");
- fd_note(2, "STDERR");
-
- if ((s = getenv("HARVEST_HOME")) != NULL) {
- config_file = (char *) xcalloc(1, strlen(s) + 64);
- sprintf(config_file, "%s/lib/cached.conf", s);
- } else {
- config_file = xstrdup("/usr/local/harvest/lib/cached.conf");
- }
-
- /* enable syslog by default */
- syslog_enable = 0;
- /* preinit for debug module */
- debug_log = stderr;
- hash_init(0);
+ int c;
- while ((c = getopt(argc, argv, "vCDRVbsif:a:p:u:m:zh?")) != -1)
+ while ((c = getopt(argc, argv, "vCDRVbsif:a:p:u:m:zh?")) != -1) {
switch (c) {
case 'v':
printf("Harvest Cache: Version %s\n", SQUID_VERSION);
usage();
break;
}
-
- if (catch_signals) {
- signal(SIGSEGV, death);
- signal(SIGBUS, death);
}
- signal(SIGPIPE, SIG_IGN);
- signal(SIGCHLD, sig_child);
- signal(SIGHUP, rotate_logs);
- signal(SIGTERM, shut_down);
- signal(SIGINT, shut_down);
+}
+static void mainInitialize()
+{
parseConfigFile(config_file);
- if (!neighbors) {
- neighbors_create();
- ++neighbors;
- };
+ neighbors_create();
if (asciiPortNumOverride > 0)
setAsciiPortNum(asciiPortNumOverride);
ftpInitialize();
-
#if defined(MALLOC_DBG)
malloc_debug(0, malloc_debug_level);
#endif
do_mallinfo = 1;
debug(1, 0, "Ready to serve requests.\n");
+}
+
+
+int main(argc, argv)
+ int argc;
+ char **argv;
+{
+ int errcount = 0;
+ char *s = NULL;
+ int n; /* # of GC'd objects */
+ time_t last_maintain = 0;
+
+ errorInitialize();
+
+ cached_starttime = getCurrentTime();
+ failure_notify = fatal_dump;
+
+ mainParseOptions(argc, argv);
+
+ setMaxFD();
+
+ for (n = getMaxFD(); n > 2; n--)
+ close(n);
+
+#if HAVE_MALLOPT
+ /* set malloc option */
+ /* use small block algorithm for faster allocation */
+ /* grain of small block */
+ mallopt(M_GRAIN, 16);
+ /* biggest size that is considered a small block */
+ mallopt(M_MXFAST, 4096);
+ /* number of holding small block */
+ mallopt(M_NLBLKS, 100);
+#endif
+
+ /*init comm module */
+ comm_init();
+
+ /* we have to init fdstat here. */
+ fdstat_init(PREOPEN_FD);
+ fdstat_open(0, LOG);
+ fdstat_open(1, LOG);
+ fdstat_open(2, LOG);
+ fd_note(0, "STDIN");
+ fd_note(1, "STDOUT");
+ fd_note(2, "STDERR");
+
+ if (config_file == NULL) {
+ if ((s = getenv("HARVEST_HOME")) != NULL) {
+ config_file = (char *) xcalloc(1, strlen(s) + 64);
+ sprintf(config_file, "%s/lib/cached.conf", s);
+ } else {
+ config_file = xstrdup("/usr/local/harvest/lib/cached.conf");
+ }
+ }
+ /* enable syslog by default */
+ syslog_enable = 0;
+
+ /* preinit for debug module */
+ debug_log = stderr;
+ hash_init(0);
+
+ if (catch_signals) {
+ signal(SIGSEGV, death);
+ signal(SIGBUS, death);
+ }
+ signal(SIGPIPE, SIG_IGN);
+ signal(SIGCHLD, sig_child);
+ signal(SIGHUP, rotate_logs);
+ signal(SIGTERM, shut_down);
+ signal(SIGINT, shut_down);
+
+ mainInitialize();
+
/* main loop */
if (getCleanRate() > 0)
next_cleaning = time(0L) + getCleanRate();
errcount++;
debug(1, 0, "Select loop Error. Retry. %d\n", errcount);
if (errcount == 10)
- fatal_dump("Select Loop failed.!");
+ fatal_dump("Select Loop failed!");
break;
case COMM_TIMEOUT:
/* this happens after 1 minute of idle time, or
}
/* house keeping */
break;
+ case COMM_SHUTDOWN:
+ normal_shutdown();
+ exit(0);
default:
fatal_dump("MAIN: Internal error -- this should never happen.");
break;
-/* $Id: neighbors.cc,v 1.10 1996/04/06 00:53:06 wessels Exp $ */
+/* $Id: neighbors.cc,v 1.11 1996/04/08 17:08:03 wessels Exp $ */
+
+/* TODO:
+ * - change 'neighbor' to 'sibling'
+ * - change 'edge' to neighbor?
+ * - make ->flags structure
+ * - fix "can't continue" if DNS lookup for neighbor fails.
+ */
/*
* DEBUG: Section 15 neighbors:
friends->n++;
}
+static void neighborFriendsFree()
+{
+ edge *e = NULL;
+ edge *next = NULL;
+
+ debug(15, 1, "neighborFriendsFree()\n");
+
+ for (e = friends->edges_head; e; e = next) {
+ next = e->next;
+ safe_free(e->host);
+ safe_free(e);
+ }
+ friends->edges_head = NULL;
+}
+
+static void neighborsOpenLog(fname)
+ char *fname;
+{
+ int log_fd;
+
+ /* Close and reopen the log. It may have been renamed "manually"
+ * before HUP'ing us. */
+ if (cache_hierarchy_log) {
+ file_close(fileno(cache_hierarchy_log));
+ fclose(cache_hierarchy_log);
+ }
+ log_fd = file_open(fname, NULL, O_WRONLY | O_CREAT | O_APPEND);
+ if (log_fd < 0) {
+ debug(15, 0, "rotate_logs: %s: %s\n", fname, xstrerror());
+ debug(15, 1, "Hierachical logging is disabled.\n");
+ } else if ((cache_hierarchy_log = fdopen(log_fd, "a")) == NULL) {
+ debug(15, 0, "rotate_logs: %s: %s\n", fname, xstrerror());
+ debug(15, 1, "Hierachical logging is disabled.\n");
+ }
+}
+
void neighbors_open(fd)
int fd;
{
struct sockaddr_in our_socket_name;
struct sockaddr_in *ap;
int sock_name_length = sizeof(our_socket_name);
- int log_fd;
char *fname = NULL;
char **list = NULL;
edge *e = NULL;
}
friends->fd = fd;
- /* open log file */
- if ((fname = getHierarchyLogFile())) {
- log_fd = file_open(fname, NULL, O_WRONLY | O_CREAT | O_APPEND);
- if (log_fd < 0) {
- debug(15, 1, "%s: %s\n", fname, xstrerror());
- debug(15, 1, "Hierachical logging is disabled.\n");
- } else if (!(cache_hierarchy_log = fdopen(log_fd, "a"))) {
- debug(15, 1, "%s: %s\n", fname, xstrerror());
- debug(15, 1, "Hierachical logging is disabled.\n");
- }
- }
+ if ((fname = getHierarchyLogFile()))
+ neighborsOpenLog(fname);
+
/* Prepare neighbor connections, one at a time */
for (e = friends->edges_head; e; e = e->next) {
debug(15, 2, "Finding IP addresses for '%s'\n", e->host);
void neighbors_rotate_log()
{
+ char *fname = NULL;
int i;
static char from[MAXPATHLEN];
static char to[MAXPATHLEN];
- char *fname = NULL;
- int log_fd;
if ((fname = getHierarchyLogFile()) == NULL)
return;
sprintf(to, "%s.%d", fname, 0);
rename(fname, to);
}
- /* Close and reopen the log. It may have been renamed "manually"
- * before HUP'ing us. */
- fclose(cache_hierarchy_log);
- log_fd = file_open(fname, NULL, O_WRONLY | O_CREAT | O_APPEND);
- if (log_fd < 0) {
- debug(15, 0, "rotate_logs: %s: %s\n", fname, xstrerror());
- debug(15, 1, "Hierachical logging is disabled.\n");
- } else if ((cache_hierarchy_log = fdopen(log_fd, "a")) == NULL) {
- debug(15, 0, "rotate_logs: %s: %s\n",
- fname, xstrerror());
- debug(15, 1, "Hierachical logging is disabled.\n");
- }
+ neighborsOpenLog(fname);
}
-/* $Id: squid.h,v 1.8 1996/04/01 18:20:46 wessels Exp $ */
+/* $Id: squid.h,v 1.9 1996/04/08 17:08:03 wessels Exp $ */
#include "config.h"
#include "autoconf.h"
extern time_t cached_starttime; /* main.c */
extern time_t next_cleaning; /* main.c */
extern int catch_signals; /* main.c */
+extern int do_reuse;
+extern int theAsciiConnection;
+extern int theUdpConnection;
-/* $Id: tools.cc,v 1.23 1996/04/04 19:03:36 wessels Exp $ */
+/* $Id: tools.cc,v 1.24 1996/04/08 17:08:04 wessels Exp $ */
/*
* DEBUG: Section 21 tools
#endif
}
+void normal_shutdown()
+{
+ debug(21, 1, "Shutting down...\n");
+ if (getPidFilename())
+ safeunlink(getPidFilename(), 0);
+ storeWriteCleanLog();
+ PrintRusage(NULL, debug_log);
+ debug(21, 0, "Harvest Cache (Version %s): Exiting normally.\n",
+ SQUID_VERSION);
+ exit(0);
+}
+
+#ifdef OLD_SHUTDOWN
void shut_down(sig)
int sig;
{
SQUID_VERSION, sig);
exit(1);
}
+#else
+void shut_down(sig)
+ int sig;
+{
+ debug(21, 1, "Preparing for shutdown...\n");
+ if (theAsciiConnection) {
+ debug(21, 1, "FD %d Closing Ascii connection\n",
+ theAsciiConnection);
+ comm_close(theAsciiConnection);
+ comm_set_select_handler(theAsciiConnection,
+ COMM_SELECT_READ,
+ NULL,
+ 0);
+ theAsciiConnection = -1;
+ }
+ if (theUdpConnection) {
+ debug(21, 1, "FD %d Closing Udp connection\n",
+ theUdpConnection);
+ comm_close(theUdpConnection);
+ comm_set_select_handler(theUdpConnection,
+ COMM_SELECT_READ,
+ NULL,
+ 0);
+ theUdpConnection = -1;
+ }
+ ipcacheShutdownServers();
+}
+#endif
void fatal_common(message)
char *message;