diff --git a/appl/popper/pop_dropinfo.c b/appl/popper/pop_dropinfo.c new file mode 100644 index 000000000..7f8dc972e --- /dev/null +++ b/appl/popper/pop_dropinfo.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ + +#ifndef lint +static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; +static char SccsId[] = "@(#)@(#)pop_dropinfo.c 2.1 2.1 3/18/91"; +#endif not lint + +#include +#include +#include +#include +#include +#include +#include "popper.h" + +extern int errno; +extern int sys_nerr; +extern char *sys_errlist[]; + +/* + * dropinfo: Extract information about the POP maildrop and store + * it for use by the other POP routines. + */ + +pop_dropinfo(p) +POP * p; +{ + char buffer[BUFSIZ]; /* Read buffer */ + MsgInfoList * mp; /* Pointer to message + info list */ + register int msg_num; /* Current message + counter */ + int nchar; /* Bytes written/read */ + + /* Initialize maildrop status variables in the POP parameter block */ + p->msg_count = 0; + p->msgs_deleted = 0; + p->last_msg = 0; + p->bytes_deleted = 0; + p->drop_size = 0; + + /* Allocate memory for message information structures */ + p->msg_count = ALLOC_MSGS; + p->mlp = (MsgInfoList *)calloc((unsigned)p->msg_count,sizeof(MsgInfoList)); + if (p->mlp == NULL){ + (void)fclose (p->drop); + p->msg_count = 0; + return pop_msg (p,POP_FAILURE, + "Can't build message list for '%s': Out of memory", p->user); + } + + rewind (p->drop); + + /* Scan the file, loading the message information list with + information about each message */ + + for (msg_num = p->drop_size = 0, mp = p->mlp - 1; + fgets(buffer,MAXMSGLINELEN,p->drop);) { + + nchar = strlen(buffer); + + if (strncmp(buffer,"From ",5) == 0) { + + if (++msg_num > p->msg_count) { + p->mlp=(MsgInfoList *) realloc(p->mlp, + (p->msg_count+=ALLOC_MSGS)*sizeof(MsgInfoList)); + if (p->mlp == NULL){ + (void)fclose (p->drop); + p->msg_count = 0; + return pop_msg (p,POP_FAILURE, + "Can't build message list for '%s': Out of memory", + p->user); + } + mp = p->mlp + msg_num - 2; + } +#ifdef DEBUG + if(p->debug) + pop_log(p,POP_DEBUG, + "Msg %d at offset %d is %d octets long and has %u lines.", + mp->number,mp->offset,mp->length,mp->lines); +#endif DEBUG + ++mp; + mp->number = msg_num; + mp->length = 0; + mp->lines = 0; + mp->offset = ftell(p->drop) - nchar; + mp->del_flag = FALSE; + mp->retr_flag = FALSE; +#ifdef DEBUG + if(p->debug) + pop_log(p,POP_DEBUG, "Msg %d being added to list", mp->number); +#endif DEBUG + } + mp->length += nchar; + p->drop_size += nchar; + mp->lines++; + } + p->msg_count = msg_num; + +#ifdef DEBUG + if(p->debug && msg_num > 0) { + register i; + for (i = 0, mp = p->mlp; i < p->msg_count; i++, mp++) + pop_log(p,POP_DEBUG, + "Msg %d at offset %d is %d octets long and has %u lines.", + mp->number,mp->offset,mp->length,mp->lines); + } +#endif DEBUG + + return(POP_SUCCESS); +} diff --git a/appl/popper/pop_get_command.c b/appl/popper/pop_get_command.c new file mode 100644 index 000000000..ffe8f06d0 --- /dev/null +++ b/appl/popper/pop_get_command.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ + +#ifndef lint +static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; +static char SccsId[] = "@(#)@(#)pop_get_command.c 2.1 2.1 3/18/91"; +#endif not lint + +#include +#include +#include +#include "popper.h" + +/* + * get_command: Extract the command from an input line form a POP client + */ + +static state_table states[] = { + auth1, "user", 1, 1, pop_user, {auth1, auth2}, + auth2, "pass", 1, 1, pop_pass, {auth1, trans}, +#ifdef RPOP + auth2, "rpop", 1, 1, pop_rpop, {auth1, trans}, +#endif RPOP + auth1, "quit", 0, 0, pop_quit, {halt, halt}, + auth2, "quit", 0, 0, pop_quit, {halt, halt}, + 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, "xtnd", 1, 99, pop_xtnd, {trans, trans}, + trans, "quit", 0, 0, pop_updt, {halt, halt}, + (state) 0, NULL, 0, 0, NULL, {halt, halt}, +}; + +state_table *pop_get_command(p,mp) +POP * p; +register char * mp; /* Pointer to unparsed line + received from the client */ +{ + state_table * s; + char buf[MAXMSGLINELEN]; + + /* Save a copy of the original client line */ +#ifdef DEBUG + if(p->debug) strcpy (buf,mp); +#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 */ + 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) + return((state_table *)pop_msg(p,POP_FAILURE, + "Too few arguments for the %s command.",p->pop_command)); + + /* Were too many parameters passed to the command? */ + if (p->parm_count > s->max_parms) + return((state_table *)pop_msg(p,POP_FAILURE, + "Too many arguments for the %s command.",p->pop_command)); + + /* 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 */ + return((state_table *)pop_msg(p,POP_FAILURE, + "Unknown command: \"%s\".",p->pop_command)); +} diff --git a/appl/popper/pop_get_subcommand.c b/appl/popper/pop_get_subcommand.c new file mode 100644 index 000000000..84d0dfd68 --- /dev/null +++ b/appl/popper/pop_get_subcommand.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ + +#ifndef lint +static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; +static char SccsId[] = "@(#)@(#)pop_get_subcommand.c 2.1 2.1 3/18/91"; +#endif not lint + +#include +#include +#include +#include "popper.h" + +/* + * get_subcommand: Extract a POP XTND subcommand from a client input line + */ + +static xtnd_table subcommands[] = { + "xmit", 0, 0, pop_xmit, + NULL +}; + +xtnd_table *pop_get_subcommand(p) +POP * p; +{ + xtnd_table * s; + + /* Search for the POP command in the command/state table */ + for (s = subcommands; s->subcommand; s++) { + + if (strcmp(s->subcommand,p->pop_subcommand) == 0) { + + /* Were too few parameters passed to the subcommand? */ + if ((p->parm_count-1) < s->min_parms) + return((xtnd_table *)pop_msg(p,POP_FAILURE, + "Too few arguments for the %s %s command.", + p->pop_command,p->pop_subcommand)); + + /* Were too many parameters passed to the subcommand? */ + if ((p->parm_count-1) > s->max_parms) + return((xtnd_table *)pop_msg(p,POP_FAILURE, + "Too many arguments for the %s %s command.", + p->pop_command,p->pop_subcommand)); + + /* Return a pointer to the entry for this subcommand + in the XTND command table */ + return (s); + } + } + /* The client subcommand was not located in the XTND command table */ + return((xtnd_table *)pop_msg(p,POP_FAILURE, + "Unknown command: \"%s %s\".",p->pop_command,p->pop_subcommand)); +}