home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume2 / calentool / patch5b / calencheck.c next >
Encoding:
C/C++ Source or Header  |  1990-02-04  |  9.1 KB  |  376 lines

  1. /*
  2.  * $Header: calencheck.c,v 2.1 89/12/15 17:04:41 billr Exp $
  3.  *
  4.  * calencheck.c - check for pending appts without the overhead
  5.  *          of the full blown calentool
  6.  *
  7.  * Copyright (C) 1989 Tektronix, Inc.
  8.  *    All Rights Reserved
  9.  * Permission is hereby granted to use and modify this file in source
  10.  * or binary form as long as it is not sold for profit and this copyright
  11.  * notice remains intact.
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <sys/time.h>
  16. #include <sys/file.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include <sunwindow/defaults.h>
  20. #include "ct.h"
  21.  
  22. int read_only = 1;        /* no modifications allowed */
  23. int n_tslots, otherfile = 0;
  24. int day_is_open;
  25. int include_old = 0, save_old = 0;
  26. struct tm current, today;
  27. struct tm First, Last;
  28. char *progname, *othername;
  29. struct dayslot slots[N_SLOTS];
  30. int show_future = 1;
  31. int one_based = 0, version2 = 0;
  32. char apts_pathname[160], tmpapts_pathname[2];
  33. char apts_dir[128], lib_dir[128];
  34. char *strcpy(), *strcat(), *rindex(), *getenv();
  35.  
  36. main(argc,argv)
  37. int argc;
  38. char *argv[];
  39. {
  40.     int flag;
  41.     extern char *optarg;
  42.     
  43.     if (progname = rindex(*argv, '/'))
  44.         progname++;
  45.     else
  46.         progname = *argv;
  47.  
  48.     n_tslots = (N_TSLOTS > N_SLOTS ? N_SLOTS : N_TSLOTS);
  49.  
  50.     get_today();    /* initial day is today */
  51.     current = today;
  52.     
  53.     while ((flag = getopt(argc, argv, "f:")) != EOF)
  54.         switch (flag) {
  55.             case 'f':   /* use this file */
  56.             otherfile = 1;
  57.             othername = optarg;
  58.             break;
  59.  
  60.             case '?':
  61.             default:
  62.             fprintf(stderr, "usage: %s [-f <appt_file>]\n", progname);
  63.             exit(1);
  64.         }
  65.  
  66.     err2console(TRUE);
  67.     do_files();
  68.     check_calendar();
  69.     for (;;) {
  70.         /* only check appointments every TIME_OUT minutes */
  71.         sleep(TIME_OUT);
  72.         check_calendar();
  73.     }
  74. }
  75.  
  76. /*
  77.  * When timer has expired check to see if we are close to an
  78.  * appointment. If so, print message on the console.
  79.  */
  80. check_calendar()
  81. {
  82.     int appt_pending = 0;     /* no appointments pending */
  83.     int some_appts = 0;    /* no appointments today */
  84.     int slotno = 0;     /* start with first timeslot */
  85.     static int echoed_sno = -1;
  86.     static int new_day = 0;
  87.     static time_t lastmod = (time_t)0;
  88.     struct stat stbuf;
  89.     int sno;
  90.     FILE *console;
  91.  
  92.     sno = echoed_sno;    /* assume no console echo */
  93.     get_today();
  94.     stat(apts_pathname, &stbuf);
  95.     /*
  96.      * Check to see if we've run over into the next day or if
  97.      * the appts file has been modified recently. If so,
  98.      * we need to update our slot information.
  99.      */
  100.     if (ymd_compare(current, today) != 0) {
  101.         current = today;
  102.         lastmod = stbuf.st_mtime;
  103.         (void)get_day_appts();
  104.         if (!new_day) {
  105.             new_day++;
  106.             sno = echoed_sno = -1;
  107.         }
  108.     } else if (stbuf.st_mtime > lastmod) {
  109.         lastmod = stbuf.st_mtime;
  110.         (void)get_day_appts();
  111.         sno = echoed_sno = -1;
  112.         new_day = 0;
  113.     } else
  114.         new_day = 0;
  115.     if (today.tm_hour >= START_HOUR) {
  116.         slotno = (today.tm_hour - START_HOUR)*2 + today.tm_min/30;
  117.         if (slotno < n_tslots) {
  118.             if (slots[slotno].active != INACTIVE) {
  119.                 /* appointment is happening now */
  120.                 appt_pending++;
  121.                 if (slots[slotno].active == ACTIVE)
  122.                     sno = slotno;
  123.             } else if (slotno+1 < n_tslots) {
  124.                 if (slots[slotno+1].active != INACTIVE)
  125.                     /* are we within 10 mins of an appointment? */
  126.                     if ((today.tm_min % 30) >= 20) {
  127.                         appt_pending++;
  128.                         if (slots[slotno+1].active == ACTIVE)
  129.                             sno = slotno+1;
  130.                     }
  131.             }
  132.         }
  133.     }
  134.     if (!appt_pending) {
  135.         /*
  136.          * Is there anything happening today (optionally
  137.          * including memos)?
  138.          * Don't care about things that happened before now
  139.          * so start looking at <slotno>, which was set above to
  140.          * reflect the current hour (or 0 if before START_HOUR).
  141.          */
  142.         /*
  143.          * APPT_CHECK_LIMIT is typically either "n_tslots"
  144.          * or "N_SLOTS" depending on whether we include the
  145.          * notes section when indicating that we still have
  146.          * appts today.
  147.          */
  148.         while (slotno < APPT_CHECK_LIMIT)
  149.             if (slots[slotno++].active != INACTIVE) {
  150.                 some_appts++;
  151.                 break;
  152.             }
  153.     } else {
  154.          /* notify the user via the console (once) ... */
  155.         if (sno != echoed_sno) {
  156.             echoed_sno = sno;
  157.             if (getenv("WINDOW_PARENT") != NULL && (console = fopen("/dev/console", "w")) != NULL) {
  158.                 fprintf(console, "<< %s >> %s\n", progname, slots[sno].cur_appt->str);
  159.                 fclose(console);
  160.             } else {
  161.                 fprintf(stderr, "\007\007<< %s >> %s\n", progname, slots[sno].cur_appt->str);
  162.             }
  163.         }
  164.     }
  165.     if (new_day) {
  166.         new_day = 0;
  167.     }
  168. }
  169.  
  170. /* stripped down version of do_files() from init.c */
  171. do_files()
  172. {
  173.     char *slash, *default_ptr, *envptr;
  174.     char buff[80];
  175.     int to_slash, getpid(), fd, errflag, numask;
  176.     struct passwd *pw;
  177.     struct stat statbuf;
  178.     FILE *appts;
  179.  
  180.     if (otherfile) {
  181.         strcpy(apts_pathname, othername);
  182.         if ((slash = rindex(apts_pathname, '/')) != NULL) {
  183.             to_slash = slash - apts_pathname;
  184.             strncpy(apts_dir, apts_pathname, to_slash);
  185.             apts_dir[to_slash] = '\0';
  186.         } else {
  187.             strcpy(apts_dir, ".");
  188.         }
  189.     } else {
  190.         if ((default_ptr = defaults_get_string("/CalenTool/Appts", NULL, 0)) != NULL) {
  191.             if ((slash = rindex(default_ptr, '/')) != NULL) {
  192.                 to_slash = slash - default_ptr;
  193.                 strncpy(apts_dir, default_ptr, to_slash);
  194.                 apts_dir[to_slash] = '\0';
  195.             } else {
  196.                 strcpy(apts_dir, ".");
  197.             }
  198.         } else if ((envptr = getenv("CALENTOOL_DIR")) != NULL) {   
  199.             strcpy(apts_dir, envptr);
  200.         } else if ((envptr = getenv("HOME")) != NULL) {   
  201.             strcpy(apts_dir, envptr);
  202.         } else {   
  203.             apts_dir[0] = '\0';
  204.         }
  205.         if (*apts_dir) {
  206.             /* prepend directory on pathnames */
  207.             sprintf(apts_pathname, "%s/.appointments", apts_dir);
  208.         } else {
  209.             /* use current directory */
  210.             strcpy(apts_pathname, ".appointments");
  211.         }
  212.     }
  213.     
  214.     /* directory for date/event data files */
  215.     if ((default_ptr = defaults_get_string("/CalenTool/LibDir", NULL, 0)) != NULL)
  216.         strcpy(lib_dir, default_ptr);
  217.     else
  218.         strcpy(lib_dir, DATELIB_DIR);
  219.  
  220.     errflag = 0;
  221.     if (access(apts_pathname, R_OK) == -1) {
  222.         fprintf(stderr, "Cannot access calendar file %s - create? ", apts_pathname);
  223.         fgets(buff, 80, stdin);
  224.         if (buff[0] == 'y' || buff[0] == 'Y') {
  225.             if ((fd=open(apts_pathname, O_CREAT|O_RDWR, 0644)) <= 0) {
  226.                 perror(apts_pathname);
  227.                 return(1);
  228.             } else {
  229.                 if (write(fd, HEADER, sizeof(HEADER)) != sizeof(HEADER)) {
  230.                     perror("writing header");
  231.                     close(fd);
  232.                     return(1);
  233.                 }
  234.                 close(fd);
  235.                 one_based = 1;
  236.             }
  237.         } else
  238.             return(1);
  239.     }
  240.  
  241.     /* check first line of appts file to see if it is the new style */
  242.     if ((appts = fopen(apts_pathname, "r")) != NULL) {
  243.         fgets(buff, 80, appts);
  244.         fclose(appts);
  245.         if (!strcmp(buff, HEADER)) {
  246.             version2 = 1;
  247.             one_based = 1;
  248.         } else
  249.             err_rpt("wrong version appointments file format", FATAL);
  250.     }
  251.     return;
  252. }
  253.  
  254. /* stubs for needed routines where we don't want the whole
  255.  * thing.
  256.  */
  257. deactivate_slot(bi, dpyflag)
  258. int bi;
  259. int dpyflag;
  260. {
  261.     slots[bi].active = INACTIVE;
  262. }
  263.  
  264. /* returns pointer to slot containing arrow head */
  265. int
  266. deactivate_lower_arrows(bi, dpyflag)
  267. int bi, dpyflag;
  268. {
  269.     while (bi < N_SLOTS-1) {
  270.         bi++;
  271.         if (slots[bi].active != ARROW_SHAFT &&
  272.             slots[bi].active != ARROW_HEAD)
  273.             return(bi-1);
  274.         slots[bi].active = INACTIVE;
  275.     }
  276. }
  277.  
  278. draw_day_appts()
  279. {
  280. }
  281.  
  282. /* activate a hidden appt and make it visible */
  283. int
  284. activate_slot(bi, dpyflag)
  285. int bi;
  286. int dpyflag;
  287. {
  288.     int n, e_slot;
  289.  
  290.     if (slots[bi].count <= 0)
  291.         /* nothing to activate */
  292.         return(0);
  293.     if (slots[bi].cur_appt == NULL) {
  294.         /* may be hidden arrows */
  295.         /* find appt that they came from so we can see if
  296.          * it should be arrow shaft or arrow head
  297.          */
  298.         n = bi;
  299.         while (--n >= 0 && slots[n].active != ACTIVE)
  300.             ;
  301.         if (n >= 0) {
  302.             e_slot = n + slots[n].cur_appt->arrows;
  303.             if (e_slot < bi)
  304.                 /* no arrows here to show */
  305.                 return(0);
  306.             while (++n < e_slot && slots[n].active != ACTIVE)
  307.                 slots[n].active = ARROW_SHAFT;
  308.             if (slots[n].active != ACTIVE)
  309.                 slots[n].active = ARROW_HEAD;
  310.         } else
  311.             /* no active appt above */
  312.             return(0);
  313.     } else {
  314.         /* there's a real appt hidden */
  315.         slots[bi].active = ACTIVE;
  316.         if (slots[bi].cur_appt->arrows > 0) {
  317.             e_slot = bi + slots[bi].cur_appt->arrows;
  318.             while (++bi < e_slot && slots[bi].active != ACTIVE)
  319.                 slots[bi].active = ARROW_SHAFT;
  320.             if (slots[bi].active != ACTIVE)
  321.                 slots[bi].active = ARROW_HEAD;
  322.         }
  323.     }
  324.     if (dpyflag)
  325.         draw_day_appts();    /* redraw display */
  326.     return(1);
  327. }
  328.  
  329. next_appt(bi, dpyflag)
  330. int bi;
  331. int dpyflag;
  332. {
  333.     if (slots[bi].active == ACTIVE) {
  334.         deactivate_slot(bi, dpyflag);
  335.         if (slots[bi].cur_appt->arrows > 0)
  336.             (void)deactivate_lower_arrows(bi, dpyflag);
  337.     } else
  338.         /* must have arrows displayed */
  339.         (void)deactivate_lower_arrows(bi, dpyflag);
  340.  
  341.     if (slots[bi].cur_appt == NULL)
  342.         /* end of the chain */
  343.         slots[bi].cur_appt = slots[bi].first;
  344.     else
  345.         /* activate next in chain */
  346.         slots[bi].cur_appt = slots[bi].cur_appt->next;
  347.     /* make sure it is not a deleted one */
  348.     if (chk_deleted(bi))
  349.         next_appt(bi, dpyflag); /* try next in chain */
  350.     else if (!activate_slot(bi, dpyflag))
  351.         next_appt(bi, dpyflag); /* try next in chain */
  352. }
  353.  
  354. /* check to see if current is deleted */
  355. int
  356. chk_deleted(bi)
  357. int bi;
  358. {
  359.     int found = 0;
  360.     struct appt_entry *aptr;
  361.  
  362.     if (slots[bi].cur_appt == NULL)
  363.         return(0);
  364.     if (slots[bi].cur_appt->flags & DELETED)
  365.         return(1);
  366.     /* run through the list to see if there are any deleted */
  367.     for (aptr=slots[bi].first; aptr; aptr=aptr->next)
  368.         if (aptr->flags & DELETED) {
  369.             /* now see if the current one matches */
  370.             if (!strcmp(aptr->str, slots[bi].cur_appt->str))
  371.                 return(1);
  372.         }
  373.     
  374.     return(0);
  375. }
  376.