home *** CD-ROM | disk | FTP | other *** search
- /* -*-C-*-
- *******************************************************************************
- *
- * File: compactmail.m
- * RCS: /usr/local/sources/CVS/mailapp-utilities/compactmail.m,v 1.4 1997/04/19 17:37:19 tom Exp
- * Description: Compact Mail.app mailboxes (expunge deleted messages)
- * Author: Carl Edman
- * Created: Fri Mar 12 18:21:23 1993
- * Modified: Sat Nov 30 23:28:56 1996 Tom Hageman <tom@basil.icce.rug.nl>
- * Language: Objective C
- * Package: mailapp-utilities
- * Status: First release.
- *
- * (C) Copyright 1993, but otherwise this file is perfect freeware.
- *
- *******************************************************************************
- */
-
- #import <libc.h>
- #import <errno.h>
- //#import <stdlib.h>
- //#import <stdio.h>
- //#import <string.h>
- //#import <time.h>
- #import <regex.h>
- //#import <sys/file.h>
- //#import <sys/param.h>
- //#import <sys/types.h>
- //#import <sys/stat.h>
- #import <defaults/defaults.h>
- #import "mailutil.h"
- #import "mailtoc.h"
- #import "optutil.h"
-
- #define USAGE "\
- Usage: %s [-nruv] [-d days] [-f from] [-s subject] [-V|-H] mbox...\n"
-
- #define HELP "\
- -n skip mailbox if locked\n\
- -r expunge read messages too (default deleted messages only)\n\
- -u expunge all messages (even unread)\n\
- -v talkative mode\n\
- -d days restrict to messages of at least `days' days old.\n\
- -f from restrict to messages whose From: header matches (regexp)\n\
- -s subject restrict to messages whose Subject: header matches (regexp)\n\
- -V show version\n\
- -H this help\n\
- "
-
- char line[LINELEN];
-
- int main(int ac,char *av[])
- {
- char *buf=0;
- int c,pos;
- int nowaitflg=0,verboseflg=0,deletereadflg=0,deleteunreadflg=0;
- int days=-1;
- struct regex *subjectregexp=0,*fromregexp=0;
- time_t mboxtime;
- int mboxdis,tocdis,msgdis,changed;
- int mboxfd=-1;
- FILE *tocf=NULL;
- struct table_of_contents_header *toch=0;
- struct message_index *mi=0;
- int status=EXIT_SUCCESS;
-
- set_progname(av[0]);
-
- while((c=getopt(ac,av,"d:s:f:nruvVH"))!=EOF) switch(c)
- {
- case 'd':
- if (days!=-1 || (days=atoi(optarg))<=0)
- status=EXIT_USAGE;
- break;
- case 's':
- if (subjectregexp || !(subjectregexp=re_compile(optarg,0)))
- status=EXIT_USAGE;
- break;
- case 'f':
- if (fromregexp || !(fromregexp=re_compile(optarg,0)))
- status=EXIT_USAGE;
- break;
- case 'n':
- nowaitflg++;
- break;
- case 'r':
- deletereadflg++;
- break;
- case 'u':
- deleteunreadflg++;
- break;
- case 'v':
- verboseflg++;
- break;
- case 'V':
- status=EXIT_VERSION;
- break;
- case 'H':
- status=EXIT_HELP;
- break;
- case '?':
- default:
- status=EXIT_USAGE;
- }
- if (status==EXIT_SUCCESS && optind>=ac) status=EXIT_USAGE;
- handle_usage_help_version(status, USAGE, HELP);
-
- for(;optind<ac;optind++)
- {
- if (verboseflg) fprintf(stderr,"Entering %s...\n",av[optind]);
- if (cd_mbox(av[optind],1)) goto next;
- if (lock_mbox(nowaitflg)) goto next;
-
- mboxtime=mtime("mbox");
-
- if (((mboxfd=open("mbox",O_RDWR))==-1) ||
- ((tocf=fopen("table_of_contents","r+b"))==NULL))
- {
- fprintf(stderr,"%s: opening %s: %s\n",progname(),av[optind],strerror(errno));
- status=EXIT_FAILURE;
- goto unlock;
- }
-
- toch=get_table_of_contents_header(tocf,0);
- if (!toch)
- {
- fprintf(stderr,"%s: %s: invalid old table_of_contents\n",progname(),av[optind]);
- status=EXIT_FAILURE;
- goto unlock;
- }
-
- if (toch->mbox_time!=mboxtime)
- {
- fprintf(stderr,"%s: %s: table of contents out of sync\n",progname(),av[optind]);
- status=EXIT_FAILURE;
- goto unlock;
- }
-
- for(changed=FALSE,msgdis=mboxdis=tocdis=c=0;c<toch->num_msgs;c++)
- {
- if ((mi=get_message_index(tocf))==0)
- {
- fprintf(stderr,"%s: %s: reading old mbox entries: %s\n",progname(),av[optind],(errno?strerror(errno):"invalid"));
- status=EXIT_FAILURE;
- goto unlock;
- }
- if ((mi->status=='d' || mi->status=='D' || deleteunreadflg ||
- (mi->status!='*' && deletereadflg)) &&
- (days==-1 || message_age(mi)>=days) &&
- (!subjectregexp || re_match(message_subject(mi),subjectregexp)) &&
- (!fromregexp || re_match(message_from(mi),fromregexp)))
- {
- if (verboseflg>1)
- {
- fprintf(stderr,"Expunging \"%s\" from %s (%d days old).\n",message_subject(mi),message_from(mi),message_age(mi));
- }
- if (mi->msgtype=='r')
- {
- char *dir=mi->data;
- dir+=strlen(dir)+1;
- dir+=strlen(dir)+1;
- if (*dir)
- {
- int pid,childpid=fork();
- union wait status;
-
- switch (childpid)
- {
- case -1:
- break;
- case 0:
- execl("/bin/rm", "rm", "-rf", dir, NULL);
- _exit(255);
- default:
- while ((pid=wait(&status))>=0 && pid!=childpid) ;
- }
- }
- }
- changed=TRUE;
- msgdis++;
- tocdis +=mi->record_length;
- mboxdis+=mi->mes_length;
- }
- else
- {
- if (verboseflg>2)
- {
- fprintf(stderr,"Keeping \"%s\" from %s (%d days old).\n",message_subject(mi),message_from(mi),message_age(mi));
- }
- if (mboxdis!=0)
- {
- lseek(mboxfd,mi->mes_offset,L_SET);
- buf=malloc(mi->mes_length);
- read(mboxfd,buf,mi->mes_length);
- mi->mes_offset -= mboxdis;
- lseek(mboxfd,mi->mes_offset,L_SET);
- write(mboxfd,buf,mi->mes_length);
- free(buf); buf=0;
- }
-
- if (tocdis!=0 || mboxdis!=0)
- {
- pos=ftell(tocf);
- fseek(tocf,-mi->record_length-tocdis,SEEK_CUR);
- put_message_index(tocf,mi);
- fseek(tocf,pos,SEEK_SET);
- }
- }
- free(mi); mi=0;
- }
-
- if (tocdis!=0)
- {
- fflush(tocf);
- pos=fseek(tocf,0,SEEK_END);
- ftruncate(fileno(tocf),pos-tocdis);
- }
-
- if (mboxdis!=0)
- {
- pos=lseek(mboxfd,0,L_XTND);
- ftruncate(mboxfd,pos-mboxdis);
- }
- close(mboxfd), mboxfd=-1;
-
- toch->num_msgs-=msgdis;
- mboxtime=mtime("mbox");
- if ((toch->mbox_time!=mboxtime) || changed)
- {
- toch->mbox_time=mboxtime;
- fseek(tocf,0,SEEK_SET);
- if (put_table_of_contents_header(tocf,toch))
- {
- fprintf(stderr,"%s: %s: writing updated table_of_contents: %s\n",progname(),av[optind],strerror(errno));
- status=EXIT_FAILURE;
- goto unlock;
- }
- }
- unlock:
- if(mboxfd>=0) close(mboxfd), mboxfd=-1;
- if(tocf!=NULL) fclose(tocf), tocf=NULL;
- unlock_mbox();
- next:;
- if (toch) { free(toch); toch=0; }
- if (mi) { free(mi); mi=0; }
- if (buf) { free(buf); buf=0; }
- uncd_mbox();
- }
- exit(status);
- }
-