|
|
1.1 ! root 1: /* ! 2: * calendar ! 3: * Reminder utililty: read calendar files and lines with dates matching ! 4: * the current date or the date specified in the option string. ! 5: */ ! 6: ! 7: #include <stdio.h> ! 8: #include <sys/types.h> ! 9: #include <time.h> ! 10: #include <sys/timeb.h> ! 11: #include <string.h> ! 12: #include <ctype.h> ! 13: ! 14: char *message = ! 15: "Usage: calendar [ -a ] [ -ffile ]... [ -d[date] ] [ -w[date] ] [ -m[month] ]\n\ ! 16: Options:\n\ ! 17: -a Search calendars of all users and send mail.\n\ ! 18: -ffile Search each \"file\" in order given.\n\ ! 19: -d[date] Print all entries matching \"date\".\n\ ! 20: -w[date] Print entries in the week beginning with \"date\".\n\ ! 21: -m[month] Print entries in the given \"month\".\n\ ! 22: The default calendar is $HOME/.calendar. The default date is today.\n\ ! 23: "; ! 24: ! 25: char *argv0; ! 26: int all = 0; ! 27: int wday; ! 28: int advance; ! 29: char CurLine[512]; ! 30: char *CurLinep; ! 31: char *getenv(); ! 32: ! 33: enum {NONE, DAY, WEEK, MONTH} mflag; ! 34: ! 35: #define CALFILE "/.calendar" ! 36: ! 37: main(argc, argv) ! 38: int argc; ! 39: char *argv[]; ! 40: { ! 41: register int arg = 1; ! 42: register char *cp; ! 43: char *thisline; ! 44: char *matchstr; ! 45: char *filename[10]; ! 46: FILE *fp[10]; ! 47: int matchdate; ! 48: int foundfiles; ! 49: int nfiles; ! 50: int thismonth, thisday, thisyear; ! 51: int thisdate; ! 52: char *atsign; ! 53: ! 54: argv0 = argv[0]; ! 55: mflag = NONE; /* Default to no match */ ! 56: for (arg = 1; arg < argc; arg++) { /* Read option string */ ! 57: cp = argv[arg]; ! 58: sw: switch (*cp) { ! 59: case '-': ! 60: cp++; ! 61: goto sw; ! 62: case 'a': ! 63: all = 1; ! 64: break; ! 65: case 'f': ! 66: filename[arg-1] = ++cp; ! 67: nfiles++; ! 68: continue; ! 69: case 'd': ! 70: matchstr = ++cp; ! 71: mflag = DAY; ! 72: continue; ! 73: case 'w': ! 74: matchstr = ++cp; ! 75: mflag = WEEK; ! 76: continue; ! 77: case 'm': ! 78: matchstr = ++cp; ! 79: mflag = MONTH; ! 80: continue; ! 81: default: ! 82: fprintf(stderr, "%s: unrecognized option '%c'\n", argv0, *cp); ! 83: usage(); ! 84: } ! 85: } ! 86: if (all) ! 87: doall(); ! 88: /* ! 89: * Open files. ! 90: */ ! 91: if (nfiles) { ! 92: for (arg = 0; arg < nfiles; arg++ ) { ! 93: if ((fp[arg] = fopen(filename[arg], "r")) == NULL) ! 94: fprintf(stderr, "cannot open file %s\n", filename[arg]); ! 95: else ! 96: foundfiles++; ! 97: } ! 98: if (!foundfiles) ! 99: fatal("cannot open any files specified"); ! 100: } else { ! 101: char *hp; ! 102: ! 103: nfiles = 1; ! 104: if ((hp = getenv("HOME")) == NULL) ! 105: fatal("can't find my way back HOME"); ! 106: filename[0] = malloc(strlen(hp) + strlen(CALFILE) + 1); ! 107: if (filename[0] == NULL) ! 108: fatal("out of memory"); ! 109: strcpy(filename[0], hp); ! 110: strcat(filename[0], CALFILE); ! 111: if ((fp[0] = fopen(filename[0], "r")) == NULL) ! 112: fatal("cannot open file $HOME/.calendar"); ! 113: } ! 114: /* ! 115: * Find match condition from options or current date ! 116: */ ! 117: switch (mflag) { ! 118: case NONE: ! 119: matchdate = current(0); ! 120: break; ! 121: case DAY: ! 122: case WEEK: ! 123: if (*matchstr == '\0') ! 124: matchdate = current(0); ! 125: else { ! 126: strncpy(CurLine, matchstr, sizeof(CurLine)); ! 127: CurLinep = &CurLine[0]; ! 128: if ((thismonth = findmon()) == -1) ! 129: fatal("invalid month in match date"); ! 130: if ((thisday = findday()) == -1) ! 131: fatal("invalid day in match date"); ! 132: if ((thisyear = findyear()) == -1) ! 133: thisyear = current(1); ! 134: matchdate = date(thisday, thismonth, thisyear); ! 135: } ! 136: break; ! 137: case MONTH: ! 138: if (*matchstr == '\0') ! 139: matchdate = current(2); ! 140: else { ! 141: strncpy(CurLine, matchstr, sizeof(CurLine)); ! 142: CurLinep = &CurLine[0]; ! 143: if ((matchdate = findmon()) == -1) ! 144: fatal("invalid month in match date"); ! 145: } ! 146: break; ! 147: } ! 148: /* ! 149: * Read the calendar files, print matched lines. ! 150: */ ! 151: for (arg = 0; arg < nfiles; arg++) { ! 152: if (fp[arg] == NULL) ! 153: continue; ! 154: while ((thisline = fgets(CurLine,sizeof(CurLine),fp[arg]))!=NULL) { ! 155: CurLinep = &CurLine[0]; ! 156: advance = 0; ! 157: if ((atsign = strchr(CurLinep, '@')) != NULL) ! 158: advance = atoi(atsign + 1); ! 159: if ((thismonth = findmon()) == -1) ! 160: thismonth = 0; ! 161: if ((thisday = findday()) == -1) ! 162: thisday = 0; ! 163: if ((thisyear = findyear()) == -1) ! 164: thisyear = current(1); ! 165: thisdate = date(thisday, thismonth, thisyear); ! 166: if (thisdate >= matchdate && ! 167: thisdate <= matchdate + advance) ! 168: printf("%s", thisline); ! 169: else switch (mflag) { ! 170: case NONE: ! 171: if (wday == 6) ! 172: if (thisdate == matchdate || ! 173: thisdate == matchdate + 1 || ! 174: thisdate == matchdate + 2 || ! 175: thisdate == matchdate + 3) ! 176: printf("%s", thisline); ! 177: if (wday == 7) ! 178: if (thisdate == matchdate || ! 179: thisdate == matchdate + 1 || ! 180: thisdate == matchdate + 2) ! 181: printf("%s", thisline); ! 182: if (0 <= wday && wday < 6) ! 183: if (thisdate == matchdate || ! 184: thisdate == matchdate + 1) ! 185: printf("%s", thisline); ! 186: break; ! 187: case DAY: ! 188: if (thisdate == matchdate) ! 189: printf("%s", thisline); ! 190: break; ! 191: case WEEK: ! 192: if (matchdate <= thisdate && ! 193: thisdate <= matchdate+7) ! 194: printf("%s", thisline); ! 195: break; ! 196: case MONTH: ! 197: if (thismonth == matchdate) ! 198: printf("%s", thisline); ! 199: break; ! 200: } ! 201: thisline = NULL; ! 202: } ! 203: } ! 204: } ! 205: ! 206: usage() ! 207: { ! 208: fprintf(stderr, "%s", message); ! 209: exit(1); ! 210: } ! 211: ! 212: fatal(str) ! 213: char *str; ! 214: { ! 215: fprintf(stderr, "%s: %r\n", argv0, &str); ! 216: exit(1); ! 217: } ! 218: ! 219: int ! 220: findmon() ! 221: { ! 222: register int i; ! 223: register int month; ! 224: register char *t; ! 225: static char tbuf[100]; ! 226: static char *mon[12] = { ! 227: "[Jj][Aa][Nn][Uu. :1-9]", ! 228: "[Ff][Ee][Bb][Rr. :1-9]", ! 229: "[Mm][Aa][Rr][Cc. :1-9]", ! 230: "[Aa][Pp][Rr][Ii. :1-9]", ! 231: "[Mm][Aa][Yy][ :1-9]", ! 232: "[Jj][Uu][Nn][Ee. :1-9]", ! 233: "[Jj][Uu][Ll][Yy. :1-9]", ! 234: "[Aa][Uu][Gg][Uu. :1-9]", ! 235: "[Ss][Ee][Pp][Tt. :1-9]", ! 236: "[Oo][Cc][Tt][Oo. :1-9]", ! 237: "[Nn][Oo][Vv][Ee. :1-9]", ! 238: "[Dd][Ee][Cc][Ee. :1-9]" ! 239: }; ! 240: ! 241: t = &tbuf[0]; ! 242: for (i = 0; ! 243: ((*t = CurLinep[i]) != ':') && (*t != '\n') && (*t != '\0'); ! 244: i++) ! 245: ++t; ! 246: t[1] = '\0'; ! 247: t = &tbuf[0]; ! 248: ! 249: month = 0; ! 250: for (i = 0; i <= 11; i++) /* Look for month in word form. */ ! 251: if (pnmatch(t, mon[i], 1)) { ! 252: month = i+1; ! 253: break; ! 254: } ! 255: if (month == 0) { /* Month must be in numerical form */ ! 256: for (; *t && !isdigit(*t); t++) ! 257: CurLinep++; ! 258: while (*t && isdigit(*t)) { ! 259: month = 10*month + *t++ - '0'; ! 260: CurLinep++; ! 261: } ! 262: CurLinep++; /* Truncate global line pointer */ ! 263: } ! 264: if (month == 0 || month > 12) ! 265: month = -1; ! 266: return (month); ! 267: } ! 268: ! 269: findday() ! 270: { ! 271: register int day = 0; ! 272: ! 273: for (; *CurLinep && !isdigit(*CurLinep); CurLinep++); ! 274: ; ! 275: while (*CurLinep && isdigit(*CurLinep)) ! 276: day = 10*day + *CurLinep++ - '0'; ! 277: if (day == 0 || day > 31) /* Invalid day of the month */ ! 278: day = -1; ! 279: return (day); ! 280: } ! 281: ! 282: findyear() ! 283: { ! 284: register int c; ! 285: register int year; ! 286: ! 287: year = 0; ! 288: for (; (c = *CurLinep) != '\0' && !isdigit(c); CurLinep++) ! 289: if (c == '\n' || c == ':' || c == '\0') ! 290: break; ! 291: while (isdigit(*CurLinep)) ! 292: year = 10*year + *CurLinep++ -'0'; ! 293: if (year >= 83 && year <= 99) ! 294: year += 1900; ! 295: else if (year < 1990 || year > 3000) ! 296: year = -1; ! 297: return(year); ! 298: } ! 299: ! 300: int ! 301: current(opt) ! 302: int opt; ! 303: { ! 304: struct tm *stimep; ! 305: time_t timep; ! 306: int retval; ! 307: ! 308: time(&timep); ! 309: stimep = localtime(&timep); ! 310: switch (opt) { ! 311: case 0: ! 312: retval = date(stimep->tm_mday, stimep->tm_mon+1, stimep ! 313: ->tm_year+1900); ! 314: wday = stimep->tm_wday; ! 315: break; ! 316: case 1: ! 317: retval = stimep->tm_year+1900; ! 318: break; ! 319: case 2: ! 320: retval = stimep->tm_mon+1; ! 321: break; ! 322: default: ! 323: fatal("bad opt to current"); ! 324: } ! 325: return (retval); ! 326: } ! 327: ! 328: int ! 329: date(day, month, year) ! 330: int day, month, year; ! 331: { ! 332: int date=0; ! 333: register int i; ! 334: static int m[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; ! 335: ! 336: if (year == 0) ! 337: year = current(1); ! 338: for (i = 0; i < month-1; i++) ! 339: date += m[i]; ! 340: date += day; ! 341: if ((year%4) == 0 && month > 2 && (year%100) != 0) ! 342: date++; ! 343: for (i = 1984; i < year; i++) { ! 344: if ((i%4) == 0) ! 345: date += 366; ! 346: else ! 347: date += 365; ! 348: } ! 349: return (date); ! 350: } ! 351: ! 352: doall() ! 353: { ! 354: register FILE *fp; ! 355: static char pline[256]; /* Current line in passwd file */ ! 356: static char uname[32]; ! 357: static char ucalfile[128]; ! 358: static char cmd[128]; ! 359: register char *cp1; ! 360: char *cp2, *cp3; ! 361: int i; ! 362: ! 363: if ((fp = fopen("/etc/passwd", "r")) == NULL) ! 364: fatal("cannot open /etc/passwd"); ! 365: while ((fgets(&pline[0],sizeof(pline),fp) != NULL) && *pline) { ! 366: for (cp1 = &pline[0]; *cp1 != '\0'; cp1++) ! 367: if (*cp1 == '\n') { ! 368: *cp1 = '\0'; ! 369: break; ! 370: } ! 371: cp1 = &pline[0]; ! 372: for (cp2 = &uname[0]; *cp1 != '\0' && *cp1 != ':'; ) ! 373: *cp2++ = *cp1++; ! 374: *cp2 = '\0'; ! 375: for (i = 0; i < 4 && *cp1 != '\0'; i++) ! 376: for (cp1++; *cp1 != '\0' && *cp1 != ':'; cp1++) ! 377: ; ! 378: cp1++; ! 379: cp3 = &ucalfile[0]; ! 380: for (; *cp1 != '\0' && *cp1 != ':'; ) ! 381: *cp3++ = *cp1++; ! 382: *cp3 = '\0'; ! 383: if (ucalfile[0] == '\0') ! 384: continue; ! 385: strcat(ucalfile, "/.calendar"); ! 386: if (open(ucalfile, 0) >= 0) { /* file is readable */ ! 387: strcpy(cmd, argv0); ! 388: strcat(cmd, " -f"); ! 389: strcat(cmd, ucalfile); ! 390: strcat(cmd, " | /bin/mail "); ! 391: strcat(cmd, uname); ! 392: system(cmd); ! 393: } ! 394: } ! 395: exit(0); ! 396: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.