home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-387-Vol-3of3.iso
/
b
/
bmh02src.zip
/
RMM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-16
|
6KB
|
212 lines
/*
rmm.c : Copyright Paul Healy, EI9GL, 1992.
911227 : Added this header
920708 : Version 0.1
920711 : Profiled and optimised a bit.
The program spends at least 60% of its time scanning for the
next message. About the only thing that could be done is to
block copy the rest of the file after the last message to be
deleted is found - this is a special case optimisiation which
will not be any good when a message is to be deleted at or towards
the end of the mail file.
920808 : Changed selection for new current message after a message(s) is
deleted.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
#include <io.h>
#include <alloc.h>
#include "buffer.h"
#include "rc.h"
#include "lock.h"
#include "misc.h"
#include "help.h"
#include "current.h"
#include "name.h"
#ifdef BMH
#define main rmm_main
#endif
#define check(condition, msg, file) if (condition) { \
fprintf(stderr, msg, file); \
unlink(new); \
if (locked) bm_unlock(lock); \
return -1; \
}
static int
update(char *lock, char *new, long size)
{
struct stat statbuf;
char txt[256], old[256];
int locked = 0;
sprintf(old, "%s.old", lock);
sprintf(txt, "%s%s", lock, EXT);
check(bm_lock(lock) != 0, "rmm: can't lock %s\n", txt);
locked = 1;
check(stat(txt, &statbuf) == -1, "rmm: can't stat %s\n", txt);
check(statbuf.st_size != size, "rmm: %s has been changed\n", txt);
check((access(old, 0)==0) && (unlink(old) == -1), "rmm: can't unlink %s\n", old);
check(rename(txt, old) == -1, "rmm: can't rename %s to make backup\n", txt);
check(rename(new, txt) == -1, "rmm: can't rename %s to make new mailfile\n", new);
check(bm_unlock(lock) != 0, "rmm: can't unlock %s\n", txt);
return unlink(new);
}
#undef check
#ifdef notdef
while ( (p<end) && (*p!='F') )
if (putc(*p++, fp) == EOF) {
fprintf(stderr, "rmm: can't to write temporary file\n");
fclose(fp);
return -1;
}
#endif
static int
delmsgs(char *p, char *end, int argc, char *argv[], char *folder, int default_msg)
{
char s[2048], new[256], basename[256], *result, *start;
int msg = 0, num;
FILE *fp;
long fsize = filesize();
sprintf(basename, "%s/%s", getrc(maildir), folder);
sprintf(new, "%s.new", basename);
if ((fp=fopen(new, "wb")) == NULL) {
fprintf(stderr, "rmm: can't open %s\n", new);
return -1;
}
if (setvbuf(fp, NULL, _IOFBF, 4096) != 0) {
fprintf(stderr,"rmm: warning can't buffer %s\n(tried 4096, coreleft=%u)\n", new, coreleft());
if (setvbuf(fp, NULL, _IOFBF, 1024) != 0)
fprintf(stderr,"rmm: warning can't buffer %s\n(tried 1024, coreleft=%u)\n", new, coreleft());
}
while (1) {
start = p;
{
register char *rp = p;
/*
* 60 to 70% of this programs life is spent executing the
* next 2 lines of code according to the profiler.
*/
while ( *rp != 'F' )
rp++;
p = rp;
}
if (p != start) {
num = p - start;
if (fwrite(start, sizeof(char), num, fp) != num) {
fprintf(stderr, "rmm: can't to write temporary file\n");
fclose(fp);
unlink(new);
return -1;
}
}
if ( (p==end) && (refill(&p, &end) != 0) )
break;
else { /* may have found a From */
if (*(p-1) != '\n') {
if (putc(*p++, fp) != EOF)
continue; /* at while 1 */
fprintf(stderr, "rmm: can't write temporary file\n");
fclose(fp);
return -1;
}
result = getstring(&p, &end, s, sizeof(s));
if (strncmp(s, "From ", 5) == 0) {
msg++;
/*
printf("rmm: considering %s\n", s);
*/
while ((result != NULL ) &&
(wanted(msg, argc, argv, default_msg) == 1) )
while ((result=getstring(&p, &end, s, sizeof(s))) != NULL)
if (strncmp(s, "From ", 5) == 0) {
msg++;
break;
}
if (result != NULL) {
fputs(s, fp); /* unwanted From line */
fputs("\r\n", fp);
}
}
else {
fputs(s, fp); /* string with 'F' in it */
fputs("\r\n", fp);
}
}
} /* while 1 */
fclose(fp);
return update(basename, new, fsize);
}
/*
* remove a zero length file
*/
static void
checkempty(char *folder)
{
/*
printf("%s\n%s\n%s\n%s\n", getnm(BaseName), getnm(TxtName), getnm(NewName), getnm(OldName));
*/
if (bm_lock(getnm(BaseName)) == 0) {
struct stat statbuf;
if ( (stat(getnm(TxtName), &statbuf) == 0) && (statbuf.st_size == 0))
(void) unlink(getnm(TxtName));
if (bm_unlock(getnm(BaseName)) != 0)
fprintf(stderr, "rmm: warning %s may have been left locked\n", getnm(TxtName));
}
}
int
main(int argc, char *argv[])
{
char *p, *end, *s;
int msg;
dohelp(argc, argv, "rmm [+folder] <msg 1> ... <msg n>");
if (loadconfig()==-1) /* don't use setupbm, as we don't need */
return -1; /* to buffer stdout */
if (getcurrent(argc, argv, &s, &msg) == -1)
return -1;
if (loadmail("rmm", s, &p, &end) == -1)
return -1;
delmsgs(p, end, argc, argv, s, msg);
checkempty(s);
/*
* The previous message to the first deleted message becomes the
* new current message
*/
msg--;
currentmsg(&msg);
return 0;
}