00001
00002
00003
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
00018 #define MAIL1 "/usr/bin/mail"
00019 #define MAIL2 "/bin/mail"
00020 #define PASSWD "/etc/passwd"
00021 #define MAX_EXP 4
00022
00023 char *mail;
00024 regexp *exp[MAX_EXP];
00025 int nexp;
00026 char calfile[PATH_MAX];
00027
00028 int rflg;
00029 int mflg;
00030 char *cmd;
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
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++;
00056 else if (strcmp(s, "r") == 0)
00057 rflg++, mflg++;
00058 }
00059
00060 if (mflg) {
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
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
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
00111 int i;
00112 char *t;
00113 static char str[512];
00114
00115 for (i = 0; i < n && *s; s++)
00116 if (*s == ':') i++;
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;
00124 {
00125
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);
00143 r++;
00144 }
00145 return r;
00146 }
00147
00148 void grep(file, user)
00149 char *file, *user;
00150 {
00151 int i;
00152 char command[128];
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
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;
00197 }
00198 return(r);
00199 }
00200
00201 char *date_pat(t)
00202 time_t t;
00203 {
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 {
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 }