REMIND 2.2 05/05
David F. Skoll
dfs at doe.carleton.ca
Sat Nov 17 05:48:57 AEST 1990
#!/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
More information about the Alt.sources
mailing list