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.
8 __RCSID("$Heimdal: pop_get_command.c 13928 2004-06-14 08:18:18Z joda $"
12 * get_command: Extract the command from an input line form a POP client
15 int pop_capa (POP
*p
);
16 static state_table states
[] = {
17 {auth1
, "user", 1, 1, pop_user
, {auth1
, auth2
}},
18 {auth2
, "pass", 1, 99, pop_pass
, {auth1
, trans
}},
20 {auth2
, "rpop", 1, 1, pop_rpop
, {auth1
, trans
}},
23 {auth1
, "auth", 1, 2, pop_auth
, {auth1
, trans
}},
25 {auth1
, "quit", 0, 0, pop_quit
, {halt
, halt
}},
26 {auth2
, "quit", 0, 0, pop_quit
, {halt
, halt
}},
28 {auth1
, "capa", 0, 0, pop_capa
, {auth1
, auth1
}},
29 {auth2
, "capa", 0, 0, pop_capa
, {auth2
, auth2
}},
30 {trans
, "capa", 0, 0, pop_capa
, {trans
, trans
}},
32 {trans
, "stat", 0, 0, pop_stat
, {trans
, trans
}},
33 {trans
, "list", 0, 1, pop_list
, {trans
, trans
}},
34 {trans
, "retr", 1, 1, pop_send
, {trans
, trans
}},
35 {trans
, "dele", 1, 1, pop_dele
, {trans
, trans
}},
36 {trans
, "noop", 0, 0, NULL
, {trans
, trans
}},
37 {trans
, "rset", 0, 0, pop_rset
, {trans
, trans
}},
38 {trans
, "top", 2, 2, pop_send
, {trans
, trans
}},
39 {trans
, "last", 0, 0, pop_last
, {trans
, trans
}},
40 {trans
, "quit", 0, 0, pop_updt
, {halt
, halt
}},
41 {trans
, "help", 0, 0, pop_help
, {trans
, trans
}},
43 {trans
, "uidl", 0, 1, pop_uidl
, {trans
, trans
}},
46 {trans
, "xover", 0, 0, pop_xover
, {trans
, trans
}},
49 {trans
, "xdele", 1, 2, pop_xdele
, {trans
, trans
}},
51 {(state
) 0, NULL
, 0, 0, NULL
, {halt
, halt
}},
57 /* Search for the POP command in the command/state table */
58 pop_msg (p
,POP_SUCCESS
, "Capability list follows");
59 if(p
->auth_level
== AUTH_NONE
|| p
->auth_level
== AUTH_OTP
)
60 fprintf(p
->output
, "USER\r\n");
61 fprintf(p
->output
, "TOP\r\n");
62 fprintf(p
->output
, "PIPELINING\r\n");
63 fprintf(p
->output
, "EXPIRE NEVER\r\n");
64 fprintf(p
->output
, "RESP-CODES\r\n");
69 fprintf(p
->output
, "UIDL\r\n");
72 fprintf(p
->output
, "XOVER\r\n");
75 fprintf(p
->output
, "XDELE\r\n");
77 if(p
->CurrentState
== trans
)
78 fprintf(p
->output
, "IMPLEMENTATION %s-%s\r\n", PACKAGE
, VERSION
);
79 fprintf(p
->output
,".\r\n");
82 p
->flags
|= POP_FLAG_CAPA
;
88 pop_get_command(POP
*p
, char *mp
)
91 char buf
[MAXMSGLINELEN
];
93 /* Save a copy of the original client line */
95 if(p
->debug
) strlcpy (buf
, mp
, sizeof(buf
));
98 /* Parse the message into the parameter array */
99 if ((p
->parm_count
= pop_parse(p
,mp
)) < 0) return(NULL
);
101 /* Do not log cleartext passwords */
104 if(strcmp(p
->pop_command
,"pass") == 0)
105 pop_log(p
,POP_DEBUG
,"Received: \"%s xxxxxxxxx\"",p
->pop_command
);
107 /* Remove trailing <LF> */
108 buf
[strlen(buf
)-2] = '\0';
109 pop_log(p
,POP_DEBUG
,"Received: \"%s\"",buf
);
114 /* Search for the POP command in the command/state table */
115 for (s
= states
; s
->command
; s
++) {
117 /* Is this a valid command for the current operating state? */
118 if (strcmp(s
->command
,p
->pop_command
) == 0
119 && s
->ValidCurrentState
== p
->CurrentState
) {
121 /* Were too few parameters passed to the command? */
122 if (p
->parm_count
< s
->min_parms
) {
123 pop_msg(p
,POP_FAILURE
,
124 "Too few arguments for the %s command.",
129 /* Were too many parameters passed to the command? */
130 if (p
->parm_count
> s
->max_parms
) {
131 pop_msg(p
,POP_FAILURE
,
132 "Too many arguments for the %s command.",
137 /* Return a pointer to the entry for this command in
138 the command/state table */
142 /* The client command was not located in the command/state table */
143 pop_msg(p
,POP_FAILURE
,
144 "Unknown command: \"%s\".",p
->pop_command
);
153 pop_msg(p
, POP_SUCCESS
, "help");
155 for (s
= states
; s
->command
; s
++) {
156 fprintf (p
->output
, "%s\r\n", s
->command
);
158 fprintf (p
->output
, ".\r\n");