Initial revision
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@107 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
203
appl/popper/pop_updt.c
Normal file
203
appl/popper/pop_updt.c
Normal file
@@ -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 <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#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));
|
||||||
|
}
|
172
appl/popper/popper.h
Normal file
172
appl/popper/popper.h
Normal file
@@ -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 <syslog.h>
|
||||||
|
#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();
|
||||||
|
|
Reference in New Issue
Block a user