Path: utzoo!attcan!uunet!decwrl!ucbvax!THUMPER.BELLCORE.COM!nsb From: nsb@THUMPER.BELLCORE.COM (Nathaniel Borenstein) Newsgroups: comp.soft-sys.andrew Subject: Eatmail sources Message-ID: <0ahgL2_0M2Yt94qmNj@thumper.bellcore.com> Date: 1 Aug 90 12:06:26 GMT References: <22445.649457687@cise.nsf.gov> Sender: daemon@ucbvax.BERKELEY.EDU Organization: The Internet Lines: 376 I've gotten several requests for the "eatmail" program I referenced in a previous post. Since it hasn't yet made it onto a patch, and since it is very short, I thought I'd post it here. You only need two files, Imakefile and eatmail.c -- I put them in a directory called contrib/eatmail. The Imakefile looks like this: LOCALINCLUDES = -I${BASEDIR}/include/ams OBJS = eatmail.o LIBS= \ ${BASEDIR}/lib/libmail.a \ ${BASEDIR}/lib/liberrors.a \ ${UTILLIB} NormalObjectRule() ProgramTarget(eatmail, ${OBJS}, ${LIBS} , ) DependTarget() And eatmail.c looks like this: /* This includes most of the code from ams/libs/ms/cvtold.c, so a better eventual solution would be to modularize it; unfortunately, the biggest differences are things I was able to remove to shrink the size of the eatmail binary, but which are really needed by the message server... */ #include #include #include #include /* sys/types.h sys/file.h sys/time.h */ #include /* #include */ #include #include #include #include #include extern char *malloc(), *index(); extern int errno; extern FILE *fopen(); extern char *getenv(), *getprofile(); char home[1+MAXPATHLEN]; long mserrcode; #undef AMS_RETURN_ERRCODE #define AMS_RETURN_ERRCODE(x,y,z) return(-1); main() { char SpoolFileName[1 + MAXPATHLEN], SourceDir[1+MAXPATHLEN], *SpoolFile; int numfound = 0, errcode; struct passwd *pswd; CheckAMSConfiguration(); pswd = getpwuid(getuid()); if (!pswd) { fprintf(stderr, "Cannot get your password file entry\n"); exit(-1); } strcpy(home, pswd->pw_dir); SpoolFile = getenv("MAIL"); if (SpoolFile == NULL || *SpoolFile == '\0') SpoolFile = getprofile("mailboxfile"); if (SpoolFile == NULL || *SpoolFile == '\0') { sprintf(SpoolFileName, "%s/%s", AMS_MailBoxPrefix, pswd->pw_name); } else { strcpy(SpoolFileName, SpoolFile); } sprintf(SourceDir, "%s/Mailbox", home); if (ConvertIncomingMail(SpoolFileName, SourceDir, &numfound)) { fprintf(stderr, "Error: Could not move mail from %s to %s\n", SpoolFileName, SourceDir); exit(-1); } exit(0); } /* * Remove the mail lock, and note that we no longer * have it locked. */ static int rmlock(name, lockFD) char name[]; int lockFD; { struct stat statb; if (lockFD >= 0) close(lockFD); if (stat(name, &statb) < 0) return(-1); if ((statb.st_mode & S_IFMT) != S_IFREG) { errno = EISDIR; return(-1); } if (unlink(name)) { #if SY_B4x != 0 return(truncate(name, 0)); #else /* SY_B4x */ return 0; #endif /* SY_B4x */ } return(0); } /* * Lock the specified mail file by setting the file mailfile.lock. * We must, of course, be careful to rmlock the lock file by a call * to unlock before we stop. The algorithm used here is to see if * the lock exists, and if it does, return an error. * * Attempt to set the lock by creating the temporary file, * then doing a link/unlink. If it fails, return -1 else 0 */ static int lock(file, lockedFile, lockedFDp) char *file, *lockedFile; int *lockedFDp; { register int f, g; char locktmp[1+MAXPATHLEN]; /* Usable lock temporary */ char *s; s = rindex(file, '/'); if (*s != '/') return -1; strcpy(lockedFile, SpoolMailLockDir); strcat(lockedFile, s); strcat(lockedFile, ".lock"); g = open(lockedFile, osi_O_READLOCK, 0); if (g < 0) return -1; if (osi_ExclusiveLockNoBlock(g) != 0) { close(g); return -1; } strcpy(locktmp, SpoolMailLockTemp); mktemp(locktmp); rmlock(locktmp, -1); f = creat(locktmp, 0); if (f < 0) { close(g); return(-1); } close(f); if (link(locktmp, lockedFile) < 0) { rmlock(locktmp, g); return(-1); } rmlock(locktmp, -1); *lockedFDp = g; return(0); } static int SetHoldFromFile(fname, holdP) char *fname; int *holdP; {/* Set or unset ``hold'' as in the file ``fname''. */ FILE *fp; char InBuf[300]; char *sp, *scmd; int DoSet, errsave; errno = 0; fp = fopen(fname, "r"); if (fp == NULL) { if (errno == ENOENT) return 0; if (errno == 0) errno = ENOMEM; AMS_RETURN_ERRCODE(errno, EIN_FOPEN, EVIA_CONVERTINCOMING); } for (;;) { NextLine: sp = fgets(InBuf, sizeof(InBuf), fp); if (sp == NULL) break; while (*sp != '\0' && isspace(*sp)) ++sp; scmd = sp; while (*sp != '\0' && !isspace(*sp)) ++sp; *sp++ = '\0'; if (strcmp(scmd, "set") == 0) DoSet = 1; else if (strcmp(scmd, "unset") == 0) DoSet = 0; else continue; for (;;) { while (*sp != '\0' && isspace(*sp)) ++sp; if (*sp == '\0') goto NextLine; scmd = sp; while (*sp != '\0' && !isspace(*sp)) ++sp; *sp++ = '\0'; if (strcmp(scmd, "hold") == 0) *holdP = DoSet; } } if (ferror(fp)) { errsave = errno; (void) fclose(fp); if (errsave == 0) errsave = ENOMEM; AMS_RETURN_ERRCODE(errno, EIN_READ, EVIA_CONVERTINCOMING); } (void) fclose(fp); } static int CheckMailrcHold() {/* Check whether the ~/.mailrc or /usr/lib/Mail.rc file has set the ``hold'' variable; return 0 if it isn't set, or an mserrcode. */ static int HoldVal = -1; int RC, TempVal; char MyMailrc[1+MAXPATHLEN]; if (HoldVal >= 0) return HoldVal; TempVal = 0; RC = SetHoldFromFile("/usr/lib/Mail.rc", &TempVal); if (RC != 0) return RC; sprintf(MyMailrc, "%s/.mailrc", home); RC = SetHoldFromFile(MyMailrc, &TempVal); if (RC != 0) return RC; HoldVal = TempVal; /* Got it all right. */ if (HoldVal != 0) { AMS_RETURN_ERRCODE(EMSHOLDSET, EIN_PARAMCHECK, EVIA_CONVERTINCOMING); } return 0; } #define FALSE 0 #define TRUE 1 #define buffsize 1024 #define MAXTRIES 25 int ConvertIncomingMail(MailSpoolFile, MailDir, FilesReadIn) char *MailSpoolFile, *MailDir; int *FilesReadIn; { FILE *fp; int wfd = 0, i, errsave, tfd, AnyWrittenToThisOne, LockFD; short FileOpen, ReadyToStartAgain; struct stat statbuf; char buffer[buffsize], FName[1+MAXPATHLEN], CurLock[1+MAXPATHLEN]; *FilesReadIn = 0; if ((stat(MailDir, &statbuf)) == -1){ if (errno == ENOENT) { return(0); } AMS_RETURN_ERRCODE(errno, EIN_STAT, EVIA_CONVERTINCOMING); } if ((stat(MailSpoolFile, &statbuf)) == -1){ if (errno == ENOENT) { return(0); } AMS_RETURN_ERRCODE(errno, EIN_STAT, EVIA_CONVERTINCOMING); } if (statbuf.st_size <= 0){ return(0); } errsave = CheckMailrcHold(); if (errsave != 0) return(errsave); if (AMS_StrictStandaloneLocking && (lock(MailSpoolFile, CurLock, &LockFD)) != 0){ AMS_RETURN_ERRCODE(errno, EIN_UCBMAILLOCK, EVIA_CONVERTINCOMING); } if ((fp = fopen(MailSpoolFile, "r")) == NULL){ if (AMS_StrictStandaloneLocking) rmlock(CurLock, LockFD); AMS_RETURN_ERRCODE(errno, EIN_OPEN, EVIA_CONVERTINCOMING); } FileOpen = FALSE; ReadyToStartAgain = 0; AnyWrittenToThisOne = 0; while (TRUE) { if (fgets(buffer, buffsize, fp) == NULL) { errsave = errno; if (feof(fp)) break; /* Done reading */ fclose(fp); if (AMS_StrictStandaloneLocking) rmlock(CurLock, LockFD); AMS_RETURN_ERRCODE(errsave, EIN_READ, EVIA_CONVERTINCOMING); } if (ReadyToStartAgain && FileOpen && (AMS_DemandSeparatingCharacter || IsNewFrom(buffer)) && AnyWrittenToThisOne) { (*FilesReadIn)++; if (vclose(wfd)) { fclose(fp); if (AMS_StrictStandaloneLocking) rmlock(CurLock, LockFD); AMS_RETURN_ERRCODE(errno, EIN_VCLOSE, EVIA_CONVERTINCOMING); } FileOpen = FALSE; } if (!FileOpen){ for (i=0; i