dfs@doe.carleton.ca (David F. Skoll) (11/17/90)
#!/bin/sh # This is part 05 of Remind-2.2 if touch 2>&1 | fgrep 'amc' > /dev/null then TOUCH=touch else TOUCH=true fi # ============= timed.c ============== if test X"$1" != X"-c" -a -f 'timed.c'; then echo "File already exists: skipping 'timed.c'" else echo "x - extracting timed.c (Text)" sed 's/^X//' << 'SHAR_EOF' > timed.c && X#include <stdio.h> X#include <signal.h> X#include <malloc.h> X#include "defines.h" X#include "globals.h" X#include "protos.h" X X/***************************************************************/ X/* */ X/* TIMED.C */ X/* */ X/* Contains routines for triggering timed reminders */ X/* */ X/* By David Skoll - 12 Nov 1990 */ X/* */ X/* (C) 1990 by David Skoll */ X/* */ X/***************************************************************/ X X/* Global pointer to AT reminders */ X Xstatic AtEntry AtQueue = X{ X 0, 0, 0, 0, 0, NULL, NULL X}; X X/***************************************************************/ X/* */ X/* AddEntry */ X/* */ X/* Add an entry to the AT queue, keeping things sorted by */ X/* trigger time. */ X/* */ X/* Returns 0 for success, nonzero for failure */ X/* */ X/***************************************************************/ Xint AddEntry(e) XAtEntry *e; X{ X AtEntry *current, *prev; X prev = &AtQueue; X current = prev->next; X while (current) { X if (e->firsttime < current->firsttime) { X prev->next = e; X e->next = current; X break; X } else { X prev = current; X current = prev->next; X } X } X if (!current) { X prev->next = e; X e->next = NULL; X } X} X X/***************************************************************/ X/* */ X/* DoAt */ X/* Creates an entry for an At reminder, puts it on the queue */ X/* Updates the global variable NumAtsQueued */ X/* */ X/***************************************************************/ X#ifndef UNIX Xint DoAt(int tim, int tdelta, int trep, char *body, enum Token_t type) X#else Xint DoAt(tim, tdelta, trep, body, type) Xint tim, tdelta, trep; Xchar *body; Xenum Token_t type; X#endif X{ X AtEntry *e; X int curtime; X X curtime = (int) (SystemTime() / 60); X X /* If the trigger time is in the past, don't add to the at queue */ X if (tim < curtime) return 0; X X /* Allocate space for the entry */ X e = (AtEntry *) malloc(sizeof(AtEntry)); X if (e == (AtEntry *) NULL) { X Eprint("Can't malloc memory for AT!\n"); X return 1; X } X e->text = malloc(strlen(body)+1); X if (e->text == NULL) { X Eprint("Can't malloc memory for body of AT!\n"); X return 1; X } X strcpy(e->text, body); X X /* Find out the next trigger time */ X e->firsttime = FindNextTriggerTime(tim, trep, tdelta, curtime); X e->repeat = trep; X e->type = type; X e->time = tim; X e->delta = tdelta; X AddEntry(e); X NumAtsQueued++; X return 0; X} X X/***************************************************************/ X/* */ X/* int FindNextTriggerTime */ X/* */ X/* Returns the next time a queued AT should be triggered. */ X/* Returns -1 if the AT has expired. */ X/* */ X/***************************************************************/ X#ifndef UNIX Xint FindNextTriggerTime(int tim, int rep, int delta, int curtime) X#else Xint FindNextTriggerTime(tim, rep, delta, curtime) Xint tim, rep, delta, curtime; X#endif X{ X int trigger = tim; X X if (delta <= 0) X if (trigger < curtime) return -1; else return trigger; X X trigger -= delta; X if (rep == -1) rep = delta; X X if (trigger < curtime) trigger += ((curtime - trigger) / rep) * rep; X if (trigger < curtime) trigger += rep; X if (trigger > tim) trigger = tim; X if (trigger < curtime) return -1; else return trigger; X} X X/***************************************************************/ X/* */ X/* HandleQueuedAts */ X/* */ X/* Handles all the queued AT reminders. Sits in a sleep loop */ X/* to trigger reminders. */ X/* */ X/***************************************************************/ Xvoid HandleQueuedAts() X{ X AtEntry *e; X long TimeToSleep; X unsigned SleepTime; X long now; X 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 X /* Be paranoid and assume that unsigneds are only two bytes long - X therefore, do the sleeping in 30000-second chunks. */ X X while (TimeToSleep) { X if (TimeToSleep > 30000L) SleepTime = 30000; X else SleepTime = (unsigned) TimeToSleep; X sleep(SleepTime); X TimeToSleep -= (long) SleepTime; X } X X /* Over here, we trigger the reminder */ X DoSubst(e->text, WorkBuf, CurDay, CurMon, CurYear, JulianToday, e->type, e->time); X if (e->type == Run_t) system(WorkBuf); X else printf("%s\n", WorkBuf); X X /* Remove the entry from the queue */ X AtQueue.next = e->next; X X /* Check if this reminder should be re-triggered */ X e->firsttime = FindNextTriggerTime(e->time, e->repeat, X e->delta, e->firsttime + 1); X X if (e->firsttime != -1) AddEntry(e); X else { X /* Not to be added - free the memory */ X free(e->text); X free(e); X } X } X} X X/***************************************************************/ X/* */ X/* SigHupHandler */ X/* */ X/* For debugging purposes, when sent a HUP, we print the */ X/* contents of the queue. */ X/* */ X/***************************************************************/ Xvoid SigHupHandler() X{ X AtEntry *e; X X printf("Contents of AT queue:\n"); X X e = AtQueue.next; X while (e) { X printf("Trigger: %02d:%02d Activate: %02d:%02d Rep: %d Delta: %d\n", X e->time / 60, e->time % 60, e->firsttime / 60, e->firsttime % 60, X e->repeat, e->delta); X printf("Text: %s %s\n\n", ((e->type == Msg_t) ? "MSG" : "RUN"), e->text); X e = e->next; X } X printf("\n"); X} SHAR_EOF $TOUCH -am 1115093590 timed.c && chmod 0600 timed.c || echo "restore of timed.c failed" set `wc -c timed.c`;Wc_c=$1 if test "$Wc_c" != "7436"; then echo original size 7436, current size $Wc_c fi fi exit 0