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