a34b05d2e6
This opens an OpenBSD-mirabile (aka MirBSD) repository. ### MirBSD is: # Copyright (c) 1982-2003 by Thorsten "mirabile" Glaser <x86@ePost.de> # Copyright © 1968-2003 The authors of And contributors to UNIX®, the # C Language, BSD/Berkeley Unix; 386BSD, NetBSD 1.1 and OpenBSD. # # Anyone who obtained a copy of this work is hereby permitted to freely use, # distribute, modify, merge, sublicence, give away or sell it as long as the # authors are given due credit and the following notice is retained: # # This work is provided "as is", with no explicit or implicit warranty what- # soever. Use it only at your own risk. In no event may an author or contri- # butor be held liable for any damage, directly or indirectly, that origina- # ted through or is caused by creation or modification of this work. MirBSD is my private tree. MirBSD does not differ very much from OpenBSD and intentionally tracks OpenBSD. That's why it _is_ OpenBSD, just not the official one. It's like with DarrenBSD. At time of this writing, no advertising for MirBSD must be done, because the advertising clause has not yet been sorted out. http://templeofhate.com/tglaser/MirBSD/index.php
206 lines
4.3 KiB
C
206 lines
4.3 KiB
C
/* $OpenBSD: mail.c,v 1.9 1999/06/15 01:18:35 millert Exp $ */
|
|
|
|
/*
|
|
* Mailbox checking code by Robert J. Gibson, adapted for PD ksh by
|
|
* John R. MacMillan
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#ifdef KSH
|
|
#include "sh.h"
|
|
#include "ksh_stat.h"
|
|
#include "ksh_time.h"
|
|
|
|
#define MBMESSAGE "you have mail in $_"
|
|
|
|
typedef struct mbox {
|
|
struct mbox *mb_next; /* next mbox in list */
|
|
char *mb_path; /* path to mail file */
|
|
char *mb_msg; /* to announce arrival of new mail */
|
|
time_t mb_mtime; /* mtime of mail file */
|
|
} mbox_t;
|
|
|
|
/*
|
|
* $MAILPATH is a linked list of mboxes. $MAIL is a treated as a
|
|
* special case of $MAILPATH, where the list has only one node. The
|
|
* same list is used for both since they are exclusive.
|
|
*/
|
|
|
|
static mbox_t *mplist;
|
|
static mbox_t mbox;
|
|
static time_t mlastchkd; /* when mail was last checked */
|
|
static time_t mailcheck_interval;
|
|
|
|
static void munset ARGS((mbox_t *mlist)); /* free mlist and mval */
|
|
static mbox_t * mballoc ARGS((char *p, char *m)); /* allocate a new mbox */
|
|
static void mprintit ARGS((mbox_t *mbp));
|
|
|
|
void
|
|
mcheck()
|
|
{
|
|
register mbox_t *mbp;
|
|
time_t now;
|
|
struct tbl *vp;
|
|
struct stat stbuf;
|
|
|
|
now = time((time_t *) 0);
|
|
if (mlastchkd == 0)
|
|
mlastchkd = now;
|
|
if (now - mlastchkd >= mailcheck_interval) {
|
|
mlastchkd = now;
|
|
|
|
if (mplist)
|
|
mbp = mplist;
|
|
else if ((vp = global("MAIL")) && (vp->flag & ISSET))
|
|
mbp = &mbox;
|
|
else
|
|
mbp = NULL;
|
|
|
|
while (mbp) {
|
|
if (mbp->mb_path && stat(mbp->mb_path, &stbuf) == 0
|
|
&& S_ISREG(stbuf.st_mode))
|
|
{
|
|
if (stbuf.st_size
|
|
&& mbp->mb_mtime != stbuf.st_mtime
|
|
&& stbuf.st_atime <= stbuf.st_mtime)
|
|
mprintit(mbp);
|
|
mbp->mb_mtime = stbuf.st_mtime;
|
|
} else {
|
|
/*
|
|
* Some mail readers remove the mail
|
|
* file if all mail is read. If file
|
|
* does not exist, assume this is the
|
|
* case and set mtime to zero.
|
|
*/
|
|
mbp->mb_mtime = 0;
|
|
}
|
|
mbp = mbp->mb_next;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
mcset(interval)
|
|
long interval;
|
|
{
|
|
mailcheck_interval = interval;
|
|
}
|
|
|
|
void
|
|
mbset(p)
|
|
register char *p;
|
|
{
|
|
struct stat stbuf;
|
|
|
|
if (mbox.mb_msg)
|
|
afree((void *)mbox.mb_msg, APERM);
|
|
if (mbox.mb_path)
|
|
afree((void *)mbox.mb_path, APERM);
|
|
/* Save a copy to protect from export (which munges the string) */
|
|
mbox.mb_path = str_save(p, APERM);
|
|
mbox.mb_msg = NULL;
|
|
if (p && stat(p, &stbuf) == 0 && S_ISREG(stbuf.st_mode))
|
|
mbox.mb_mtime = stbuf.st_mtime;
|
|
else
|
|
mbox.mb_mtime = 0;
|
|
}
|
|
|
|
void
|
|
mpset(mptoparse)
|
|
register char *mptoparse;
|
|
{
|
|
register mbox_t *mbp;
|
|
register char *mpath, *mmsg, *mval;
|
|
char *p;
|
|
|
|
munset( mplist );
|
|
mplist = NULL;
|
|
mval = str_save(mptoparse, APERM);
|
|
while (mval) {
|
|
mpath = mval;
|
|
if ((mval = strchr(mval, PATHSEP)) != NULL) {
|
|
*mval = '\0', mval++;
|
|
}
|
|
/* POSIX/bourne-shell say file%message */
|
|
for (p = mpath; (mmsg = strchr(p, '%')); ) {
|
|
/* a literal percent? (POSIXism) */
|
|
if (mmsg[-1] == '\\') {
|
|
/* use memmove() to avoid overlap problems */
|
|
memmove(mmsg - 1, mmsg, strlen(mmsg) + 1);
|
|
p = mmsg + 1;
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
/* at&t ksh says file?message */
|
|
if (!mmsg && !Flag(FPOSIX))
|
|
mmsg = strchr(mpath, '?');
|
|
if (mmsg) {
|
|
*mmsg = '\0';
|
|
mmsg++;
|
|
}
|
|
mbp = mballoc(mpath, mmsg);
|
|
mbp->mb_next = mplist;
|
|
mplist = mbp;
|
|
}
|
|
}
|
|
|
|
static void
|
|
munset(mlist)
|
|
register mbox_t *mlist;
|
|
{
|
|
register mbox_t *mbp;
|
|
|
|
while (mlist != NULL) {
|
|
mbp = mlist;
|
|
mlist = mbp->mb_next;
|
|
if (!mlist)
|
|
afree((void *)mbp->mb_path, APERM);
|
|
afree((void *)mbp, APERM);
|
|
}
|
|
}
|
|
|
|
static mbox_t *
|
|
mballoc(p, m)
|
|
char *p;
|
|
char *m;
|
|
{
|
|
struct stat stbuf;
|
|
register mbox_t *mbp;
|
|
|
|
mbp = (mbox_t *)alloc(sizeof(mbox_t), APERM);
|
|
mbp->mb_next = NULL;
|
|
mbp->mb_path = p;
|
|
mbp->mb_msg = m;
|
|
if (stat(mbp->mb_path, &stbuf) == 0 && S_ISREG(stbuf.st_mode))
|
|
mbp->mb_mtime = stbuf.st_mtime;
|
|
else
|
|
mbp->mb_mtime = 0;
|
|
return(mbp);
|
|
}
|
|
|
|
static void
|
|
mprintit( mbp )
|
|
mbox_t *mbp;
|
|
{
|
|
struct tbl *vp;
|
|
|
|
#if 0
|
|
/*
|
|
* I doubt this $_ overloading is bad in /bin/sh mode. Anyhow, we
|
|
* crash as the code looks now if we do not set vp. Now, this is
|
|
* easy to fix too, but I'd like to see what POSIX says before doing
|
|
* a change like that.
|
|
*/
|
|
if (!Flag(FSH))
|
|
#endif
|
|
/* Ignore setstr errors here (arbitrary) */
|
|
setstr((vp = local("_", FALSE)), mbp->mb_path, KSH_RETURN_ERROR);
|
|
|
|
shellf("%s\n", substitute(mbp->mb_msg ? mbp->mb_msg : MBMESSAGE, 0));
|
|
|
|
unset(vp, 0);
|
|
}
|
|
#endif /* KSH */
|