/* * * =================================== * HARP | Host ATM Research Platform * =================================== * * * This Host ATM Research Platform ("HARP") file (the "Software") is * made available by Network Computing Services, Inc. ("NetworkCS") * "AS IS". NetworkCS does not provide maintenance, improvements or * support of any kind. * * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED, * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE. * In no event shall NetworkCS be responsible for any damages, including * but not limited to consequential damages, arising from or relating to * any use of the Software or related support. * * Copyright 1994-1998 Network Computing Services, Inc. * * Copies of this Software may be made, however, the above copyright * notice must be reproduced on all copies. * * @(#) $Id: atmarpd.c,v 1.5 1998/08/13 20:11:13 johnc Exp $ * */ /* * Server Cache Synchronization Protocol (SCSP) Support * ---------------------------------------------------- * * SCSP-ATMARP server interface: main line code * */ #ifndef lint static char *RCSid = "@(#) $Id: atmarpd.c,v 1.5 1998/08/13 20:11:13 johnc Exp $"; #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../scspd/scsp_msg.h" #include "../scspd/scsp_if.h" #include "../scspd/scsp_var.h" #include "atmarp_var.h" /* * Global variables */ char *prog; int atmarp_debug_mode = 0; int atmarp_max_socket = 0; Atmarp_intf *atmarp_intf_head = (Atmarp_intf *)0; Atmarp_slis *atmarp_slis_head = (Atmarp_slis *)0; FILE *atmarp_log_file = (FILE *)0; char *atmarp_log_file_name = (char *)0; Harp_timer cache_timer, perm_timer; /* * Print a usage message * * Arguments: * none * * Returns: * exits, does not return * */ void usage() { fprintf(stderr, "usage: %s [-d] [-l ] ...\n", prog); exit(1); } /* * Process command line parameters * * Arguments: * argc number of command-line arguments * argv list of pointers to command-line arguments * * Returns: * none * */ static void initialize(argc, argv) int argc; char *argv[]; { int i, rc; /* * Save program name, ignoring any path components */ if (prog = (char *)strrchr(argv[0], '/')) prog++; else prog = argv[0]; /* * Make sure we're being invoked by the super user */ i = getuid(); if (i != 0) { fprintf(stderr, "%s: You must be root to run this program\n", prog); exit(1); } /* * Scan arguments, checking for options */ for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { if (strcmp(argv[i], "-d") == 0) { atmarp_debug_mode = TRUE; } else if (strcmp(argv[i], "-l") == 0) { i++; if (i >= argc) { fprintf(stderr, "%s: Log file name missing\n", prog); exit(1); } atmarp_log_file_name = argv[i]; } else { fprintf(stderr, "%s: Unrecognized option \"%s\"\n", prog, argv[i]); exit(1); } } else { /* * Parameter is a network interface name */ rc = atmarp_cfg_netif(argv[i]); if (rc) { fprintf(stderr, "%s: Error configuring network interface %s\n", prog, argv[i]); exit(1); } } } /* * Make sure we had at least one interface configured */ if (!atmarp_intf_head) { usage(); } } /* * Daemon housekeeping * * Arguments: * None * * Returns: * None * */ static void start_daemon() { int dpid, fd, file_count, rc; /* * Ignore selected signals */ #ifdef SIGTTOU signal(SIGTTOU, SIG_IGN); #endif #ifdef SIGTTIN signal(SIGTTIN, SIG_IGN); #endif #ifdef SIGTSTP signal(SIGTSTP, SIG_IGN); #endif #ifdef SIGPIPE signal(SIGPIPE, SIG_IGN); #endif /* * Skip putting things into the background if we're * in debugging mode */ if (atmarp_debug_mode) goto daemon_bypass; /* * Set up syslog for error logging */ if (!atmarp_log_file) { openlog(prog, LOG_PID | LOG_CONS, LOG_DAEMON); } /* * Put the daemon into the background */ dpid = fork(); if (dpid < 0) { atmarp_log(LOG_ERR, "fork failed"); exit(1); } if (dpid > 0) { /* * This is the parent process--just exit and let * the daughter do all the work */ exit(0); } /* * Disassociate from any controlling terminal */ rc = setpgrp(0, getpid()); if (rc < 0) { atmarp_log(LOG_ERR, "can't change process group"); exit(1); } fd = open("/dev/tty", O_RDWR); if (fd >= 0) { ioctl(fd, TIOCNOTTY, (char *)0); close(fd); } /* * Close all open file descriptors */ file_count = getdtablesize(); for (fd=0; fdai_next) { if (atmarp_if_ready(aip)) { (void)atmarp_scsp_connect(aip); } } /* * Read the cache from the kernel */ atmarp_get_updated_cache(); /* * Main program loop -- wait for data to come in from SCSP. * When the timer fires, it will be handled elsewhere. */ while (1) { /* * Wait for input from SCSP */ FD_ZERO(&read_set); FD_ZERO(&write_set); FD_ZERO(&except_set); for (aip = atmarp_intf_head; aip; aip = aip->ai_next) { if (aip->ai_scsp_sock != -1) { FD_SET(aip->ai_scsp_sock, &read_set); } } rc = select(atmarp_max_socket + 1, &read_set, &write_set, &except_set, (struct timeval *)0); if (rc < 0) { if (harp_timer_exec) { timer_proc(); continue; } else if (errno = EINTR) { continue; } else { atmarp_log(LOG_ERR, "Select failed"); abort(); } } /* * Read and process the input from SCSP */ for (i = 0; i <= atmarp_max_socket; i++) { if (FD_ISSET(i, &read_set)) { aip = atmarp_find_intf_sock(i); if (aip) rc = atmarp_scsp_read(aip); } } } }