home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Header: calencheck.c,v 2.1 89/12/15 17:04:41 billr Exp $
- *
- * calencheck.c - check for pending appts without the overhead
- * of the full blown calentool
- *
- * Copyright (C) 1989 Tektronix, Inc.
- * All Rights Reserved
- * Permission is hereby granted to use and modify this file in source
- * or binary form as long as it is not sold for profit and this copyright
- * notice remains intact.
- */
-
- #include <stdio.h>
- #include <sys/time.h>
- #include <sys/file.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sunwindow/defaults.h>
- #include "ct.h"
-
- int read_only = 1; /* no modifications allowed */
- int n_tslots, otherfile = 0;
- int day_is_open;
- int include_old = 0, save_old = 0;
- struct tm current, today;
- struct tm First, Last;
- char *progname, *othername;
- struct dayslot slots[N_SLOTS];
- int show_future = 1;
- int one_based = 0, version2 = 0;
- char apts_pathname[160], tmpapts_pathname[2];
- char apts_dir[128], lib_dir[128];
- char *strcpy(), *strcat(), *rindex(), *getenv();
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int flag;
- extern char *optarg;
-
- if (progname = rindex(*argv, '/'))
- progname++;
- else
- progname = *argv;
-
- n_tslots = (N_TSLOTS > N_SLOTS ? N_SLOTS : N_TSLOTS);
-
- get_today(); /* initial day is today */
- current = today;
-
- while ((flag = getopt(argc, argv, "f:")) != EOF)
- switch (flag) {
- case 'f': /* use this file */
- otherfile = 1;
- othername = optarg;
- break;
-
- case '?':
- default:
- fprintf(stderr, "usage: %s [-f <appt_file>]\n", progname);
- exit(1);
- }
-
- err2console(TRUE);
- do_files();
- check_calendar();
- for (;;) {
- /* only check appointments every TIME_OUT minutes */
- sleep(TIME_OUT);
- check_calendar();
- }
- }
-
- /*
- * When timer has expired check to see if we are close to an
- * appointment. If so, print message on the console.
- */
- check_calendar()
- {
- int appt_pending = 0; /* no appointments pending */
- int some_appts = 0; /* no appointments today */
- int slotno = 0; /* start with first timeslot */
- static int echoed_sno = -1;
- static int new_day = 0;
- static time_t lastmod = (time_t)0;
- struct stat stbuf;
- int sno;
- FILE *console;
-
- sno = echoed_sno; /* assume no console echo */
- get_today();
- stat(apts_pathname, &stbuf);
- /*
- * Check to see if we've run over into the next day or if
- * the appts file has been modified recently. If so,
- * we need to update our slot information.
- */
- if (ymd_compare(current, today) != 0) {
- current = today;
- lastmod = stbuf.st_mtime;
- (void)get_day_appts();
- if (!new_day) {
- new_day++;
- sno = echoed_sno = -1;
- }
- } else if (stbuf.st_mtime > lastmod) {
- lastmod = stbuf.st_mtime;
- (void)get_day_appts();
- sno = echoed_sno = -1;
- new_day = 0;
- } else
- new_day = 0;
- if (today.tm_hour >= START_HOUR) {
- slotno = (today.tm_hour - START_HOUR)*2 + today.tm_min/30;
- if (slotno < n_tslots) {
- if (slots[slotno].active != INACTIVE) {
- /* appointment is happening now */
- appt_pending++;
- if (slots[slotno].active == ACTIVE)
- sno = slotno;
- } else if (slotno+1 < n_tslots) {
- if (slots[slotno+1].active != INACTIVE)
- /* are we within 10 mins of an appointment? */
- if ((today.tm_min % 30) >= 20) {
- appt_pending++;
- if (slots[slotno+1].active == ACTIVE)
- sno = slotno+1;
- }
- }
- }
- }
- if (!appt_pending) {
- /*
- * Is there anything happening today (optionally
- * including memos)?
- * Don't care about things that happened before now
- * so start looking at <slotno>, which was set above to
- * reflect the current hour (or 0 if before START_HOUR).
- */
- /*
- * APPT_CHECK_LIMIT is typically either "n_tslots"
- * or "N_SLOTS" depending on whether we include the
- * notes section when indicating that we still have
- * appts today.
- */
- while (slotno < APPT_CHECK_LIMIT)
- if (slots[slotno++].active != INACTIVE) {
- some_appts++;
- break;
- }
- } else {
- /* notify the user via the console (once) ... */
- if (sno != echoed_sno) {
- echoed_sno = sno;
- if (getenv("WINDOW_PARENT") != NULL && (console = fopen("/dev/console", "w")) != NULL) {
- fprintf(console, "<< %s >> %s\n", progname, slots[sno].cur_appt->str);
- fclose(console);
- } else {
- fprintf(stderr, "\007\007<< %s >> %s\n", progname, slots[sno].cur_appt->str);
- }
- }
- }
- if (new_day) {
- new_day = 0;
- }
- }
-
- /* stripped down version of do_files() from init.c */
- do_files()
- {
- char *slash, *default_ptr, *envptr;
- char buff[80];
- int to_slash, getpid(), fd, errflag, numask;
- struct passwd *pw;
- struct stat statbuf;
- FILE *appts;
-
- if (otherfile) {
- strcpy(apts_pathname, othername);
- if ((slash = rindex(apts_pathname, '/')) != NULL) {
- to_slash = slash - apts_pathname;
- strncpy(apts_dir, apts_pathname, to_slash);
- apts_dir[to_slash] = '\0';
- } else {
- strcpy(apts_dir, ".");
- }
- } else {
- if ((default_ptr = defaults_get_string("/CalenTool/Appts", NULL, 0)) != NULL) {
- if ((slash = rindex(default_ptr, '/')) != NULL) {
- to_slash = slash - default_ptr;
- strncpy(apts_dir, default_ptr, to_slash);
- apts_dir[to_slash] = '\0';
- } else {
- strcpy(apts_dir, ".");
- }
- } else if ((envptr = getenv("CALENTOOL_DIR")) != NULL) {
- strcpy(apts_dir, envptr);
- } else if ((envptr = getenv("HOME")) != NULL) {
- strcpy(apts_dir, envptr);
- } else {
- apts_dir[0] = '\0';
- }
- if (*apts_dir) {
- /* prepend directory on pathnames */
- sprintf(apts_pathname, "%s/.appointments", apts_dir);
- } else {
- /* use current directory */
- strcpy(apts_pathname, ".appointments");
- }
- }
-
- /* directory for date/event data files */
- if ((default_ptr = defaults_get_string("/CalenTool/LibDir", NULL, 0)) != NULL)
- strcpy(lib_dir, default_ptr);
- else
- strcpy(lib_dir, DATELIB_DIR);
-
- errflag = 0;
- if (access(apts_pathname, R_OK) == -1) {
- fprintf(stderr, "Cannot access calendar file %s - create? ", apts_pathname);
- fgets(buff, 80, stdin);
- if (buff[0] == 'y' || buff[0] == 'Y') {
- if ((fd=open(apts_pathname, O_CREAT|O_RDWR, 0644)) <= 0) {
- perror(apts_pathname);
- return(1);
- } else {
- if (write(fd, HEADER, sizeof(HEADER)) != sizeof(HEADER)) {
- perror("writing header");
- close(fd);
- return(1);
- }
- close(fd);
- one_based = 1;
- }
- } else
- return(1);
- }
-
- /* check first line of appts file to see if it is the new style */
- if ((appts = fopen(apts_pathname, "r")) != NULL) {
- fgets(buff, 80, appts);
- fclose(appts);
- if (!strcmp(buff, HEADER)) {
- version2 = 1;
- one_based = 1;
- } else
- err_rpt("wrong version appointments file format", FATAL);
- }
- return;
- }
-
- /* stubs for needed routines where we don't want the whole
- * thing.
- */
- deactivate_slot(bi, dpyflag)
- int bi;
- int dpyflag;
- {
- slots[bi].active = INACTIVE;
- }
-
- /* returns pointer to slot containing arrow head */
- int
- deactivate_lower_arrows(bi, dpyflag)
- int bi, dpyflag;
- {
- while (bi < N_SLOTS-1) {
- bi++;
- if (slots[bi].active != ARROW_SHAFT &&
- slots[bi].active != ARROW_HEAD)
- return(bi-1);
- slots[bi].active = INACTIVE;
- }
- }
-
- draw_day_appts()
- {
- }
-
- /* activate a hidden appt and make it visible */
- int
- activate_slot(bi, dpyflag)
- int bi;
- int dpyflag;
- {
- int n, e_slot;
-
- if (slots[bi].count <= 0)
- /* nothing to activate */
- return(0);
- if (slots[bi].cur_appt == NULL) {
- /* may be hidden arrows */
- /* find appt that they came from so we can see if
- * it should be arrow shaft or arrow head
- */
- n = bi;
- while (--n >= 0 && slots[n].active != ACTIVE)
- ;
- if (n >= 0) {
- e_slot = n + slots[n].cur_appt->arrows;
- if (e_slot < bi)
- /* no arrows here to show */
- return(0);
- while (++n < e_slot && slots[n].active != ACTIVE)
- slots[n].active = ARROW_SHAFT;
- if (slots[n].active != ACTIVE)
- slots[n].active = ARROW_HEAD;
- } else
- /* no active appt above */
- return(0);
- } else {
- /* there's a real appt hidden */
- slots[bi].active = ACTIVE;
- if (slots[bi].cur_appt->arrows > 0) {
- e_slot = bi + slots[bi].cur_appt->arrows;
- while (++bi < e_slot && slots[bi].active != ACTIVE)
- slots[bi].active = ARROW_SHAFT;
- if (slots[bi].active != ACTIVE)
- slots[bi].active = ARROW_HEAD;
- }
- }
- if (dpyflag)
- draw_day_appts(); /* redraw display */
- return(1);
- }
-
- next_appt(bi, dpyflag)
- int bi;
- int dpyflag;
- {
- if (slots[bi].active == ACTIVE) {
- deactivate_slot(bi, dpyflag);
- if (slots[bi].cur_appt->arrows > 0)
- (void)deactivate_lower_arrows(bi, dpyflag);
- } else
- /* must have arrows displayed */
- (void)deactivate_lower_arrows(bi, dpyflag);
-
- if (slots[bi].cur_appt == NULL)
- /* end of the chain */
- slots[bi].cur_appt = slots[bi].first;
- else
- /* activate next in chain */
- slots[bi].cur_appt = slots[bi].cur_appt->next;
- /* make sure it is not a deleted one */
- if (chk_deleted(bi))
- next_appt(bi, dpyflag); /* try next in chain */
- else if (!activate_slot(bi, dpyflag))
- next_appt(bi, dpyflag); /* try next in chain */
- }
-
- /* check to see if current is deleted */
- int
- chk_deleted(bi)
- int bi;
- {
- int found = 0;
- struct appt_entry *aptr;
-
- if (slots[bi].cur_appt == NULL)
- return(0);
- if (slots[bi].cur_appt->flags & DELETED)
- return(1);
- /* run through the list to see if there are any deleted */
- for (aptr=slots[bi].first; aptr; aptr=aptr->next)
- if (aptr->flags & DELETED) {
- /* now see if the current one matches */
- if (!strcmp(aptr->str, slots[bi].cur_appt->str))
- return(1);
- }
-
- return(0);
- }
-