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