home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume6 / bday / bday.c < prev    next >
C/C++ Source or Header  |  1989-05-14  |  6KB  |  291 lines

  1. /*
  2. **  When you care enough to send the very best....
  3. **  Written by Rich $alz, <rsalz@bbn.com>, after seeing the MIT program
  4. **  in action.  This package has no copyright.
  5. */
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <sys/types.h>
  9. #include <time.h>
  10. #include <fcntl.h>
  11. #include <sgtty.h>
  12. #ifndef    lint
  13. #ifndef    SABER
  14. static char RCS[] =
  15.     "$Header: bday.c,v 1.1 89/05/08 11:13:22 rsalz Exp $";
  16. #endif    /* SABER */
  17. #endif    /* lint */
  18.  
  19. /* Compilation control. */
  20. #define STRCHR        strchr        /* Maybe index            */
  21. #define STRRCHR        strrchr        /* Maybe rindex            */
  22. #undef WEEKEND_HACK            /* Work harder on Friday?    */
  23.  
  24. /* Manifest constants. */
  25. #define TRUE        1
  26. #define FALSE        0
  27. #define LEN        128
  28. #define FROM        "The Birthday Wizard <wizard@pineapple.bbn.com>"
  29.  
  30. /* Syntactic sugar. */
  31. #define WHITE(c)    ((c) == ' ' || (c) == '\t')
  32. #define Fprintf        (void)fprintf
  33. #ifdef    lint
  34. #undef    putc
  35. #endif    /* lint */
  36.  
  37.  
  38. /* Global data. */
  39. static char    *progname;
  40. static char    *ReportTo    = NULL;
  41. static char    *Birthdays    = "/usr/adm/bdaylist";
  42. static char    *Message    = "/usr/adm/bdaymesg";
  43. static char    *sendmail    = "/usr/lib/sendmail.sun -t -oi";
  44. /*static char    *sendmail    = "/usr/lib/sendmail -t -oi"; */
  45.  
  46.  
  47. /* Linked in later. */
  48. extern int     errno;
  49. extern char    *optarg;
  50. extern time_t     time();
  51. extern char    *sprintf();        /* Too painful, my ass        */
  52. extern char    *strcpy();
  53. extern char    *STRCHR();
  54. extern char    *STRRCHR();
  55.  
  56.  
  57. /*
  58. **  Return the text string that corresponds to errno.
  59. */
  60. static char *
  61. strerror(e)
  62.     int         e;
  63. {
  64.     extern int     sys_nerr;
  65.     extern char    *sys_errlist[];
  66.     static char     buff[30];
  67.  
  68.     if (e > 0 && e < sys_nerr)
  69.     return sys_errlist[e];
  70.     (void)sprintf(buff, "Error code %d", e);
  71.     return buff;
  72. }
  73.  
  74.  
  75. /*
  76. **  Send mail to the person.
  77. */
  78. static void
  79. Doit(Name)
  80.     char    *Name;
  81. {
  82.     register FILE    *F;
  83.     register FILE    *M;
  84.     register int     c;
  85.  
  86.     /* Prep the pipe. */
  87.     if ((F = popen(sendmail, "w")) == NULL) {
  88.     Fprintf(stderr, "%s: Doit(%s) failed to popen \"%s\", %s.\n",
  89.         progname, Name, sendmail, strerror(errno));
  90.     return;
  91.     }
  92.  
  93.     /* Write headers. */
  94.     Fprintf(F, "From: %s\n", FROM);
  95.     Fprintf(F, "To: %s\n", Name);
  96.     Fprintf(F, "Subject: Happy birthday!\n");
  97.     Fprintf(F, "\n");
  98.  
  99.     /* Feed in the message. */
  100.     if (M = fopen(Message, "r")) {
  101.     while ((c = getc(M)) != EOF)
  102.         (void)putc(c, F);
  103.     (void)fclose(M);
  104.     }
  105.  
  106.     /* Close up.  Done? */
  107.     (void)pclose(F);
  108.     if (ReportTo == NULL)
  109.     return;
  110.  
  111.     /* Report it. */
  112.     if ((F = popen(sendmail, "w")) == NULL) {
  113.     Fprintf(stderr, "%s: Doit(%s) couldn't report, %s.\n",
  114.         progname, Name, strerror(errno));
  115.     return;
  116.     }
  117.  
  118.     /* Write the report. */
  119.     Fprintf(F, "To: %s\n", ReportTo);
  120.     Fprintf(F, "Subject: Greetings sent\n");
  121.     Fprintf(F, "\n");
  122.     Fprintf(F, "Sent a message to %s.\n", Name);
  123.  
  124.     /* Close up.  Definitely done. */
  125.     (void)pclose(F);
  126. }
  127.  
  128.  
  129. /*
  130. **  Return pointer to first non-whitespace.
  131. */
  132. static char *
  133. Skip(p)
  134.     register char    *p;
  135. {
  136.     while (*p && WHITE(*p))
  137.     p++;
  138.     return p;
  139. }
  140.  
  141.  
  142. /*
  143. **  Check the list in the file for birthdays.
  144. */
  145. static void
  146. ScanForWork(ThisMonth, ThisDay)
  147.     int             ThisMonth;
  148.     int             ThisDay;
  149. {
  150.     register FILE    *F;
  151.     register char    *p;
  152.     int             UserMonth;
  153.     int             UserDay;
  154.     char         UserName[LEN];
  155.     char         buff[LEN];
  156.  
  157.     /* Open the list of birthdays. */
  158.     if ((F = fopen(Birthdays, "r")) == NULL) {
  159.     Fprintf(stderr, "%s: ScanForWork can't open \"%s\" for reading, %s.\n",
  160.         progname, Birthdays, strerror(errno));
  161.     return;
  162.     }
  163.  
  164.     /* Scan all lines. */
  165.     while (fgets(buff, sizeof buff, F)) {
  166.     /* Clobber comment markers and newlines. */
  167.     if (p = STRCHR(buff, '#'))
  168.         *p = '\0';
  169.     if (p = STRCHR(buff, '\n'))
  170.         *p = '\0';
  171.  
  172.     /* Skip blank or comment lines. */
  173.     if (buff[0] == '\0')
  174.         continue;
  175.  
  176.     /* First field is the user name. */
  177.     for (p = buff; *p && !WHITE(*p); p++)
  178.         ;
  179.     *p++ = '\0';
  180.     (void)strcpy(UserName, buff);
  181.     if (UserName[0] == '\0')
  182.         continue;
  183.  
  184.     /* Second field is the month of the user's birthday. */
  185.     p = Skip(p);
  186.     if (*p == '\0')
  187.         continue;
  188.     for (UserMonth = atoi(p); *p && isdigit(*p); p++)
  189.         ;
  190.     if (UserMonth == 0)
  191.         continue;
  192.  
  193.     /* Third field is the date of the user's birthday. */
  194.     p = Skip(p);
  195.     if (*p == '\0')
  196.         continue;
  197.     UserDay = atoi(p);
  198.     if (UserDay == 0)
  199.         continue;
  200.  
  201.     /* Is this one for us? */
  202.     if (UserMonth == ThisMonth && UserDay == ThisDay)
  203.         Doit(UserName);
  204.     }
  205.  
  206.     (void)fclose(F);
  207. }
  208.  
  209.  
  210. /*
  211. **  Make sure the file was specified and is readable.
  212. */
  213. static void
  214. CheckFile(Name, Purpose)
  215.     char    *Name;
  216.     char    *Purpose;
  217. {
  218.     FILE    *F;
  219.  
  220.     if (Name == NULL) {
  221.     Fprintf(stderr, "%s:  No %s file given.\n", progname, Purpose);
  222.     exit(1);
  223.     }
  224.  
  225.     if ((F = fopen(Name, "r")) == NULL) {
  226.     Fprintf(stderr, "%s: Can't open \"%s\" for %s, %s.\n",
  227.         progname, Name, Purpose, strerror(errno));
  228.     exit(1);
  229.     }
  230.  
  231.     (void)fclose(F);
  232. }
  233.  
  234.  
  235. main(ac, av)
  236.     int         ac;
  237.     char    *av[];
  238. {
  239.     int         i;
  240.     time_t     t;
  241.     struct tm    *tm;
  242.     char    *p;
  243.  
  244.     /* Parse JCL. */
  245.     progname = (p = STRRCHR(av[0], '/')) ? p + 1 : av[0];
  246.     while ((i = getopt(ac, av, "b:m:r:s:")) != EOF)
  247.     switch (i) {
  248.     default:
  249.         Fprintf(stderr, "Usage:\n\t%s %s\n",
  250.             progname,
  251.             "[-b list] [-m message] [-s sendcmd] [-r admin]");
  252.         exit(1);
  253.     case 'b':
  254.         Birthdays = optarg;
  255.         break;
  256.     case 'm':
  257.         Message = optarg;
  258.         break;
  259.     case 'r':
  260.         ReportTo = optarg;
  261.         break;
  262.     case 's':
  263.         sendmail = optarg;
  264.         break;
  265.     }
  266.  
  267.     /* Make sure the user gave us readable files. */
  268.     CheckFile(Birthdays, "birthday list");
  269.     CheckFile(Message, "message");
  270.  
  271.     /* What time is it? */
  272.     t = time((time_t *)NULL);
  273.     tm = localtime(&t);
  274.     ScanForWork(tm->tm_mon + 1, tm->tm_mday);
  275.  
  276. #ifdef    WEEKEND_HACK
  277.     /* If it's Friday, check for Saturday and Sunday birthdays. */
  278.     if (tm->tm_wday == 5) {
  279.     /* This is easy/sleazy, we avoid checking for end of month... */
  280.     t += 24 * 60 * 60;
  281.     tm = localtime(&t);
  282.     ScanForWork(tm->tm_mon + 1, tm->tm_mday);
  283.     t += 24 * 60 * 60;
  284.     tm = localtime(&t);
  285.     ScanForWork(tm->tm_mon + 1, tm->tm_mday);
  286.     }
  287. #endif    /* WEEKEND_HACK */
  288.  
  289.     exit(0);
  290. }
  291.