calendar.c

Go to the documentation of this file.
00001 /* calendar - reminder service          Authors: S. & K. Hirabayashi */
00002 
00003 /* Permission is hereby granted for nonprofit use. */
00004 
00005 #include <sys/types.h>
00006 #include <sys/stat.h>
00007 #include <time.h>
00008 #include <regexp.h>
00009 #include <limits.h>
00010 #include <stdlib.h>
00011 #include <string.h>
00012 #include <termcap.h>
00013 #include <unistd.h>
00014 #include <utime.h>
00015 #include <stdio.h>
00016 
00017 /* Change these two lines for your system needs. */
00018 #define MAIL1   "/usr/bin/mail"
00019 #define MAIL2   "/bin/mail"
00020 #define PASSWD  "/etc/passwd"   /* system password file */
00021 #define MAX_EXP         4       /* see date_exp() function */
00022 
00023 char *mail;                     /* mail command path ("/bin/mail" etc) */
00024 regexp *exp[MAX_EXP];           /* date expressions */
00025 int nexp;                       /* # of the date expressions */
00026 char calfile[PATH_MAX];         /* calendar file for the user */
00027 
00028 int rflg;                       /* consult aged 'calendar' file and touch */
00029 int mflg;                       /* mail (multi user) service */
00030 char *cmd;                      /* the name of this command */
00031 char buf[BUFSIZ];
00032 
00033 _PROTOTYPE(int main, (int argc, char **argv));
00034 _PROTOTYPE(void calendar, (void));
00035 _PROTOTYPE(char *getstr, (char *s, int n));
00036 _PROTOTYPE(int newaccess, (char *file));
00037 _PROTOTYPE(void grep, (char *file, char *user));
00038 _PROTOTYPE(int date_exp, (void));
00039 _PROTOTYPE(char *date_pat, (time_t t));
00040 /*
00041 _PROTOTYPE(void regerror, (char *s));
00042 */
00043 _PROTOTYPE(void error, (char *s, char *t));
00044 
00045 int main(argc, argv)
00046 int argc;
00047 char **argv;
00048 {
00049   char *s;
00050 
00051   cmd = *argv;
00052   while (--argc > 0 && (*++argv)[0] == '-') {
00053         s = argv[0] + 1;
00054         if (*s == '\0')
00055                 mflg++;         /* mail service */
00056         else if (strcmp(s, "r") == 0)
00057                 rflg++, mflg++;
00058   }
00059 
00060   if (mflg) {                   /* check mailing agent */
00061         if (access(MAIL1, X_OK) == 0)
00062                 mail = MAIL1;
00063         else if (access(MAIL2, X_OK) == 0)
00064                 mail = MAIL2;
00065         else
00066                 error("cannot find %s", MAIL1);
00067   }
00068   nexp = date_exp();
00069   calendar();
00070   exit(0);
00071 }
00072 
00073 void calendar()
00074 {
00075   int i;
00076   char *s;
00077   FILE *fp;
00078 
00079   if (!mflg) {
00080         grep("calendar", "");
00081         return;
00082   }
00083 
00084   /* Mail sevice */
00085   if ((fp = fopen(PASSWD, "r")) == (FILE *) NULL)
00086         error("cannot open %s", PASSWD);
00087 
00088   while (fgets(buf, BUFSIZ, fp) != (char *) NULL) {
00089         for (i = 0, s = buf; *s && *s != '\n'; s++)
00090                 if (*s == ':') i++;
00091         *s = '\0';
00092         if (i != 6) error("illegal '/etc/passwd' format: %s", buf);
00093 
00094         /* Calendar file = ${HOME}/calendar */
00095         sprintf(calfile, "%s/%s", getstr(buf, 5), "calendar");
00096 
00097         if ((access(calfile, R_OK) != 0) || (rflg && !newaccess(calfile)))
00098                 continue;
00099 
00100         grep(calfile, getstr(buf, 0));
00101   }
00102 
00103   fclose(fp);
00104 }
00105 
00106 char *getstr(s, n)
00107 char *s;
00108 int n;
00109 {
00110 /* Returns the string value of the n-th field in the record (s) */
00111   int i;
00112   char *t;
00113   static char str[512];
00114 
00115   for (i = 0; i < n && *s; s++)
00116         if (*s == ':') i++;             /* field separator */
00117   for (i = 0, t = str; *s && *s != ':' && i < 511; i++) *t++ = *s++;
00118   *t = '\0';
00119   return str;
00120 }
00121 
00122 int newaccess(file)
00123 char *file;                     /* file name */
00124 {
00125 /* Check whether the file has been touched today. */
00126 
00127   int r = 0;
00128   struct tm *tm;
00129   struct stat stbuf;
00130   time_t clk;
00131   char newdate[8], olddate[8];
00132 
00133   time(&clk);
00134   tm = localtime(&clk);
00135   sprintf(newdate, "%02d%02d%02d", tm->tm_year, tm->tm_mon + 1, tm->tm_mday);
00136 
00137   if (stat(file, &stbuf) == -1) error("cannot stat %s", file);
00138   tm = localtime(&stbuf.st_mtime);
00139   sprintf(olddate, "%02d%02d%02d", tm->tm_year, tm->tm_mon + 1, tm->tm_mday);
00140 
00141   if (strcmp(newdate, olddate) != 0) {
00142         utime(file, NULL);      /* touch */
00143         r++;
00144   }
00145   return r;
00146 }
00147 
00148 void grep(file, user)
00149 char *file, *user;
00150 {                               /* grep 'exp[]' [| mail user] */
00151   int i;
00152   char command[128];            /* mail command */
00153   FILE *ifp, *ofp;
00154 
00155   if ((ifp = fopen(file, "r")) == (FILE *) NULL)
00156         error("cannot open %s", file);
00157   if (*user != '\0') {
00158         sprintf(command, "%s %s", mail, user);
00159         ofp = (FILE *) NULL;
00160   } else {
00161         ofp = stdout;
00162   }
00163 
00164   while (fgets(buf, BUFSIZ, ifp) != (char *) NULL) {
00165         for (i = 0; i < nexp; i++) {
00166                 if (regexec(exp[i], buf, 1)) {
00167                         if ((ofp == (FILE *) NULL) &&
00168                                   (ofp = popen(command, "w")) == (FILE *) NULL)
00169                                 error("cannot popen %s", mail);
00170                         fputs(buf, ofp);
00171                         break;
00172                 }
00173         }
00174   }
00175 
00176   fclose(ifp);
00177   if (ofp == stdout)
00178         fflush(ofp);
00179   else if (ofp != (FILE *) NULL)
00180         pclose(ofp);
00181 }
00182 
00183 int date_exp()
00184 {
00185 /* Set compiled regular expressions into the exp[] array. */
00186   static int n[] = {2, 2, 2, 2, 2, 4, 3};
00187   int i, r, wday;
00188   time_t clk;
00189 
00190   time(&clk);
00191   wday = localtime(&clk)->tm_wday;
00192   r = n[wday];
00193   if (r > MAX_EXP) error("too many date expressions", "");
00194   for (i = 0; i < r; i++) {
00195         exp[i] = regcomp(date_pat(clk));
00196         clk += 60 * 60 * 24L;   /* 24 hours */
00197   }
00198   return(r);
00199 }
00200 
00201 char *date_pat(t)
00202 time_t t;
00203 {                               /* returns date expression for the time (t) */
00204   static char *month[] = {
00205          "[Jj]an", "[Ff]eb", "[Mm]ar", "[Aa]pr", "[Mm]ay", "[Jj]un",
00206           "[Jj]ul", "[Aa]ug", "[Ss]ep", "[Oo]ct", "[Nn]ov", "[Dd]ec"
00207   };
00208   static char str[512];
00209   struct tm *tm;
00210 
00211   tm = localtime(&t);
00212   sprintf(str,
00213         "(^|[ \t(,;])(((%s[^ \t]*[ \t])|0*%d/|\\*/)(0*%d|\\*))([^0123456789]|$)",
00214         month[tm->tm_mon], tm->tm_mon + 1, tm->tm_mday);
00215 
00216   return str;
00217 }
00218 
00219 void regerror(s)
00220 const char *s;
00221 {                               /* regcomp() needs this */
00222   error("REGULAR EXPRESSION ERROR (%s)", (char *) s);
00223 }
00224 
00225 void error(s, t)
00226 char *s, *t;
00227 {
00228   fprintf(stderr, "%s: ", cmd);
00229   fprintf(stderr, s, t);
00230   fprintf(stderr, "\n");
00231   exit(1);
00232 }

Generated on Fri Apr 14 22:57:04 2006 for minix by  doxygen 1.4.6