1 /* popd.c - the POP server */
3 static char ident[] = "@(#)$Id: popd.c,v 1.16 1993/08/25 17:23:05 jromine Exp $";
6 /* Author: Marshall T. Rose <MRose@UDel> (MTR)
7 Department of Computer Science and Information Sciences
12 Date: Sun Oct 28 16:23:26 1984
18 #include "../h/strings.h"
20 #include <sys/types.h>
23 #include <sys/ioctl.h>
25 #include <sys/socket.h>
28 #include <sys/resource.h>
31 #include <netinet/in.h>
33 #include <arpa/inet.h>
37 static Key_schedule schedule;
38 static KTEXT_ST ticket;
39 static AUTH_DAT kdata;
47 #define u_short ushort
53 #define NULLCP ((char *) 0)
54 #define NULLRP ((struct rusage *) 0)
56 #define FAST /* fast start-up of BBoards */
63 extern char *sys_errlist[];
64 extern char *sys_siglist[];
69 static int nbits = ((sizeof (int)) * 8);
70 static int options = 0;
73 #define POPSERVICE "pop"
76 char *myname = "popd";
78 static char *myprotocol = "tcp";
79 static char *myservice = POPSERVICE;
81 static struct sockaddr_in in_socket;
82 static struct sockaddr_in *isock = &in_socket;
85 static AUTH_DAT kdata;
88 static TYPESIG chldser ();
89 void padios (), padvise ();
91 static server(), arginit(), envinit();
96 main (argc, argv, envp)
108 struct sockaddr_in out_socket,
109 *osock = &out_socket;
113 i = sizeof(in_socket);
114 if (getpeername(0, &in_socket, &i) < 0)
115 padios("getpeername", "bad status");
117 if ((sp = getservbyname (myservice, myprotocol)) == NULL)
118 padios (NULLCP, "%s/%s: unknown service", myprotocol, myservice);
119 isock -> sin_family = AF_INET;
120 isock -> sin_port = sp -> s_port;
121 isock -> sin_addr.s_addr = INADDR_ANY;
130 #if defined(BSD42) && !defined(WAITINT)
146 (void) wait3 (&status, 0, NULLRP);
147 if (WIFEXITED (status))
148 (void) sprintf (reason, "exit=0%o", status.w_retcode);
150 if (WIFSIGNALED (status))
151 (void) sprintf (reason, "signal=%s%s",
152 status.w_termsig < NSIG
153 ? sys_siglist[status.w_termsig] : "unknown",
154 status.w_coredump ? " (core dumped)" : NULL);
156 (void) strcpy (reason, "stopped(!!)");
157 padvise (NULLCP, LOG_WARNING, "%s/%s server has terminated -- %s",
158 sp -> s_proto, sp -> s_name, reason);
166 openlog (myname, LOG_PID);
168 openlog (myname, LOG_PID, LOG_DAEMON);
170 padvise (NULLCP, LOG_INFO, "restart");
175 if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == NOTOK)
176 padios ("socket", "unable to create");
178 if (options & SO_DEBUG)
179 if (setsockopt (sd, SOL_SOCKET, SO_DEBUG, NULL, 0) == NOTOK)
180 padvise ("SO_DEBUG", LOG_WARNING, "unable to set socket option");
181 if (setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, NULL, 0) == NOTOK)
182 padvise ("SO_KEEPALIVE", LOG_WARNING, "unable to set socket option");
184 if (options & SO_DEBUG)
185 if (setsockopt (sd, SOL_SOCKET, SO_DEBUG, &on, sizeof on) == NOTOK)
186 padvise ("SO_DEBUG", LOG_WARNING, "unable to set socket option");
187 if (setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof on) == NOTOK)
188 padvise ("SO_KEEPALIVE", LOG_WARNING, "unable to set socket option");
190 if (bind (sd, (struct sockaddr *) isock, sizeof *isock) == NOTOK)
191 padios ("socket", "unable to bind");
194 (void) signal (SIGCHLD, chldser);
196 (void) listen (sd, SOMAXCONN);
203 int i = sizeof *osock;
205 if ((fd = accept (sd, (struct sockaddr *) osock, &i)) == NOTOK) {
207 padvise ("socket", LOG_WARNING,
208 "unable to accept connection on");
220 (void) signal (SIGCHLD, SIG_DFL);
226 padvise ("socket", LOG_WARNING,
227 "no forks, so rejecting connection on");
239 static server (fd, sin)
241 struct sockaddr_in *sin;
245 struct in_addr *addr;
249 struct sockaddr_in faddr;
250 char instance[INST_SZ];
257 openlog (myname, LOG_PID);
259 openlog (myname, LOG_PID, LOG_DAEMON);
261 port = ntohs (sin -> sin_port);
262 addr = &sin -> sin_addr;
263 hp = gethostbyaddr ((char *)addr, sizeof *addr, sin -> sin_family);
264 padvise (NULLCP, LOG_INFO, "servicing %s/%d",
265 hp ? hp -> h_name : inet_ntoa (*addr), port);
274 sin_len = sizeof (struct sockaddr_in);
275 if (getpeername(0, &faddr, &sin_len) < 0) {
276 padvise("getpeername", LOG_INFO, "");
279 strcpy(instance, "*");
280 auth = krb_recvauth(0L, 0, &ticket, "pop", instance,
281 &faddr, (struct sockaddr_in *)NULL,
282 &kdata, "", schedule, version);
283 if (auth == KSUCCESS)
284 auth = krb_kntoln(&kdata, user);
286 if (auth != KSUCCESS) {
287 padvise(NULLCP, LOG_INFO, "bad kerberos data, not ok'ing");
288 kpop (0, 1, NULLCP, NULLCP, auth); /* respond(NOTOK, krb_err_txt[auth]); */
290 kpop (0, 1, user, (hp ? hp -> h_name : NULLCP), 0);
293 pop (0, 1, sin -> sin_family == AF_INET && port < IPPORT_RESERVED && hp,
294 hp ? hp -> h_name : NULLCP);
307 if (myname = rindex (*vec, '/'))
309 if (myname == NULL || *myname == 0)
312 (void) gethostname (myhost, sizeof myhost);
313 if (hp = gethostbyname (myhost))
314 (void) strcpy (myhost, hp -> h_name);
318 nbits = getdtablesize ();
321 for (vec++; ap = *vec; vec++) {
329 if ((ap = *++vec) == NULL
331 || (port = atoi (ap)) <= 0)
332 padios (NULLCP, "usage: %s -p portno", myname);
333 isock -> sin_port = htons ((u_short) port);
337 padios (NULLCP, "-%s: unknown switch", ap);
340 padios (NULLCP, "usage: %s [switches]", myname);
351 if (!(debug = isatty (2))) {
352 for (i = 0; i < 5; i++) {
369 if ((sd = open ("/dev/null", O_RDWR)) == NOTOK)
370 padios ("/dev/null", "unable to read");
372 (void) dup2 (sd, 0), (void) close (sd);
376 if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) {
378 (void) ioctl (sd, TIOCNOTTY, NULLCP);
379 #endif /* TIOCNOTTY */
384 for (sd = 3; sd < nbits; sd++)
388 (void) signal (SIGPIPE, SIG_IGN);
391 openlog (myname, LOG_PID);
393 openlog (myname, LOG_PID, LOG_DAEMON);
395 padvise (NULLCP, LOG_INFO, "starting");
397 padvise (NULLCP, LOG_DEBUG, "options=0x%x port=%d",
398 options, ntohs (isock -> sin_port));
409 static TYPESIG chldser (sig, code, sc)
412 struct sigcontext *sc;
414 #if defined(BSD42) && !defined(WAITINT)
420 while (wait3 (&status, WNOHANG, NULLRP) > 0)
431 void padios (what, fmt, a, b, c, d, e, f, g, h, i, j)
445 padvise (what, LOG_ERR, fmt, a, b, c, d, e, f, g, h, i, j);
453 void padvise (what, code, fmt, a, b, c, d, e, f, g, h, i, j)
471 (void) sprintf (buffer, fmt, a, b, c, d, e, f, g, h, i, j);
473 if (eindex > 0 && eindex < sys_nerr)
474 syslog (code, "%s %s: %s", buffer, what, sys_errlist[eindex]);
476 syslog (code, "%s %s: Error %d", buffer, what, eindex);
478 syslog (code, "%s", buffer);
481 fprintf (stderr, "[%d] %s", code, buffer);
483 (void) fputc (' ', stderr), perror (what);
485 (void) fputc ('\n', stderr);
486 (void) fflush (stderr);