From 3e6d3ab860a2ffa3cab17828e824c34277b30b26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Groenvall?= Date: Thu, 21 Sep 1995 08:35:04 +0000 Subject: [PATCH] Initial revision git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@107 ec53bebd-3082-4978-b11e-865c3cabbd6b --- appl/popper/pop_updt.c | 203 +++++++++++++++++++++++++++++++++++++++++ appl/popper/popper.h | 172 ++++++++++++++++++++++++++++++++++ 2 files changed, 375 insertions(+) create mode 100644 appl/popper/pop_updt.c create mode 100644 appl/popper/popper.h diff --git a/appl/popper/pop_updt.c b/appl/popper/pop_updt.c new file mode 100644 index 000000000..0afacecff --- /dev/null +++ b/appl/popper/pop_updt.c @@ -0,0 +1,203 @@ +/* + * 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_updt.c 2.3 2.3 3/20/91"; +#endif not lint + +#include +#include +#include +#include +#include +#include +#include "popper.h" + +extern int errno; + +static char standard_error[] = + "Error error updating primary drop. Mailbox unchanged"; + +/* + * updt: Apply changes to a user's POP maildrop + */ + +int pop_updt (p) +POP * p; +{ + FILE * md; /* Stream pointer for + the user's maildrop */ + int mfd; /* File descriptor for + above */ + char buffer[BUFSIZ]; /* Read buffer */ + + MsgInfoList * mp; /* Pointer to message + info list */ + register int msg_num; /* Current message + counter */ + register int status_written; /* Status header field + written */ + int nchar; /* Bytes read/written */ + + long offset; /* New mail offset */ + +#ifdef DEBUG + if (p->debug) { + pop_log(p,POP_DEBUG,"Performing maildrop update..."); + pop_log(p,POP_DEBUG,"Checking to see if all messages were deleted"); + } +#endif DEBUG + + if (p->msgs_deleted == p->msg_count) { + /* Truncate before close, to avoid race condition, DO NOT UNLINK! + Another process may have opened, and not yet tried to lock */ + (void)ftruncate ((int)fileno(p->drop),0); + (void)fclose(p->drop) ; + return (POP_SUCCESS); + } + +#ifdef DEBUG + if (p->debug) + pop_log(p,POP_DEBUG,"Opening mail drop \"%s\"",p->drop_name); +#endif DEBUG + + /* Open the user's real maildrop */ + if ((mfd = open(p->drop_name,O_RDWR|O_CREAT,0600)) == -1 || + (md = fdopen(mfd,"r+")) == NULL) { + return pop_msg(p,POP_FAILURE,standard_error); + } + + /* Lock the user's real mail drop */ + if ( flock(mfd,LOCK_EX) == -1 ) { + (void)fclose(md) ; + return pop_msg(p,POP_FAILURE, "flock: '%s': %s", p->temp_drop, + (errno < sys_nerr) ? sys_errlist[errno] : ""); + } + + /* Go to the right places */ + offset = lseek((int)fileno(p->drop),0,L_XTND) ; + + /* Append any messages that may have arrived during the session + to the temporary maildrop */ + while ((nchar=read(mfd,buffer,BUFSIZ)) > 0) + if ( nchar != write((int)fileno(p->drop),buffer,nchar) ) { + nchar = -1; + break ; + } + if ( nchar != 0 ) { + (void)fclose(md) ; + (void)ftruncate((int)fileno(p->drop),(int)offset) ; + (void)fclose(p->drop) ; + return pop_msg(p,POP_FAILURE,standard_error); + } + + rewind(md); + (void)ftruncate(mfd,0) ; + + /* Synch stdio and the kernel for the POP drop */ + rewind(p->drop); + (void)lseek((int)fileno(p->drop),0,L_SET); + + /* Transfer messages not flagged for deletion from the temporary + maildrop to the new maildrop */ +#ifdef DEBUG + if (p->debug) + pop_log(p,POP_DEBUG,"Creating new maildrop \"%s\" from \"%s\"", + p->drop_name,p->temp_drop); +#endif DEBUG + + for (msg_num = 0; msg_num < p->msg_count; ++msg_num) { + + int doing_body; + + /* Get a pointer to the message information list */ + mp = &p->mlp[msg_num]; + + if (mp->del_flag) { +#ifdef DEBUG + if(p->debug) + pop_log(p,POP_DEBUG, + "Message %d flagged for deletion.",mp->number); +#endif DEBUG + continue; + } + + (void)fseek(p->drop,mp->offset,0); + +#ifdef DEBUG + if(p->debug) + pop_log(p,POP_DEBUG,"Copying message %d.",mp->number); +#endif DEBUG + for(status_written = doing_body = 0 ; + fgets(buffer,MAXMSGLINELEN,p->drop);) { + + if (doing_body == 0) { /* Header */ + + /* Update the message status */ + if (strncasecmp(buffer,"Status:",7) == 0) { + if (mp->retr_flag) + (void)fputs("Status: RO\n",md); + else + (void)fputs(buffer, md); + status_written++; + continue; + } + /* A blank line signals the end of the header. */ + if (*buffer == '\n') { + doing_body = 1; + if (status_written == 0) { + if (mp->retr_flag) + (void)fputs("Status: RO\n\n",md); + else + (void)fputs("Status: U\n\n",md); + } + else (void)fputs ("\n", md); + continue; + } + /* Save another header line */ + (void)fputs (buffer, md); + } + else { /* Body */ + if (strncmp(buffer,"From ",5) == 0) break; + (void)fputs (buffer, md); + } + } + } + + /* flush and check for errors now! The new mail will writen + without stdio, since we need not separate messages */ + + (void)fflush(md) ; + if (ferror(md)) { + (void)ftruncate(mfd,0) ; + (void)fclose(md) ; + (void)fclose(p->drop) ; + return pop_msg(p,POP_FAILURE,standard_error); + } + + /* Go to start of new mail if any */ + (void)lseek((int)fileno(p->drop),offset,L_SET); + + while((nchar=read((int)fileno(p->drop),buffer,BUFSIZ)) > 0) + if ( nchar != write(mfd,buffer,nchar) ) { + nchar = -1; + break ; + } + if ( nchar != 0 ) { + (void)ftruncate(mfd,0) ; + (void)fclose(md) ; + (void)fclose(p->drop) ; + return pop_msg(p,POP_FAILURE,standard_error); + } + + /* Close the maildrop and empty temporary maildrop */ + (void)fclose(md); + (void)ftruncate((int)fileno(p->drop),0); + (void)fclose(p->drop); + + return(pop_quit(p)); +} diff --git a/appl/popper/popper.h b/appl/popper/popper.h new file mode 100644 index 000000000..ae4d64721 --- /dev/null +++ b/appl/popper/popper.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 1989 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + * + * static char copyright[] = "Copyright (c) 1990 Regents of the University of California.\nAll rights reserved.\n"; + * static char SccsId[] = "@(#)@(#)popper.h 2.2 2.2 4/2/91"; + * + */ + +/* LINTLIBRARY */ + +/* + * Header file for the POP programs + */ + +#include +#include "version.h" + +#define NULLCP ((char *) 0) +#define SPACE 32 +#define TAB 9 +#define TRUE 1 +#define FALSE 0 +#define NEWLINE '\n' + +#define MAXHOSTNAMELEN 256 +#define MAXUSERNAMELEN 65 +#define MAXDROPLEN 64 +#define MAXLINELEN 1024 +#define MAXMSGLINELEN 1024 +#define MAXCMDLEN 4 +#define MAXPARMCOUNT 5 +#define MAXPARMLEN 10 +#define ALLOC_MSGS 20 +#define MAIL_COMMAND "/usr/lib/sendmail" + +#define POP_FACILITY LOG_LOCAL0 +#define POP_PRIORITY LOG_NOTICE +#define POP_DEBUG LOG_DEBUG +#define POP_LOGOPTS 0 +#define POP_MAILDIR "/usr/spool/mail" +#define POP_DROP "/usr/spool/mail/.%s.pop" + /* POP_TMPSIZE needs to be big enough to hold the string + * defined by POP_TMPDROP. POP_DROP and POP_TMPDROP + * must be in the same filesystem. + */ +#define POP_TMPDROP "/usr/spool/mail/tmpXXXXXX" +#define POP_TMPSIZE 256 +#define POP_TMPXMIT "/tmp/xmitXXXXXX" +#define POP_OK "+OK" +#define POP_ERR "-ERR" +#define POP_SUCCESS 1 +#define POP_FAILURE 0 +#define POP_TERMINATE '.' + +extern int errno; +extern int sys_nerr; +extern char * sys_errlist[]; +extern char * sys_siglist[]; + +#define pop_command pop_parm[0] /* POP command is first token */ +#define pop_subcommand pop_parm[1] /* POP XTND subcommand is the + second token */ + +typedef enum { /* POP processing states */ + auth1, /* Authorization: waiting for + USER command */ + auth2, /* Authorization: waiting for + PASS command */ + trans, /* Transaction */ + update, /* Update: session ended, + process maildrop changes */ + halt, /* (Halt): stop processing + and exit */ + error /* (Error): something really + bad happened */ +} state; + +typedef struct { /* State information for + each POP command */ + state ValidCurrentState; /* The operating state of + the command */ + char * command; /* The POP command */ + int min_parms; /* Minimum number of parms + for the command */ + int max_parms; /* Maximum number of parms + for the command */ + int (*function) (); /* The function that process + the command */ + state result[2]; /* The resulting state after + command processing */ +#define success_state result[0] /* State when a command + succeeds */ +} state_table; + +typedef struct { /* Table of extensions */ + char * subcommand; /* The POP XTND subcommand */ + int min_parms; /* Minimum number of parms for + the subcommand */ + int max_parms; /* Maximum number of parms for + the subcommand */ + int (*function) (); /* The function that processes + the subcommand */ +} xtnd_table; + +typedef struct { /* Message information */ + int number; /* Message number relative to + the beginning of list */ + long length; /* Length of message in + bytes */ + int lines; /* Number of (null-terminated) lines in the message */ + long offset; /* Offset from beginning of + file */ + int del_flag; /* Flag indicating if message + is marked for deletion */ + int retr_flag; /* Flag indicating if message + was retrieved */ +} MsgInfoList; + +typedef struct { /* POP parameter block */ + int debug; /* Debugging requested */ + char * myname; /* The name of this POP + daemon program */ + char myhost[MAXHOSTNAMELEN]; /* The name of our host + computer */ + char * client; /* Canonical name of client + computer */ + char * ipaddr; /* Dotted-notation format of + client IP address */ + unsigned short ipport; /* Client port for privileged + operations */ + char user[MAXUSERNAMELEN]; /* Name of the POP user */ + state CurrentState; /* The current POP operational state */ + MsgInfoList * mlp; /* Message information list */ + int msg_count; /* Number of messages in + the maildrop */ + int msgs_deleted; /* Number of messages flagged + for deletion */ + int last_msg; /* Last message touched by + the user */ + long bytes_deleted; /* Number of maildrop bytes + flagged for deletion */ + char drop_name[MAXDROPLEN]; /* The name of the user's + maildrop */ + char temp_drop[MAXDROPLEN]; /* The name of the user's + temporary maildrop */ + long drop_size; /* Size of the maildrop in + bytes */ + FILE * drop; /* (Temporary) mail drop */ + FILE * input; /* Input TCP/IP communication + stream */ + FILE * output; /* Output TCP/IP communication stream */ + FILE * trace; /* Debugging trace file */ + char * pop_parm[MAXPARMCOUNT]; /* Parse POP parameter list */ + int parm_count; /* Number of parameters in + parsed list */ +} POP; + +extern int pop_dele(); +extern int pop_last(); +extern int pop_list(); +extern int pop_pass(); +extern int pop_quit(); +extern int pop_rset(); +extern int pop_send(); +extern int pop_stat(); +extern int pop_updt(); +extern int pop_user(); +extern int pop_xtnd(); +extern int pop_xmit(); +