[BACK]Return to calendar.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / calendar

Diff for /src/usr.bin/calendar/calendar.c between version 1.1.1.1 and 1.13

version 1.1.1.1, 1995/10/18 08:44:57 version 1.13, 2000/06/30 16:00:11
Line 1 
Line 1 
 /*      $NetBSD: calendar.c,v 1.8 1995/09/02 05:38:38 jtc Exp $ */  /*      $OpenBSD$       */
   
 /*  /*
  * Copyright (c) 1989, 1993, 1994   * Copyright (c) 1989, 1993, 1994
Line 34 
Line 34 
  */   */
   
 #ifndef lint  #ifndef lint
 static char copyright[] =  static const char copyright[] =
 "@(#) Copyright (c) 1989, 1993\n\  "@(#) Copyright (c) 1989, 1993\n\
         The Regents of the University of California.  All rights reserved.\n";          The Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */  #endif /* not lint */
   
 #ifndef lint  #ifndef lint
 #if 0  #if 0
 static char sccsid[] = "@(#)calendar.c  8.4 (Berkeley) 1/7/95";  static const char sccsid[] = "@(#)calendar.c  8.3 (Berkeley) 3/25/94";
   #else
   static char rcsid[] = "$OpenBSD$";
 #endif  #endif
 static char rcsid[] = "$NetBSD: calendar.c,v 1.8 1995/09/02 05:38:38 jtc Exp $";  
 #endif /* not lint */  #endif /* not lint */
   
 #include <sys/param.h>  
 #include <sys/time.h>  
 #include <sys/stat.h>  
 #include <sys/uio.h>  
 #include <sys/wait.h>  
   
 #include <ctype.h>  
 #include <err.h>  #include <err.h>
 #include <errno.h>  #include <errno.h>
 #include <fcntl.h>  #include <locale.h>
 #include <pwd.h>  #include <pwd.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
   #include <time.h>
 #include <tzfile.h>  #include <tzfile.h>
 #include <unistd.h>  #include <unistd.h>
   
 #include "pathnames.h"  #include "pathnames.h"
   #include "calendar.h"
   
 struct passwd *pw;  struct passwd *pw;
 int doall;  int doall = 0;
   time_t f_time = 0;
   
 void     cal __P((void));  int f_dayAfter = 0; /* days after current date */
 void     closecal __P((FILE *));  int f_dayBefore = 0; /* days before current date */
 int      getday __P((char *));  
 int      getfield __P((char *, char **, int *));  
 int      getmonth __P((char *));  
 int      isnow __P((char *));  
 FILE    *opencal __P((void));  
 void     settime __P((void));  
 void     usage __P((void));  
   
   struct specialev spev[NUMEV];
   
 int  int
 main(argc, argv)  main(argc, argv)
         int argc;          int argc;
         char *argv[];          char *argv[];
 {  {
         extern int optind;          int ch, i;
         int ch;  
         char *caldir;          char *caldir;
   
         while ((ch = getopt(argc, argv, "-a")) != EOF)          (void)setlocale(LC_ALL, "");
   
           while ((ch = getopt(argc, argv, "-af:t:A:B:")) != -1)
                 switch (ch) {                  switch (ch) {
                 case '-':               /* backward contemptible */                  case '-':               /* backward contemptible */
                 case 'a':                  case 'a':
                         if (getuid()) {                          if (getuid())
                                 errno = EPERM;                                  errx(1, "%s", strerror(EPERM));
                                 err(1, NULL);  
                         }  
                         doall = 1;                          doall = 1;
                         break;                          break;
                 case '?':  
                   case 'f': /* other calendar file */
                           calendarFile = optarg;
                           break;
   
                   case 't': /* other date, undocumented, for tests */
                           if ((f_time = Mktime(optarg)) <= 0)
                                   errx(1, "specified date is outside allowed range");
                           break;
   
                   case 'A': /* days after current date */
                           f_dayAfter = atoi(optarg);
                           break;
   
                   case 'B': /* days before current date */
                           f_dayBefore = atoi(optarg);
                           break;
   
                 default:                  default:
                         usage();                          usage();
                 }                  }
Line 107 
Line 115 
         if (argc)          if (argc)
                 usage();                  usage();
   
         settime();          /* use current time */
         if (doall)          if (f_time <= 0)
               (void)time(&f_time);
   
           if (f_dayBefore) {
                   /* Move back in time and only look forwards */
                   f_dayAfter += f_dayBefore;
                   f_time -= SECSPERDAY * f_dayBefore;
                   f_dayBefore = 0;
           }
           settime(&f_time);
   
           if (doall) {
                 while ((pw = getpwent()) != NULL) {                  while ((pw = getpwent()) != NULL) {
                           (void)setlocale(LC_ALL, "");
                         (void)setegid(pw->pw_gid);                          (void)setegid(pw->pw_gid);
                           (void)initgroups(pw->pw_name, pw->pw_gid);
                         (void)seteuid(pw->pw_uid);                          (void)seteuid(pw->pw_uid);
                         if (!chdir(pw->pw_dir))                          if (!chdir(pw->pw_dir)) {
                                 cal();                                  cal();
                                   /* Keep user settings from propogating */
                                   for (i = 0; i < NUMEV; i++)
                                           if (spev[i].uname != NULL)
                                                   free(spev[i].uname);
                           }
                         (void)seteuid(0);                          (void)seteuid(0);
                 }                  }
           }
         else if ((caldir = getenv("CALENDAR_DIR")) != NULL) {          else if ((caldir = getenv("CALENDAR_DIR")) != NULL) {
                         if(!chdir(caldir))                  if(!chdir(caldir))
                                 cal();                          cal();
         } else          } else
                 cal();                  cal();
   
         exit(0);          exit(0);
 }  }
   
 void  
 cal()  
 {  
         register int printing;  
         register char *p;  
         FILE *fp;  
         int ch;  
         char buf[2048 + 1];  
   
         if ((fp = opencal()) == NULL)  
                 return;  
         for (printing = 0; fgets(buf, sizeof(buf), stdin) != NULL;) {  
                 if ((p = strchr(buf, '\n')) != NULL)  
                         *p = '\0';  
                 else  
                         while ((ch = getchar()) != '\n' && ch != EOF);  
                 if (buf[0] == '\0')  
                         continue;  
                 if (buf[0] != '\t')  
                         printing = isnow(buf) ? 1 : 0;  
                 if (printing)  
                         (void)fprintf(fp, "%s\n", buf);  
         }  
         closecal(fp);  
 }  
   
 struct iovec header[] = {  
         "From: ", 6,  
         NULL, 0,  
         " (Reminder Service)\nTo: ", 24,  
         NULL, 0,  
         "\nSubject: ", 10,  
         NULL, 0,  
         "'s Calendar\nPrecedence: bulk\n\n",  30,  
 };  
   
 /* 1-based month, 0-based days, cumulative */  
 int daytab[][14] = {  
         0, -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364,  
         0, -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365,  
 };  
 struct tm *tp;  
 int *cumdays, offset, yrdays;  
 char dayname[10];  
   
 void  void
 settime()  
 {  
         time_t now;  
   
         (void)time(&now);  
         tp = localtime(&now);  
         if (isleap(tp->tm_year + 1900)) {  
                 yrdays = DAYSPERLYEAR;  
                 cumdays = daytab[1];  
         } else {  
                 yrdays = DAYSPERNYEAR;  
                 cumdays = daytab[0];  
         }  
         /* Friday displays Monday's events */  
         offset = tp->tm_wday == 5 ? 3 : 1;  
         header[5].iov_base = dayname;  
         header[5].iov_len = strftime(dayname, sizeof(dayname), "%A", tp);  
 }  
   
 /*  
  * Possible date formats include any combination of:  
  *      3-charmonth                     (January, Jan, Jan)  
  *      3-charweekday                   (Friday, Monday, mon.)  
  *      numeric month or day            (1, 2, 04)  
  *  
  * Any character may separate them, or they may not be separated.  Any line,  
  * following a line that is matched, that starts with "whitespace", is shown  
  * along with the matched line.  
  */  
 int  
 isnow(endp)  
         char *endp;  
 {  
         int day, flags, month, v1, v2;  
   
 #define F_ISMONTH       0x01  
 #define F_ISDAY         0x02  
         flags = 0;  
         /* didn't recognize anything, skip it */  
         if (!(v1 = getfield(endp, &endp, &flags)))  
                 return (0);  
         if (flags & F_ISDAY || v1 > 12) {  
                 /* found a day */  
                 day = v1;  
                 month = tp->tm_mon + 1;  
         } else if (flags & F_ISMONTH) {  
                 month = v1;  
                 /* if no recognizable day, assume the first */  
                 if (!(day = getfield(endp, &endp, &flags)))  
                         day = 1;  
         } else {  
                 v2 = getfield(endp, &endp, &flags);  
                 if (flags & F_ISMONTH) {  
                         day = v1;  
                         month = v2;  
                 } else {  
                         /* F_ISDAY set, v2 > 12, or no way to tell */  
                         month = v1;  
                         /* if no recognizable day, assume the first */  
                         day = v2 ? v2 : 1;  
                 }  
         }  
         if (flags & F_ISDAY)  
                 day = tp->tm_mday + (((day - 1) - tp->tm_wday + 7) % 7);  
         day = cumdays[month] + day;  
   
         /* if today or today + offset days */  
         if (day >= tp->tm_yday && day <= tp->tm_yday + offset)  
                 return (1);  
         /* if number of days left in this year + days to event in next year */  
         if (yrdays - tp->tm_yday + day <= offset)  
                 return (1);  
         return (0);  
 }  
   
 int  
 getfield(p, endp, flags)  
         char *p, **endp;  
         int *flags;  
 {  
         int val;  
         char *start, savech;  
   
         for (; !isdigit(*p) && !isalpha(*p) && *p != '*'; ++p);  
         if (*p == '*') {                        /* `*' is current month */  
                 *flags |= F_ISMONTH;  
                 *endp = p+1;  
                 return (tp->tm_mon + 1);  
         }  
         if (isdigit(*p)) {  
                 val = strtol(p, &p, 10);        /* if 0, it's failure */  
                 for (; !isdigit(*p) && !isalpha(*p) && *p != '*'; ++p);  
                 *endp = p;  
                 return (val);  
         }  
         for (start = p; isalpha(*++p););  
         savech = *p;  
         *p = '\0';  
         if ((val = getmonth(start)) != 0)  
                 *flags |= F_ISMONTH;  
         else if ((val = getday(start)) != 0)  
                 *flags |= F_ISDAY;  
         else {  
                 *p = savech;  
                 return (0);  
         }  
         for (*p = savech; !isdigit(*p) && !isalpha(*p) && *p != '*'; ++p);  
         *endp = p;  
         return (val);  
 }  
   
 char path[MAXPATHLEN + 1];  
   
 FILE *  
 opencal()  
 {  
         int fd, pdes[2];  
   
         /* open up calendar file as stdin */  
         if (!freopen("calendar", "r", stdin)) {  
                 if (doall)  
                         return (NULL);  
                 errx(1, "no calendar file.");  
         }  
         if (pipe(pdes) < 0)  
                 return (NULL);  
         switch (vfork()) {  
         case -1:                        /* error */  
                 (void)close(pdes[0]);  
                 (void)close(pdes[1]);  
                 return (NULL);  
         case 0:  
                 /* child -- stdin already setup, set stdout to pipe input */  
                 if (pdes[1] != STDOUT_FILENO) {  
                         (void)dup2(pdes[1], STDOUT_FILENO);  
                         (void)close(pdes[1]);  
                 }  
                 (void)close(pdes[0]);  
                 execl(_PATH_CPP, "cpp", "-P", "-I.", _PATH_INCLUDE, NULL);  
                 warn("execl: %s", _PATH_CPP);  
                 _exit(1);  
         }  
         /* parent -- set stdin to pipe output */  
         (void)dup2(pdes[0], STDIN_FILENO);  
         (void)close(pdes[0]);  
         (void)close(pdes[1]);  
   
         /* not reading all calendar files, just set output to stdout */  
         if (!doall)  
                 return (stdout);  
   
         /* set output to a temporary file, so if no output don't send mail */  
         (void)snprintf(path, sizeof(path), "%s/_calXXXXXX", _PATH_TMP);  
         if ((fd = mkstemp(path)) < 0)  
                 return (NULL);  
         return (fdopen(fd, "w+"));  
 }  
   
 void  
 closecal(fp)  
         FILE *fp;  
 {  
         struct stat sbuf;  
         int nread, pdes[2], status;  
         char buf[1024];  
   
         if (!doall)  
                 return;  
   
         (void)rewind(fp);  
         if (fstat(fileno(fp), &sbuf) || !sbuf.st_size)  
                 goto done;  
         if (pipe(pdes) < 0)  
                 goto done;  
         switch (vfork()) {  
         case -1:                        /* error */  
                 (void)close(pdes[0]);  
                 (void)close(pdes[1]);  
                 goto done;  
         case 0:  
                 /* child -- set stdin to pipe output */  
                 if (pdes[0] != STDIN_FILENO) {  
                         (void)dup2(pdes[0], STDIN_FILENO);  
                         (void)close(pdes[0]);  
                 }  
                 (void)close(pdes[1]);  
                 execl(_PATH_SENDMAIL, "sendmail", "-i", "-t", "-F",  
                     "\"Reminder Service\"", "-f", "root", NULL);  
                 warn("execl: %s", _PATH_SENDMAIL);  
                 _exit(1);  
         }  
         /* parent -- write to pipe input */  
         (void)close(pdes[0]);  
   
         header[1].iov_base = header[3].iov_base = pw->pw_name;  
         header[1].iov_len = header[3].iov_len = strlen(pw->pw_name);  
         writev(pdes[1], header, 7);  
         while ((nread = read(fileno(fp), buf, sizeof(buf))) > 0)  
                 (void)write(pdes[1], buf, nread);  
         (void)close(pdes[1]);  
 done:   (void)fclose(fp);  
         (void)unlink(path);  
         while (wait(&status) >= 0);  
 }  
   
 static char *months[] = {  
         "jan", "feb", "mar", "apr", "may", "jun",  
         "jul", "aug", "sep", "oct", "nov", "dec", NULL,  
 };  
   
 int  
 getmonth(s)  
         register char *s;  
 {  
         register char **p;  
   
         for (p = months; *p; ++p)  
                 if (!strncasecmp(s, *p, 3))  
                         return ((p - months) + 1);  
         return (0);  
 }  
   
 static char *days[] = {  
         "sun", "mon", "tue", "wed", "thu", "fri", "sat", NULL,  
 };  
   
 int  
 getday(s)  
         register char *s;  
 {  
         register char **p;  
   
         for (p = days; *p; ++p)  
                 if (!strncasecmp(s, *p, 3))  
                         return ((p - days) + 1);  
         return (0);  
 }  
   
 void  
 usage()  usage()
 {  {
         (void)fprintf(stderr, "usage: calendar [-a]\n");          (void)fprintf(stderr,
               "usage: calendar [-a] [-A days] [-B days] [-f calendarfile] [-t [[[yy]yy][mm]]dd]\n");
         exit(1);          exit(1);
 }  }

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.13