1: #ifndef lint 2: static char *sccsid = "@(#)netaux.c 1.11 (Berkeley) 2/25/88"; 3: #endif 4: 5: /* 6: * Routines to deal with network stuff for 7: * stand-alone version of server. 8: */ 9: 10: #include "common.h" 11: #include <sys/socket.h> 12: #include <netinet/in.h> 13: #ifndef EXCELAN 14: #include <netdb.h> 15: #endif not EXCELAN 16: #include <sys/ioctl.h> 17: #include <signal.h> 18: #ifdef USG 19: #include <time.h> 20: #else not USG 21: #include <sys/time.h> 22: #endif USG 23: 24: #ifdef ALONE 25: 26: 27: /* 28: * disassociate this process from the invoker's terminal. 29: * Close all file descriptors, and then open 0, 1, and 2 to 30: * somewhere bogus (i.e., "/", O_RDONLY). This way we will know 31: * that stdin/out/err will at least be claimed. 32: * 33: * Parameters: None. 34: * 35: * Returns: Nothing. 36: * 37: * Side effects: Disassociates this process from 38: * a terminal; closes file descriptors; 39: * fd 0-2 opened as O_RDONLY to /. 40: */ 41: 42: disassoc() 43: { 44: register int i; 45: 46: #ifdef USG 47: (void) signal(SIGTERM, SIG_IGN); 48: (void) signal(SIGINT, SIG_IGN); 49: (void) signal(SIGQUIT, SIG_IGN); 50: #endif 51: 52: if (fork()) 53: exit(0); 54: 55: for (i = 0; i < 10; i++) 56: (void) close(i); 57: 58: #ifdef USG 59: (void) open("/", 0); 60: (void) dup2(0, 1); 61: (void) dup2(0, 2); 62: setpgrp(); 63: umask(000); 64: #else not USG 65: i = open("/dev/tty", O_RDWR); 66: if (i >= 0) { 67: ioctl(i, TIOCNOTTY, 0); 68: (void) close(i); 69: } 70: 71: i = open("/", O_RDONLY); 72: if (i >= 0) { 73: if (i != 0) { /* should never happen */ 74: (void) dup2(i, 0); 75: (void) close(i); 76: } 77: (void) dup2(0, 1); 78: (void) dup2(1, 2); 79: } 80: #endif not USG 81: } 82: 83: 84: /* 85: * get_socket -- create a socket bound to the appropriate 86: * port number. 87: * 88: * Parameters: None. 89: * 90: * Returns: Socket bound to correct address. 91: * 92: * Side effects: None. 93: * 94: * Errors: Syslogd, cause aboriton. 95: */ 96: 97: get_socket() 98: { 99: int s; 100: struct sockaddr_in sin; 101: #ifndef EXCELAN 102: struct servent *sp; 103: 104: sp = getservbyname("nntp", "tcp"); 105: if (sp == NULL) { 106: #ifdef SYSLOG 107: syslog(LOG_ERR, "get_socket: tcp/nntp, unknown service."); 108: #endif 109: exit(1); 110: } 111: #endif not EXCELAN 112: 113: bzero((char *) &sin, sizeof (sin)); 114: sin.sin_family = AF_INET; 115: sin.sin_addr.s_addr = htonl(INADDR_ANY); 116: #ifndef EXCELAN 117: sin.sin_port = sp->s_port; 118: 119: s = socket(AF_INET, SOCK_STREAM, 0); 120: #else EXCELAN 121: sin.sin_port = htons(IPPORT_NNTP); 122: s = 3; /* WTF??? */ 123: s = socket(SOCK_STREAM, (struct sockproto *)0, &sin, 124: (SO_KEEPALIVE|SO_ACCEPTCONN)); 125: #endif EXCELAN 126: if (s < 0) { 127: #ifdef EXCELAN 128: sleep(5); 129: return (-1); 130: #else not EXCELAN 131: #ifdef SYSLOG 132: syslog(LOG_ERR, "get_socket: socket: %m"); 133: #endif SYSLOG 134: exit(1); 135: #endif not EXCELAN 136: } 137: 138: #ifndef EXCELAN 139: if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { 140: #ifdef SYSLOG 141: syslog(LOG_ERR, "get_socket: bind: %m"); 142: #endif 143: exit(1); 144: } 145: #endif not EXCELAN 146: 147: return (s); 148: } 149: 150: /* 151: * make_stdio -- make a given socket be our standard input 152: * and output. 153: * 154: * Parameters: "sockt" is the socket we want to 155: * be file descriptors 0, 1, and 2. 156: * 157: * Returns: Nothing. 158: * 159: * Side effects: None. 160: */ 161: 162: make_stdio(sockt) 163: int sockt; 164: { 165: if (sockt != 0) { 166: (void) dup2(sockt, 0); 167: (void) close(sockt); 168: } 169: (void) dup2(0, 1); 170: (void) dup2(1, 2); 171: } 172: 173: /* 174: * set_timer -- set up the interval timer so that 175: * the active file is read in every so often. 176: * 177: * Parameters: None. 178: * 179: * Returns: Nothing. 180: * 181: * Side effects: Sets interval timer to READINTVL seconds. 182: * Sets SIGALRM to call read_again. 183: */ 184: 185: set_timer() 186: { 187: #ifndef USG 188: struct itimerval new, old; 189: #endif not USG 190: extern int read_again(); 191: 192: (void) signal(SIGALRM, read_again); 193: #ifdef USG 194: alarm(READINTVL); 195: #else not USG 196: 197: new.it_value.tv_sec = READINTVL; 198: new.it_value.tv_usec = 0; 199: new.it_interval.tv_sec = READINTVL; 200: new.it_interval.tv_usec = 0; 201: old.it_value.tv_sec = 0; 202: old.it_value.tv_usec = 0; 203: old.it_interval.tv_sec = 0; 204: old.it_interval.tv_usec = 0; 205: 206: if (setitimer(ITIMER_REAL, &new, &old) < 0) { 207: #ifdef SYSLOG 208: syslog(LOG_ERR, "set_timer: setitimer: %m\n"); 209: #endif SYSLOG 210: exit(1); 211: } 212: #endif not USG 213: } 214: 215: 216: /* 217: * read_again -- (maybe) read in the active file again, 218: * if it's changed since the last time we checked. 219: * 220: * Parameters: None (called by interrupt). 221: * 222: * Returns: Nothing. 223: * 224: * Side effects: May change "num_groups" and "group_array". 225: */ 226: 227: read_again() 228: { 229: static long last_mtime; /* Last time active file was changed */ 230: struct stat statbuf; 231: 232: if (stat(activefile, &statbuf) < 0) 233: return; 234: 235: if (statbuf.st_mtime != last_mtime) { 236: last_mtime = statbuf.st_mtime; 237: num_groups = read_groups(); 238: } 239: } 240: 241: 242: /* 243: * reaper -- reap children who are ready to die. 244: * Called by signal. 245: * 246: * Parameters: None. 247: * 248: * Returns: Nothing. 249: * 250: * Side effects: None. 251: */ 252: 253: reaper() 254: { 255: #ifndef USG 256: union wait status; 257: 258: while (wait3(&status, WNOHANG, (struct rusage *)0) > 0) 259: ; 260: #endif not USG 261: } 262: 263: #else not ALONE 264: 265: /* Kludge for greenhill's C compiler */ 266: 267: static 268: netaux_greenkludge() 269: { 270: } 271: #endif not ALONE