home *** CD-ROM | disk | FTP | other *** search
- From: dfs@doe.carleton.ca (David F. Skoll)
- Newsgroups: alt.sources
- Subject: REMIND 2.2 03/05
- Message-ID: <dfs.658781264@yar>
- Date: 16 Nov 90 18:47:44 GMT
-
-
- #!/bin/sh
- # This is part 03 of Remind-2.2
- if touch 2>&1 | fgrep 'amc' > /dev/null
- then TOUCH=touch
- else TOUCH=true
- fi
- # ============= main.c ==============
- if test X"$1" != X"-c" -a -f 'main.c'; then
- echo "File already exists: skipping 'main.c'"
- else
- echo "x - extracting main.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > main.c &&
- X/***************************************************************/
- X/* */
- X/* REMIND - version 2.2 */
- X/* */
- X/* By David Skoll - 13 Novemeber 1990 */
- X/* */
- X/* (C) 1990 by David Skoll - all rights reserved */
- X/* */
- X/***************************************************************/
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <ctype.h>
- X#ifndef UNIX
- X#include <stdlib.h>
- X#include <dos.h>
- X#include <stdarg.h>
- X#else
- X#include <varargs.h>
- X#include <sys/types.h>
- X#ifdef SYSV
- X#include <time.h>
- X#else
- X#include <sys/time.h>
- X#endif
- X#endif
- X#include "defines.h"
- X#include "protos.h"
- X
- X
- X/* List of months */
- Xchar *MonthName[] = {
- X "January", "February", "March", "April", "May", "June",
- X "July", "August", "September", "October", "November", "December"
- X};
- X
- X/* List of weekdays */
- Xchar *DayName[] = {
- X "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
- X};
- X
- X/* List of recognized tokens */
- X
- XToken keywd[] = {
- X { "BANNER", Banner_t, 0 },
- X { "OMIT", Omit_t, 0 },
- X { "REM", Rem_t, 0 },
- X { "January", Month_t, 0 },
- X { "February", Month_t, 1 },
- X { "March", Month_t, 2 },
- X { "April", Month_t, 3 },
- X { "May", Month_t, 4 },
- X { "June", Month_t, 5 },
- X { "July", Month_t, 6 },
- X { "August", Month_t, 7 },
- X { "September", Month_t, 8 },
- X { "October", Month_t, 9 },
- X { "November", Month_t, 10 },
- X { "December", Month_t, 11 },
- X { "Monday", WkDay_t, 0 },
- X { "Tuesday", WkDay_t, 1 },
- X { "Wednesday", WkDay_t, 2 },
- X { "Thursday", WkDay_t, 3 },
- X { "Friday", WkDay_t, 4 },
- X { "Saturday", WkDay_t, 5 },
- X { "Sunday", WkDay_t, 6 },
- X { "MSG", Msg_t, 0 },
- X { "RUN", Run_t, 0 },
- X { "ONCE", Once_t, 0 },
- X { "INCLUDE", Include_t, 0},
- X { "AT", At_t, 0}
- X};
- X
- X/* List of days in month - Feb MUST be 29 for CheckDate to work. */
- Xint MonthDays[] = {
- X 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- X};
- X
- X/* Index of the first day of each month. First array is non-leap-year;
- X second is leap-year. */
- Xint MonthIndex[2][12] = {
- X { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 },
- X { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }
- X};
- X
- X/* Global ommissions array */
- Xint FullOmitArray[FOMITSIZE];
- X
- X/* Global partial omissions array */
- Xint PartOmitArray[POMITSIZE];
- X
- X/* Define the working buffers */
- Xchar Line[512], WorkBuf[512];
- Xchar TmpBuf[512];
- Xint Fresh; /* True if the contents of Line are fresh */
- X
- X/* Global variables */
- Xint Purge, Debug, Verbose, IgRun, IgOnce;
- Xint LastRun;
- Xchar FileName[200];
- Xint CurLine;
- Xchar Banner[200] = "Reminders for %w, %d%s %m, %y%o:";
- Xint NumEmitted, NumRem;
- Xint NumFullOmit, NumPartOmit;
- Xint JulianToday, RealToday;
- Xint CurYear, CurMon, CurDay;
- Xint QueueAts, PrintAts, NumAtsQueued;
- Xint Calendar, CalTime, CalWidth, SimpleCalendar;
- X
- Xstatic int JulFirst; /* Julian date of 1 Jan Current_year */
- Xstatic int FirstYear;
- X#ifndef UNIX
- Xint int_comp(int *a, int *b) { return *a - *b; }
- X#else
- Xint int_comp(a, b)
- X int *a;
- X int *b;
- X{ return *a - *b; }
- X#endif
- X
- X/***************************************************************/
- X/* */
- X/* Output */
- X/* Output a string with line separators. */
- X/* */
- X/***************************************************************/
- X#ifndef UNIX
- Xvoid Output(char *s)
- X#else
- Xvoid Output(s)
- Xchar *s;
- X#endif
- X{
- X while (*s) {
- X if (*s == '\n') putchar('\\');
- X putchar(*s++);
- X }
- X putchar('\n');
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int MoveBack(...) */
- X/* */
- X/* Move back by specified number of days, skipping holidays */
- X/* */
- X/***************************************************************/
- X#ifndef UNIX
- Xint MoveBack (int jul, int back, int d, int m, int y, int omit)
- X#else
- Xint MoveBack (jul, back, d, m, y, omit)
- X int jul;
- X int back;
- X int d;
- X int m;
- X int y;
- X int omit;
- X#endif
- X{
- X int temp;
- X
- X if (!NumFullOmit && !NumPartOmit && !omit) return jul - back;
- X while (back) {
- X jul--;
- X if (omit & 1 << (jul % 7)) continue; /* Omitted due to weekday */
- X
- X /* Omit if in fully-specified omit list */
- X if (NumFullOmit && bsearch(&jul, FullOmitArray, NumFullOmit, sizeof(int), int_comp)) continue;
- X
- X if (NumPartOmit) {
- X d--;
- X if (d == 0) {
- X m--;
- X if (m < 0) {
- X y--;
- X m = 11;
- X }
- X d = DaysInMonth(m, y);
- X }
- X temp = (m << 5) + d;
- X if (bsearch(&temp, PartOmitArray, NumPartOmit, sizeof(int), int_comp)) continue;
- X }
- X back--;
- X }
- X return jul;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int ProcessLine() */
- X/* */
- X/* Process the line in the "Line" buffer. */
- X/* */
- X/* Normally returns 0. Returns 1 only if we're in Calendar */
- X/* mode and we hit a reminder which should be placed in the */
- X/* calendar. */
- X/* */
- X/***************************************************************/
- X#ifndef UNIX
- Xint ProcessLine(void)
- X#else
- Xint ProcessLine()
- X#endif
- X{
- X char *s = Line;
- X Token tok;
- X int i;
- X
- X while (isspace(*s)) s++;
- X
- X /* Skip comments and blank lines */
- X if (*s == '#' || *s == 0) {
- X if (Purge && TopLevel()) Output(Line);
- X return 0;
- X }
- X
- X tok = ParseToken(&s);
- X switch(tok.type) {
- X case Banner_t: DoBanner(&s);
- X if (Purge && TopLevel()) Output(Line);
- X break;
- X
- X case Omit_t: i = DoGlobalOmit(&s);
- X if (Purge && TopLevel())
- X if (i < 0) Eprint("Purged '%s'\n", Line);
- X else Output(Line);
- X break;
- X
- X case Rem_t: i = DoRem(&s);
- X if (Calendar) return i;
- X if (Purge && TopLevel())
- X if (i < 0) Eprint("Purged '%s'\n", Line);
- X else Output(Line);
- X NumRem++;
- X break;
- X
- X case Include_t: if (Purge && TopLevel()) Output(Line);
- X DoInclude(&s);
- X break;
- X
- X
- X default: if (Purge && TopLevel()) Output(Line);
- X Eprint("Unknown command '%s'\n", tok.str);
- X }
- X return 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X#ifndef UNIX
- X/* void Eprint(const char *f, ...) */
- X#else
- X/* void Eprint(va_alist) */
- X#endif
- X/* */
- X/* Prints an error message. */
- X/* */
- X/***************************************************************/
- X#ifndef UNIX
- Xvoid Eprint(const char *f, ...)
- X#else
- X/*VARARGS0*/
- Xvoid Eprint(va_alist)
- Xva_dcl
- X#endif
- X{
- X#ifndef UNIX
- X va_list args;
- X#else
- X va_list args;
- X char *f;
- X#endif
- X
- X#ifndef UNIX
- X if (Verbose & Fresh) {
- X#else
- X if (Verbose & Fresh) {
- X#endif
- X fprintf(stderr, "\n--- %s\n", Line);
- X Fresh = 0;
- X }
- X if (Verbose) fprintf(stderr, "--- ");
- X fprintf(stderr, "%s(%d): ", FileName, CurLine);
- X#ifndef UNIX
- X va_start(args, f);
- X#else
- X va_start(args);
- X f = va_arg(args, char *);
- X#endif
- X vfprintf(stderr, f, args);
- X#ifdef UNIX
- X va_end(args);
- X#endif
- X}
- X
- X
- X/***************************************************************/
- X/* */
- X/* int DoBanner(char **s) */
- X/* */
- X/* Sets the "Reminders for..." banner. */
- X/* */
- X/***************************************************************/
- X#ifndef UNIX
- Xint DoBanner(char **s)
- X#else
- Xint DoBanner(s)
- X char **s;
- X#endif
- X{
- X if (Purge) return 0;
- X while (isspace(**s)) (*s)++;
- X strcpy(Banner, *s);
- X if (! *Banner)
- X {
- X if (Debug) Eprint("Empty banner.\n");
- X strcpy(Banner, "Reminders for %w, %d%s %m, %y%o:");
- X }
- X if (NumRem && Debug) Eprint("Warning: Banner after reminder.\n");
- X return 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int CheckDate(int d, int m, int y) */
- X/* */
- X/* Checks that a date is valid - returns 0 for OK, 1 for BAD. */
- X/* */
- X/* If y=-1, just checks that month & day are valid, giving */
- X/* benefit of the doubt for February 29. */
- X/* */
- X/* No point in checking if month is valid - months are named */
- X/* and thus a month out of range can never be entered into */
- X/* the system. */
- X/* */
- X/***************************************************************/
- X#ifndef UNIX
- Xint CheckDate(int d, int m, int y)
- X#else
- Xint CheckDate(d, m, y)
- X int d;
- X int m;
- X int y;
- X#endif
- X{
- X if (y == -1)
- X if (d > 0 && d <= MonthDays[m]) return 0; else return 1;
- X else
- X if (y < BASE || y > BASE + 85) return 1;
- X else if (d > 0 && d <= DaysInMonth(m, y)) return 0; else return 1;
- X}
- X
- X
- X/***************************************************************/
- X/* */
- X/* int DoGlobalOmit(char **s) */
- X/* */
- X/* Add an entry to the global ommissions array. Either */
- X/* a fully-specified date, or a mm-yy type date. */
- X/* Return 0 if OK, -1 if date is in past, 1 if problem. */
- X/* */
- X/***************************************************************/
- X#ifndef UNIX
- Xint DoGlobalOmit(char **s)
- X#else
- Xint DoGlobalOmit(s)
- X char **s;
- X#endif
- X{
- X int d = -1, m = -1, y = -1;
- X int omit;
- X int *ptr;
- X Token tok;
- X
- X tok.type = Unknown_t;
- X while(tok.type != Eol_t) {
- X tok = ParseToken(s);
- X switch (tok.type) {
- X case Year_t: y = tok.val; break;
- X case Month_t: m = tok.val; break;
- X case Day_t: d = tok.val; break;
- X case Eol_t: break;
- X default: Eprint("Invalid token '%s' for OMIT command.\n", tok.str);
- X return 1;
- X }
- X }
- X
- X if (d == -1 || m == -1 || CheckDate(d, m, y)) {
- X Eprint("Invalid date specification.\n");
- X return 1;
- X }
- X
- X if (y == -1) { /* Only mm-dd specified */
- X if (NumPartOmit == POMITSIZE) {
- X Eprint("Too many partially-specified OMITs.\n");
- X return 1;
- X }
- X omit = (m << 5) + d;
- X ptr = PartOmitArray + NumPartOmit;
- X NumPartOmit++;
- X while (ptr > PartOmitArray && *(ptr-1) > omit) {
- X *ptr = *(ptr-1);
- X ptr--;
- X }
- X *ptr = omit;
- X
- X /* Check if the bonehead already has it - if so, delete it */
- X if (ptr > PartOmitArray && *(ptr-1) == *ptr) {
- X if (Debug) Eprint("Duplicated partially-specified OMIT.\n");
- X NumPartOmit--;
- X while (ptr < NumPartOmit+PartOmitArray) {
- X *ptr = *(ptr + 1);
- X ptr++;
- X }
- X }
- X } else { /* All three specified */
- X if (NumFullOmit == FOMITSIZE) {
- X Eprint("Too many fully-specified OMITs.\n");
- X return 1;
- X }
- X omit = Julian(d, m, y);
- X if (omit < JulianToday) {
- X if (Debug) Eprint("Omit has expired.\n");
- X return -1;
- X }
- X
- X ptr = FullOmitArray + NumFullOmit;
- X NumFullOmit++;
- X while (ptr > FullOmitArray && *(ptr-1) > omit) {
- X *ptr = *(ptr-1);
- X ptr--;
- X }
- X *ptr = omit;
- X
- X /* Check if the bonehead already has it - if so, delete it */
- X if (ptr > FullOmitArray && *(ptr-1) == *ptr) {
- X if (Debug) Eprint("Duplicated fully-specified OMIT.\n");
- X NumFullOmit--;
- X while (ptr < NumFullOmit+FullOmitArray) {
- X *ptr = *(ptr + 1);
- X ptr++;
- X }
- X }
- X }
- X return 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int strnicmp(char *s1, char*s1, int n) */
- X/* */
- X/* Compares first n chars of string ignoring case. */
- X/* */
- X/***************************************************************/
- X#ifndef UNIX
- Xint strncmpi(char *s1, char *s2, int n)
- X#else
- Xint strncmpi(s1, s2, n)
- X char *s1;
- X char *s2;
- X int n;
- X#endif
- X{
- X register int u1, u2;
- X while (n)
- X {
- X if (!*s1 || !*s2) return upper(*s1) - upper(*s2);
- X u1 = upper(*s1);
- X u2 = upper(*s2);
- X if (u1 != u2) return (u1 - u2);
- X n--;
- X s1++;
- X s2++;
- X }
- X return 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* ParseToken(char **s); */
- X/* */
- X/* Parse the next token and adjust the character pointer. */
- X/* */
- X/***************************************************************/
- X#ifndef UNIX
- XToken ParseToken(char **s)
- X#else
- XToken ParseToken(s)
- X char **s;
- X#endif
- X{
- X
- X Token tok;
- X char *t = TmpBuf;
- X int i, h, m;
- X int len;
- X char *colon = (char *) NULL;
- X
- X *t = 0;
- X tok.str = TmpBuf;
- X
- X /* Skip blank space */
- X while (isspace(**s)) (*s)++;
- X
- X /* End of line ? */
- X if (**s == 0) {
- X tok.type = Eol_t;
- X tok.val = 0;
- X return tok;
- X }
- X
- X /* Grab a space-delimited token */
- X while (**s != 0 && !isspace(**s)) {
- X *t++ = **s;
- X (*s)++;
- X }
- X *t = 0;
- X len = t - TmpBuf;
- X
- X /* Check if it's a built-in token */
- X for (i=0; i < sizeof(keywd)/sizeof(keywd[0]); i++)
- X if (len >= 3 && !strncmpi(TmpBuf, keywd[i].str, len)) return keywd[i];
- X
- X /* ARGH. Check for "AT" as special case: < 3 chars */
- X if (len == 2 && !strncmpi(TmpBuf, "AT", 2)) {
- X tok.type = At_t;
- X return tok;
- X }
- X
- X tok.type = Unknown_t;
- X
- X /* If it's a comment, ignore the rest of the line */
- X if (*(tok.str) == '#') {
- X tok.type = Eol_t;
- X return tok;
- X }
- X
- X /* Check if it's a number (optional +/-/* ahead of number */
- X t = TmpBuf;
- X if (isdigit(*t)) {
- X while (*++t){
- X if (*t == ':') {
- X if (colon) return tok; else colon = t;
- X } else if (!isdigit(*t)) return tok;
- X }
- X }
- X else if (*t == '+' || *t == '-' || *t == '*') {
- X if (!isdigit(*++t)) return tok;
- X while (*++t) if (!isdigit(*t)) return tok;
- X }
- X else return tok;
- X
- X /* OK, here we have a number - either a pure number, a delta, a time,
- X back or a repeat marker */
- X
- X if (colon) { /* got a time here */
- X h = atoi(TmpBuf);
- X m = atoi(colon + 1);
- X if (h >= 0 && h <= 23 && m >= 0 && m <= 59) {
- X tok.type = Time_t;
- X tok.val = 60*h+m;
- X }
- X else return tok;
- X }
- X else if (*TmpBuf == '+') {
- X tok.type = Delta_t;
- X tok.val = atoi(TmpBuf + 1);
- X }
- X else if (*TmpBuf == '-') {
- X tok.type = Back_t;
- X tok.val = atoi(TmpBuf + 1);
- X }
- X else if (*TmpBuf == '*') {
- X tok.type = Repeat_t;
- X tok.val = atoi(TmpBuf + 1);
- X }
- X else {
- X tok.val = atoi(TmpBuf);
- X if (tok.val > 0 && tok.val <= 31) tok.type = Day_t;
- X else if (tok.val >= 100) tok.type = Year_t;
- X else {
- X tok.type = Year_t;
- X tok.val += 1900;
- X }
- X }
- X return tok;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int FromJulian(int jul, int *d, int *m, int *y) */
- X/* */
- X/* Convert a date from Julian to normal form. Returns */
- X/* 0 if conversion ok, -1 otherwise. */
- X/* */
- X/***************************************************************/
- X#ifndef UNIX
- Xint FromJulian(int jul, int *d, int *m, int *y)
- X#else
- Xint FromJulian(jul, d, m, y)
- X int jul;
- X int *d;
- X int *m;
- X int *y;
- X#endif
- X{
- X int t;
- X
- X if (jul < 0) return 1;
- X
- X if (jul >= JulFirst && JulFirst != -1) {
- X *y = FirstYear;
- X jul -= JulFirst;
- X } else *y = BASE;
- X
- X *m = 0;
- X
- X t = DaysInYear(*y);
- X while (jul >= t) {
- X jul -= t;
- X (*y)++;
- X t = DaysInYear(*y);
- X }
- X
- X t = DaysInMonth(*m, *y);
- X while (jul >= t) {
- X jul -= t;
- X (*m)++;
- X t = DaysInMonth(*m, *y);
- X }
- X *d = jul + 1;
- X return 0;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int Julian(d, m, y) */
- X/* */
- X/* Converts a date to the number of days after Jan 1 1990. */
- X/* Returns -1 if date is before Jan 1 1990. */
- X/* */
- X/***************************************************************/
- X#ifndef UNIX
- Xint Julian(int d, int m, int y)
- X#else
- Xint Julian(d, m, y)
- X int d;
- X int m;
- X int y;
- X#endif
- X{
- X int iy;
- X int jul = 0;
- X
- X if (y < BASE) return -1;
- X if (JulFirst == -1 || y < FirstYear)
- X for (iy = BASE; iy < y; iy++) jul += DaysInYear(iy);
- X else {
- X jul = JulFirst;
- X for (iy = FirstYear; iy < y; iy++) jul += DaysInYear(iy);
- X }
- X
- X return jul + MonthIndex[IsLeapYear(y)][m] + d - 1;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* int FindTodaysDate(int *d, int *m, int *y) */
- X/* */
- X/* Obtains today's date. Returns Julian date or -1 for */
- X/* failure. */
- X/* */
- X/***************************************************************/
- X#ifndef UNIX
- Xint FindTodaysDate(int *d, int *m, int *y)
- X#else
- Xint FindTodaysDate(d, m, y)
- X int *d;
- X int *m;
- X int *y;
- X#endif
- X{
- X#ifndef UNIX
- X struct dosdate_t buf;
- X
- X _dos_getdate(&buf);
- X
- X *d = buf.day;
- X *m = buf.month - 1;
- X *y = buf.year;
- X#else
- X time_t tloc;
- X struct tm *t;
- X
- X (void) time(&tloc);
- X t = localtime(&tloc);
- X
- X *d = t->tm_mday;
- X *m = t->tm_mon;
- X *y = t->tm_year + 1900;
- X
- X#endif
- X if (CheckDate(*d, *m, *y)) return -1;
- X return Julian(*d, *m, *y);
- X}
- X
- X#ifndef UNIX
- Xint main(int argc, char *argv[])
- X#else
- Xint main(argc, argv)
- X int argc;
- X char *argv[];
- X#endif
- X{
- X#ifdef UNIX
- X#ifdef SYSV
- X pid_t pid;
- X#else
- X int pid;
- X#endif
- X#endif
- X
- X NumEmitted = 0;
- X NumRem = 0;
- X JulFirst = -1; /* Initialize JulFirst so it's not used by Julian */
- X
- X JulianToday = FindTodaysDate(&CurDay, &CurMon, &CurYear);
- X if (JulianToday < 0) {
- X fprintf(stderr, "remind: System date is illegal - Ensure that year is at least %d.\n", BASE);
- X return 1;
- X }
- X
- X RealToday = JulianToday;
- X
- X initialize(argc, argv);
- X
- X FirstYear = CurYear;
- X JulFirst = Julian(1, 0, CurYear); /* Do expensive computation once */
- X FirstYear = CurYear;
- X
- X if (Calendar) {
- X DoCalendar();
- X return 0;
- X }
- X while (1) {
- X if (ReadLine()) break;
- X ProcessLine();
- X }
- X if (NumEmitted == 0 && NumAtsQueued == 0 && !Purge && !Debug)
- X printf("No reminders.\n");
- X#ifdef UNIX
- X if (NumEmitted == 0 && NumAtsQueued != 0 && !Purge && !Debug)
- X printf("%d reminder%s queued for later today.\n", NumAtsQueued,
- X (NumAtsQueued == 1) ? "" : "s");
- X
- X if (NumAtsQueued) {
- X pid = fork();
- X if (pid == -1) Eprint("Can't fork to perform ATs!\n");
- X if (pid != 0) return 0;
- X HandleQueuedAts();
- X }
- X#endif
- X}
- X/***************************************************************/
- X/* */
- X/* SystemTime */
- X/* */
- X/* Returns current system time in seconds past midnight. */
- X/* */
- X/***************************************************************/
- X#ifndef UNIX
- Xlong SystemTime(void)
- X#else
- Xlong SystemTime()
- X#endif
- X{
- X#ifdef UNIX
- X time_t tloc;
- X struct tm *t;
- X
- X (void) time(&tloc);
- X t = localtime(&tloc);
- X return (long) t->tm_hour * 3600L + (long) t->tm_min * 60L + (long) t->tm_sec;
- X
- X#else
- X struct dostime_t tloc;
- X _dos_gettime(&tloc);
- X return (long) tloc.hour * 3600L + (long) tloc.minute * 60L + (long) tloc.second;
- X#endif
- X}
- SHAR_EOF
- $TOUCH -am 1115165290 main.c &&
- chmod 0600 main.c ||
- echo "restore of main.c failed"
- set `wc -c main.c`;Wc_c=$1
- if test "$Wc_c" != "21719"; then
- echo original size 21719, current size $Wc_c
- fi
- fi
- # ============= nextdate.c ==============
- if test X"$1" != X"-c" -a -f 'nextdate.c'; then
- echo "File already exists: skipping 'nextdate.c'"
- else
- echo "x - extracting nextdate.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > nextdate.c &&
- X#include "defines.h"
- X#include "globals.h"
- X#include "protos.h"
- X
- X/***************************************************************/
- X/* */
- X/* int TryNextDate(int *retday, int *retmon, int *retyr, */
- X/* int startday, int startmon, int startyr, */
- X/* int conday, int conmon, int conyr, */
- X/* int wkday, int cons, int inc) */
- X/* */
- X/* This function tries to find the next date satisfying */
- X/* the given constraints. Returns */
- X/* 0 for success. Returns non-zero if a constraint would */
- X/* be violated. Note that if DAY and WEEKDAY are both */
- X/* constrained, then MONTH and YEAR may be violated. */
- X/* Otherwise, all constraints are honoured. */
- X/* The starting point for the search is thisday, etc. */
- X/* */
- X/* If inc is non-zero, then the search begins from the day */
- X/* after the specified date. Note that this function assumes */
- X/* that the given date is valid. */
- X/* */
- X/***************************************************************/
- X#ifndef UNIX
- Xint TryNextDate(int *retday, int *retmon, int *retyr,
- X int d, int m, int y,
- X int conday, int conmon, int conyr,
- X int wkday, int cons, int inc)
- X#else
- Xint TryNextDate(retday, retmon, retyr, d, m, y, conday, conmon, conyr,
- X wkday, cons, inc)
- X int *retday, *retmon, *retyr, d, m, y, conday, conmon, conyr, wkday, cons, inc;
- X
- X#endif
- X
- X{
- X int jul, jul2;
- X int dd = d, mm = m, yy = y;
- X
- X if (inc)
- X {
- X d++;
- X if (d > DaysInMonth(m, y)) {
- X m++; d = 1;
- X if (m > 11) {
- X y++; m = 0;
- X }
- X }
- X }
- X
- X
- X switch (cons & 15) {
- X
- X case 0: /* No constraints - just use the start date */
- X *retday = d;
- X *retmon = m;
- X *retyr = y;
- X return 0;
- X
- X case 1: /* Day constrained to be d */
- X *retday = conday;
- X if (d > conday) {
- X m++;
- X if (m > 11) {y++; m=0;}
- X }
- X while (conday > DaysInMonth(m, y)) {
- X m++;
- X if (m > 11) {y++; m=0;}
- X }
- X *retmon = m;
- X *retyr = y;
- X return 0;
- X
- X case 2: /* Month constrained to be m */
- X *retmon = conmon;
- X if (m > conmon) {y++; d = 1;}
- X else if (m < conmon) d = 1;
- X *retday = d;
- X *retyr = y;
- X return 0;
- X
- X case 3: /* Month and day constrained */
- X *retmon = conmon;
- X *retday = conday;
- X if (m > conmon || (m == conmon && d > conday)) y++;
- X while (conday > DaysInMonth(conmon, y)) y++;
- X *retyr = y;
- X return 0;
- X
- X case 4: /* Year alone constrained */
- X if (y > conyr) return 1;
- X *retyr = conyr;
- X if (y < conyr) {
- X *retmon = 0;
- X *retday = 1;
- X }
- X else {
- X *retmon = m;
- X *retday = d;
- X }
- X return 0;
- X
- X case 5: /* Year and day constrained */
- X if (y > conyr) return 1;
- X *retyr = conyr;
- X *retday = conday;
- X if (y < conyr) {
- X *retmon = 0;
- X return 0;
- X }
- X if (d > conday) {
- X m++;
- X if (m > 11) return 1;
- X }
- X while (conday > DaysInMonth(m, y)) {
- X m++;
- X if (m > 11) return 1;
- X }
- X *retmon = m;
- X return 0;
- X
- X case 6: /* Year and month constrained */
- X if (y > conyr || (y == conyr && m > conmon)) return 1;
- X *retyr = conyr;
- X *retmon = conmon;
- X if (y < conyr || (y == conyr && m < conmon)) {
- X *retday = 1;
- X return 0;
- X }
- X *retday = d;
- X return 0;
- X
- X case 7: /* Year, month and day constrained */
- X *retday = conday;
- X *retmon = conmon;
- X *retyr = conyr;
- X if (y > conyr || (y == conyr && m > conmon) ||
- X (y == conyr && m == conmon && d > conday)) return 1;
- X return 0;
- X
- X case 8: /* Only the weekday constrained. Let's go to Julian mode */
- X jul = Julian(d, m, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X
- X case 9: /* GASP! day and weekday constrained .. bleah! */
- X /* First, try last month. */
- X jul2 = Julian(d, m, y);
- X if (m != 0 || y != BASE)
- X {
- X mm--;
- X if (mm < 0) {yy--; mm = 11;}
- X
- X /* If there are fewer days in month than required, it
- X can't possibly match. */
- X if (conday <= DaysInMonth(mm, yy)) {
- X jul = Julian(conday, mm, yy);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X if (jul >= jul2) { /* SUCCESS! */
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X }
- X }
- X /* Didn't work - try this month */
- X if (conday <= DaysInMonth(m, y)) {
- X jul = Julian(conday, m, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X if (jul >= jul2) { /* SUCCESS! */
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X }
- X /* Argh! Try next available month */
- X mm = m;
- X yy = y;
- X do {
- X mm++;
- X if (mm > 11) {mm = 0; yy++;}
- X } while (conday > DaysInMonth(mm, yy));
- X jul = Julian(conday, mm, yy);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X
- X case 10: /* Month and Weekday constrained */
- X if (m < conmon) {
- X jul = Julian(1, conmon, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X } else if (m == conmon) {
- X jul = Julian(d, conmon, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X if (*retmon != conmon) {
- X jul = Julian(1, conmon, y+1);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X }
- X return 0;
- X } else { /* m > conmon */
- X jul = Julian(1, conmon, y+1);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X
- X case 11: /* Day, Month and Weekday constrained */
- X jul2 = Julian(d, m, y);
- X
- X /* Blip up to next valid year */
- X while (conday > DaysInMonth(m, y)) y++;
- X
- X /* Try this year */
- X jul = Julian(conday, conmon, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X if (jul >= jul2) {
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X
- X /* Must be next year */
- X jul = Julian(conday, conmon, y+1);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X
- X case 12: /* Weekday and year specified */
- X if (y > conyr) return 1;
- X if (y == conyr) {mm = m; dd = d;} else {mm = 0; dd = 1;}
- X jul = Julian(dd, mm, conyr);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X
- X case 13: /* Weekday, year and day specified */
- X if (y > conyr+1 || (y > conyr && m>0)) return 1;
- X jul2 = Julian(d, m, y);
- X if (y > conyr ) {
- X jul = Julian(conday, 11, conyr);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X if (jul >= jul2) {
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X } else if (y < conyr) {
- X jul = Julian(conday, 0, conyr);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X else {
- X /* Try last month */
- X if (m > 0) {
- X mm = m - 1;
- X while (conday > DaysInMonth(mm, y)) mm--;
- X jul = Julian(conday, mm, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X if (jul >= jul2) {
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X }
- X /* Try this month */
- X if (conday <= DaysInMonth(m,y)) {
- X jul = Julian(conday, m, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X if (jul >= jul2) {
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X }
- X /* Try next month */
- X if (m == 11) return 1;
- X m++;
- X while (conday > DaysInMonth(m, y)) m++;
- X jul = Julian(conday, m, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X }
- X
- X case 14: /* Weekday, Month and Year specified */
- X if (y > conyr || (y == conyr && m > conmon)) return 1;
- X if (conyr > y || (conyr == y && conmon > m)) {
- X jul = Julian(1, conmon, conyr);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X return 0;
- X } else {
- X jul = Julian(d, m, y);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X if (*retmon == conmon) return 0; else return 1;
- X
- X }
- X
- X case 15: /* Weekday, day, month and year specified */
- X jul2 = Julian(d, m, y);
- X jul = Julian(conday, conmon, conyr);
- X while (!(wkday & (1 << (jul % 7)))) jul++;
- X FromJulian(jul, retday, retmon, retyr);
- X if (jul < jul2) return 1;
- X return 0;
- X }
- X}
- SHAR_EOF
- $TOUCH -am 1115093690 nextdate.c &&
- chmod 0600 nextdate.c ||
- echo "restore of nextdate.c failed"
- set `wc -c nextdate.c`;Wc_c=$1
- if test "$Wc_c" != "8637"; then
- echo original size 8637, current size $Wc_c
- fi
- fi
- # ============= protos.h ==============
- if test X"$1" != X"-c" -a -f 'protos.h'; then
- echo "File already exists: skipping 'protos.h'"
- else
- echo "x - extracting protos.h (Text)"
- sed 's/^X//' << 'SHAR_EOF' > protos.h &&
- X
- X/* Function Prototypes go here */
- X
- X#ifndef UNIX
- Xint CheckDate (int d, int m, int y);
- Xint DoBanner (char **s);
- Xvoid DoCalendar (void);
- Xint DoGlobalOmit(char **s);
- Xvoid DoInclude (char **s);
- Xint DoRem (char **s);
- Xint DoSubst (char *src, char *dst, int d, int m, int y, int jul, enum Token_t t, int tim);
- Xvoid Eprint(const char *f, ...);
- Xint FindTodaysDate(int *d, int *m, int *y);
- Xint FromJulian (int jul, int *d, int *m, int *y);
- Xint GetTriggerDate (int d, int m, int y, int wd, int cons, int back, int repeat, int omit);
- Xvoid HandleQueuedAts(void);
- Xvoid initialize (int argc, char *argv[]);
- Xint int_comp (int *, int *);
- Xint Julian (int d, int m, int y);
- Xint MoveBack (int jul, int back, int d, int m, int y, int omit);
- Xvoid OpenFile (char *s);
- Xvoid Output (char *s);
- XToken ParseToken (char **s);
- Xint ProcessLine (void);
- Xint ReadLine (void);
- Xlong SystemTime (void);
- Xint TopLevel (void);
- Xint TryNextDate(int *retday, int *retmon, int *retyr,
- X int startday, int startmon, int startyr,
- X int conday, int conmon, int conyr,
- X int wkday, int cons, int inc);
- X#else
- Xint CheckDate ();
- Xint DoBanner ();
- Xvoid DoCalendar ();
- Xint DoGlobalOmit();
- Xvoid DoInclude ();
- Xint DoRem ();
- Xint DoSubst ();
- Xvoid Eprint();
- Xint FindTodaysDate();
- Xint FromJulian ();
- Xint GetTriggerDate();
- Xvoid HandleQueuedAts();
- Xvoid initialize ();
- Xint int_comp ();
- Xint Julian ();
- Xint MoveBack ();
- Xvoid OpenFile ();
- Xvoid Output ();
- XToken ParseToken ();
- Xint ProcessLine ();
- Xint ReadLine ();
- Xvoid SigHupHandler();
- Xlong SystemTime ();
- Xint TopLevel ();
- Xint TryNextDate ();
- X#endif
- X
- SHAR_EOF
- $TOUCH -am 1115095890 protos.h &&
- chmod 0600 protos.h ||
- echo "restore of protos.h failed"
- set `wc -c protos.h`;Wc_c=$1
- if test "$Wc_c" != "1717"; then
- echo original size 1717, current size $Wc_c
- fi
- fi
- # ============= remind-all.csh ==============
- if test X"$1" != X"-c" -a -f 'remind-all.csh'; then
- echo "File already exists: skipping 'remind-all.csh'"
- else
- echo "x - extracting remind-all.csh (Text)"
- sed 's/^X//' << 'SHAR_EOF' > remind-all.csh &&
- X#!/bin/csh -f
- X
- X# Shell script to mail all users reminders.
- X
- X# Run it AFTER MIDNIGHT so that date is correct!
- X# On our system, we have the following in our crontab:
- X# 05 5 * * * /usr/share/lib/remind/remind-all > /dev/null 2>&1
- X
- X# Also, you MUST use the -r and -q options on REMIND, otherwise SEVERE
- X# security hole could develop. I recommend making this script
- X# readable and executable only by root to minimize security problems.
- X# DO NOT make the script setuid!
- X
- X# The following line gets a list of users for systems using SUN's
- X# NIS service:
- Xset USERS = `ypcat passwd | awk -F: '{print $1}'`
- X
- X# The following line gets a list of users by examining /etc/passwd:
- X# set USERS = `awk -F: '{print $1}' /etc/passwd`
- X
- X# If neither of the above methods works, you must come up with some
- X# way of getting a list of users on the system
- X
- X# Set the following variables as appropriate for your system
- Xset REMIND = /usr/local/bin/remind
- Xset MAIL = /usr/ucb/mail
- Xset CMP = /usr/bin/cmp
- Xset RM = "/usr/bin/rm -f"
- X
- Xset EMPTY = /tmp/Empty.$$
- Xset FULL = /tmp/Full.$$
- X
- X# Create the dummy empty reminder file
- X$REMIND -rq /dev/null > $EMPTY
- X
- X# Scan each user's directory for a .reminders file
- Xforeach i ($USERS)
- X if (-r ~$i/.reminders) then
- X
- X# echo "$i has a .reminders file." DEBUGGING PURPOSES ONLY
- X
- X $REMIND -rq ~$i/.reminders > $FULL
- X $CMP -s $EMPTY $FULL
- X if ($status != 0) then
- X
- X# echo "Sending mail to $i" DEBUGGING PURPOSES ONLY
- X
- X $MAIL -s "Reminders" $i < $FULL
- X endif
- X $RM $FULL
- X endif
- Xend
- X
- X$RM $EMPTY
- SHAR_EOF
- $TOUCH -am 1113132790 remind-all.csh &&
- chmod 0700 remind-all.csh ||
- echo "restore of remind-all.csh failed"
- set `wc -c remind-all.csh`;Wc_c=$1
- if test "$Wc_c" != "1568"; then
- echo original size 1568, current size $Wc_c
- fi
- fi
- # ============= remind-all.sh ==============
- if test X"$1" != X"-c" -a -f 'remind-all.sh'; then
- echo "File already exists: skipping 'remind-all.sh'"
- else
- echo "x - extracting remind-all.sh (Text)"
- sed 's/^X//' << 'SHAR_EOF' > remind-all.sh &&
- X# Shell script to mail all users reminders.
- X
- X# Thanks to Bill Aten for this script.
- X
- X# Run it AFTER MIDNIGHT so that date is correct!
- X# On our system, we have the following in our crontab:
- X# 02 00 * * * /usr/local/adm/remind-all >/dev/null 2>&1
- X
- X# Also, you MUST use the -r and -q options on REMIND, otherwise a SEVERE
- X# security hole could develop. I recommend making this script
- X# readable and executable only by root to minimize security problems.
- X# DO NOT make the script setuid!
- X
- X# The following line gets a list of users for systems using SUN's
- X# NIS service:
- X# USERS=`ypcat passwd | awk -F: '{print $1}'`
- X
- X# The following line gets a list of users by examining /etc/passwd:
- XUSERS=`awk -F: '{print $1}' /etc/passwd`
- X
- X# If neither of the above methods works, you must come up with some
- X# way of getting a list of users on the system
- X
- X# Set the following variables as appropriate for your system
- XREMIND=/usr/local/bin/remind
- XMAIL=/usr/bin/mail
- XCMP=/bin/cmp
- XRM="/bin/rm -f"
- X
- XEMPTY=/tmp/Empty.$$
- XFULL=/tmp/Full.$$
- X
- X# Create the dummy empty reminder file
- X$REMIND -rq /dev/null > $EMPTY
- X
- X# Scan each user's directory for a .reminders file
- Xfor i in $USERS
- Xdo
- XHOME=`grep \^$i: /etc/passwd | awk -F: '{print $6}'`
- X if [ -r $HOME/.reminders ]; then
- X
- X# echo "$i has a .reminders file." DEBUGGING PURPOSES ONLY
- X
- X $REMIND -rq $HOME/.reminders > $FULL
- X if `$CMP -s $EMPTY $FULL`; then
- X : do nothing
- X else
- X
- X# echo "Sending mail to $i" DEBUGGING PURPOSES ONLY
- X
- X $MAIL -s "Reminders" $i < $FULL
- X fi
- X $RM $FULL
- X fi
- Xdone
- X
- X$RM $EMPTY
- SHAR_EOF
- $TOUCH -am 1116131490 remind-all.sh &&
- chmod 0700 remind-all.sh ||
- echo "restore of remind-all.sh failed"
- set `wc -c remind-all.sh`;Wc_c=$1
- if test "$Wc_c" != "1589"; then
- echo original size 1589, current size $Wc_c
- fi
- fi
- echo "End of part 3, continue with part 4"
- exit 0
-