Sync usage with man page.
[netbsd-mini2440.git] / crypto / dist / heimdal / appl / popper / popper.c
blob64b2881ab5f94fae654608e5c4f05637fbddd7d3
1 /*
2 * Copyright (c) 1989 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
7 #include <popper.h>
8 __RCSID("$Heimdal: popper.c 14321 2004-10-25 14:02:00Z joda $"
9 "$NetBSD$");
11 int hangup = FALSE ;
13 static RETSIGTYPE
14 catchSIGHUP(int sig)
16 hangup = TRUE ;
18 /* This should not be a problem on BSD systems */
19 signal(SIGHUP, catchSIGHUP);
20 signal(SIGPIPE, catchSIGHUP);
21 SIGRETURN(0);
24 int pop_timeout = POP_TIMEOUT;
26 jmp_buf env;
28 static RETSIGTYPE
29 ring(int sig)
31 longjmp(env,1);
35 * fgets, but with a timeout
37 static char *
38 tgets(char *str, int size, FILE *fp, int timeout)
40 char *ret;
42 signal(SIGALRM, ring);
43 alarm(timeout);
44 if (setjmp(env)) {
45 alarm(0);
46 signal(SIGALRM, SIG_DFL);
47 return NULL;
49 ret = fgets(str, size, fp);
50 alarm(0);
51 signal(SIGALRM, SIG_DFL);
52 return ret;
55 /*
56 * popper: Handle a Post Office Protocol version 3 session
58 int
59 main (int argc, char **argv)
61 POP p;
62 state_table * s;
63 char message[MAXLINELEN];
65 signal(SIGHUP, catchSIGHUP);
66 signal(SIGPIPE, catchSIGHUP);
68 /* Start things rolling */
69 pop_init(&p,argc,argv);
71 /* Tell the user that we are listenting */
72 pop_msg(&p,POP_SUCCESS, "POP3 server ready");
74 /* State loop. The POP server is always in a particular state in
75 which a specific suite of commands can be executed. The following
76 loop reads a line from the client, gets the command, and processes
77 it in the current context (if allowed) or rejects it. This continues
78 until the client quits or an error occurs. */
80 for (p.CurrentState=auth1;p.CurrentState!=halt&&p.CurrentState!=error;) {
81 if (hangup) {
82 pop_msg(&p, POP_FAILURE, "POP hangup: %s", p.myhost);
83 if (p.CurrentState > auth2 && !pop_updt(&p))
84 pop_msg(&p, POP_FAILURE,
85 "POP mailbox update failed: %s", p.myhost);
86 p.CurrentState = error;
87 } else if (tgets(message, MAXLINELEN, p.input, pop_timeout) == NULL) {
88 pop_msg(&p, POP_FAILURE, "POP timeout: %s", p.myhost);
89 if (p.CurrentState > auth2 && !pop_updt(&p))
90 pop_msg(&p,POP_FAILURE,
91 "POP mailbox update failed: %s", p.myhost);
92 p.CurrentState = error;
94 else {
95 /* Search for the command in the command/state table */
96 if ((s = pop_get_command(&p,message)) == NULL) continue;
98 /* Call the function associated with this command in
99 the current state */
100 if (s->function) p.CurrentState = s->result[(*s->function)(&p)];
102 /* Otherwise assume NOOP and send an OK message to the client */
103 else {
104 p.CurrentState = s->success_state;
105 pop_msg(&p,POP_SUCCESS,"time passes");
110 /* Say goodbye to the client */
111 pop_msg(&p,POP_SUCCESS,"Pop server at %s signing off.",p.myhost);
113 /* Log the end of activity */
114 pop_log(&p,POP_PRIORITY,
115 "(v%s) Ending request from \"%s\" at %s\n",VERSION,p.client,p.ipaddr);
117 /* Stop logging */
118 closelog();
120 return(0);