home *** CD-ROM | disk | FTP | other *** search
- /*
- ** When you care enough to send the very best....
- ** Written by Rich $alz, <rsalz@bbn.com>, after seeing the MIT program
- ** in action. This package has no copyright.
- */
- #include <stdio.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include <time.h>
- #include <fcntl.h>
- #include <sgtty.h>
- #ifndef lint
- #ifndef SABER
- static char RCS[] =
- "$Header: bday.c,v 1.1 89/05/08 11:13:22 rsalz Exp $";
- #endif /* SABER */
- #endif /* lint */
-
- /* Compilation control. */
- #define STRCHR strchr /* Maybe index */
- #define STRRCHR strrchr /* Maybe rindex */
- #undef WEEKEND_HACK /* Work harder on Friday? */
-
- /* Manifest constants. */
- #define TRUE 1
- #define FALSE 0
- #define LEN 128
- #define FROM "The Birthday Wizard <wizard@pineapple.bbn.com>"
-
- /* Syntactic sugar. */
- #define WHITE(c) ((c) == ' ' || (c) == '\t')
- #define Fprintf (void)fprintf
- #ifdef lint
- #undef putc
- #endif /* lint */
-
-
- /* Global data. */
- static char *progname;
- static char *ReportTo = NULL;
- static char *Birthdays = "/usr/adm/bdaylist";
- static char *Message = "/usr/adm/bdaymesg";
- static char *sendmail = "/usr/lib/sendmail.sun -t -oi";
- /*static char *sendmail = "/usr/lib/sendmail -t -oi"; */
-
-
- /* Linked in later. */
- extern int errno;
- extern char *optarg;
- extern time_t time();
- extern char *sprintf(); /* Too painful, my ass */
- extern char *strcpy();
- extern char *STRCHR();
- extern char *STRRCHR();
-
-
- /*
- ** Return the text string that corresponds to errno.
- */
- static char *
- strerror(e)
- int e;
- {
- extern int sys_nerr;
- extern char *sys_errlist[];
- static char buff[30];
-
- if (e > 0 && e < sys_nerr)
- return sys_errlist[e];
- (void)sprintf(buff, "Error code %d", e);
- return buff;
- }
-
-
- /*
- ** Send mail to the person.
- */
- static void
- Doit(Name)
- char *Name;
- {
- register FILE *F;
- register FILE *M;
- register int c;
-
- /* Prep the pipe. */
- if ((F = popen(sendmail, "w")) == NULL) {
- Fprintf(stderr, "%s: Doit(%s) failed to popen \"%s\", %s.\n",
- progname, Name, sendmail, strerror(errno));
- return;
- }
-
- /* Write headers. */
- Fprintf(F, "From: %s\n", FROM);
- Fprintf(F, "To: %s\n", Name);
- Fprintf(F, "Subject: Happy birthday!\n");
- Fprintf(F, "\n");
-
- /* Feed in the message. */
- if (M = fopen(Message, "r")) {
- while ((c = getc(M)) != EOF)
- (void)putc(c, F);
- (void)fclose(M);
- }
-
- /* Close up. Done? */
- (void)pclose(F);
- if (ReportTo == NULL)
- return;
-
- /* Report it. */
- if ((F = popen(sendmail, "w")) == NULL) {
- Fprintf(stderr, "%s: Doit(%s) couldn't report, %s.\n",
- progname, Name, strerror(errno));
- return;
- }
-
- /* Write the report. */
- Fprintf(F, "To: %s\n", ReportTo);
- Fprintf(F, "Subject: Greetings sent\n");
- Fprintf(F, "\n");
- Fprintf(F, "Sent a message to %s.\n", Name);
-
- /* Close up. Definitely done. */
- (void)pclose(F);
- }
-
-
- /*
- ** Return pointer to first non-whitespace.
- */
- static char *
- Skip(p)
- register char *p;
- {
- while (*p && WHITE(*p))
- p++;
- return p;
- }
-
-
- /*
- ** Check the list in the file for birthdays.
- */
- static void
- ScanForWork(ThisMonth, ThisDay)
- int ThisMonth;
- int ThisDay;
- {
- register FILE *F;
- register char *p;
- int UserMonth;
- int UserDay;
- char UserName[LEN];
- char buff[LEN];
-
- /* Open the list of birthdays. */
- if ((F = fopen(Birthdays, "r")) == NULL) {
- Fprintf(stderr, "%s: ScanForWork can't open \"%s\" for reading, %s.\n",
- progname, Birthdays, strerror(errno));
- return;
- }
-
- /* Scan all lines. */
- while (fgets(buff, sizeof buff, F)) {
- /* Clobber comment markers and newlines. */
- if (p = STRCHR(buff, '#'))
- *p = '\0';
- if (p = STRCHR(buff, '\n'))
- *p = '\0';
-
- /* Skip blank or comment lines. */
- if (buff[0] == '\0')
- continue;
-
- /* First field is the user name. */
- for (p = buff; *p && !WHITE(*p); p++)
- ;
- *p++ = '\0';
- (void)strcpy(UserName, buff);
- if (UserName[0] == '\0')
- continue;
-
- /* Second field is the month of the user's birthday. */
- p = Skip(p);
- if (*p == '\0')
- continue;
- for (UserMonth = atoi(p); *p && isdigit(*p); p++)
- ;
- if (UserMonth == 0)
- continue;
-
- /* Third field is the date of the user's birthday. */
- p = Skip(p);
- if (*p == '\0')
- continue;
- UserDay = atoi(p);
- if (UserDay == 0)
- continue;
-
- /* Is this one for us? */
- if (UserMonth == ThisMonth && UserDay == ThisDay)
- Doit(UserName);
- }
-
- (void)fclose(F);
- }
-
-
- /*
- ** Make sure the file was specified and is readable.
- */
- static void
- CheckFile(Name, Purpose)
- char *Name;
- char *Purpose;
- {
- FILE *F;
-
- if (Name == NULL) {
- Fprintf(stderr, "%s: No %s file given.\n", progname, Purpose);
- exit(1);
- }
-
- if ((F = fopen(Name, "r")) == NULL) {
- Fprintf(stderr, "%s: Can't open \"%s\" for %s, %s.\n",
- progname, Name, Purpose, strerror(errno));
- exit(1);
- }
-
- (void)fclose(F);
- }
-
-
- main(ac, av)
- int ac;
- char *av[];
- {
- int i;
- time_t t;
- struct tm *tm;
- char *p;
-
- /* Parse JCL. */
- progname = (p = STRRCHR(av[0], '/')) ? p + 1 : av[0];
- while ((i = getopt(ac, av, "b:m:r:s:")) != EOF)
- switch (i) {
- default:
- Fprintf(stderr, "Usage:\n\t%s %s\n",
- progname,
- "[-b list] [-m message] [-s sendcmd] [-r admin]");
- exit(1);
- case 'b':
- Birthdays = optarg;
- break;
- case 'm':
- Message = optarg;
- break;
- case 'r':
- ReportTo = optarg;
- break;
- case 's':
- sendmail = optarg;
- break;
- }
-
- /* Make sure the user gave us readable files. */
- CheckFile(Birthdays, "birthday list");
- CheckFile(Message, "message");
-
- /* What time is it? */
- t = time((time_t *)NULL);
- tm = localtime(&t);
- ScanForWork(tm->tm_mon + 1, tm->tm_mday);
-
- #ifdef WEEKEND_HACK
- /* If it's Friday, check for Saturday and Sunday birthdays. */
- if (tm->tm_wday == 5) {
- /* This is easy/sleazy, we avoid checking for end of month... */
- t += 24 * 60 * 60;
- tm = localtime(&t);
- ScanForWork(tm->tm_mon + 1, tm->tm_mday);
- t += 24 * 60 * 60;
- tm = localtime(&t);
- ScanForWork(tm->tm_mon + 1, tm->tm_mday);
- }
- #endif /* WEEKEND_HACK */
-
- exit(0);
- }
-