popd.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 413 行
C
413 行
/* popd.c - the POP server */#ifndef lintstatic char ident[] = "@(#)$Id: popd.c,v 1.1 90/07/20 11:26:24 sharpe Exp $";#endif lint/* Author: Marshall T. Rose <MRose@UDel> (MTR) Department of Computer Science and Information Sciences University of Delaware Newark, DE 19716 302/451-1951 Date: Sun Oct 28 16:23:26 1984 */#include <errno.h>#include <signal.h>#include <stdio.h>#include "../h/strings.h"#include "syslog.h"#include <sys/types.h>#include <sys/file.h>#ifndef NOIOCTLH#include <sys/ioctl.h>#endif NOIOCTLH#include <sys/socket.h>#include <sys/time.h>#ifdef SIGTSTP#include <sys/resource.h>#include <sys/wait.h>#endif SIGTSTP#include <netinet/in.h>#include <netdb.h>#include <arpa/inet.h>#ifdef SYS5#include <fcntl.h>#endif SYS5#ifdef SYS5#define u_short ushort#endif SYS5#define NOTOK (-1)#define OK 0#define NULLCP ((char *) 0)#define NULLRP ((struct rusage *) 0)#define FAST /* fast start-up of BBoards *//* */extern int errno;extern int sys_nerr;extern char *sys_errlist[];extern char *sys_siglist[];int debug = 0;static int nbits = ((sizeof (int)) * 8);static int options = 0;#ifndef POPSERVICE#define POPSERVICE "pop"#endifchar *myname = "popd";char myhost[BUFSIZ];static char *myprotocol = "tcp";static char *myservice = POPSERVICE;static struct sockaddr_in in_socket;static struct sockaddr_in *isock = &in_socket;static int chldser ();void padios (), padvise ();static server(), arginit(), envinit();/* *//* ARGSUSED */main (argc, argv, envp)int argc;char **argv, **envp;{ int fd, sd; int on = 1; struct servent *sp; struct sockaddr_in out_socket, *osock = &out_socket; if ((sp = getservbyname (myservice, myprotocol)) == NULL) padios (NULLCP, "%s/%s: unknown service", myprotocol, myservice); isock -> sin_family = AF_INET; isock -> sin_port = sp -> s_port; isock -> sin_addr.s_addr = INADDR_ANY; arginit (argv); envinit ();#ifdef RESTART for (;;) { char reason[BUFSIZ]; union wait status; switch (fork ()) { case NOTOK: sleep (5); continue; case OK: break; default: sleep (60); (void) wait3 (&status, 0, NULLRP); if (WIFEXITED (status)) (void) sprintf (reason, "exit=0%o", status.w_retcode); else if (WIFSIGNALED (status)) (void) sprintf (reason, "signal=%s%s", status.w_termsig < NSIG ? sys_siglist[status.w_termsig] : "unknown", status.w_coredump ? " (core dumped)" : NULL); else (void) strcpy (reason, "stopped(!!)"); padvise (NULLCP, LOG_WARNING, "%s/%s server has terminated -- %s", sp -> s_proto, sp -> s_name, reason); continue; } break; } closelog ();#ifndef BSD43 openlog (myname, LOG_PID);#else BSD43 openlog (myname, LOG_PID, LOG_DAEMON);#endif BSD43 padvise (NULLCP, LOG_INFO, "restart");#endif RESTART/* */ if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == NOTOK) padios ("socket", "unable to create");#ifndef BSD43 if (options & SO_DEBUG) if (setsockopt (sd, SOL_SOCKET, SO_DEBUG, NULL, 0) == NOTOK) padvise ("SO_DEBUG", LOG_WARNING, "unable to set socket option"); if (setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, NULL, 0) == NOTOK) padvise ("SO_KEEPALIVE", LOG_WARNING, "unable to set socket option");#else BSD43 if (options & SO_DEBUG) if (setsockopt (sd, SOL_SOCKET, SO_DEBUG, &on, sizeof on) == NOTOK) padvise ("SO_DEBUG", LOG_WARNING, "unable to set socket option"); if (setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof on) == NOTOK) padvise ("SO_KEEPALIVE", LOG_WARNING, "unable to set socket option");#endif BSD43 if (bind (sd, (struct sockaddr *) isock, sizeof *isock) == NOTOK) padios ("socket", "unable to bind");#ifdef SIGCHLD (void) signal (SIGCHLD, chldser);#endif SIGCHLD (void) listen (sd, SOMAXCONN);#ifdef FAST popinit ();#endif FAST for (;;) { int i = sizeof *osock; if ((fd = accept (sd, (struct sockaddr *) osock, &i)) == NOTOK) { if (errno != EINTR) padvise ("socket", LOG_WARNING, "unable to accept connection on"); continue; }#ifdef FAST popassert ();#endif FAST switch (fork ()) { case OK: (void) close (sd);#ifdef SIGCHLD (void) signal (SIGCHLD, SIG_DFL);#endif SIGCHLD server (fd, osock); _exit (0); case NOTOK: padvise ("socket", LOG_WARNING, "no forks, so rejecting connection on"); default: (void) close (fd); } }}/* */static server (fd, sin)int fd;struct sockaddr_in *sin;{ u_short port; struct hostent *hp; struct in_addr *addr; closelog ();#ifndef BSD43 openlog (myname, LOG_PID);#else BSD43 openlog (myname, LOG_PID, LOG_DAEMON);#endif BSD43 port = ntohs (sin -> sin_port); addr = &sin -> sin_addr; hp = gethostbyaddr (addr, sizeof *addr, sin -> sin_family); padvise (NULLCP, LOG_INFO, "servicing %s/%d", hp ? hp -> h_name : inet_ntoa (*addr), port); (void) dup2 (fd, 0); (void) close (fd); (void) dup2 (0, 1); pop (0, 1, sin -> sin_family == AF_INET && port < IPPORT_RESERVED && hp, hp ? hp -> h_name : NULLCP);} /* */static arginit (vec)char **vec;{ int port; register char *ap; struct hostent *hp; if (myname = rindex (*vec, '/')) myname++; if (myname == NULL || *myname == NULL) myname = *vec; (void) gethostname (myhost, sizeof myhost); if (hp = gethostbyname (myhost)) (void) strcpy (myhost, hp -> h_name); nbits = getdtablesize (); for (vec++; ap = *vec; vec++) { if (*ap == '-') switch (*++ap) { case 'd': options |= SO_DEBUG; continue; case 'p': if ((ap = *++vec) == NULL || *ap == '-' || (port = atoi (ap)) <= 0) padios (NULLCP, "usage: %s -p portno", myname); isock -> sin_port = htons ((u_short) port); continue; default: padios (NULLCP, "-%s: unknown switch", ap); } padios (NULLCP, "usage: %s [switches]", myname); }}/* */static envinit () { int i, sd; if (!(debug = isatty (2))) { for (i = 0; i < 5; i++) { switch (fork ()) { case NOTOK: sleep (5); continue; case OK: break; default: _exit (0); } break; } (void) chdir ("/"); if ((sd = open ("/dev/null", O_RDWR)) == NOTOK) padios ("/dev/null", "unable to read"); if (sd != 0) (void) dup2 (sd, 0), (void) close (sd); (void) dup2 (0, 1); (void) dup2 (0, 2); if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) {#ifdef TIOCNOTTY (void) ioctl (sd, TIOCNOTTY, NULLCP);#endif TIOCNOTTY (void) close (sd); } } for (sd = 3; sd < nbits; sd++) (void) close (sd); (void) signal (SIGPIPE, SIG_IGN);#ifndef BSD43 openlog (myname, LOG_PID);#else BSD43 openlog (myname, LOG_PID, LOG_DAEMON);#endif BSD43 padvise (NULLCP, LOG_INFO, "starting"); if (debug) padvise (NULLCP, LOG_DEBUG, "options=0x%x port=%d", options, ntohs (isock -> sin_port));}/* *//* ARGSUSED */#ifdef SIGCHLDstatic int chldser (sig, code, sc)int sig;long code;struct sigcontext *sc;{ union wait status; while (wait3 (&status, WNOHANG, NULLRP) > 0) continue;}#endif SIGCHLD/* *//* VARARGS2 */void padios (what, fmt, a, b, c, d, e, f, g, h, i, j)char *what, *fmt, *a, *b, *c, *d, *e, *f, *g, *h, *i, *j;{ padvise (what, LOG_ERR, fmt, a, b, c, d, e, f, g, h, i, j); _exit (1);}/* *//* VARARGS3 */void padvise (what, code, fmt, a, b, c, d, e, f, g, h, i, j)char *what, *fmt, *a, *b, *c, *d, *e, *f, *g, *h, *i, *j;int code;{ int eindex = errno; char buffer[BUFSIZ]; (void) sprintf (buffer, fmt, a, b, c, d, e, f, g, h, i, j); if (what) if (eindex > 0 && eindex < sys_nerr) syslog (code, "%s %s: %s", buffer, what, sys_errlist[eindex]); else syslog (code, "%s %s: Error %d", buffer, what, eindex); else syslog (code, "%s", buffer); if (debug) { fprintf (stderr, "[%d] %s", code, buffer); if (what) (void) fputc (' ', stderr), perror (what); else (void) fputc ('\n', stderr); (void) fflush (stderr); } errno = eindex;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?