home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
net
/
calendar.c
< prev
next >
Wrap
Internet Message Format
|
1986-03-17
|
21KB
From gregg@okstate.UUCP Wed Mar 12 03:23:00 1986
Path: seismo!gatech!akgua!whuxlm!whuxl!houxm!ihnp4!inuxc!pur-ee!uiucdcs!okstate.UUCP!gregg
From: gregg@okstate.UUCP
Newsgroups: net.sources
Subject: New CALENDAR(1) in C with extension
Message-ID: <5200029@okstate.UUCP>
Date: 12 Mar 86 08:23:00 GMT
Lines: 763
Nf-ID: #N:okstate.UUCP:5200029:000:20661
Nf-From: okstate.UUCP!gregg Mar 12 02:23:00 1986
Posted: Wed Mar 12 03:23:00 1986
This note contains a Shell archive (Bourne style) for the source
and documentation for a C version of the CALENDAR(1) program. Unpack
the archive, and read the README file. The program should MAKE(1) on
a System 5 machine without changes. This particular version is upward
compatible with the standard CALENDAR(1), but also includes many
extensions that allow far more versatile calendars. Supported notations
allow weekdays, as well as months to be used as the soul indentifier.
Read the README file, and the MAN(1) page for more details.
Please send me bug reports and complaints to me. The C code that
checks dates is very much simplified. This helps to speed the search,
as well as open some doors for new formats.
Gregg Wonderly
Department of Computing and Information Sciences
Oklahoma State University
UUCP: {cbosgd, ea, ihnp4, isucs1, mcvax, uokvax}!okstate!gregg
ARPA: gregg%okstate.csnet@csnet-relay.arpa
------------------------- CUT HERE ------------------------------
echo x - README
sed '1,$s/^X//' <<\!FUNKY!STUFF! > README
XThis is a substitute version of CALENDAR(1). It is upward compatible
Xwith the standard UNIX version, but has several extensions, and is
Xmuch faster, as it does not envoke EGREP(1). The executable generated
Xby compiling calendar.c (see the makefile) is envoked for each user.
XIt should be installed in /usr/lib/calendar, or the shell script
Xwill need to be changed. If you have STRCHR(3) instead of V7's INDEX(3),
Xor you have some other function for finding a character in a string,
Xchange/remove the #define in calendar.c. strchr() is used in the
XC code. If you run calendar SETUSERID to ROOT, then change the man page
Xto reflect that fact that world read access is not needed.
X
XYou should be able to just type "make install" and get a proper install.
X
XSend complaints/bugs to:
X
XGregg Wonderly
XDepartment of Computing and Information Sciences
XOklahoma State University
X
XUUCP: {cbosgd, ea, ihnp4, isucs1, mcvax, uokvax}!okstate!gregg
XARPA: gregg@A.CS.OKSTATE.EDU
!FUNKY!STUFF!
echo x - calendar.1
sed '1,$s/^X//' <<\!FUNKY!STUFF! > calendar.1
X.TH CALENDAR 1 "Oklahoma State University"
X.SH NAME
Xcalendar \- reminder service
X.SH SYNOPSIS
X.B calendar
X[ \- ]
X.SH DESCRIPTION
X.I Calendar
Xconsults the file `calendar' in the user's home directory
Xand prints out lines that contain today's,
Xtomorrow's, or a proper future date at the beginning of the line.
XMost reasonable month-day dates such as `Dec. 7,'
X`december 7,' `12/7,' etc., are recognized, but not
X`7 December' or `7/12'.
XOn weekends `tomorrow' extends through Monday.
X.sp
X.I Calendar
Xalso supports months and days of the week by themselves. This
Xallows you to specify things on a weekly or monthly basis.
XThe format for weekday names is the same
Xas that for month names; Mon., monday, tues, tue, wed, etc.
XThe month may be specified either by name, or by number. The weekday
Xwill only be recognized by name.
X.PP
X.SH EXTENDED NOTIFICATION
XIf you wish to have
X.I extended
Xnotification of a previous or upcoming
Xevent,
X.I calendar
Xsupports a notation that extends a date by a week.
X.PP
XIf "*w" is appended directly to the week day, I.E. 12/7*w, then
Xyou will be sent a reminder every day beginning approximately
X(depending on the weekend) 7 days prior to the date.
X.PP
XIf "*W" (note the significance of case "w" or "W") is appended
Xto the week day as in the above example, than you will be notified
Xbeginning one day before and extending up to 10 days after.
X.PP
XIf you wish to have both of these features, I.E. a 2 week window
Xaround the given date, you can append "*Ww" or "*wW" to the
Xweek day.
X.SH EXTENDED MESSAGES
X.I Calendar
Xwill recognize lines with leading blanks or tabs as extensions
Xto a line with a matched (the date given is "today") date. This allows
Xcomments longer than one line to be present for any given date. Below
Xis an example date specification.
X.sp
XWednesday
X.br
X Backups...
X.br
X Check all printers for paper, ribbons, etc.
X.sp
X.SH YOUR CALENDAR OR EVERYBODY'S
XWhen an argument is present,
X.I calendar
Xdoes its job for every user who has a file `calendar' in their
Xlogin directory and sends them any positive results by
X.IR mail (1).
XNormally this is done daily in the wee hours under control of
X.IR cron (8).
X.sp 2
X.SH SAMPLE FILE
X.nf
XJuly Get the budget ready for the new fiscal year
X.br
XMonday Check all printers for paper...
X.br
X Check MMDF, MDQS, and UUCP
X.br
XWednesday Backups are tonight...
X.br
XFriday Lets go party....
X.br
X6/17 John's b'day
X.br
X Mark's b'day
X.br
X.fi
X.SH FILES
X$HOME/calendar The users' calendar, $HOME is taken
X.br
X from /etc/passwd
X.br
X/usr/lib/calendar processes each users' `calendar' file.
X.br
X/etc/passwd Source of home directories.
X.br
X/tmp/Cal* Output data file used to assure that
X.br
X there are no null messages.
X.br
Xsed, mail Subprocesses
X.SH "SEE ALSO"
Xat(1), cron(8), mail(1)
X.SH BUGS
XIn general, your calendar must be readable by the public. See your system
Xadministrator for the specifics.
X.I Calendar's
Xextended idea of `tomorrow' doesn't account for holidays.
XLines containing erroneous data are silently ignored.
X.SH "CREDITS TO"
XGregg Wonderly
X.br
XOklahoma State University
!FUNKY!STUFF!
echo x - calendar.c
sed '1,$s/^X//' <<\!FUNKY!STUFF! > calendar.c
X/****************************************************************************
X
X F A S T C A L E N D A R
X
X This C program is a faster more general version of the
X standard UNIX utility CALENDAR(1). It recognizes the following
X formats for dates.
X
X numeric/numeric As is 1/12, 01/12, 12/1, ...
X
X 3-charmonth[any chars] numeric As in January 12, Jan. 12,
X jan. 12, JAN. 12, ...
X
X 3-charweekday[any chars] As in Friday, Monday, MON.,
X mon., tue, wed, ...
X
X numeric month A month from 1 to 12 as in
X 1, 2, 04, 12, ...
X
X Any lines, following a line that is matched, that have "whitespace"
X in the first column will be printed along with the matched line.
X
X****************************************************************************/
X
X#include <stdio.h>
X#include <ctype.h>
X#include <sys/types.h>
X#include <time.h>
X#include <pwd.h>
X
X/* Number of seconds in a day. */
X
X#define DAY (24*3600)
X
X/* Remove this for SYS5 machines, or others with strchr instead of index. */
X
X/* #define strchr index */
X
X/* Global input line. */
X
Xchar datebuf[300], *getdate();
X
Xmain (argc, argv)
X int argc;
X char **argv;
X{
X register char *s;
X char success;
X struct passwd *passwd, *getpwuid();
X register char file[200];
X register FILE *fp;
X register int i;
X
X /*
X Use file passed as an argument if it is there,
X otherwise use file in home directory.
X */
X
X if (argc <= 1) {
X if ((passwd = getpwuid (getuid())) == (struct passwd *)0) {
X perror ("Hi Dennis, the compiler is still broke\n");
X exit(1);
X }
X if (passwd -> pw_dir != (char *)0)
X strcpy (file, passwd -> pw_dir);
X strcat (file, "/calendar");
X } else {
X strcpy (file, argv[1]);
X }
X
X /* Open the input file. */
X
X if ((fp = fopen (file, "r")) == NULL) {
X perror (file);
X exit (1);
X }
X
X /* Initially, no success. */
X
X success = 0;
X
X /* Loop till EOF is encountered. */
X
X while (s = getdate(fp, &success)) {
X
X /* Check date for "NOW" */
X
X if (isnow (datebuf)) {
X
X /* Print it, it is valid. */
X
X printf(s);
X } else {
X
X /* Reset the "print lines with leading blanks" flag. */
X
X success = 0;
X }
X }
X
X /* Close up and exit. */
X
X fclose (fp);
X exit (0);
X}
X
X/*
X Check the input line, and get only the lines without leading
X "whitespace". Conditionally print those lines with leading blanks,
X based on the "success" flag.
X*/
X
Xchar *getdate(fp, success)
X char *success;
X register FILE *fp;
X{
X register int c;
X static char inbuf[300];
X register char *t, *s;
X
X t = inbuf;
X s = datebuf;
X
X /* Skip leading space. */
X
X while ((c = getc(fp)) <= ' ' && c != EOF) {
X ungetc(c, fp);
X fgets (inbuf, 300, fp);
X
X /* Print the line if we previously printed a match. */
X
X if (*success)
X printf (inbuf);
X }
X
X /* Assume success for now. */
X
X *success = 1;
X
X /* Return EOF if we are there. */
X
X if (c == EOF)
X return ((char *)0);
X
X /* Unget the character. */
X
X ungetc (c, fp);
X
X /* Get the input line. */
X
X fgets (t, 300, fp);
X
X /* Make a copy of it. */
X
X strcpy (s, t);
X
X return (inbuf);
X}
X
X/* Month definitions. */
X
Xchar *months[] = {
X "JAN", "FEB", "MAR",
X "APR", "MAY", "JUN",
X "JUL", "AUG", "SEP",
X "OCT", "NOV", "DEC"
X};
X
X/* Weekday definitions. */
X
Xchar *weekdays[] = {
X "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"
X};
X
X/* See if the passed string has a "NOW" date in it. */
X
Xisnow (datebuf)
X char *datebuf;
X{
X char *s, *t;
X long l;
X register int before = 0, after = 0, i, offset, month, day;
X register struct tm *tmptr;
X long timenow;
X
X /* Get the current time. */
X
X time (&timenow);
X tmptr = localtime (&timenow);
X
X /* Is the first character a digit in a Month? */
X
X t = datebuf;
X if (isdigit (*t) && (month = getnum (&t) - 1) >= 0 && month < 12) {
X
X /* Find the separating slash. */
X
X if (s = (char *) strchr (t, '/'))
X t = s + 1;
X else if (tmptr -> tm_mon == month)
X return (1);
X else
X return (0);
X
X /* Is the string a month name? */
X
X } else if ((month = ischmonth (t)) >= 0) {
X
X /* Skip till while space. */
X
X while (!isspace (*t) && *t)
X ++t;
X
X /* Skip to first NON-white space. */
X
X while (isspace (*t) && *t)
X ++t;
X
X /* Not a month, so try a DAY as in Friday, Saturday, etc... */
X
X } else if ((day = ischday (datebuf)) >= 0) {
X
X /* Is this today? */
X
X if (day == tmptr -> tm_wday || ((day + 6)%7) == tmptr -> tm_wday)
X return (1);
X else
X return (0);
X } else {
X
X /* Fail to recognize any other data as a valid date. */
X
X return (0);
X }
X
X /* Is there only what looks to be a month? If so, then OK. */
X
X if (!*t || !isdigit (*t)) {
X
X /* Is it this month? */
X
X if (tmptr -> tm_mon == month)
X return (1);
X
X return (0);
X }
X
X /* Calculate the value of the day. */
X
X day = getnum (&t);
X
X /* Check for *w or *W extended week specifiers. */
X
X if (*t == '*') {
X if (t[1] == 'w')
X ++before;
X if (t[1] == 'W')
X ++after;
X if (t[2] == 'W')
X ++after;
X if (t[2] == 'w')
X ++before;
X }
X
X /* Set weekend offset. */
X
X offset = 1;
X
X /* Get offset based on the weekend. */
X
X switch (tmptr -> tm_wday) {
X case 5:
X ++offset;
X
X case 6:
X ++offset;
X
X default:
X ++offset;
X }
X
X /* Step through all dates by DAY. */
X
X l = timenow - (after * 7 * DAY);
X
X while (l < timenow + (before * 7 * DAY) + (offset * DAY)) {
X if (istoday (l, month, day))
X return (1);
X
X l += DAY;
X }
X
X /* Return failure. */
X
X return (0);
X}
X
X/*
X Check if the string s is a DAY of the week as in monday, tues,
X wed, THU., or any derivative thereof.
X*/
X
Xischday (s)
X register char *s;
X{
X register char *tt;
X register int i, found = 0, c;
X register char t[30];
X
X /* Copy the input, and capitalize it. */
X
X for (tt = t, i=0; isalpha(*s) && i < 28; ++i)
X *tt++ = islower (c = *s++) ? toupper (c) : c;
X
X *tt = '\0';
X
X /* Search the list of valid day names for the string. */
X
X for (i = 0; i < 7; ++i) {
X if (strncmp (t, weekdays[i], 3) == 0) {
X found++;
X break;
X }
X }
X
X /* Return the numeric equivalent if we found it. */
X
X if (found)
X return (i);
X
X /* Return invalid day name. */
X
X return (-1);
X}
X
X/*
X Check if the string s is a valid derivative of the name of a
X month as in JUNE, jun, August, etc...
X*/
X
Xischmonth (s)
X register char *s;
X{
X register char *tt;
X register int i, found = 0, c;
X register char t[30];
X
X /* Copy and capitalize. */
X
X for (tt = t, i=0; isalpha(*s) && i < 28; ++i)
X *tt++ = islower (c = *s++) ? toupper (c) : c;
X
X *tt = '\0';
X
X /* Look through the list for a match. */
X
X for (i = 0; i < 12; ++i) {
X if (strncmp (t, months[i], 3) == 0) {
X found++;
X break;
X }
X }
X
X /* Return the numeric equivalent if we found it. */
X
X if (found)
X return (i);
X
X /* Return faliure. */
X
X return (-1);
X}
X
X/*
X Scan the string *t, and evaluate any integer contained there.
X It is assumed that at least 1 digit exists (**t).
X*/
X
Xgetnum (t)
X char **t;
X{
X register int i, c;
X register char *s;
X
X i = 0;
X
X /* Get the starting address. */
X
X s = *t;
X
X /* Get the starting value from the first digit. */
X
X i = (c = *s++) - '0';
X
X /* Evaluate the rest of the digits (if any). */
X
X while (isdigit (c = *s++))
X i = i * 10 + (c - '0');
X
X /* Set the new address. */
X
X *t = --s;
X
X /* Return the value. */
X
X return (i);
X}
X
X/*
X Return whether or not the time t corresponds to the month and day.
X*/
X
Xistoday (t, month, day)
X long t;
X register int month, day;
X{
X register struct tm *tm;
X
X tm = localtime(&t);
X
X return (tm -> tm_mon == month && tm -> tm_mday == day);
X}
!FUNKY!STUFF!
echo x - calendar.doc
sed '1,$s/^X//' <<\!FUNKY!STUFF! > calendar.doc
X
X
X
X CCCCAAAALLLLEEEENNNNDDDDAAAARRRR((((1111)))) UUUUNNNNIIIIXXXX 5555....0000 ((((OOOOkkkkllllaaaahhhhoooommmmaaaa SSSSttttaaaatttteeee UUUUnnnniiiivvvveeeerrrrssssiiiittttyyyy)))) CCCCAAAALLLLEEEENNNNDDDDAAAARRRR((((1111))))
X
X
X
X NNNNAAAAMMMMEEEE
X calendar - reminder service
X
X SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
X ccccaaaalllleeeennnnddddaaaarrrr [ - ]
X
X DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
X _C_a_l_e_n_d_a_r consults the file `calendar' in the user's home
X directory and prints out lines that contain today's,
X tomorrow's, or a proper future date at the beginning of the
X line. Most reasonable month-day dates such as `Dec. 7,'
X `december 7,' `12/7,' etc., are recognized, but not `7
X December' or `7/12'. On weekends `tomorrow' extends through
X Monday.
X
X _C_a_l_e_n_d_a_r also supports months and days of the week by
X themselves. This allows you to specify things on a weekly
X or monthly basis. The format for weekday names is the same
X as that for month names; Mon., monday, tues, tue, wed, etc.
X The month may be specified either by name, or by number.
X The weekday will only be recognized by name.
X
X EEEEXXXXTTTTEEEENNNNDDDDEEEEDDDD NNNNOOOOTTTTIIIIFFFFIIIICCCCAAAATTTTIIIIOOOONNNN
X If you wish to have _e_x_t_e_n_d_e_d notification of a previous or
X upcoming event, _c_a_l_e_n_d_a_r supports a notation that extends a
X date by a week.
X
X If "*w" is appended directly to the week day, I.E. 12/7*w,
X then you will be sent a reminder every day beginning
X approximately (depending on the weekend) 7 days prior to the
X date.
X
X If "*W" (note the significance of case "w" or "W") is
X appended to the week day as in the above example, than you
X will be notified beginning one day before and extending up
X to 10 days after.
X
X If you wish to have both of these features, I.E. a 2 week
X window around the given date, you can append "*Ww" or "*wW"
X to the week day.
X
X EEEEXXXXTTTTEEEENNNNDDDDEEEEDDDD MMMMEEEESSSSSSSSAAAAGGGGEEEESSSS
X _C_a_l_e_n_d_a_r will recognize lines with leading blanks or tabs as
X extensions to a line with a matched (the date given is
X "today") date. This allows comments longer than one line to
X be present for any given date. Below is an example date
X specification.
X
X Wednesday
X Backups...
X Check all printers for paper, ribbons, etc.
X
X
X
X
X Page 1 (last mod. 3/12/86)
X
X
X
X
X
X
X CCCCAAAALLLLEEEENNNNDDDDAAAARRRR((((1111)))) UUUUNNNNIIIIXXXX 5555....0000 ((((OOOOkkkkllllaaaahhhhoooommmmaaaa SSSSttttaaaatttteeee UUUUnnnniiiivvvveeeerrrrssssiiiittttyyyy)))) CCCCAAAALLLLEEEENNNNDDDDAAAARRRR((((1111))))
X
X
X
X YYYYOOOOUUUURRRR CCCCAAAALLLLEEEENNNNDDDDAAAARRRR OOOORRRR EEEEVVVVEEEERRRRYYYYBBBBOOOODDDDYYYY''''SSSS
X When an argument is present, _c_a_l_e_n_d_a_r does its job for every
X user who has a file `calendar' in their login directory and
X sends them any positive results by _m_a_i_l(1). Normally this
X is done daily in the wee hours under control of _c_r_o_n(8).
X
X
X
X SSSSAAAAMMMMPPPPLLLLEEEE FFFFIIIILLLLEEEE
X July Get the budget ready for the new fiscal year
X Monday Check all printers for paper...
X Check MMDF, MDQS, and UUCP
X Wednesday Backups are tonight...
X Friday Lets go party....
X 6/17 John's b'day
X Mark's b'day
X
X FFFFIIIILLLLEEEESSSS
X $HOME/calendar The users' calendar, $HOME is taken
X from /etc/passwd
X /usr/lib/calendar processes each users' `calendar' file.
X /etc/passwd Source of home directories.
X /tmp/Cal* Output data file used to assure that
X there are no null messages.
X sed, mail Subprocesses
X
X SSSSEEEEEEEE AAAALLLLSSSSOOOO
X at(1), cron(8), mail(1)
X
X BBBBUUUUGGGGSSSS
X In general, your calendar must be readable by the public.
X See your system administrator for the specifics. _C_a_l_e_n_d_a_r'_s
X extended idea of `tomorrow' doesn't account for holidays.
X Lines containing erroneous data are silently ignored.
X
X CCCCRRRREEEEDDDDIIIITTTTSSSS TTTTOOOO
X Gregg Wonderly
X Oklahoma State University
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X Page 2 (last mod. 3/12/86)
X
X
X
!FUNKY!STUFF!
echo x - calendar.sh
sed '1,$s/^X//' <<\!FUNKY!STUFF! > calendar.sh
X#
X# Replacement calendar program
X# By: Gregg Wonderly <gregg@okstate> on 01/24/86
X
XPATH=/bin:/usr/bin
Xtmp=/tmp/Cal$$
Xcal="calendar"
Xlib=/usr/lib
Xtrap "rm $tmp;exit" 1 2 13 15
X
Xcase $1 in
X-)
X sed 's/\([^:]*\):.*:\(.*\):[^:]*$/dir=\2 login=\1/' /etc/passwd | \
X while read x
X do
X eval $x
X if test -r $dir/$cal; then
X $lib/calendar $dir/$cal >$tmp
X if test -s $tmp; then
X /bin/mail $login -f "Reminder Service" <$tmp >/dev/null 2>&1
X fi
X rm $tmp
X fi
X done;;
X*)
X $lib/calendar;;
Xesac
!FUNKY!STUFF!
echo x - makefile
sed '1,$s/^X//' <<\!FUNKY!STUFF! > makefile
XLIB=/usr/lib
XBIN=/bin
XCFLAGS=-i -O
X
Xcalendar: calendar.c
X cc $(CFLAGS) calendar.c -o calendar
X
Xinstall: calendar calendar.sh
X cp calendar.sh $(BIN)/calendar
X cp calendar $(LIB)/calendar
X chmod 511 $(LIB)/calendar $(BIN)/calendar
!FUNKY!STUFF!