Merge from vendor branch GCC:
[dragonfly.git] / crypto / heimdal-0.6.3 / appl / popper / pop_get_command.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: pop_get_command.c,v 1.16 2002/07/04 14:09:47 joda Exp $");
9
10 /* 
11  *  get_command:    Extract the command from an input line form a POP client
12  */
13
14 int pop_capa (POP *p);
15 static state_table states[] = {
16         {auth1,  "user", 1,  1,  pop_user,   {auth1, auth2}},
17         {auth2,  "pass", 1,  99, pop_pass,   {auth1, trans}},
18 #ifdef RPOP
19         {auth2,  "rpop", 1,  1,  pop_rpop,   {auth1, trans}},
20 #endif /* RPOP */
21         {auth1,  "quit", 0,  0,  pop_quit,   {halt,  halt}},
22         {auth2,  "quit", 0,  0,  pop_quit,   {halt,  halt}},
23 #ifdef CAPA
24         {auth1,  "capa", 0,  0,  pop_capa,   {auth1, auth1}},
25         {auth2,  "capa", 0,  0,  pop_capa,   {auth2, auth2}},
26         {trans,  "capa", 0,  0,  pop_capa,   {trans, trans}},
27 #endif
28         {trans,  "stat", 0,  0,  pop_stat,   {trans, trans}},
29         {trans,  "list", 0,  1,  pop_list,   {trans, trans}},
30         {trans,  "retr", 1,  1,  pop_send,   {trans, trans}},
31         {trans,  "dele", 1,  1,  pop_dele,   {trans, trans}},
32         {trans,  "noop", 0,  0,  NULL,       {trans, trans}},
33         {trans,  "rset", 0,  0,  pop_rset,   {trans, trans}},
34         {trans,  "top",  2,  2,  pop_send,   {trans, trans}},
35         {trans,  "last", 0,  0,  pop_last,   {trans, trans}},
36         {trans,  "quit", 0,  0,  pop_updt,   {halt,  halt}},
37         {trans,  "help", 0,  0,  pop_help,   {trans, trans}},
38 #ifdef UIDL
39         {trans,  "uidl", 0,  1,  pop_uidl,   {trans, trans}},
40 #endif
41 #ifdef XOVER
42         {trans, "xover", 0,  0,  pop_xover,  {trans, trans}},
43 #endif
44 #ifdef XDELE
45         {trans,  "xdele", 1,  2,  pop_xdele,   {trans, trans}},
46 #endif
47         {(state) 0,  NULL,   0,  0,  NULL,       {halt,  halt}},
48 };
49
50 int
51 pop_capa (POP *p)
52 {
53     /*  Search for the POP command in the command/state table */
54     pop_msg (p,POP_SUCCESS, "Capability list follows");
55     fprintf(p->output, "USER\r\n");
56     fprintf(p->output, "TOP\r\n");
57     fprintf(p->output, "PIPELINING\r\n");
58     fprintf(p->output, "EXPIRE NEVER\r\n");
59     fprintf(p->output, "RESP-CODES\r\n");
60 #ifdef UIDL
61     fprintf(p->output, "UIDL\r\n");
62 #endif
63 #ifdef XOVER
64     fprintf(p->output, "XOVER\r\n");
65 #endif
66 #ifdef XDELE
67     fprintf(p->output, "XDELE\r\n");
68 #endif
69     if(p->CurrentState == trans)
70         fprintf(p->output, "IMPLEMENTATION %s-%s\r\n", PACKAGE, VERSION);
71     fprintf(p->output,".\r\n");
72     fflush(p->output);
73
74     p->flags |= POP_FLAG_CAPA;
75
76     return(POP_SUCCESS);
77 }
78
79 state_table *
80 pop_get_command(POP *p, char *mp)
81 {
82     state_table     *   s;
83     char                buf[MAXMSGLINELEN];
84
85     /*  Save a copy of the original client line */
86 #ifdef DEBUG
87     if(p->debug) strlcpy (buf, mp, sizeof(buf));
88 #endif /* DEBUG */
89
90     /*  Parse the message into the parameter array */
91     if ((p->parm_count = pop_parse(p,mp)) < 0) return(NULL);
92
93     /*  Do not log cleartext passwords */
94 #ifdef DEBUG
95     if(p->debug){
96         if(strcmp(p->pop_command,"pass") == 0)
97             pop_log(p,POP_DEBUG,"Received: \"%s xxxxxxxxx\"",p->pop_command);
98         else {
99             /*  Remove trailing <LF> */
100             buf[strlen(buf)-2] = '\0';
101             pop_log(p,POP_DEBUG,"Received: \"%s\"",buf);
102         }
103     }
104 #endif /* DEBUG */
105
106     /*  Search for the POP command in the command/state table */
107     for (s = states; s->command; s++) {
108
109         /*  Is this a valid command for the current operating state? */
110         if (strcmp(s->command,p->pop_command) == 0
111              && s->ValidCurrentState == p->CurrentState) {
112
113             /*  Were too few parameters passed to the command? */
114             if (p->parm_count < s->min_parms) {
115                 pop_msg(p,POP_FAILURE,
116                         "Too few arguments for the %s command.",
117                         p->pop_command);
118                 return NULL;
119             }
120
121             /*  Were too many parameters passed to the command? */
122             if (p->parm_count > s->max_parms) {
123                 pop_msg(p,POP_FAILURE,
124                         "Too many arguments for the %s command.",
125                         p->pop_command);
126                 return NULL;
127            }
128
129             /*  Return a pointer to the entry for this command in 
130                 the command/state table */
131             return (s);
132         }
133     }
134     /*  The client command was not located in the command/state table */
135     pop_msg(p,POP_FAILURE,
136             "Unknown command: \"%s\".",p->pop_command);
137     return NULL;
138 }
139
140 int
141 pop_help (POP *p)
142 {
143     state_table         *s;
144
145     pop_msg(p, POP_SUCCESS, "help");
146
147     for (s = states; s->command; s++) {
148         fprintf (p->output, "%s\r\n", s->command);
149     }
150     fprintf (p->output, ".\r\n");
151     fflush (p->output);
152     return POP_SUCCESS;
153 }