home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume7 / sunmailwatch < prev    next >
Text File  |  1986-12-09  |  15KB  |  515 lines

  1. Subject:  v07i085:  A mail watcher for SUNwindows
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: seismo!ut-sally!ut-ngp!clyde (Head UNIX Hacquer)
  6. Mod.sources: Volume 7, Issue 85
  7. Archive-name: sunmailwatch
  8.  
  9. # This is a little hack that I put together to watch for incoming mail.
  10. # I use it instead of biff(1) for this.  Originally this was a shell script,
  11. # but I got tired of the slowness and other problems (such as signal
  12. # handling), so I converted it to C.
  13. #
  14. # So when new mail arrives at my SUN, an icon on my desktop changes to let
  15. # me know.  Slightly expensive (requires running a shelltool), but worth
  16. # it and simple.
  17. #
  18. #    This is a shell archive.
  19. #!/bin/sh
  20. # shar:    Shell Archiver
  21. #    Run the following text with /bin/sh to create:
  22. #    README
  23. #    Makefile
  24. #    emptymbox
  25. #    fullmbox
  26. #    mailwatch.1
  27. #    mailwatch.c
  28. cat << \SHAR_EOF > README
  29. Mailwatch distribution notes
  30.  
  31. README        - this file
  32. Makefile    - q.e.d
  33. emptymbox    - 'empty mailbox' icon (place in /usr/include/images)
  34. fullmbox    - 'full mailbox' icon (place in /usr/include/images)
  35. mailwatch.1    - manual page
  36. mailwatch.c    - C source
  37.  
  38. Bugs to clyde@ngp.utexas.edu, ihnp4!ut-ngp!clyde
  39. SHAR_EOF
  40. cat << \SHAR_EOF > Makefile
  41. mailwatch:    mailwatch.c
  42.     cc -o mailwatch -O mailwatch.c
  43. SHAR_EOF
  44. cat << \SHAR_EOF > emptymbox
  45. /* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
  46.  */
  47.     0x8888,0x8888,0x8888,0x8888,0x8888,0x8888,0x8888,0x8888,
  48.     0x2222,0x2222,0x2222,0x2222,0x2222,0x2222,0x22FF,0x2222,
  49.     0x8888,0x8888,0x8B00,0xC888,0x8888,0x8888,0x9C00,0x2888,
  50.     0x2222,0x2222,0x6000,0x1222,0x2222,0x2223,0x8000,0x0A22,
  51.     0x8888,0x888C,0x0000,0x0C88,0x8888,0x88F0,0x0000,0x0488,
  52.     0x2222,0x2300,0x0000,0x0222,0x2222,0x27F0,0x0000,0x0222,
  53.     0x8888,0x980C,0x0000,0x0288,0x8888,0xE003,0x0000,0x0288,
  54.     0x2222,0x8000,0x8000,0x0222,0x2223,0x0000,0x4000,0x0222,
  55.     0x888A,0x0000,0x2000,0x0288,0x888A,0x0000,0x2000,0x0288,
  56.     0x2224,0x0000,0x1000,0x0222,0x2224,0x0000,0x1000,0x0222,
  57.     0x8888,0x0000,0x0800,0x0288,0x8888,0x0000,0x0800,0x2288,
  58.     0x2228,0x0000,0x0800,0xE222,0x2228,0x0000,0x0801,0xE222,
  59.     0x8888,0x0000,0x0803,0xE288,0x8888,0x0000,0x080E,0xE288,
  60.     0x2229,0x1013,0x081C,0xE222,0x2229,0xB301,0x0830,0xE222,
  61.     0x8889,0x5091,0x0820,0xCC88,0x8889,0x5391,0x0800,0x8888,
  62.     0x2229,0x1491,0x0800,0x3222,0x2229,0x1391,0x0800,0x6222,
  63.     0x8888,0x0000,0x0800,0x8888,0x8888,0x0000,0x0801,0x8888,
  64.     0x2228,0x0000,0x0802,0x2222,0x2228,0x0000,0x0806,0x2222,
  65.     0x8888,0x0000,0x0808,0x8888,0x8888,0x0000,0x0818,0x8888,
  66.     0x2228,0x0000,0x0822,0x2222,0x2228,0x0000,0x08E2,0x2222,
  67.     0x8888,0x0000,0x0988,0x8888,0x8888,0x0000,0x0A88,0x8888,
  68.     0x2228,0x0000,0x0E22,0x2222,0x222F,0xFFFF,0xFE22,0x2222,
  69.     0x8888,0x8888,0xBE88,0x8888,0x8888,0x8888,0xBE88,0x8888,
  70.     0x2222,0x2222,0x3E22,0x2222,0x2222,0x2222,0x3E22,0x2222,
  71.     0x8888,0x8888,0xBE88,0x8888,0x8888,0x8888,0xBE88,0x8888,
  72.     0x2222,0x2222,0x3E22,0x2222,0x2222,0x2222,0x3E22,0x2222,
  73.     0x8888,0x8888,0xBE88,0x8888,0x8888,0x8888,0xBE88,0x8888,
  74.     0x2222,0x2222,0x3E22,0x2222,0x2222,0x2222,0x3E22,0x2222,
  75.     0x8888,0x8888,0xBE88,0x8888,0x8888,0x8888,0xBE88,0x8888,
  76.     0x2222,0x2222,0x3E22,0x2222,0x2222,0x2222,0x3E22,0x2222,
  77.     0x8888,0x8888,0xBE88,0x8888,0x8888,0x8888,0xBE88,0x8888,
  78.     0x2222,0x2222,0x3E22,0x2222,0x2222,0x2222,0x3E22,0x2222
  79. SHAR_EOF
  80. cat << \SHAR_EOF > fullmbox
  81. /* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
  82.  */
  83.     0x8888,0x8888,0x8888,0x8888,0x8888,0x8888,0x8888,0x8888,
  84.     0x2222,0x2222,0x2222,0x2222,0x2222,0x2222,0x22FF,0x2222,
  85.     0x8888,0x8888,0x8B00,0xC888,0x8888,0x8888,0x9C00,0x2888,
  86.     0x2222,0x2222,0x6000,0x1222,0x2222,0x2223,0x8000,0x0A22,
  87.     0x8888,0x888C,0x0000,0x0C88,0x8888,0x88F0,0x0000,0x0488,
  88.     0x2222,0x2300,0x0001,0x0222,0x2222,0x27F0,0x0007,0x0222,
  89.     0x8888,0x9AAC,0x001F,0x0288,0x8888,0xF557,0x003F,0x0288,
  90.     0x2222,0xAAAA,0x803F,0x0222,0x2223,0x5555,0x403F,0x0222,
  91.     0x888A,0xAAAA,0xA03E,0x0288,0x888B,0x5555,0x6038,0x0288,
  92.     0x2226,0xAAAA,0xB030,0x0222,0x2225,0x5555,0x5030,0x0222,
  93.     0x888A,0xAAAA,0xA830,0x0288,0x888D,0x5555,0x5830,0x0288,
  94.     0x222A,0xAAAA,0xA830,0x0222,0x222D,0x5555,0x5830,0x0222,
  95.     0x888A,0xAAAA,0xA830,0x0288,0x888D,0x5555,0x5830,0x0288,
  96.     0x222A,0xAAAA,0xA830,0x0222,0x222D,0x5555,0x7830,0x0222,
  97.     0x888A,0xAAAA,0xE820,0x0C88,0x888D,0x5555,0xD800,0x0888,
  98.     0x222A,0xAAAB,0x0800,0x3222,0x222D,0x5555,0x0800,0x6222,
  99.     0x888A,0xAAB9,0x0800,0x8888,0x888D,0x5571,0x0801,0x8888,
  100.     0x222A,0xAAE1,0x0802,0x2222,0x222D,0x5543,0x0806,0x2222,
  101.     0x888A,0xAE8C,0x0808,0x8888,0x888D,0x5D30,0x1818,0x8888,
  102.     0x222A,0xBAC0,0x2822,0x2222,0x222D,0x7700,0x58E2,0x2222,
  103.     0x888A,0xAB55,0xA988,0x8888,0x888F,0x5555,0x5A88,0x8888,
  104.     0x222E,0xAAAA,0xAE22,0x2222,0x222F,0xFFFF,0xFE22,0x2222,
  105.     0x8890,0x0000,0x1E88,0x8888,0x88A0,0x0000,0x3E88,0x8888,
  106.     0x2240,0x0000,0x7E22,0x2222,0x2280,0x0000,0xBE22,0x2222,
  107.     0x8900,0x0001,0xBE88,0x8888,0x8A00,0x0002,0xBE88,0x8888,
  108.     0x2400,0x0006,0x3E22,0x2222,0x2800,0x000A,0x3E22,0x2222,
  109.     0x9000,0x0018,0xBE88,0x8888,0xA000,0x0028,0xBE88,0x8888,
  110.     0x4000,0x0062,0x3E22,0x2222,0x4000,0x00A2,0x3E22,0x2222,
  111.     0xC000,0x0188,0xBE88,0x8888,0xA000,0x0688,0xBE88,0x8888,
  112.     0x3000,0x0A22,0x3E22,0x2222,0x2E01,0xF222,0x3E22,0x2222,
  113.     0x89FE,0x8888,0xBE88,0x8888,0x8888,0x8888,0xBE88,0x8888,
  114.     0x2222,0x2222,0x3E22,0x2222,0x2222,0x2222,0x3E22,0x2222
  115. SHAR_EOF
  116. cat << \SHAR_EOF > mailwatch.1
  117. .TH MAILWATCH 1
  118. .SH NAME
  119. mailwatch \- watch for mail
  120. .SH SYNOPSIS
  121. .B mailwatch
  122. [
  123. .B \-a
  124. ] [
  125. .B \-c
  126. ] [
  127. .B \-e
  128. ] [
  129. .B \-o
  130. ] [
  131. .B \-i
  132. .I empty-icon
  133. ] [
  134. .B \-I
  135. .I full-icon
  136. ] [
  137. .B \-l
  138. .I empty-label
  139. ] [
  140. .B \-L
  141. .I full-label
  142. ] [
  143. .B \-m
  144. .I mail-reader
  145. ] [
  146. .B \-t
  147. .I check-time
  148. ]
  149. .SH DESCRIPTION
  150. .I Mailwatch
  151. monitors the users' mailbox (as given in the
  152. .B MAIL
  153. environment setting) and alerts the user when there is new mail.
  154. .I Mailwatch
  155. uses the SUN
  156. .IR shelltool (1)
  157. terminal emulation capabilities to post the new mail alert.
  158. It will not function properly unless running in a SUN tty emulation window.
  159. .PP
  160. While waiting for mail, the window will be closed and displaying the
  161. .I empty-mailbox
  162. icon.  When new mail arrives, the
  163. .I full-mailbox
  164. icon is displayed.  The
  165. .I mailwatch
  166. window may optionally pop to the front of the screen, open and start up
  167. a mail reader.
  168. After the mail reader has exited and the mail
  169. disposed of, the window is closed and the
  170. .I empty-mailbox
  171. icon is displayed.
  172. .SH OPTIONS
  173. .TP 15
  174. .B  \-a
  175. Ask before starting up the mail reader program.
  176. .TP
  177. .B \-c
  178. Clear the terminal emulator window before starting up the mail reader program.
  179. .TP
  180. .B \-e
  181. Bring window to front when mail arrives.
  182. .TP
  183. .B \-o
  184. Automatically open window when mail arrives.
  185. .TP
  186. \fB\-i\fP\fI empty-icon\fP
  187. Icon to display when mailbox empty.
  188. (Default is \fI/usr/include/images/emptymbox\fP).
  189. .TP
  190. \fB\-I\fP\fI full-icon\fP
  191. Icon to display when mail arrives.
  192. (Default is \fI/usr/include/images/fullmbox\fP).
  193. .TP
  194. \fB\-l \fP\fIempty-label\fP
  195. String to use as label for empty mailbox icon. (Default is for no label).
  196. .TP
  197. \fB\-L \fP\fIfull-label\fP
  198. String to use as label for full mailbox icon. (Default is for no label).
  199. .TP
  200. \fB\-m \fP\fImail-reader\fP
  201. Mail reading program to use. (Default is
  202. .IR Mail(1)).
  203. .TP
  204. \fB\-t \fP\fIinterval\fP
  205. Check for mail every
  206. .I interval
  207. seconds.  (Default is 60 seconds).
  208. .PP
  209. .I Mailwatch
  210. can also be forced to check the mailbox by sending it an interrupt signal
  211. (\fBSIGINT\fP).  Sending a quit signal (\fBSIGQUIT\fP) causes 
  212. .I mailwatch
  213. to exit.
  214. .PP
  215. .I Mailwatch
  216. uses the SUN tty emulator window capabilities which are controlled by
  217. command strings, so it need not run on the SUN workstation itself.
  218. .SH BUGS
  219. .PP
  220. The window is closed only if the mailbox file is empty.
  221. .sp
  222. All pending input is flushed when new mail is detected, and this sometimes
  223. causes 
  224. .I mailwatch
  225. output to be garbled.
  226. .sp
  227. This program could well run as an actual tool, sparing the expense of running a
  228. shelltool for mail monitoring.
  229. .sp
  230. SUN UNIX 3.0 has a
  231. .I mailtool
  232. which performs many of these functions, but we don\'t run 3.0 yet.
  233. .SH AUTHOR
  234. Clyde Hoover, University of Texas Compuation Center, Austin Texas.
  235. .SH FILES
  236. The name of the mail file watched is taken from the
  237. .B MAIL
  238. environment entry.
  239. .br
  240. .I /usr/include/images/emptymbox
  241. and
  242. .I /usr/include/images/fullmbox
  243. are the default icons displayed.
  244. SHAR_EOF
  245. cat << \SHAR_EOF > mailwatch.c
  246. /*
  247.  *    mailwatch - New mail watcher which manipulates SUN tty windows
  248.  *        Changes icons when new mail arrives and optionally
  249.  *        opens SUN window and starts up mail reading program
  250.  *
  251.  *    Usage: mailwatch -a (Ask before starting up mail reader)
  252.  *             -c (Clear screen before reading mail)
  253.  *             -e (Bring window to top when mail arrives)
  254.  *             -o (Automatically open window for new mail)
  255.  *             -i (Icon to display when mailbox empty)
  256.  *             -I (Icon to display when mailbox full)
  257.  *             -l (Label for empty mailbox icon)
  258.  *             -L (Label for full mailbox icon)
  259.  *             -m (Mail reading program)
  260.  *             -t (New mail check time)
  261.  *
  262.  *    Compliation:    cc -o mailwatch -O mailwatch.c
  263.  *    Ownership:    any/any
  264.  *    Mode:        0755
  265.  *    Binary:        anywhere
  266.  */
  267. #include <stdio.h>
  268. #include <sys/types.h>
  269. #include <sys/ioctl.h>
  270. #include <sys/stat.h>
  271. #include <sys/time.h>
  272. #include <signal.h>
  273. #include <setjmp.h>
  274.  
  275. int    CheckTime = 120;    /* Time between mail checks */
  276. char    *MailBox;        /* Mailbox file */
  277.  
  278. char    *EmptyMboxIcon = "/usr/include/images/emptymbox", /* CONFIG */
  279.         /* Icon for empty mailbox */
  280.     *FullMboxIcon = "/usr/include/images/fullmbox";      /* CONFIG */
  281.         /* Icon for full mailbox */
  282.  
  283. char    *EmptyMboxLabel = "",    /* Label for empty mbox icon */
  284.     *FullMboxLabel = "";    /* Label for full mbox icon */
  285.  
  286. char    *MailReader = "Mail";    /* Mail reading program */
  287.  
  288. int    AutoOpen = 0,        /* Automatically open window for mail */
  289.     Clear = 0,        /* Clear window before starting MailReader */
  290.     Ask = 0,        /* Ask before starting MailReader */
  291.     Expose = 0;        /* Expose sun window for mail */
  292.  
  293. int    OnSun;            /* Running under SUN windows */
  294.  
  295. char    *clr_window = "\014",    /* Clear SUN window */
  296.     *c_window = "\033[2t",    /* Close SUN window */
  297.     *o_window = "\033[1t",    /* Open SUN window */
  298.     *e_window = "\033[5t",    /* Expose SUN window */
  299.     *i_label = "\033]L%s\033\\",    /* Set icon label */
  300.     *s_label = "\033]l%s\033\\",    /* Set top stripe label */
  301.     *s_icon = "\033]I%s\033\\";    /* Set icon */
  302.  
  303. int    checked = 0;        /* Mail check commanded (via SIGINT) */
  304. jmp_buf    here;            /* Where to return to for signals */
  305.  
  306.     /* Usage message */
  307. char    *Usage = "Usage: mailwatch [-a] [-c] [-e] [-o]\n\
  308.     [-i emptymboxicon] [-I fullmboxicon]\n\
  309.     [-l emptymboxlabel] [-L fullmboxlabel]\n\
  310.     [-m mailreader] [-t check-time]\n";
  311.  
  312. /*
  313.  *    Simple things
  314.  */
  315. #define    seticon(I)    printf(s_icon, I)
  316. #define    seticonlabel(S)    printf(i_label, S)
  317. #define    setstripe(S)    printf(s_label, S)
  318. #define    putstr(S)    fputs(S, stdout)
  319.  
  320. #define    CLOSED    0    /* Window is closed */
  321. #define    OPEN    1    /* Window is open */
  322.  
  323. main(argc, argv)
  324. int    argc;
  325. char    **argv;
  326. {
  327.     int    state = OPEN;    /* Current window status */
  328.     int    catcher();    /* Signal catcher */
  329.  
  330.     setbuf(stdout, (char *)NULL);
  331.     init(argc, argv);
  332.     (void) signal(SIGINT, catcher);
  333.     (void) signal(SIGQUIT, catcher);
  334.  
  335.     setjmp(here);
  336.     for (;;) {
  337.         if (filesize(MailBox) > 0) {
  338.             state = OPEN;
  339.             seticon(FullMboxIcon);
  340.             seticonlabel(FullMboxLabel);
  341.             setstripe("      You have mail.");
  342.             if (Expose)
  343.                 putstr(e_window);
  344.             if (AutoOpen)
  345.                 putstr(o_window);
  346.             if (Ask) {
  347.                 char    buf[80];    /* Input buffer */
  348.  
  349.                 putstr("\nPress RETURN to read mail");
  350.                 fflush(stdout);
  351.                 tossinput();
  352.                 (void) fgets(buf, 80, stdin);
  353.             }
  354.             if (Clear)
  355.                 putstr(clr_window);
  356.             (void) system(MailReader);
  357.         }
  358.         else {
  359.             if (state == OPEN) {
  360.                 putstr(c_window);
  361.                 seticon(EmptyMboxIcon);
  362.                 seticonlabel(EmptyMboxLabel);
  363.                 setstripe("      Waiting for mail.");
  364.                 state = CLOSED;
  365.             }
  366.             if (checked) {
  367.                 putstr("No mail.\n");
  368.                 checked = 0;
  369.             }
  370.             tsleep(CheckTime);
  371.         }
  372.     }
  373. }
  374.  
  375. /*
  376.  *    filesize - get size of file
  377.  *
  378.  *    Returns: size of file or -1 if file not found
  379.  */
  380. filesize(file)
  381. char    *file;        /* File to size */
  382. {
  383.     struct stat s;    /* File status */
  384.  
  385.     if (stat(file, &s) < 0)
  386.         return(-1);
  387.     return(s.st_size);
  388. }
  389.  
  390. /*
  391.  *    catcher - signal catcher
  392.  */
  393. catcher(sig)
  394. int    sig;    /* Signal which got us here */
  395. {
  396.     if (sig == SIGQUIT) {
  397.         putstr("\nQuit\n");
  398.         exit(1);
  399.     }
  400.     checked = 1;        /* Set user check flag */
  401.     longjmp(here, 1);
  402. }
  403.  
  404. /*
  405.  *    tossinput - flush pending terminal input
  406.  */
  407. tossinput()
  408. {
  409.     tsleep(2);
  410.     ioctl(0, TIOCFLUSH, 0);
  411. }
  412.  
  413.  
  414. /*
  415.  *    tsleep -- sleep for <time> seconds or until terminal
  416.  *        is ready for input.
  417.  */
  418. tsleep(time)
  419. int    time;        /* Seconds to sleep */
  420. {
  421.     struct timeval    kw;    /* Select timeout */
  422.     int    imask;    /* Input fd mask */ /* XXX SELECT TYPE */
  423.  
  424.     kw.tv_sec = time;
  425.     kw.tv_usec = 0;
  426.     imask = (1 << fileno(stdin));
  427.     return(select(fileno(stdin)+1, &imask, (int *)0, (int *)0, &kw));
  428. }
  429.  
  430. /*
  431.  *    init - process arguments and initialize options
  432.  *
  433.  * Arguments are:
  434.  * a = auto open
  435.  * c = clear before mailreader exec
  436.  * e = expose window when mail arrives
  437.  * i fn = empty icon
  438.  * I fn = full icon
  439.  * l str = empty label
  440.  * L str = full label
  441.  * t time = sleep time
  442.  * m prog = mail-reader
  443.  */
  444. init(argc, argv)
  445. int    argc;        /* Arg count from main() */
  446. char    **argv;        /* Arg vector from main() */
  447. {
  448.     extern int    optind;        /* From getopt() */
  449.     extern char    *optarg;    /* From getopt() */
  450.     char    *p;        /* Temp */
  451.     int    argchar;    /* Temp */
  452.     char    *optstring = "acei:I:l:L:t:m:o?";    /* Option list */
  453.  
  454.     extern char    *getenv();
  455.  
  456.     OnSun = (int )getenv("WINDOW_ME");
  457.     /*
  458.      * If running under suntools, ignore stop signals.
  459.      * Actually this is desirable ONLY if running directly under
  460.      * shelltool, but there is no easy way to figure that out.
  461.      */
  462.     if (OnSun)
  463.         (void) signal(SIGTSTP, SIG_IGN);
  464.  
  465.     /*
  466.      * If TERM != sun, all bets are off!
  467.      */
  468.     p = getenv("TERM");
  469.     if (strncmp(p, "sun", 3) && strcmp(p, "Mu")) {
  470.         printf("Warning: TERM not set to 'sun'.\n");
  471.         printf("\tMailwatch will only work in SUN tty emulator window\n");
  472.     }
  473.  
  474.     if ((MailBox = getenv("MAIL")) == (char *)0) {
  475.         fprintf(stderr, "No mailbox\n");
  476.         exit(1);
  477.     }
  478.  
  479.     while ((argchar = getopt(argc, argv, optstring)) != EOF) {
  480.         switch(argchar) {
  481.         case 'a':    Ask = 1; break;
  482.         case 'c':    Clear = 1; break;
  483.         case 'e':    Expose = 1; break;
  484.         case 'i':    EmptyMboxIcon = optarg; break;
  485.         case 'I':    FullMboxIcon = optarg; break;
  486.         case 'l':    EmptyMboxLabel = optarg; break;
  487.         case 'L':    FullMboxLabel = optarg; break;
  488.         case 'm':    MailReader = optarg; break;
  489.         case 'o':    AutoOpen = 1; break;
  490.         case 't':    CheckTime = atoi(optarg); break;
  491.         case '?':    printf(Usage); exit(1);
  492.         }
  493.     }
  494.     if (filesize(EmptyMboxIcon) < 0) {
  495.         fprintf(stderr, "Can't find empty mailbox icon %s\n",
  496.             EmptyMboxIcon);
  497.         exit(1);
  498.     }
  499.     if (filesize(FullMboxIcon) < 0) {
  500.         fprintf(stderr, "Can't find full mailbox icon %s\n",
  501.             FullMboxIcon);
  502.         exit(1);
  503.     }
  504. /*
  505.  *    printf("Mailwatch starting. 
  506.  *        Will check mail every %d seconds\n
  507.  *        SIGINT to check mail\n
  508.  *        SIGQUIT to exit\n", CheckTime);
  509.  */
  510. }
  511. SHAR_EOF
  512. #    End of shell archive
  513. exit 0
  514.  
  515.