1: /* $Header: xnscourierd.c,v 2.0 85/11/21 07:21:56 jqj Exp $ */ 2: 3: /* 4: * daemon for XNS Courier. Listens on SPP socket 5 for requests for 5: * Courier connections. Forks one process per SPP connection to service 6: * the Courier requests 7: */ 8: 9: /* 10: * $Log: xnscourierd.c,v $ 11: * Revision 2.0 85/11/21 07:21:56 jqj 12: * 4.3BSD standard release 13: * 14: * Revision 1.1 85/11/21 06:06:52 jqj 15: * Initial revision 16: * 17: */ 18: 19: #include <stdio.h> /* for lots of things */ 20: #include <errno.h> /* for EINTR */ 21: #include <signal.h> /* for signal() */ 22: #include <sys/wait.h> /* for struct wait and WNOHANG */ 23: #include <sgtty.h> 24: #include <sys/types.h> /* for lots of things, e.g. xn.h */ 25: #include <sys/socket.h> /* for SOCK_STREAM, AF_NS, etc. */ 26: #include <netns/ns.h> /* for sockaddr_ns, etc. */ 27: #include <netns/sp.h> 28: #include <xnscourier/courier.h> /* for lots of things */ 29: #include <xnscourier/realcourierconnection.h> /* for CourierConnection */ 30: 31: struct sockaddr_ns here, dest; 32: 33: int CourierServerDebuggingFlag = 0; 34: 35: 36: /* 37: * Message stream handle. 38: */ 39: CourierConnection *_serverConnection = 0; 40: Unspecified tid; /* transaction ID */ 41: 42: 43: static void 44: reapchild() 45: { 46: union wait status; 47: 48: while (wait3(&status, WNOHANG, 0) > 0) 49: ; 50: } 51: 52: main(argc, argv) 53: int argc; 54: char *argv[]; 55: { 56: int s, pid; 57: extern int errno; 58: 59: here.sns_family = AF_NS; 60: here.sns_addr.x_port = htons(IDPPORT_COURIER); 61: 62: #ifndef DEBUG 63: if (fork()) 64: exit(0); 65: for (s = 0; s < 10; s++) 66: (void) close(s); 67: (void) open("/", 0); 68: (void) dup2(0, 1); 69: (void) dup2(0, 2); 70: s = open("/dev/tty", 2); 71: if (s > 0) { 72: ioctl(s, TIOCNOTTY, 0); 73: close(s); 74: } 75: #endif 76: while ((s = socket(AF_NS, SOCK_SEQPACKET, 0)) < 0) { 77: perror("xnscourierd: socket"); 78: sleep(5); 79: } 80: while (bind(s, &here, sizeof here) < 0) { 81: perror("xnscourierd: bind"); 82: sleep(5); 83: } 84: signal(SIGCHLD, reapchild); 85: listen(s, 10); 86: for (;;) { 87: int s2, fromlen = sizeof(struct sockaddr_ns); 88: /* int padbefore[100]; */ 89: struct sockaddr_ns from; 90: /* int padafter[100]; */ 91: 92: s2 = accept(s, (caddr_t)&from, &fromlen); 93: if (s2 < 0) { 94: if (errno == EINTR) 95: continue; 96: perror("xnscourierd: accept"); 97: sleep(1); 98: continue; 99: } 100: #ifndef DEBUGDBX 101: if ((pid = fork()) < 0) { 102: perror("xnscourierd: Out of processes"); 103: sleep(5); 104: } 105: else if (pid == 0) { 106: /* child */ 107: signal(SIGCHLD, SIG_DFL); 108: close(s); /* don't keep accepting */ 109: doit(s2, &from); 110: /*NOTREACHED*/ 111: } 112: #else 113: signal(SIGCHLD, SIG_DFL); 114: doit(s2, &from); 115: #endif 116: close(s2); 117: } 118: /*NOTREACHED*/ 119: } 120: 121: static CourierConnection connblock; 122: 123: /* 124: * f is the socket on which we have gotten an SPP connection. 125: * who is the sockaddr_ns for the other end. 126: */ 127: doit(f, who) 128: int f; 129: struct sockaddr_ns *who; 130: { 131: LongCardinal programnum; 132: Cardinal versionnum; 133: int skipcount; 134: Unspecified skippedwords[8]; 135: Unspecified *bp; 136: static Cardinal ourversion = COURIERVERSION; 137: 138: /* set up the CourierConnection data */ 139: _serverConnection = &connblock; 140: _serverConnection->fd = f; 141: _serverConnection->state = wantversion; 142: _serverConnection->bdtstate = wantdata; 143: /* send our version number */ 144: bp = skippedwords; 145: bp += externalize_Cardinal(&ourversion, bp); 146: bp += externalize_Cardinal(&ourversion, bp); 147: CourierWrite(_serverConnection, (bp-skippedwords), skippedwords, 148: 0, (Unspecified*) NULL); 149: /* read and process a connection message */ 150: for (;;) { 151: skipcount = LookAheadCallMsg(&programnum, &versionnum, 152: skippedwords); 153: if (skipcount < 0) fatal("connection timed out"); 154: #ifdef DEBUG 155: fprintf(stderr,"Chaining to %d(%d). Skipcount =%d\n", 156: programnum, versionnum, skipcount); 157: #endif 158: ExecCourierProgram(programnum, versionnum, skipcount, 159: skippedwords); 160: } 161: } 162: 163: 164: fatal(msg) 165: char *msg; 166: { 167: (void) fprintf(stderr, "xnscourierd: %s.\n", msg); 168: exit(1); 169: }