remove gcc34
[dragonfly.git] / crypto / heimdal-0.6.3 / appl / popper / popper.c
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  */
6
7 #include <popper.h>
8 RCSID("$Id: popper.c,v 1.16 2002/07/04 14:09:25 joda Exp $");
9
10 int hangup = FALSE ;
11
12 static RETSIGTYPE
13 catchSIGHUP(int sig)
14 {
15     hangup = TRUE ;
16
17     /* This should not be a problem on BSD systems */
18     signal(SIGHUP,  catchSIGHUP);
19     signal(SIGPIPE, catchSIGHUP);
20     SIGRETURN(0);
21 }
22
23 int     pop_timeout = POP_TIMEOUT;
24
25 jmp_buf env;
26
27 static RETSIGTYPE
28 ring(int sig)
29 {
30   longjmp(env,1);
31 }
32   
33 /*
34  * fgets, but with a timeout
35  */
36 static char *
37 tgets(char *str, int size, FILE *fp, int timeout)
38 {
39   signal(SIGALRM, ring);
40   alarm(timeout);
41   if (setjmp(env))
42     str = NULL;
43   else
44     str = fgets(str,size,fp);
45   alarm(0);
46   signal(SIGALRM,SIG_DFL);
47   return(str);
48 }
49
50 /* 
51  *  popper: Handle a Post Office Protocol version 3 session
52  */
53 int
54 main (int argc, char **argv)
55 {
56     POP                 p;
57     state_table     *   s;
58     char                message[MAXLINELEN];
59
60     signal(SIGHUP,  catchSIGHUP);
61     signal(SIGPIPE, catchSIGHUP);
62
63     /*  Start things rolling */
64     pop_init(&p,argc,argv);
65
66     /*  Tell the user that we are listenting */
67     pop_msg(&p,POP_SUCCESS, "POP3 server ready");
68
69     /*  State loop.  The POP server is always in a particular state in 
70         which a specific suite of commands can be executed.  The following 
71         loop reads a line from the client, gets the command, and processes 
72         it in the current context (if allowed) or rejects it.  This continues 
73         until the client quits or an error occurs. */
74
75     for (p.CurrentState=auth1;p.CurrentState!=halt&&p.CurrentState!=error;) {
76         if (hangup) {
77             pop_msg(&p, POP_FAILURE, "POP hangup: %s", p.myhost);
78             if (p.CurrentState > auth2 && !pop_updt(&p))
79                 pop_msg(&p, POP_FAILURE,
80                         "POP mailbox update failed: %s", p.myhost);
81             p.CurrentState = error;
82         } else if (tgets(message, MAXLINELEN, p.input, pop_timeout) == NULL) {
83             pop_msg(&p, POP_FAILURE, "POP timeout: %s", p.myhost);
84             if (p.CurrentState > auth2 && !pop_updt(&p))
85                 pop_msg(&p,POP_FAILURE,
86                         "POP mailbox update failed: %s", p.myhost);
87             p.CurrentState = error;
88         }
89         else {
90             /*  Search for the command in the command/state table */
91             if ((s = pop_get_command(&p,message)) == NULL) continue;
92
93             /*  Call the function associated with this command in 
94                 the current state */
95             if (s->function) p.CurrentState = s->result[(*s->function)(&p)];
96
97             /*  Otherwise assume NOOP and send an OK message to the client */
98             else {
99                 p.CurrentState = s->success_state;
100                 pop_msg(&p,POP_SUCCESS,NULL);
101             }
102         }       
103     }
104
105     /*  Say goodbye to the client */
106     pop_msg(&p,POP_SUCCESS,"Pop server at %s signing off.",p.myhost);
107
108     /*  Log the end of activity */
109     pop_log(&p,POP_PRIORITY,
110         "(v%s) Ending request from \"%s\" at %s\n",VERSION,p.client,p.ipaddr);
111
112     /*  Stop logging */
113     closelog();
114
115     return(0);
116 }