Path: utzoo!dciem!nrcaer!cunews!dfs From: dfs@doe.carleton.ca (David F. Skoll) Newsgroups: alt.sources Subject: REMIND 2.2 Patch 03 Message-ID: Date: 28 Nov 90 17:05:43 GMT Sender: news@ccs.carleton.ca (news) Organization: Carleton University, Ottawa, Canada Lines: 822 This is Patch 03 for Remind; read the shar for more information. You must have Remind 2.2, patchlevel 2 before applying this patch. -- David F. Skoll #!/bin/sh # This is Remind-2.2-patch.03, a shell archive (shar 3.32) # made 11/28/1990 16:56 UTC by dfs@yar # Source directory /enterprise/transporter/dfs/work/.rem/work # # existing files will NOT be overwritten # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 20501 -rw------- patch.03 # 1034 -rwx------ kall # # # This patch fixes the following problems: # - Calendar now uses correct OMIT context # - Calendar now correctly formats words that "just" fit # - stdout not flushed when REMIND forked - this could result in extra # reminders if you pipe the output to a file - has been fixed # - Makefile made more configurable # - Type inconsistency in 'timed.c' fixed # - Bug in calendar formatting fixed # - Man page corrected and updated # This patch adds the following features: # - OMIT commands can have MSG or RUN components to reduce redundancy # - RUN reminders can be placed in the calendar if you so specify # - REMIND will not terminate if it finds that stdout is no longer a tty. # You must explicitly kill it - hence the kall script. # The kall script is a script to kill processes whose command-name matches # a string. For example, if you want to kill all your remind processes # when you log out, put 'kall remind' in your .logout file. Read the # script for more information. NOTE: You may (in fact, you probably will) # have to edit the script to suit your flavour of 'ps' if touch 2>&1 | fgrep 'amc' > /dev/null then TOUCH=touch else TOUCH=true fi # ============= patch.03 ============== if test X"$1" != X"-c" -a -f 'patch.03'; then echo "File already exists: skipping 'patch.03'" else echo "x - extracting patch.03 (Text)" sed 's/^X//' << 'SHAR_EOF' > patch.03 && XPatch 03 - 28 November 1990 XFixes various problems and adds a couple of conveniences. X XThis patch modifies the Makefile to make it more configurable for Xvarious systems. X*** ../work-backup/Makefile Thu Nov 15 15:30:41 1990 X--- ./Makefile Wed Nov 28 09:50:37 1990 X*************** X*** 1,10 **** X--- 1,24 ---- X # Makefile for REMIND - simple file X X+ #--------------- BEGINNING OF THINGS YOU CAN CHANGE -------------- X+ X #If you have a BSD system: X CFLAGS= -O -DUNIX X X #If you have a SYSV system, comment previous line and uncomment next line: X #CFLAGS= -O -DUNIX -DSYSV X+ X+ #If your system does not include , uncomment next line: X+ #CFLAGS += -DNO_MALLOC_H X+ X+ #If you have a SYSV system which does not implement the pid_t type, X+ #uncomment the next line: X+ #CFLAGS += -Dpid_t=int X+ X+ #If you want to use gcc: X+ #CC= gcc X+ X+ #--------------- SHOULDN'T CHANGE STUFF BELOW HERE --------------- X X all: dorem.o files.o main.o nextdate.o init.o dosubst.o timed.o calendar.o cache.o X $(LINK.c) -o remind dorem.o files.o main.o nextdate.o init.o dosubst.o timed.o calendar.o cache.o X XThis patch allows you to specify whether or not you have XAlso caches OMIT statements as well as REMs X*** ../work-backup/cache.c Fri Nov 16 13:38:47 1990 X--- ./cache.c Wed Nov 28 10:03:06 1990 X*************** X*** 9,15 **** X--- 9,17 ---- X /***************************************************************/ X X #include X+ #ifndef NO_MALLOC_H X #include X+ #endif X #ifndef UNIX X #include X #endif X*************** X*** 83,89 **** X X s = Line; X tok = ParseToken(&s); X! if (tok.type == Rem_t) { /* Yup, this is a REM, so cache it */ X c = (Centry *) malloc(sizeof(Centry)); X if (c == NULL) { X CacheFailed = 1; X--- 85,92 ---- X X s = Line; X tok = ParseToken(&s); X! if (tok.type == Rem_t || tok.type == Omit_t) { X! /* Yup, this is a REM or OMIT, so cache it */ X c = (Centry *) malloc(sizeof(Centry)); X if (c == NULL) { X CacheFailed = 1; X*************** X*** 126,131 **** X--- 129,138 ---- X void ResetCache() X #endif X { X+ /* Reset the OMIT context */ X+ NumFullOmit = 0; X+ NumPartOmit = 0; X+ X if (CacheFailed) OpenFile(FileName); X else Current = Cache.next; X } X XThis patch allows you to specify whether or not you have XAlso fixes formatting of output if a word will *just* fit in the calendar. XFixes the OMIT context for calendar creation. X*** ../work-backup/calendar.c Fri Nov 16 09:57:28 1990 X--- ./calendar.c Wed Nov 28 10:55:11 1990 X*************** X*** 9,15 **** X--- 9,17 ---- X /* */ X /***************************************************************/ X #include X+ #ifndef NO_MALLOC_H X #include X+ #endif X #include X #ifndef UNIX X #include X*************** X*** 46,52 **** X X /* Make function prototypes local - they're not used anywhere else */ X #ifndef UNIX X! CalEntry *CreateCalEntry(void); X void AddCalEntry(CalEntry *e); X void EmitOneCalendarLine(void); X void InitCalendar(int m, int y); X--- 48,54 ---- X X /* Make function prototypes local - they're not used anywhere else */ X #ifndef UNIX X! CalEntry *CreateCalEntry(int type); X void AddCalEntry(CalEntry *e); X void EmitOneCalendarLine(void); X void InitCalendar(int m, int y); X*************** X*** 207,213 **** X { X if (SimpleCalendar) return; X putchar('\f'); X- putchar('\n'); X } X X /***************************************************************/ X--- 209,214 ---- X*************** X*** 229,235 **** X used[DayOfWeek(JulianToday)] = CurDay; X if (GetLine()) break; X i = ProcessLine(); X! if (i) if (e = CreateCalEntry()) AddCalEntry(e); X } X X /* Now figure out if we should print the calendar */ X--- 230,236 ---- X used[DayOfWeek(JulianToday)] = CurDay; X if (GetLine()) break; X i = ProcessLine(); X! if (i>0) if (e = CreateCalEntry()) AddCalEntry(e); X } X X /* Now figure out if we should print the calendar */ X*************** X*** 299,309 **** X /* */ X /* Allocates and creates a calendar entry. */ X /* */ X /***************************************************************/ X #ifndef UNIX X! CalEntry *CreateCalEntry(void) X #else X! CalEntry *CreateCalEntry() X #endif X { X CalEntry *e; X--- 300,314 ---- X /* */ X /* Allocates and creates a calendar entry. */ X /* */ X+ /* Type = 1: MSG type = 2: RUN */ X+ /* */ X+ /* */ X /***************************************************************/ X #ifndef UNIX X! CalEntry *CreateCalEntry(int type) X #else X! CalEntry *CreateCalEntry(type) X! int type; X #endif X { X CalEntry *e; X*************** X*** 333,340 **** X s++; X } X X /* If we found one, look for another */ X! if (t != s) { X s = t; X while (*s) { X if (*s == '%' && *(s+1) == '\"') { X--- 338,351 ---- X s++; X } X X+ /* If it's a RUN type, and there's no %" mark, ignore it. */ X+ if (type == 2 && t == WorkBuf) { X+ free(e); X+ return NULL; X+ } X+ X /* If we found one, look for another */ X! if (t != WorkBuf) { X s = t; X while (*s) { X if (*s == '%' && *(s+1) == '\"') { X*************** X*** 377,383 **** X *t++ = '\n'; X while (isspace(*s)) s++; X } X! else if (column != 0 && column+l >= CalWidth) { X *t++ = '\n'; X column = 0; X if (l >= CalWidth) { X--- 388,394 ---- X *t++ = '\n'; X while (isspace(*s)) s++; X } X! else if (column != 0 && column+l > CalWidth) { X *t++ = '\n'; X column = 0; X if (l >= CalWidth) { X*************** X*** 401,407 **** X CopyWord(&s, &t, l); X while (isspace(*s)) s++; X *t++ = ' '; X! if (column == CalWidth) { X *(t-1) = '\n'; X column = 0; X } X--- 412,418 ---- X CopyWord(&s, &t, l); X while (isspace(*s)) s++; X *t++ = ' '; X! if (column > CalWidth) { X *(t-1) = '\n'; X column = 0; X } X*** ../work-backup/defines.h Thu Nov 15 09:41:13 1990 X--- ./defines.h Wed Nov 28 10:03:42 1990 X*************** X*** 13,19 **** X the number of fully-specified (dd-mm-yy) and partially-specified X (dd-mm) holidays. */ X #define BASE 1990 X! #define FOMITSIZE 100 X #define POMITSIZE 75 X X /* Useful macros */ X--- 13,19 ---- X the number of fully-specified (dd-mm-yy) and partially-specified X (dd-mm) holidays. */ X #define BASE 1990 X! #define FOMITSIZE 150 X #define POMITSIZE 75 X X /* Useful macros */ X*** ../work-backup/dorem.c Thu Nov 15 09:40:48 1990 X--- ./dorem.c Wed Nov 28 10:11:43 1990 X*************** X*** 242,252 **** X X jul = GetTriggerDate(d, m, y, wd, cons, back, repeat, omit); X if (Calendar) { X! if (jul == JulianToday && tok.type == Msg_t) { X while (isspace(**s)) (*s)++; X strcpy(WorkBuf, *s); X CalTime = tim; X! return 1; X } else return 0; X } X X--- 242,252 ---- X X jul = GetTriggerDate(d, m, y, wd, cons, back, repeat, omit); X if (Calendar) { X! if (jul == JulianToday) { X while (isspace(**s)) (*s)++; X strcpy(WorkBuf, *s); X CalTime = tim; X! if (tok.type == Run_t) return 2; else return 1; X } else return 0; X } X XThis patch allows you to specify whether or not you have X*** ../work-backup/files.c Thu Nov 15 09:39:23 1990 X--- ./files.c Wed Nov 28 09:43:02 1990 X*************** X*** 3,9 **** X--- 3,11 ---- X #include X #endif X #include X+ #ifndef NO_MALLOC_H X #include X+ #endif X #ifndef UNIX X #include X #endif X XThis patch updates the PATCHLEVEL to 3. X*** ../work-backup/init.c Wed Nov 28 09:40:24 1990 X--- ./init.c Wed Nov 28 10:23:26 1990 X*************** X*** 7,13 **** X #include "globals.h" X #include "protos.h" X X! #define PATCHLEVEL 2 X X static char DPMsg[] = "Debug and Purge options conflict - Purge chosen.\n"; X static char DPCMsg[] = "Calendar overrides Debug and Purge options.\n"; X--- 7,13 ---- X #include "globals.h" X #include "protos.h" X X! #define PATCHLEVEL 3 X X static char DPMsg[] = "Debug and Purge options conflict - Purge chosen.\n"; X static char DPCMsg[] = "Calendar overrides Debug and Purge options.\n"; X XThis patch modifies the OMIT command to allow MSG and RUN tokens. XAlso fixes the return values to allow OMIT to appear in a calendar. X*** ../work-backup/main.c Thu Nov 15 16:52:20 1990 X--- ./main.c Wed Nov 28 10:19:39 1990 X*************** X*** 221,228 **** 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--- 221,229 ---- X break; X X case Omit_t: i = DoGlobalOmit(&s); X+ if (Calendar) return i; X if (Purge && TopLevel()) X! if (i == -1) Eprint("Purged '%s'\n", Line); X else Output(Line); X break; X X*************** X*** 357,363 **** 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 X--- 358,364 ---- 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, -2 if problem. */ X /* */ X /***************************************************************/ X #ifndef UNIX X*************** X*** 371,399 **** 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--- 372,405 ---- X int omit; X int *ptr; X Token tok; X+ char *olds = *s; X X tok.type = Unknown_t; X! while(tok.type != Eol_t && tok.type != Run_t && tok.type != Msg_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! X! case Delta_t: X! case Eol_t: X! case Msg_t: X! case Run_t: break; X default: Eprint("Invalid token '%s' for OMIT command.\n", tok.str); X! return -2; X } X } X X if (d == -1 || m == -1 || CheckDate(d, m, y)) { X Eprint("Invalid date specification.\n"); X! return -2; X } X X if (y == -1) { /* Only mm-dd specified */ X if (NumPartOmit == POMITSIZE) { X Eprint("Too many partially-specified OMITs.\n"); X! return -2; X } X omit = (m << 5) + d; X ptr = PartOmitArray + NumPartOmit; X*************** X*** 413,422 **** 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--- 419,430 ---- X ptr++; X } X } X+ /* If we got a MSG or a RUN, then execute DoRem */ X+ if (tok.type == Run_t || tok.type == Msg_t) return DoRem(&olds); X } else { /* All three specified */ X if (NumFullOmit == FOMITSIZE) { X Eprint("Too many fully-specified OMITs.\n"); X! return -2; X } X omit = Julian(d, m, y); X if (omit < JulianToday) { X*************** X*** 441,446 **** X--- 449,456 ---- X ptr++; X } X } X+ /* If we got a MSG or a RUN, then execute DoRem */ X+ if (tok.type == Run_t || tok.type == Msg_t) return DoRem(&olds); X } X return 0; X } X*************** X*** 606,612 **** X { X int t; X X! if (jul < 0) return 1; X X if (jul >= JulFirst && JulFirst != -1) { X *y = FirstYear; X--- 616,622 ---- X { X int t; X X! if (jul < 0) return -1; X X if (jul >= JulFirst && JulFirst != -1) { X *y = FirstYear; X*************** X*** 753,758 **** X--- 763,771 ---- X printf("%d reminder%s queued for later today.\n", NumAtsQueued, X (NumAtsQueued == 1) ? "" : "s"); X X+ fflush(stdout); /* Flush output so we don't get 2 copies when directing */ X+ /* stdout to a file. */ X+ X if (NumAtsQueued) { X pid = fork(); X if (pid == -1) Eprint("Can't fork to perform ATs!\n"); X XThis patch fixes some errors in the manual, clears up some omissions, and Xadds some more useful information. X*** ../work-backup/remind.1 Wed Nov 28 09:40:24 1990 X--- ./remind.1 Wed Nov 28 11:04:22 1990 X*************** X*** 57,68 **** X option is not compatible with the \fB\-p\fR or \fB\-d\fR options. X .TP X .B \-w\fR\fIn\fR X! The \fB\-w\fR flag causes \fBremind\fR to format the calendar for a device X whose output width is \fIn\fR columns. The default is to produce a calendar X for an 80-column device. X .TP X .B \-s X! The \fB\-s\fB flag causes \fBremind\fR to send an unformatted "simple X calendar" listing to standard output. This can be used if you wish to X format the calendar with another program rather than using \fBremind\fR's X built-in calendar format. X--- 57,70 ---- X option is not compatible with the \fB\-p\fR or \fB\-d\fR options. X .TP X .B \-w\fR\fIn\fR X! The \fB\-w\fR flag, when used in conjunction with \fB\-c\fR, X! causes \fBremind\fR to format the calendar for a device X whose output width is \fIn\fR columns. The default is to produce a calendar X for an 80-column device. X .TP X .B \-s X! The \fB\-s\fB flag, when used in conjunction with \fB\-c\fR, X! causes \fBremind\fR to send an unformatted "simple X calendar" listing to standard output. This can be used if you wish to X format the calendar with another program rather than using \fBremind\fR's X built-in calendar format. X*************** X*** 839,844 **** X--- 841,861 ---- X with business reminders (for which omission of holidays is appropriate) X following the X .I global OMITs. X+ .PP X+ For convenience, you can include a \fIdelta\fR and a \fIMSG\fR or \fIRUN\fR X+ token in a global \fIOMIT\fR. This is useful to avoid duplication of holiday X+ entries. For example, the line: X+ .PP X+ .nf X+ OMIT 25 Dec +2 MSG %"Christmas%" is %b. X+ .fi X+ .PP X+ is exactly equivalent to: X+ .PP X+ .nf X+ OMIT 25 Dec X+ REM 25 Dec +2 MSG %"Christmas%" is %b. X+ .fi X .SH THE INCLUDE COMMAND X The X .I INCLUDE X*************** X*** 1056,1067 **** X causes the need for the "...ago" forms. X .TP X .B %2 X! is replaced with "at \fIhh\fR:\fImm\fRam" or "..pm" depending on the X .I AT X time of the reminder. X .TP X .B %3 X! is replaced with "at \fIhh\fR:\fImm\fR" in 24-hour format. X .TP X .B %4 X is replaced with "\fImm\fR" where \fImm\fR is the number of minutes between X--- 1073,1084 ---- X causes the need for the "...ago" forms. X .TP X .B %2 X! is replaced with "\fIhh\fR:\fImm\fRam" or "..pm" depending on the X .I AT X time of the reminder. X .TP X .B %3 X! is replaced with "\fIhh\fR:\fImm\fR" in 24-hour format. X .TP X .B %4 X is replaced with "\fImm\fR" where \fImm\fR is the number of minutes between X*************** X*** 1167,1176 **** X being entered into the calendar, and the time of each reminder is printed X before the reminder text. X .PP X! Note that only \fIMSG\fR reminders are included in the calendar; \fIRUN\fR X! reminders are ignored. If you indicate empty text for the calendar entry X with the sequence \fB%"%"\fR, then the reminder is ignored when producing X! the calendar. X .SH THE BANNER COMMAND X When X .B remind X--- 1184,1203 ---- X being entered into the calendar, and the time of each reminder is printed X before the reminder text. X .PP X! Note that by default, only \fIMSG\fR reminders are included in the calendar; X! \fIRUN\fR reminders are ignored. However, if you explicitly place the %" X! escape sequences in a \fIRUN\fR reminder, then it will be included in the X! calendar. X! If you indicate empty text for the calendar entry X with the sequence \fB%"%"\fR, then the reminder is ignored when producing X! the calendar, whether is is a \fIMSG\fR or \fIRUN\fR type. X! .PP X! If your reminder file has errors in it, when you produce a calendar, you X! will get many error messages apparently coming from the file "*cache*" X! This is because \fBremind\fR caches the reminder file for efficient X! production of the calendar. Thus, you should check that your reminder X! file is error-free (by running \fBremind\fR with the \fB\-\d\fR option) X! before attempting to produce a calendar. X .SH THE BANNER COMMAND X When X .B remind X*************** X*** 1263,1269 **** X .PP X .nf X REM 5 Feb 1991 AT 14:00 +45 *30 \\ X! RUN mail -s "Meeting %2" $LOGNAME XAlso fixes a type mismatch that some compilers complained about. X*** ../work-backup/timed.c Thu Nov 15 09:35:21 1990 X--- ./timed.c Wed Nov 28 10:01:12 1990 X*************** X*** 1,6 **** X--- 1,8 ---- X #include X #include X+ #ifndef NO_MALLOC_H X #include X+ #endif X #include "defines.h" X #include "globals.h" X #include "protos.h" X*************** X*** 21,27 **** X X static AtEntry AtQueue = X { X! 0, 0, 0, 0, 0, NULL, NULL X }; X X /***************************************************************/ X--- 23,29 ---- X X static AtEntry AtQueue = X { X! 0, 0, 0, 0, Unknown_t, NULL, NULL X }; X X /***************************************************************/ X*************** X*** 151,160 **** X signal(SIGHUP, SigHupHandler); X X while (e = AtQueue.next) { X- /* Check if the user has logged off. If so, die gracefully. */ X- if (!isatty(1)) { X- exit(0); X- } X now = SystemTime(); X TimeToSleep = (long) e->firsttime * 60L - now; X if (TimeToSleep < 0L) TimeToSleep = 0L; X--- 153,158 ---- SHAR_EOF $TOUCH -am 1128112390 patch.03 && chmod 0600 patch.03 || echo "restore of patch.03 failed" set `wc -c patch.03`;Wc_c=$1 if test "$Wc_c" != "20501"; then echo original size 20501, current size $Wc_c fi fi # ============= kall ============== if test X"$1" != X"-c" -a -f 'kall'; then echo "File already exists: skipping 'kall'" else echo "x - extracting kall (Text)" sed 's/^X//' << 'SHAR_EOF' > kall && X#!/bin/sh X# X# kall - kill all processes belonging to this user that match X# specified string. X Xsignal=`echo $1 | grep '^\-.*'` Xme=`basename $0` X Xif [ "$signal" != "" ]; then X shift Xelse X signal="-TERM" Xfi X Xif [ "$1" = "" ]; then X echo "usage: $me [-signal] string [string...]" X echo " kills all of your processes where command name matches" X echo " any of the given strings." X exit Xfi X Xmsg="0" X Xwhile [ "$1" != "" ]; do X X# NOTE: You may have to modify the next line, since PS is non-portable. X# Basically, we list all processes owned by this user, edit out the 'kall' X# process itself, and collect all processes matching $1. This is accomplished X# by the 'sed' command. The 'awk' command picks out the process IDs to pass X# them on to kill. X rprocs=`ps -cx | sed -n -e /$me/d -e /$1/p | awk '{print $1}'` X if [ "$rprocs" != "" ]; then X msg="1" X echo -n "${me}: Sending $signal signal to $1 process(es)" X echo '...' X kill $signal $rprocs X fi X shift Xdone X Xif [ $msg = "1" ]; then X echo "${me}: Done." Xfi SHAR_EOF $TOUCH -am 1128115390 kall && chmod 0700 kall || echo "restore of kall failed" set `wc -c kall`;Wc_c=$1 if test "$Wc_c" != "1034"; then echo original size 1034, current size $Wc_c fi fi exit 0 Brought to you by Super Global Mega Corp .com