1 /* calendar - reminder service Authors: S. & K. Hirabayashi */
3 /* Permission is hereby granted for nonprofit use. */
17 /* Change these two lines for your system needs. */
18 #define MAIL1 "/usr/bin/mail"
19 #define MAIL2 "/bin/mail"
20 #define PASSWD "/etc/passwd" /* system password file */
21 #define MAX_EXP 4 /* see date_exp() function */
23 char *mail
; /* mail command path ("/bin/mail" etc) */
24 regexp
*exp
[MAX_EXP
]; /* date expressions */
25 int nexp
; /* # of the date expressions */
26 char calfile
[PATH_MAX
]; /* calendar file for the user */
28 int rflg
; /* consult aged 'calendar' file and touch */
29 int mflg
; /* mail (multi user) service */
30 char *cmd
; /* the name of this command */
33 _PROTOTYPE(int main
, (int argc
, char **argv
));
34 _PROTOTYPE(void calendar
, (void));
35 _PROTOTYPE(char *getstr
, (char *s
, int n
));
36 _PROTOTYPE(int newaccess
, (char *file
));
37 _PROTOTYPE(void grep
, (char *file
, char *user
));
38 _PROTOTYPE(int date_exp
, (void));
39 _PROTOTYPE(char *date_pat
, (time_t t
));
41 _PROTOTYPE(void regerror, (char *s));
43 _PROTOTYPE(void error
, (char *s
, char *t
));
52 while (--argc
> 0 && (*++argv
)[0] == '-') {
55 mflg
++; /* mail service */
56 else if (strcmp(s
, "r") == 0)
60 if (mflg
) { /* check mailing agent */
61 if (access(MAIL1
, X_OK
) == 0)
63 else if (access(MAIL2
, X_OK
) == 0)
66 error("cannot find %s", MAIL1
);
85 if ((fp
= fopen(PASSWD
, "r")) == (FILE *) NULL
)
86 error("cannot open %s", PASSWD
);
88 while (fgets(buf
, BUFSIZ
, fp
) != (char *) NULL
) {
89 for (i
= 0, s
= buf
; *s
&& *s
!= '\n'; s
++)
92 if (i
!= 6) error("illegal '/etc/passwd' format: %s", buf
);
94 /* Calendar file = ${HOME}/calendar */
95 sprintf(calfile
, "%s/%s", getstr(buf
, 5), "calendar");
97 if ((access(calfile
, R_OK
) != 0) || (rflg
&& !newaccess(calfile
)))
100 grep(calfile
, getstr(buf
, 0));
110 /* Returns the string value of the n-th field in the record (s) */
113 static char str
[512];
115 for (i
= 0; i
< n
&& *s
; s
++)
116 if (*s
== ':') i
++; /* field separator */
117 for (i
= 0, t
= str
; *s
&& *s
!= ':' && i
< 511; i
++) *t
++ = *s
++;
123 char *file
; /* file name */
125 /* Check whether the file has been touched today. */
131 char newdate
[8], olddate
[8];
134 tm
= localtime(&clk
);
135 sprintf(newdate
, "%02d%02d%02d", tm
->tm_year
, tm
->tm_mon
+ 1, tm
->tm_mday
);
137 if (stat(file
, &stbuf
) == -1) error("cannot stat %s", file
);
138 tm
= localtime(&stbuf
.st_mtime
);
139 sprintf(olddate
, "%02d%02d%02d", tm
->tm_year
, tm
->tm_mon
+ 1, tm
->tm_mday
);
141 if (strcmp(newdate
, olddate
) != 0) {
142 utime(file
, NULL
); /* touch */
148 void grep(file
, user
)
150 { /* grep 'exp[]' [| mail user] */
152 char command
[128]; /* mail command */
155 if ((ifp
= fopen(file
, "r")) == (FILE *) NULL
)
156 error("cannot open %s", file
);
158 sprintf(command
, "%s %s", mail
, user
);
164 while (fgets(buf
, BUFSIZ
, ifp
) != (char *) NULL
) {
165 for (i
= 0; i
< nexp
; i
++) {
166 if (regexec(exp
[i
], buf
, 1)) {
167 if ((ofp
== (FILE *) NULL
) &&
168 (ofp
= popen(command
, "w")) == (FILE *) NULL
)
169 error("cannot popen %s", mail
);
179 else if (ofp
!= (FILE *) NULL
)
185 /* Set compiled regular expressions into the exp[] array. */
186 static int n
[] = {2, 2, 2, 2, 2, 4, 3};
191 wday
= localtime(&clk
)->tm_wday
;
193 if (r
> MAX_EXP
) error("too many date expressions", "");
194 for (i
= 0; i
< r
; i
++) {
195 exp
[i
] = regcomp(date_pat(clk
));
196 clk
+= 60 * 60 * 24L; /* 24 hours */
203 { /* returns date expression for the time (t) */
204 static char *month
[] = {
205 "[Jj]an", "[Ff]eb", "[Mm]ar", "[Aa]pr", "[Mm]ay", "[Jj]un",
206 "[Jj]ul", "[Aa]ug", "[Ss]ep", "[Oo]ct", "[Nn]ov", "[Dd]ec"
208 static char str
[512];
213 "(^|[ \t(,;])(((%s[^ \t]*[ \t])|0*%d/|\\*/)(0*%d|\\*))([^0123456789]|$)",
214 month
[tm
->tm_mon
], tm
->tm_mon
+ 1, tm
->tm_mday
);
221 { /* regcomp() needs this */
222 error("REGULAR EXPRESSION ERROR (%s)", (char *) s
);
228 fprintf(stderr
, "%s: ", cmd
);
229 fprintf(stderr
, s
, t
);
230 fprintf(stderr
, "\n");