home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-09-11 | 29.8 KB | 1,209 lines |
- Subject: junkmail - delete outdated mail automatically
- Newsgroups: mod.sources
- Approved: jpn@panda.UUCP
-
- Mod.sources: Volume 5, Issue 6
- Submitted by: Wombat <pur-ee!pucc-j.Purdue.EDU!rsk>
-
- # This is a shell archive.
- # Remove everything above and including the cut line.
- # Then run the rest of the file through sh.
- #----cut here-----cut here-----cut here-----cut here----#
- #!/bin/sh
- # shar: Shell Archiver
- # Run the following text with /bin/sh to create:
- # README
- # junkmail.8
- # junkmail.c
- # This archive created: Thu May 15 14:37:16 1986
- # By: Wombat (Purdue University)
- cat << \SHAR_EOF > README
- Junkmail is designed to be run from "cron" or "at" on a regular basis
- in order to keep the size of /usr/spool/mail within reasonable limits.
- It deletes old/large mail according to criteria described in the manual
- page, and settable at compile or run time.
-
- It should be compatible with 4.x BSD; don't know about AT&T Unix.
-
- It is also capable of deleting all mail from a specified user--a feature
- which is occasionally handy when a malicious/naive user discovers mail.
- Comments and bugs to:
-
- Rich Kulawiec, pucc-j!rsk, rsk@asc.purdue.edu
-
- README This file
- junkmail.c Superfluous/malicious mail deletion program
- (cc -O -DPUCC -DBSD4_2 -o junkmail junkmail.c)
- junkmail.8l Manual page for above
- (nroff -man junkmail.8l)
- SHAR_EOF
- cat << \SHAR_EOF > junkmail.8
- .TH JUNKMAIL 8
- .UC 4
- .SH NAME
- junkmail \- delete undesired mail from /usr/spool/mail
- .SH SYNOPSIS
- .B junkmail \fR[\fB-a\fR] [\fB-w\fR] [\fB-dn\fR[\fB-m\fR]] [\fB-u\fRusername] [directory]
- .SH DESCRIPTION
- .I Junkmail
- is designed to cope with overuse of /usr/spool/mail.
- It searches
- /usr/spool/mail/*
- for old and/or large letters and deletes them,
- leaving a message informing the user of this action.
- It may also be used to delete all mail from a specified user.
-
- The following options are interpreted by
- .I junkmail.
- .TP
- .B \-a
- Select an audit trail.
- .TP
- .B \-w
- Specifies that shortened files are to be written,
- containing letters that indicate what has been deleted.
- Otherwise, only an audit is performed.
- .TP
- .BI \-d n[-m]
- Specifies that the following number
- .I
- n
- or range of numbers
- .I
- n-m
- defines the age of discarded letters.
- A letter newer than
- .I
- n
- days will only be discarded if the mail file
- exceeds the limit by 100%.
- A letter between
- .I
- n
- and
- .I
- m
- days old will be discarded if the mail file exceeds the size
- limit.
- A letter older than
- .I
- m
- days will always be discarded.
- .I
- N
- defaults to 7;
- .I
- m,
- to 21.
- If a single value is specified, it is taken to be
- .I
- m,
- and
- .I
- n
- is assumed to be 7.
- Of course,
- .I
- m
- must be greater than
- .I
- n.
- .TP
- .B \-u\fRusername
- specifies that all mail originating from user
- "username"
- be deleted, whether or not it satisfies the aging constraints.
- All other mail will be untouched, and no letter informing the
- recipient(s) of the deletion will be left.
- .TP
- [directory]
- is the optional mail directory name,
- with "/usr/spool/mail" as the default.
- .SH FILES
- /usr/spool/mail/*
- .SH "SEE ALSO"
- mail(1)
- .SH BUGS
- When an individual username is selected,
- .I
- junkmail
- cannot cope with large files and prints a message to that
- effect rather than deleting the letters.
- SHAR_EOF
- cat << \SHAR_EOF > junkmail.c
-
- /*==========================================================
- *
- * junkmail - delete undesired mail from /usr/spool/mail/*
- *
- * Copyright, Purdue University Computing Center, 1982, all
- * rights reserved.
- *
- * Author: V. Abell
- * Modifications: R. Kulawiec 8/83 added -u flag.
- * Rewrote a lot of the code to handle buffering.
- * R. Kulawiec 10/84 added audit trail for -u flag.
- * added "reason for deletion"
- * added extra line on rewritten headers
- * R. Kulawiec 6/85 rewritten headers now conform to RFC822.
- *
- * junkmail [-a] [-w] [-dn[-m]] [-u username] [directory]
- *
- * -a selects an audit trail.
- *
- * -w specifies that shortened files are to
- * be written, containing letters that
- * indicate what has been deleted.
- * Otherwise, only an audit is performed.
- *
- * -d specifies that the following number, n,
- * or range of numbers, n-m, defines the
- * age of discarded letters. A letter
- * newer than n days will only be discarded
- * if the mail file size exceeds the limit
- * by 100%. A letter older than m days will
- * be discarded. n defaults to 7; m, to 21.
- * If a single value is specified, it is
- * taken to be m, and n is assumed to be 7.
- * Of course, m must be > n.
- *
- * -u username specifies that all mail from user
- * "username" be deleted, regardless of age
- * or size.
- *
- * [directory] is the optional mail directory
- * name - "/usr/spool/mail" is the default.
- *
- *
- *==========================================================
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include <sys/dir.h>
- #include <sys/stat.h>
- #include <time.h>
-
- #define LINE_LEN 1024 /* Maximum length of a line */
- #define LOC_TIME_ZONE 5*60 /* local time zone offset (EST) */
- #define FILENAME_LEN 128 /* Length of individual filenames */
- #define DIRECTORY_LEN 128 /* Length of directory name */
- #define USERNAME_LEN 128 /* Maximum length of any originator */
-
-
- #define FAILED -1 /* Failure return code from call */
- #define FAILED_LONG -1l /* Failure return code from call */
- #define SUCCEED 0 /* Success return code from call */
- #define SUCCEED_LONG 0l /* Success return code from call */
-
-
- #define DIRECT "/usr/spool/mail/" /* directory name for mail */
-
- #define SENDER "MAILER-DAEMON" /* audit letter sender */
-
- #define MAX_AGE 21L /* maximum letter age (default) */
- #define MIN_AGE 7L /* minimum letter age (default) */
-
- #define PROTECT_MODE 0600 /* protection mode */
-
- #define MAX_SIZE 50000 /* nominal maximum mailbox size */
- #define ABS_MAX_SIZE 2*MAX_SIZE /* absolute maximum mailbox size */
-
- #define NEWLINE '\n' /* Ascii newline character */
-
- char Selectname[USERNAME_LEN]; /* name of user whose mail to blast */
- char Directory[DIRECTORY_LEN] = DIRECT; /* working directory (default) */
- char Filename[FILENAME_LEN]; /* individual files as we go */
-
- int audit_flag = 0; /* Audit trail is selected */
- int rewrite_flag = 0; /* Rewriting of files will be done */
- int select_flag = 0; /* Individual user has been selected */
- int date_flag = 0; /* User has overridden a date(s) */
-
- long max_age = MAX_AGE; /* maximum letter age */
- long min_age = MIN_AGE; /* minimum letter age */
-
- char *day_table[7] = {"Mon","Tue","Wed","Thu","Fri","Sat","Sun"};
-
- int month_size[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
-
- char *month_table[12] = {"Jan","Feb","Mar","Apr","May","Jun",
- "Jul","Aug","Sep","Oct","Nov","Dec"};
- struct zone {
- int hours_west; /* hours west of Greenwich */
- char *st; /* standard time zone name */
- char *dl; /* daylight time zone name */
- } z_tab[] = {
- 4*60, "AST", "ADT", /* Atlantic */
- 5*60, "EST", "EDT", /* Eastern */
- 6*60, "CST", "CDT", /* Central */
- 7*60, "MST", "MDT", /* Mountain */
- 8*60, "PST", "PDT", /* Pacific */
- 0000, "GMT", "GMT", /* Greenwich */
- -1 /* end of table indicator */
- };
-
- struct stat Sbuf; /* for return values from stat() call */
- struct direct Dir_entry; /* directory structure */
-
- #ifdef vax
- DIR *Dfd;
- #else
- int Dfd; /* directory file descriptor */
- #endif
-
- FILE *Mfp; /* mail file pointer */
- FILE *Tfp; /* temp file pointer */
-
- char *Tempfile = "/tmp/junkXXXXXX"; /* Temporary file for copying */
-
- char sndl[512]; /* "MAIL~SYSTEM" sender line */
- int compare_length = USERNAME_LEN; /* longest originator length */
- char Buffer[LINE_LEN]; /* Input/output mail buffer */
- char Headbuf[LINE_LEN]; /* Save area for mail header */
- long File_length = 0l; /* Length of input mail file */
-
- char *ctime(); /* Time conversion */
- char *mktemp(); /* Temporary filename maker */
-
- #ifndef vax
- char machine(); /* Machine identifier */
- #endif
-
- int Copy_flag = 1; /* Whether or not to copy bytes through */
-
- long bytes_del; /* Number of bytes deleted from this file */
- /* (or that could be deleted). Note that */
- /* this does NOT account for bytes written */
- /* by junkmail itself. */
- long tot_bytes_del = 0; /* Total number of bytes deleted in run */
- int files_short = 0; /* Total number of files shortened */
- int files_del = 0; /* Total number of zero-length files deleted */
-
- char Loginname[255]; /* The name of the file in /usr/spool/mail. */
- /* Set to 255 to avoid unpleasant surprises */
- /* should a filename > 8 chars creep in. */
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int i;
- long time();
- long time_buf;
- char hoststr[32];
-
- i = 1;
-
- do {
- if(argc != 0)
- if(argc > 1 && strncmp(argv[i],"-",1) == 0 ) {
- if(strncmp(argv[i],"-a",2) == 0) { /* audit */
- audit_flag = 1;
- continue;
- }
- if(strncmp(argv[i],"-w",2) == 0) { /* rewrite */
- rewrite_flag = 1;
- continue;
- }
- if(strncmp(argv[i],"-d",2) == 0) { /* date ch. */
- date_flag = 1;
- if( agerange(argv[i]) == FAILED)
- usage();
- continue;
- }
- if(strncmp(argv[i],"-u",2) == 0) { /* target */
- if( get_selectname(argv[++i]) == FAILED )
- usage();
- select_flag = 1;
- rewrite_flag = 1;
- continue;
- }
- usage();
- }
- if(argc > 1) { /* chdir */
- if( get_dirname(argv[i]) == FAILED )
- usage();
- continue;
- }
- }
- while(++i < argc);
-
- if(select_flag && date_flag) {
- fprintf(stderr,"Use of -u and -d together not allowed\n");
- usage();
- }
-
- time(&time_buf);
-
- #ifdef vax
- if(gethostname(hoststr,sizeof(hoststr)) == FAILED)
- fprintf(stderr,"Gethostname() failed!\n");
- #else
- sprintf(hoststr,"pucc-%s",machine());
- #endif
-
- if(audit_flag)
- printf("\n%s, %s\n",hoststr,ctime(&time_buf));
-
- if(rewrite_flag)
- sprintf(sndl,"From %s %sReceived: by %s, %sDate: %sFrom: <pucc> %s\nTo: ",SENDER,ctime(&time_buf),hoststr,ctime(&time_buf),ctime(&time_buf),SENDER);
-
- if(rewrite_flag)
- Tempfile = mktemp(Tempfile);
-
- if(check_dirname() == FAILED)
- usage();
-
- if(select_flag)
- printf("Deleting all mail from user %s\n\n",Selectname);
-
- while( get_filename() != FAILED) {
- if(select_flag) {
- if(del_user()==FAILED)
- exit(1);
- }
- else {
- if(del_oldbig() == FAILED)
- exit(1);
- }
- if(audit_flag && (bytes_del != 0) ) {
- printf("\t%s",Filename);
- if(rewrite_flag)
- printf(" was shortened by ");
- else
- printf(" could be shortened by ");
- printf("%ld bytes\n",bytes_del);
- }
- }
- if(audit_flag) {
- printf("----------\n");
- printf("%d files",files_short);
- if(rewrite_flag)
- printf(" were shortened by ");
- else
- printf(" could be shortened by ");
- printf("%ld bytes\n",tot_bytes_del);
- if( !select_flag) {
- printf("%d zero-length files",files_del);
- if(rewrite_flag)
- printf(" were deleted\n");
- else
- printf(" could be deleted\n");
- }
- printf("----------\n");
- }
- }
- /*==================================================
- *
- * usage() - print argument usage message and exit.
- *
- *
- *==================================================
- */
-
- usage()
- {
- fprintf(stderr,"Usage: junkmail [-a] [-w] [-dn[-m]] [-u username] [directory]\n");
- exit(1);
- }
-
- /*==================================================
- *
- * get_selectname(p) - Get the username pointed to.
- *
- *
- *==================================================
- */
-
- get_selectname(p)
- char *p;
- {
- if(strlen(p) > USERNAME_LEN) /* Username can't be more */
- return(FAILED); /* than this long */
- if(strlen(p) <= 0 ) /* Username can't this */
- return(FAILED); /* long either */
- else {
- strcpy(Selectname,p);
- return(SUCCEED);
- }
- }
-
- /*==================================================
- *
- * get_dirname(p) - Get the directory name pointed to.
- *
- *
- *==================================================
- */
-
- get_dirname(p)
- char *p;
- {
- if(strlen(p) > DIRECTORY_LEN) /* Username can't be more */
- return(FAILED); /* than this long */
- if(strlen(p) <= 0 ) /* Username can't this */
- return(FAILED); /* long either */
- else {
- strcpy(Directory,p);
- return(SUCCEED);
- }
- }
-
- /*==========================================================
- *
- * agerange(p) - assemble the age range represented by the
- * characters at (p).
- *
- * exit return = 0 if range assembled
- * -1 if assembly error detected
- * (min_age) = minimum age
- * (max_age) = maximum age
- *
- *==========================================================
- */
-
- agerange(p)
- char *p;
- {
- int n; /* number being assembled */
- /*
- * Assemble first number.
- */
- p += 2; /* Skip over the "-d" flag */
-
- for(n = 0; *p >= '0' && *p <= '9'; p++)
- n = 10 * n + *p - '0';
- if(*p != '\0') {
- if(*p++ != '-')
- return(FAILED);
- /*
- * If the first number is terminated by a minus sign ("-"),
- * assemble the second number of an "n-m" range.
- */
- min_age = (long) n;
- for(n = 0; *p >= '0' && *p <= '9'; p++)
- n = 10 * n + *p - '0';
- }
- max_age = (long) n;
- if(min_age <= 0l || max_age <= 0l || min_age >= max_age)
- return(FAILED);
- return(SUCCEED);
- }
-
- /*======================================================================
- *
- * long dysince(a) - convert the ctime() format date, addressed by (a)
- * to the number of days since that date.
- *
- * exit return = -1L if the date cannot be converted
- *
- *======================================================================
- */
- long dysince(a)
- char *a;
- {
-
- int day; /* day */
- int hours; /* hours */
- int minutes; /* minutes */
- int month; /* month */
- int seconds; /* seconds */
- int year; /* year */
- int z = LOC_TIME_ZONE; /* time zone offset */
- long time_buf; /* time buffer */
- long time_sec = 0l; /* time in seconds */
- register int i; /* temporary index */
- /*
- * Check and skip day of week.
- */
- if(ckalpha(a,3) == 0)
- return(FAILED_LONG);
- for(i = 0; i < 7; i++)
- if(strncmp(a,day_table[i],3) == 0)
- break;
- if(i > 6)
- return(FAILED_LONG);
- a += 3;
- if(*a++ != ' ')
- return(FAILED_LONG);
- /*
- * Check month and convert to integer.
- */
- if(ckalpha(a,3) == 0)
- return(FAILED_LONG);
- for(month = 0; month < 12; month++)
- if(strncmp(a,month_table[month],3) == 0)
- break;
- if(month > 11)
- return(FAILED_LONG);
- a += 3;
- while(*a == ' ') {
- if(*a == '\0')
- return(FAILED_LONG);
- a++;
- }
- /*
- * Convert day number.
- */
- day = atoi(a);
- while(*a >= '0' && *a <= '9')
- a++;
- while(*a == ' ') {
- if(*a == '\0')
- return(FAILED_LONG);
- a++;
- }
- /*
- * Convert time.
- */
- hours = atoi(a);
- while(*a >= '0' && *a <= '9')
- a++;
- if(hours < 0 || hours > 23 || *a++ != ':')
- return(FAILED_LONG);
- minutes = atoi(a);
- while(*a >= '0' && *a <= '9')
- a++;
- if(minutes < 0 || minutes > 59 || *a++ != ':')
- return(FAILED_LONG);
- seconds = atoi(a);
- while(*a >= '0' && *a <= '9')
- a++;
- if(seconds < 0 || seconds > 59 || *a++ != ' ')
- return(FAILED_LONG);
- /*
- * Convert time zone and year.
- */
- if((*a >= 'a' && *a <= 'z') || (*a >= 'A' && *a <= 'Z')) {
- if(ckalpha(a,3) == 0)
- return(FAILED_LONG);
- for(i = 0; (z = z_tab[i].hours_west) >= 0; i++) {
- if(strncmp(a,z_tab[i].st,3) == 0
- || strncmp(a,z_tab[i].dl,3) == 0)
- break;
- }
- if(z == -1)
- return(FAILED_LONG);
- while(*a < '0' || *a > '9') {
- if(*a == '\0')
- return(FAILED_LONG);
- a++;
- }
- }
- minutes += z;
- year = atoi(a);
- /*
- * Check year.
- */
- if(year < 1970)
- return(FAILED_LONG);
- /*
- * Cope with February in leap/non-leap years.
- */
- if(leap(year))
- month_size[1] = 29;
- else
- month_size[1] = 28;
- if(day < 1 || day > month_size[month])
- return(FAILED_LONG);
- /*
- * Calculate seconds since the epoch.
- */
- for(i = 1970; i < year; i++)
- time_sec += (leap(i) ? 366 : 365);
- while(--month >= 0)
- time_sec += month_size[month];
- time_sec += (long) day - 1l;
- time_sec = time_sec*24l + (long) hours;
- time_sec = time_sec*60l + (long) minutes;
- time_sec = time_sec*60l + (long) seconds;
- /*
- * Return days from today as (seconds from today).
- * ------------------
- * 24 * 60 * 60
- */
- time(&time_buf);
- if(time_sec > time_buf)
- return(FAILED_LONG);
- return((time_buf - time_sec) / 86400l);
- }
-
- /*=============================================
- *
- * leap(y) - test (y) for a leap year
- *
- * exit return = 0 if not a leap year
- * 1 if a leap year
- *
- *=============================================
- */
-
- leap(y)
- int y;
- {
- return(y%4 == 0 && y%100 != 0 || y%400 == 0);
- }
-
- /*====================================================================
- *
- * ckalpha(a,n) - check for n consecutive alpha characters, starting
- * at (a).
- *
- * exit return = 0 if non-alpha character encountered
- * 1 if characters available
- *
- *====================================================================
- */
-
- ckalpha(a,n)
-
- char *a;
- int n;
-
- {
- register int i; /* temporary index */
-
- for(i = 0; i < n; i++)
- if( (! isascii(*a)) || (! isalpha(*a)) )
- return(0);
- return(1);
- }
-
- /*====================================================================
- *
- * check_dirname() - Verify that "Directory" exists, is a
- * directory, and is readable.
- *
- * exit return = 0 if a legitimate directory has been found
- * -1 otherwise
- *
- *====================================================================
- */
- check_dirname()
- {
-
- if( stat(Directory,&Sbuf) == FAILED) {
- fprintf(stderr,"Can't stat %s\n",Directory);
- return(FAILED);
- }
- if( ((Sbuf.st_mode & S_IFDIR) == 0) || Sbuf.st_ino == 0 ) {
- fprintf(stderr,"%s is not a directory\n",Directory);
- return(FAILED);
- }
- #ifdef vax
- if( (Dfd = opendir(Directory)) == NULL) {
- #else
- if( (Dfd = open(Directory,0)) == FAILED) {
- #endif
- fprintf(stderr,"Can't open directory %s\n",Directory);
- return(FAILED);
- }
- return(SUCCEED);
- }
- /*====================================================================
- *
- * get_filename() - Get the next file in directory "Directory".
- *
- * exit return = 0 if a legitimate file has been found
- * -1 otherwise
- *
- * Note: "Reads through" '.' and '..' transparently.
- *
- *====================================================================
- */
- get_filename()
- {
- int pathlength;
- #ifdef vax
- struct direct *dirent;
- #endif
- /* Add tailing slash to directory name if user forgot it */
-
- if(Directory[strlen(Directory)-1] != '/')
- strcat(Directory,"/");
-
- strcpy(Filename,Directory);
- pathlength = strlen(Filename);
-
- #ifdef vax
- while( (dirent = readdir(Dfd)) != NULL) {
- if(dirent->d_ino == 0) /* File has been deleted */
- continue;
- if(strncmp(dirent->d_name,".",1) == 0) /* Skip "." */
- continue;
- if(strncmp(dirent->d_name,"..",2) == 0) /* Skip ".." */
- continue;
- strncpy(&Filename[pathlength],dirent->d_name,sizeof(dirent->d_name));
- strcpy(Loginname,dirent->d_name);
- return(SUCCEED);
- }
- closedir(Dfd);
- return(FAILED);
- #else
- while(read(Dfd,&Dir_entry,sizeof(Dir_entry)) > 0) {
- if(Dir_entry.d_ino == 0) /* File has been deleted */
- continue;
- if(strncmp(Dir_entry.d_name,".",1) == 0) /* Skip "." */
- continue;
- if(strncmp(Dir_entry.d_name,"..",2) == 0) /* Skip ".." */
- continue;
- strncpy(&Filename[pathlength],Dir_entry.d_name,sizeof(Dir_entry.d_name));
- strcpy(Loginname,Dir_entry.d_name);
- return(SUCCEED);
- }
- if( close(Dfd) == FAILED)
- fprintf(stderr,"Couldn't close %s\n",Directory);
-
- return(FAILED); /* Have read entire dir. */
- #endif
- }
- /*==================================================
- *
- * del_oldbig() - remove letters that are either too old or too big.
- * remove mailboxes that are zero length.
- * exit - 0 if no problems encountered
- * 1 if couldn't open or other nastiness
- *
- *==================================================
- */
- del_oldbig()
- {
- long finalsize;
- long size_date();
- long filemark; /* Marks beginning of current letter */
- int onetrip; /* Whether or not we've made first */
- /* trip through mail scanning loop */
- int copy; /* Temporary loop index for saving */
- /* mail headers */
- int wrote_sndl; /* Whether or not we've written our */
- /* "From" line to temp file */
-
- if( stat(Filename,&Sbuf) == FAILED) {
- fprintf(stderr,"Can't stat %s\n",Filename);
- return(FAILED);
- }
-
- /* Reset delete counter in case we exit before setting it below */
-
- bytes_del = 0l;
-
- /* If file is zero length, mark it for deletion */
-
- if(Sbuf.st_size == 0) {
- ++files_del;
- if(rewrite_flag)
- unlink(Filename);
- if(audit_flag && rewrite_flag)
- printf("\t%s was zero-length, deleted\n",Filename);
- if(audit_flag && !rewrite_flag)
- printf("\t%s is zero-length\n",Filename);
- return(SUCCEED);
- }
-
- /* Determine what the final size for this file should be */
-
- if( (finalsize = size_date()) == FAILED_LONG) {
- fprintf(stderr,"Error determining date/size of %s\n",Filename);
- return(FAILED);
- }
-
- if(Sbuf.st_size <= finalsize) /* File is smaller than it */
- return(SUCCEED); /* has to be, no problem. */
-
- ++files_short; /* Another one shortened */
-
- File_length = Sbuf.st_size;
- filemark = File_length;
-
- onetrip = FAILED;
- wrote_sndl = FAILED;
-
- if( (Mfp = fopen(Filename,"r+")) == NULL) {
- fprintf(stderr,"Can't open %s\n",Filename);
- return(FAILED);
- }
- if(rewrite_flag) {
- if( (Tfp = fopen(Tempfile,"w+")) == NULL) {
- fprintf(stderr,"Can't open tempfile %s\n",Tempfile);
- return(FAILED);
- }
- }
-
- while( readline() == SUCCEED && File_length > finalsize) {
- if(is_a_header() == SUCCEED) {
- if(rewrite_flag && (from_system() == FAILED) ) {
- if(wrote_sndl == FAILED) {
- fprintf(Tfp,"%s",sndl);
- if( rindex(Filename,'/') == NULL) {
- fprintf(Tfp,"%s\nSubject: Mail deleted by MAILER-DAEMON\n\n",Filename);
- }
- else {
- fprintf(Tfp,"%s\nSubject: Mail deleted by MAILER-DAEMON\n\n",rindex(Filename,'/') + (char *) (1));
- }
- wrote_sndl = SUCCEED;
- }
- fprintf(Tfp," Letter deleted: ");
- writeline();
- }
- if(audit_flag && (onetrip == SUCCEED) ) {
- printf("%s: ",Loginname);
- printf("%8ld bytes: ",filemark-File_length);
- filemark = File_length;
- printhead();
- }
- if (audit_flag) {
- for(copy=0 ; copy < LINE_LEN ; copy++) {
- Headbuf[copy]= Buffer[copy];
- }
- }
- onetrip = SUCCEED;
- }
- }
-
- /* Eat up rest of last message deleted; wait for next letter header */
-
- while(readline() == SUCCEED && is_a_header() == FAILED);
-
- bytes_del = Sbuf.st_size - File_length;
- tot_bytes_del += bytes_del;
-
- /* Write out this new header, but be careful to check that */
- /* it definitely is one. (I.e., one-line loop above may have */
- /* exited due to EOF and not a "From" line. */
-
- /* Also make sure to add a newline at the end of our message */
- /* so as not to confuse any mailers. */
-
- if(rewrite_flag && is_a_header() == SUCCEED ) {
- if(finalsize == 0)
- fprintf(Tfp,"\n Reason: system mailbox older than %d days\n\n",max_age);
- else if (finalsize == MAX_SIZE)
- fprintf(Tfp,"\n Reason: system mailbox older than %d days and larger than %ld bytes\n\n",min_age,MAX_SIZE);
- else if (finalsize == ABS_MAX_SIZE)
- fprintf(Tfp,"\n Reason: system mailbox larger than %ld bytes\n\n",ABS_MAX_SIZE);
- else
- fprintf(Tfp,"\n Reason: unknown\n\n");
- writeline();
- }
- if(audit_flag) {
- printf("%s: ",Loginname);
- printf("%8ld bytes: ",filemark-File_length);
- filemark = File_length;
- printhead();
- for(copy=0 ; copy < LINE_LEN ; copy++) {
- Headbuf[copy]= Buffer[copy];
- }
- }
-
- while(readline() == SUCCEED) {
- if(rewrite_flag)
- writeline();
- }
-
- if(cleanup() == FAILED)
- return(FAILED);
- return(SUCCEED);
- }
- /*==================================================
- *
- * from_system() - returns true if this letter was
- * from a previous invocation of this
- * program; causes mail files to decay
- * to zero length eventually.
- *
- *==================================================
- */
- from_system()
- {
- if( strncmp(&Buffer[5],&sndl[5],strlen(SENDER) ) == 0)
- return(SUCCEED);
- else
- return(FAILED);
- }
-
- /*==================================================
- *
- *
- * del_user() - remove letters that are from user "Selectname"
- * exit - 0 if no problems encountered
- * 1 if couldn't open or other nastiness
- *
- *
- *==================================================
- */
- del_user()
- {
- int file_trunc; /* Set if this file truncated */
-
- long mark_beg; /* marks beginning of current letter */
- long mark_end; /* marks end of current letter */
- int copy; /* Temporary loop index for saving */
- /* mail headers */
- file_trunc = 0; /* Zero out audit counters */
- bytes_del = 0;
-
- if( stat(Filename,&Sbuf) == FAILED) {
- fprintf(stderr,"Can't stat %s\n",Filename);
- return(FAILED);
- }
-
- /* If file is zero length, don't bother with it. */
- if(Sbuf.st_size == 0)
- return(SUCCEED);
-
- if( (Mfp = fopen(Filename,"r+")) == NULL) {
- fprintf(stderr,"Can't open %s\n",Filename);
- return(FAILED);
- }
- if( (Tfp = fopen(Tempfile,"w+")) == NULL) {
- fprintf(stderr,"Can't open tempfile %s\n",Tempfile);
- return(FAILED);
- }
-
- File_length = Sbuf.st_size;
- mark_beg = File_length;
- mark_end = File_length;
- Copy_flag = 1;
-
- /* The idea of mark_beg and mark_end is that mark_end continually */
- /* keeps track of the end of the previous line, and that mark_beg */
- /* keeps track of the end of the last line of the last letter, so */
- /* the distance between reflects the number of bytes deep we are */
- /* into the current letter. When we finish with a letter, we know */
- /* how long it was. */
-
- while(readline() == SUCCEED) {
- if(is_a_header() == SUCCEED) {
- if(audit_flag && !Copy_flag) {
- printf("%s: ", Loginname);
- printf("%8ld bytes: ", mark_beg - mark_end);
- printhead();
- bytes_del += (mark_beg - mark_end);
- mark_beg = mark_end;
- }
- if(audit_flag && Copy_flag)
- mark_beg = mark_end;
- if(is_from_user() == SUCCEED) {
- Copy_flag = 0;
- file_trunc = 1;
- if(audit_flag)
- for(copy = 0; copy < LINE_LEN; copy++)
- Headbuf[copy] = Buffer[copy];
- }
- else
- Copy_flag = 1;
- }
- if(Copy_flag)
- writeline();
- mark_end = File_length;
- }
-
- if( !Copy_flag) { /* Last letter was hit */
- if(audit_flag) {
- printf("%s: ", Loginname);
- printf("%8ld bytes: ", mark_beg - mark_end);
- printhead();
- bytes_del += (mark_beg - mark_end);
- }
- }
-
- if(file_trunc == 1)
- ++files_short;
-
- tot_bytes_del += bytes_del;
-
- if(cleanup() == FAILED)
- return(FAILED);
- return(SUCCEED);
- }
- /*
- *******************************************************************
- * readline() - read a line from input mail file
- * returns 0 if line successfully read
- * -1 if out of characters to read
- *******************************************************************
- */
- readline()
- {
- int how_many_read = 0;
- char *bufptr = Buffer;
- char c;
-
- if(File_length == 0)
- return(FAILED);
- do{
- c = getc(Mfp);
- *bufptr++ = c;
- ++how_many_read;
- }
- while( (c != NEWLINE)
- && (how_many_read < LINE_LEN)
- && (how_many_read < File_length) );
-
- File_length -= how_many_read;
- return(SUCCEED);
- }
- /*
- *******************************************************************
- * writeline() - Write out a line to the temp file.
- * returns 0 ALWAYS
- *******************************************************************
- */
- writeline()
- {
- int i;
- char *bufptr = Buffer;
- char c;
-
- for( i = 0; i < LINE_LEN; i++) {
- c = *bufptr++;
- putc(c,Tfp);
- if(c == NEWLINE)
- return(SUCCEED);
- }
- return(SUCCEED);
- }
- /*
- *******************************************************************
- * printhead() - Write out a line to stdout.
- * returns 0 ALWAYS
- *******************************************************************
- */
- printhead()
- {
- int i;
- char *bufptr = Headbuf;
- char c;
-
- for( i = 0; i < LINE_LEN; i++) {
- c = *bufptr++;
- putchar(c);
- if(c == NEWLINE)
- return(SUCCEED);
- }
- return(SUCCEED);
- }
- /*
- *******************************************************************
- * is_a_header() - Is this line a mail letter header?
- * (i.e. Does it begin with "From "?
- * returns 0 if it is
- * -1 if not
- *******************************************************************
- */
- is_a_header()
- {
- if( Buffer[0] != 'F' )
- return(FAILED);
- if( Buffer[1] == 'r'
- && Buffer[2] == 'o'
- && Buffer[3] == 'm'
- && Buffer[4] == ' ') /* If succeeds, must be header */
- return(SUCCEED);
- else
- return(FAILED);
- }
- /*
- *******************************************************************
- * is_from_user() - Is this file from user "Selectname"?
- * returns 0 if it is
- * -1 if not
- *******************************************************************
- */
- is_from_user()
- {
- int j;
- for(j=0;j<strlen(Selectname);j++)
- if(Buffer[j+5] != Selectname[j])
- return(FAILED);
- return(SUCCEED);
- }
- /*
- *******************************************************************
- * size_date() - Look at modify time and size of this file
- * to determine to what length it should be cut.
- * returns 0 if everything goes ok
- * -1 if time didn't make sense.
- *******************************************************************
- */
- long
- size_date()
- {
- long finalsize;
- long days_elapsed;
- char *filetime;
-
- filetime = ctime(&Sbuf.st_mtime);
-
- days_elapsed = dysince(filetime);
-
- if(days_elapsed > max_age)
- finalsize = 0;
- if(days_elapsed <= max_age && days_elapsed > min_age)
- finalsize = MAX_SIZE;
- if(days_elapsed <= min_age && days_elapsed >= 0l)
- finalsize = ABS_MAX_SIZE;
- if(days_elapsed < 0l)
- return(FAILED_LONG);
- return(finalsize);
- }
- /*
- *******************************************************************
- * cleanup() - Copy results back to original, blast temp file.
- * returns 0 if everything goes ok
- * -1 if closes/(un)links/chown/chmod fail
- *******************************************************************
- */
- cleanup()
- {
- int c; /* Character for copying */
-
- if( !rewrite_flag) { /* If not writing, then stop here */
- if( fclose(Mfp) != SUCCEED) {
- fprintf(stderr,"Couldn't close %s\n",Filename);
- return(FAILED);
- }
- return(SUCCEED);
- }
-
- if( fflush(Mfp) != SUCCEED) {
- fprintf(stderr,"Couldn't fflush %s\n",Filename);
- return(FAILED);
- }
- if( fflush(Tfp) != SUCCEED) {
- fprintf(stderr,"Couldn't fflush tempfile %s\n",Tempfile);
- return(FAILED);
- }
- if( (Mfp=freopen(Filename,"w",Mfp)) == NULL) {
- fprintf(stderr,"Couldn't freopen %s\n",Filename);
- return(FAILED);
- }
- if( rewind(Tfp) != SUCCEED) {
- fprintf(stderr,"Couldn't rewind tempfile %s\n",Tempfile);
- return(FAILED);
- }
-
- while( (c=getc(Tfp)) != EOF)
- putc(c,Mfp);
-
- if( fclose(Mfp) != SUCCEED) {
- fprintf(stderr,"Couldn't close %s\n",Filename);
- return(FAILED);
- }
- if( fclose(Tfp) != SUCCEED) {
- fprintf(stderr,"Couldn't close tempfile %s\n",Tempfile);
- return(FAILED);
- }
- if( unlink(Tempfile) == FAILED) {
- fprintf(stderr,"Couldn't unlink tempfile %s\n",Tempfile);
- return(FAILED);
- }
- return(SUCCEED);
- }
- SHAR_EOF
- # End of shell archive
- exit 0
-
-