summaryrefslogtreecommitdiff
path: root/clients/zmailnotify
diff options
context:
space:
mode:
authorGravatar C. Anthony DellaFera <tony@mit.edu>1987-07-21 10:43:39 +0000
committerGravatar C. Anthony DellaFera <tony@mit.edu>1987-07-21 10:43:39 +0000
commit64ba6ef391d3d3101f66b665e2330ce5f192c0fd (patch)
tree2173d3e0a9ae929b15400f178d73b499b8420c2d /clients/zmailnotify
parent65bbfd7353c9c22ef57d73029f886f7632e20c0e (diff)
Initial revision
Diffstat (limited to 'clients/zmailnotify')
-rw-r--r--clients/zmailnotify/zmailwatch.c690
-rw-r--r--clients/zmailnotify/zmwnotify.c301
2 files changed, 991 insertions, 0 deletions
diff --git a/clients/zmailnotify/zmailwatch.c b/clients/zmailnotify/zmailwatch.c
new file mode 100644
index 0000000..dfb629e
--- /dev/null
+++ b/clients/zmailnotify/zmailwatch.c
@@ -0,0 +1,690 @@
+/*
+ * $Source$
+ * $Header$
+ */
+
+#ifndef lint
+static char *rcsid_mailwatch_c = "$Header$";
+#endif lint
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+
+#define NOTOK (-1)
+#define OK 0
+#define DONE 1
+
+int Pfd;
+FILE *sfi;
+FILE *sfo;
+char Errmsg[128];
+FILE *logf;
+
+static int debug = 0;
+static int Shutdown = 0;
+
+struct mailsav {
+ struct iovec m_iov[3];
+ int m_iovcnt;
+ int m_seen;
+} *Mailsav[64];
+
+int MailIndex;
+int MailSize;
+
+main()
+{
+ char *host;
+ char *user;
+ char *display;
+ register int xs;
+ register int xsmask;
+ int readfds;
+ struct timeval timeout;
+ register int curtime;
+ register int i;
+ char *getenv();
+ int cleanup();
+
+ user = getenv("USER");
+ host = getenv("MAILHOST");
+ display = getenv("DISPLAY");
+ if (user == NULL)
+ fatal("no USER defined");
+ if (host == NULL)
+ fatal("no MAILHOST defined");
+ if (display == NULL)
+ fatal("no DISPLAY defined");
+
+ if (!debug) background();
+
+ logf = fopen("/usr/adm/mailwatch.log", "a");
+ setlinebuf(logf);
+ log("startup");
+ xs = XNotifyInit(display);
+ xsmask = (1 << xs);
+ timeout.tv_usec = 0;
+
+ signal(SIGHUP, cleanup);
+ signal(SIGTERM, cleanup);
+
+ check_mail(host, user);
+ XDisplayNewWindows();
+ i = 59 - (time(0) % 60);
+ timeout.tv_sec = i;
+ while (1)
+ {
+ readfds = xsmask;
+ if (select(xs+1, &readfds, 0, 0, &timeout) > 0)
+ {
+ if (readfds & xsmask)
+ {
+ XProcessEvent();
+ display_unseen();
+ XDisplayNewWindows();
+ }
+ }
+ else
+ {
+ check_mail(host, user);
+ XDisplayNewWindows();
+ }
+ if (Shutdown)
+ {
+ log("shutdown");
+ fclose(logf);
+ XNotifyClose();
+ exit(0);
+ }
+ i = 60 - (time(0) % 60);
+ timeout.tv_sec = i;
+ }
+}
+
+background()
+{
+ register int i;
+
+ if (fork()) exit(0);
+ for (i = 0; i < 10; i++) close(i);
+ open("/", 0);
+ dup2(0, 1);
+ dup2(0, 2);
+ i = open("/dev/tty", 2);
+ if (i >= 0)
+ {
+ ioctl(i, TIOCNOTTY, 0);
+ close(i);
+ }
+}
+
+check_mail(host, user)
+ char *host;
+ char *user;
+{
+ static int LastNmsgs = -1;
+ static int LastNbytes = -1;
+ int nmsgs;
+ int nbytes;
+ static char tempname[40];
+ static FILE *mbf = NULL;
+ register int mbfi;
+ register int i;
+ register int next_msg;
+ struct mailsav *ms;
+ struct mailsav *build_mailsav();
+
+ if (pop_init(host) == NOTOK)
+ {
+ log("pop_init: %s", Errmsg);
+ error(Errmsg);
+ return(1);
+ }
+
+ if (pop_command("USER %s", user) == NOTOK ||
+ pop_command("RPOP %s", user) == NOTOK)
+ {
+ error(Errmsg);
+ log("USER|RPOP: %s", Errmsg);
+ pop_command("QUIT");
+ pop_close();
+ return(1);
+ }
+
+ if (pop_stat(&nmsgs, &nbytes) == NOTOK)
+ {
+ error(Errmsg);
+ log("pop_stat: %s", Errmsg);
+ pop_command("QUIT");
+ pop_close();
+ return(1);
+ }
+
+ if (nmsgs == 0)
+ {
+ pop_command("QUIT");
+ pop_close();
+ return(0);
+ }
+
+ if (mbf == NULL)
+ {
+ strcpy(tempname, "/tmp/pmXXXXXX");
+ mbfi = mkstemp(tempname);
+ if (mbfi < 0)
+ {
+ log("mkstemp");
+ pop_command("QUIT");
+ pop_close();
+ return(1);
+ }
+ mbf = fdopen(mbfi, "w+");
+ }
+
+ next_msg = 1;
+ if (nmsgs == LastNmsgs && nbytes == LastNbytes)
+ {
+ if (get_message(1, mbf) != 0) return(1);
+ ms = build_mailsav(mbf);
+ if (mail_compare(ms, Mailsav[0]) == 0)
+ {
+ pop_command("QUIT");
+ pop_close();
+ return(0);
+ }
+ else
+ {
+ display_mail_header(ms, 0);
+ rewind(mbf);
+ next_msg = 2;
+ }
+ }
+
+ for (i = next_msg; i <= nmsgs; i++)
+ {
+ if (get_message(i, mbf) != 0) return(1);
+ ms = build_mailsav(mbf);
+ display_mail_header(ms, i-1);
+ rewind(mbf);
+ }
+
+ LastNmsgs = nmsgs;
+ LastNbytes = nbytes;
+
+ pop_command("QUIT");
+ pop_close();
+ if (Shutdown)
+ {
+ fclose(mbf);
+ unlink(tempname);
+ }
+
+ return(0);
+}
+
+cleanup()
+{
+ Shutdown = 1;
+}
+
+get_message(i, mbf)
+ int i;
+ FILE *mbf;
+{
+ int mbx_write();
+
+ if (pop_retr(i, mbx_write, mbf) != OK)
+ {
+ error(Errmsg);
+ log("pop_retr: %s", Errmsg);
+ pop_command("QUIT");
+ pop_close();
+ return(1);
+ }
+ ftruncate(fileno(mbf), ftell(mbf));
+ return(0);
+}
+
+free_all_mailsav()
+{
+ register struct mailsav **msp;
+ register struct mailsav *ms;
+ register struct iovec *iov;
+ register int iovcnt;
+
+ for (msp = Mailsav; ms = *msp; msp++) {
+ iov = ms->m_iov;
+ iovcnt = ms->m_iovcnt;
+ while (--iovcnt >= 0) {
+ free(iov->iov_base);
+ iov++;
+ }
+ free(ms);
+ *msp = NULL;
+ }
+}
+
+free_mailsav(ms)
+register struct mailsav *ms;
+{
+ register struct iovec *iov;
+ register int iovcnt;
+
+ iov = ms->m_iov;
+ iovcnt = ms->m_iovcnt;
+ while (--iovcnt >= 0) {
+ free(iov->iov_base);
+ iov++;
+ }
+ free(ms);
+}
+
+pop_init(host)
+char *host;
+{
+ static struct hostent *hp = NULL;
+ static struct servent *sp = NULL;
+ static struct sockaddr_in sin;
+ static int initialized = 0;
+ int lport = IPPORT_RESERVED - 1;
+ char response[128];
+ char *get_errmsg();
+
+ if (!initialized) {
+
+ hp = gethostbyname(host);
+ if (hp == NULL) {
+ sprintf(Errmsg, "MAILHOST unknown: %s", host);
+ return(NOTOK);
+ }
+
+ sp = getservbyname("pop", "tcp");
+ if (sp == 0) {
+ strcpy(Errmsg, "tcp/pop: unknown service");
+ return(NOTOK);
+ }
+
+ sin.sin_family = hp->h_addrtype;
+ bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
+ sin.sin_port = sp->s_port;
+
+ initialized = 1;
+ }
+
+ Pfd = rresvport(&lport);
+ if (Pfd < 0) {
+ sprintf(Errmsg, "error creating socket: %s", get_errmsg());
+ return(NOTOK);
+ }
+
+ if (connect(Pfd, (char *)&sin, sizeof sin) < 0) {
+ sprintf(Errmsg, "error during connect: %s", get_errmsg());
+ close(Pfd);
+ return(NOTOK);
+ }
+
+ sfi = fdopen(Pfd, "r");
+ sfo = fdopen(Pfd, "w");
+ if (sfi == NULL || sfo == NULL) {
+ sprintf(Errmsg, "error in fdopen: %s", get_errmsg());
+ close(Pfd);
+ return(NOTOK);
+ }
+
+ if (getline(response, sizeof response, sfi) != OK || (*response != '+')) {
+ strcpy(Errmsg, response);
+ return(NOTOK);
+ }
+
+ return(OK);
+}
+
+pop_close()
+{
+ if (sfi != NULL) fclose(sfi);
+ if (sfi != NULL) fclose(sfo);
+ close(Pfd);
+}
+
+pop_command(fmt, a, b, c, d)
+char *fmt;
+{
+ char buf[128];
+
+ sprintf(buf, fmt, a, b, c, d);
+
+ if (debug) fprintf(stderr, "---> %s\n", buf);
+ if (putline(buf, Errmsg, sfo) == NOTOK) return(NOTOK);
+
+ if (getline(buf, sizeof buf, sfi) != OK) {
+ strcpy(Errmsg, buf);
+ return(NOTOK);
+ }
+
+ if (debug) fprintf(stderr, "<--- %s\n", buf);
+ if (*buf != '+') {
+ strcpy(Errmsg, buf);
+ return(NOTOK);
+ } else {
+ return(OK);
+ }
+}
+
+
+pop_stat(nmsgs, nbytes)
+int *nmsgs, *nbytes;
+{
+ char buf[128];
+
+ if (debug) fprintf(stderr, "---> STAT\n");
+ if (putline("STAT", Errmsg, sfo) == NOTOK) return(NOTOK);
+
+ if (getline(buf, sizeof buf, sfi) != OK) {
+ strcpy(Errmsg, buf);
+ return(NOTOK);
+ }
+
+ if (debug) fprintf(stderr, "<--- %s\n", buf);
+ if (*buf != '+') {
+ strcpy(Errmsg, buf);
+ return(NOTOK);
+ } else {
+ sscanf(buf, "+OK %d %d", nmsgs, nbytes);
+ return(OK);
+ }
+}
+
+pop_retr(msgno, action, arg)
+int (*action)();
+{
+ char buf[128];
+ int end_of_header;
+
+ sprintf(buf, "RETR %d", msgno);
+ if (debug) fprintf(stderr, "%s\n", buf);
+ if (putline(buf, Errmsg, sfo) == NOTOK) return(NOTOK);
+
+ if (getline(buf, sizeof buf, sfi) != OK) {
+ strcpy(Errmsg, buf);
+ return(NOTOK);
+ }
+
+ end_of_header = 0;
+ while (1) {
+ switch (multiline(buf, sizeof buf, sfi)) {
+ case OK:
+ if (!end_of_header)
+ {
+ (*action)(buf, arg);
+ if (*buf == 0) end_of_header = 1;
+ }
+ break;
+ case DONE:
+ return (OK);
+ case NOTOK:
+ strcpy(Errmsg, buf);
+ return (NOTOK);
+ }
+ }
+}
+
+getline(buf, n, f)
+char *buf;
+register int n;
+FILE *f;
+{
+ register char *p;
+ register int c;
+
+ p = buf;
+ while (--n > 0 && (c = fgetc(f)) != EOF)
+ if ((*p++ = c) == '\n') break;
+
+ if (ferror(f)) {
+ strcpy(buf, "error on connection");
+ return (NOTOK);
+ }
+
+ if (c == EOF && p == buf) {
+ strcpy(buf, "connection closed by foreign host");
+ return (DONE);
+ }
+
+ *p = NULL;
+ if (*--p == '\n') *p = NULL;
+ if (*--p == '\r') *p = NULL;
+ return(OK);
+}
+
+multiline(buf, n, f)
+register char *buf;
+register int n;
+FILE *f;
+{
+ if (getline(buf, n, f) != OK) return (NOTOK);
+ if (*buf == '.') {
+ if (*(buf+1) == NULL) {
+ return (DONE);
+ } else {
+ strcpy(buf, buf+1);
+ }
+ }
+ return(OK);
+}
+
+putline(buf, err, f)
+char *buf;
+char *err;
+FILE *f;
+{
+ fprintf(f, "%s\r\n", buf);
+ fflush(f);
+ if (ferror(f)) {
+ strcpy(err, "lost connection");
+ return(NOTOK);
+ }
+ return(OK);
+}
+
+mbx_write(line, mbf)
+char *line;
+FILE *mbf;
+{
+ fputs(line, mbf);
+ fputc(0x0a, mbf);
+}
+
+struct mailsav *
+build_mailsav(mbf)
+ register FILE *mbf;
+{
+ char line[128];
+ char from[80];
+ char to[80];
+ char subj[80];
+ register struct mailsav *ms;
+ register int i;
+ register char *c;
+ register struct iovec *iov;
+
+ ms = (struct mailsav *)malloc(sizeof (struct mailsav));
+ ms->m_seen = 0;
+
+ from[0] = 0;
+ to[0] = 0;
+ subj[0] = 0;
+
+ rewind(mbf);
+ while (fgets(line, 128, mbf) != NULL)
+ {
+ if (*line == '\n') break;
+ if (!strncmp(line, "From:", 5))
+ strcpy(from, line);
+ else if (!strncmp(line, "To:", 3))
+ strcpy(to, line);
+ else if (!strncmp(line, "Subject:", 8))
+ strcpy(subj, line);
+ }
+
+ /* add elipsis at end of "To:" field if it continues onto */
+ /* more than one line */
+ i = strlen(to) - 2;
+ c = &to[i];
+ if (*c++ == ',')
+ {
+ *c++ = ' ';
+ *c++ = '.';
+ *c++ = '.';
+ *c++ = '.';
+ *c++ = '\n';
+ *c = 0;
+ }
+
+ i = 0;
+ if (from[0] != 0)
+ {
+ iov = &ms->m_iov[i];
+ iov->iov_len = strlen(from);
+ iov->iov_base = (char *)malloc(iov->iov_len);
+ bcopy(from, iov->iov_base, iov->iov_len);
+ iov->iov_base[--iov->iov_len] = 0; /* remove LF */
+ i++;
+ }
+
+ if (to[0] != 0)
+ {
+ iov = &ms->m_iov[i];
+ iov->iov_len = strlen(to);
+ iov->iov_base = (char *)malloc(iov->iov_len);
+ bcopy(to, iov->iov_base, iov->iov_len);
+ iov->iov_base[--iov->iov_len] = 0; /* remove LF */
+ i++;
+ }
+
+ if (subj[0] != 0)
+ {
+ iov = &ms->m_iov[i];
+ iov->iov_len = strlen(subj);
+ iov->iov_base = (char *)malloc(iov->iov_len);
+ bcopy(subj, iov->iov_base, iov->iov_len);
+ iov->iov_base[--iov->iov_len] = 0; /* remove LF */
+ i++;
+ }
+
+ ms->m_iovcnt = i;
+ return(ms);
+}
+
+display_mail_header(ms, mi)
+ register struct mailsav *ms;
+ register int mi;
+{
+ /* This is a little tricky. If the current mail number (mi) is greater */
+ /* than the last saved mail index (MailIndex), then this is new mail and */
+ /* mi = MailIndex + 1. (MailIndex is incremented each time new mail is */
+ /* saved.) Similarly, if mi is less than or equal to MailIndex and the */
+ /* mail is different, then it is new mail, and MailIndex is set back to */
+ /* mi. */
+
+ if (mi > MailIndex || mail_compare(ms, Mailsav[mi]))
+ {
+ if (Mailsav[mi] != NULL) free_mailsav(Mailsav[mi]);
+ MailIndex = mi;
+ Mailsav[mi] = ms;
+ log("new mail");
+ }
+ else
+ {
+ free_mailsav(ms);
+ ms = Mailsav[mi];
+ }
+ if (!ms->m_seen)
+ {
+ if (notify_user(ms->m_iov, ms->m_iovcnt) == 0) ms->m_seen = 1;
+ }
+}
+
+display_unseen()
+{
+ register int i;
+ register struct mailsav *ms;
+
+ for (i = 0; i <= MailIndex; i++)
+ {
+ ms = Mailsav[i];
+ if (ms->m_seen == 0)
+ {
+ if (notify_user(ms->m_iov, ms->m_iovcnt) != 0) return;
+ ms->m_seen = 1;
+ }
+ }
+}
+
+mail_compare(m1, m2)
+register struct mailsav *m1, *m2;
+{
+ register struct iovec *iov1, *iov2;
+ register int iovcnt;
+
+ if (m1->m_iovcnt != m2->m_iovcnt) return(1);
+ iov1 = m1->m_iov;
+ iov2 = m2->m_iov;
+ iovcnt = m1->m_iovcnt;
+ while (--iovcnt >= 0) {
+ if (strcmp(iov1->iov_base, iov2->iov_base)) return(1);
+ iov1++;
+ iov2++;
+ }
+ return(0);
+}
+
+error(msg)
+{
+ fprintf(stderr, "mailwatch: %s\n");
+}
+
+fatal(msg)
+{
+ error(msg);
+ exit(1);
+}
+
+char *
+get_errmsg()
+{
+ extern int errno, sys_nerr;
+ extern char *sys_errlist[];
+ char *s;
+
+ if (errno < sys_nerr)
+ s = sys_errlist[errno];
+ else
+ s = "unknown error";
+ return(s);
+}
+
+char *Months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+log(message, a1, a2)
+char *message;
+{
+ struct tm *tm;
+ int clock;
+ char buf[64];
+
+ clock = time(0);
+ tm = localtime(&clock);
+ sprintf(buf, message, a1, a2);
+ fprintf(logf, "%s %2d %02d:%02d:%02d -- %s\n",
+ Months[tm->tm_mon], tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec,
+ buf);
+}
diff --git a/clients/zmailnotify/zmwnotify.c b/clients/zmailnotify/zmwnotify.c
new file mode 100644
index 0000000..6395fd9
--- /dev/null
+++ b/clients/zmailnotify/zmwnotify.c
@@ -0,0 +1,301 @@
+/*
+ * $Source$
+ * $Header$
+ */
+
+#ifndef lint
+static char *rcsid_mwnotify_c = "$Header$";
+#endif lint
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/syslog.h>
+#include <sys/wait.h>
+#include <ttyent.h>
+#include <pwd.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <sgtty.h>
+#include <signal.h>
+#include <errno.h>
+#include <netdb.h>
+#include <X/Xlib.h>
+
+extern char **environ;
+
+short cursor[] = {0x0000, 0x7ffe, 0x4fc2, 0x4ffe, 0x7ffe,
+ 0x7ffe, 0x781e, 0x7ffe , 0x7ffe, 0x0000};
+
+#define NW_TOP 5
+#define DEFAULT_WINDOWS 16
+#define MAX_WINDOWS 32
+
+WindowInfo Winfo;
+FontInfo Finfo;
+Font NoteFont;
+int Timeout = 0;
+int Bwidth = 2;
+int Inner = 2;
+int Volume = 0;
+int Forepix = BlackPixel;
+int Backpix = WhitePixel;
+int Brdrpix = BlackPixel;
+int Mouspix = BlackPixel;
+int Offset = NW_TOP;
+int VPos = NW_TOP;
+int WindowMask = 0;
+int WindowCount;
+int WindowMax = DEFAULT_WINDOWS;
+
+struct wsav {
+ Window w_window;
+ struct iovec *w_iov;
+ int w_iovcnt;
+ int w_flags;
+} Wsav[MAX_WINDOWS];
+
+#define W_MAPPED 1
+
+extern int errno;
+
+notify_user(iov, iovcnt)
+register struct iovec *iov;
+register int iovcnt;
+{
+ register int i;
+ register struct wsav *w;
+
+ if (WindowCount == WindowMax)
+ return(1);
+
+ w = &Wsav[WindowCount];
+ w->w_flags = 0;
+ w->w_iov = (struct iovec *)malloc(sizeof (struct iovec) * iovcnt);
+ w->w_iovcnt = iovcnt;
+ for (i = iovcnt; --i >= 0; ) {
+ w->w_iov[i].iov_base = (char *)malloc(iov[i].iov_len+1);
+ bcopy(iov[i].iov_base, w->w_iov[i].iov_base, iov[i].iov_len+1);
+ w->w_iov[i].iov_len = iov[i].iov_len;
+ }
+ w->w_window = XNotifySetup(iov, iovcnt, &VPos);
+ WindowMask |= (1 << WindowCount);
+ WindowCount++;
+ return(0);
+}
+
+XProcessEvent()
+{
+ XEvent rep;
+ register struct wsav *w;
+ register int i;
+
+ do {
+ XNextEvent(&rep);
+
+ /* find the window */
+ w = Wsav;
+ for (i = 0; i < WindowMax; w++, i++)
+ if (rep.window == w->w_window) break;
+ if (i == WindowMax) return;
+
+ /* process the event */
+ switch (rep.type) {
+ case ButtonPressed:
+ for (; i >= 0; w--, i--) {
+ if (w->w_window != NULL) {
+ XDestroyWindow(w->w_window);
+ w->w_window = NULL;
+ free_iov(w->w_iov, w->w_iovcnt);
+ WindowMask &= ~(1 << i);
+ }
+ }
+ if (WindowMask == 0) {
+ VPos = Offset;
+ WindowCount = 0;
+ }
+ break;
+
+ case ExposeWindow:
+ case ExposeRegion:
+ XClear(w->w_window);
+ display_notice(w->w_window, w->w_iov, w->w_iovcnt);
+ XFlush();
+ break;
+
+ }
+ } while (XPending() > 0);
+}
+
+free_iov(iov, iovcnt)
+register struct iovec *iov;
+register int iovcnt;
+{
+ register struct iovec *iovbase = iov;
+
+ while (--iovcnt >= 0) {
+ free(iov->iov_base);
+ iov++;
+ }
+ free(iovbase);
+}
+
+
+XNotifyInit(dname)
+char *dname;
+{
+ struct passwd *pwent;
+ char *envbuf[2];
+ char homebuf[280];
+ int reverse = 0;
+ char *option;
+ char *font_name = "6x13";
+ char *fore_color = NULL;
+ char *back_color = NULL;
+ char *brdr_color = NULL;
+ char *mous_color = NULL;
+ Color cdef;
+ char *getlogin();
+
+ if (!XOpenDisplay(dname))
+ exit(0);
+ if (pwent = getpwnam(getlogin())) {
+ strcpy(homebuf, "HOME=");
+ strcat(homebuf, pwent->pw_dir);
+ envbuf[0] = homebuf;
+ envbuf[1] = NULL;
+ environ = envbuf;
+ if (option = XGetDefault("mailwatch", "BodyFont"))
+ font_name = option;
+ fore_color = XGetDefault("mailwatch", "Foreground");
+ back_color = XGetDefault("mailwatch", "Background");
+ brdr_color = XGetDefault("mailwatch", "Border");
+ mous_color = XGetDefault("mailwatch", "Mouse");
+ if (option = XGetDefault("mailwatch", "BorderWidth"))
+ Bwidth = atoi(option);
+ if (option = XGetDefault("mailwatch", "InternalBorder"))
+ Inner = atoi(option);
+ if (option = XGetDefault("mailwatch", "Timeout"))
+ Timeout = atoi(option);
+ if (option = XGetDefault("mailwatch", "Volume"))
+ Volume = atoi(option);
+ if (option = XGetDefault("mailwatch", "Offset"))
+ Offset = atoi(option);
+ if ((option = XGetDefault("mailwatch", "ReverseVideo")) &&
+ strcmp(option, "on") == 0)
+ reverse = 1;
+ if (option = XGetDefault("mailwatch", "MaxNotices"))
+ WindowMax = atoi(option);
+ }
+ if (reverse) {
+ Brdrpix = Backpix;
+ Backpix = Forepix;
+ Forepix = Brdrpix;
+ Mouspix = Forepix;
+ }
+
+ if ((NoteFont = XGetFont(font_name)) == NULL)
+ exit(0);
+ if (DisplayCells() > 2) {
+ if (back_color && XParseColor(back_color, &cdef) &&
+ XGetHardwareColor(&cdef))
+ Backpix = cdef.pixel;
+ if (fore_color && XParseColor(fore_color, &cdef) &&
+ XGetHardwareColor(&cdef))
+ Forepix = cdef.pixel;
+ if (brdr_color && XParseColor(brdr_color, &cdef) &&
+ XGetHardwareColor(&cdef))
+ Brdrpix = cdef.pixel;
+ if (mous_color && XParseColor(mous_color, &cdef) &&
+ XGetHardwareColor(&cdef))
+ Mouspix = cdef.pixel;
+ }
+ XQueryFont(NoteFont, &Finfo);
+ XQueryWindow (RootWindow, &Winfo);
+ VPos = Offset;
+ return(dpyno());
+}
+
+XNotifyClose()
+{
+ register int i;
+ register struct wsav *w;
+
+ for (i = WindowMax, w = Wsav; --i >= 0; w++)
+ if (w->w_window != NULL) XDestroyWindow(w->w_window);
+
+}
+
+XDisplayNewWindows()
+{
+ register int i;
+ register struct wsav *w;
+ register int feepcount = 0;
+
+ for (i = 0, w = Wsav; i < WindowMax; w++, i++)
+ if (w->w_window != NULL && !(w->w_flags & W_MAPPED)) {
+ XMapWindow(w->w_window);
+ feepcount++;
+ w->w_flags |= W_MAPPED;
+ }
+ XFlush();
+ /* Now feep for each window, s l o w l y */
+ while (--feepcount >= 0) {
+ XFeep(Volume);
+ XFlush();
+ }
+}
+
+XNotifySetup (iov, iovcnt, vpos)
+struct iovec *iov;
+int iovcnt;
+register int *vpos;
+{
+ register int i;
+ register int n;
+ register int width;
+ register int height;
+ int vertical;
+ register Window w;
+
+ width = 0;
+ for (i = iovcnt; --i >= 0; ) {
+ n = XQueryWidth (iov[i].iov_base, NoteFont);
+ if (n > width) width = n;
+ }
+
+ width += Inner * 2;
+ height = iovcnt * Finfo.height + (Inner * 2);
+ vertical = *vpos;
+ *vpos += height + (Finfo.height / 2);
+
+ w = XCreateWindow(RootWindow, (Winfo.width - width - (Bwidth * 2)) / 2,
+ vertical, width, height, Bwidth,
+ XMakeTile(Brdrpix), XMakeTile(Backpix));
+ XStoreName(w, "mail-notice");
+ XSelectInput(w, ButtonPressed|ButtonReleased|ExposeWindow|ExposeRegion);
+ XDefineCursor(w, XCreateCursor(16, 10, cursor, NULL, 7, 5,
+ Mouspix, Backpix, GXcopy));
+ return(w);
+}
+
+display_notice(w, iov, iovcnt)
+Window w;
+register struct iovec *iov;
+register int iovcnt;
+{
+ register int in;
+ register int y;
+ register int height;
+
+ in = Inner - 1;
+ if (in <= 0) in = 1;
+
+ height = Finfo.height;
+ y = in;
+ while (--iovcnt >= 0) {
+ XText(w, in, y, iov->iov_base, iov->iov_len,
+ NoteFont, Forepix, Backpix);
+ y += height;
+ iov++;
+ }
+}