summaryrefslogtreecommitdiff
path: root/mail.c
diff options
context:
space:
mode:
Diffstat (limited to 'mail.c')
-rw-r--r--mail.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/mail.c b/mail.c
new file mode 100644
index 0000000..3404ed5
--- /dev/null
+++ b/mail.c
@@ -0,0 +1,203 @@
+/* $NetBSD: mail.c,v 1.9 2018/05/08 16:37:59 kamil Exp $ */
+
+/*
+ * Mailbox checking code by Robert J. Gibson, adapted for PD ksh by
+ * John R. MacMillan
+ */
+#include <sys/cdefs.h>
+
+#ifndef lint
+__RCSID("$NetBSD: mail.c,v 1.9 2018/05/08 16:37:59 kamil Exp $");
+#endif
+
+#include "config.h"
+
+#ifdef KSH
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "sh.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()
+{
+ 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)
+ 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)
+ char *mptoparse;
+{
+ mbox_t *mbp;
+ 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)
+mbox_t *mlist;
+{
+ 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;
+ 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;
+
+ /* 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 */