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