home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume17 / remind / part03 / timed.c < prev   
C/C++ Source or Header  |  1991-02-19  |  7KB  |  224 lines

  1. #include <stdio.h>
  2. #include <signal.h>
  3. #include <string.h>
  4. #ifndef NO_MALLOC_H
  5. #include <malloc.h>
  6. #endif
  7. #include "defines.h"
  8. #include "globals.h"
  9. #include "protos.h"
  10.  
  11. /***************************************************************/
  12. /*                                                             */
  13. /*  TIMED.C                                                    */
  14. /*                                                             */
  15. /*  Contains routines for triggering timed reminders           */
  16. /*                                                             */
  17. /*  By David Skoll - 12 Nov 1990                               */
  18. /*                                                             */
  19. /*  (C) 1990 by David Skoll                                    */
  20. /*                                                             */
  21. /***************************************************************/
  22.  
  23. /* Global pointer to AT reminders */
  24.  
  25. static AtEntry AtQueue =
  26. {
  27.    0, 0, 0, 0, Unknown_t, NULL, NULL
  28. };
  29.  
  30. /***************************************************************/
  31. /*                                                             */
  32. /*  AddEntry                                                   */
  33. /*                                                             */
  34. /*  Add an entry to the AT queue, keeping things sorted by     */
  35. /*  trigger time.                                              */
  36. /*                                                             */
  37. /*  Returns 0 for success, nonzero for failure                 */
  38. /*                                                             */
  39. /***************************************************************/
  40. #ifdef __STDC__
  41. int AddEntry(AtEntry *e)
  42. #else
  43. int AddEntry(e)
  44. AtEntry *e;
  45. #endif
  46. {
  47.    AtEntry *current, *prev;
  48.    prev = &AtQueue;
  49.    current = prev->next;
  50.    while (current) {
  51.       if (e->firsttime < current->firsttime) {
  52.          prev->next = e;
  53.          e->next = current;
  54.          break;
  55.       } else {
  56.          prev = current;
  57.          current = prev->next;
  58.       }
  59.    }
  60.    if (!current) {
  61.       prev->next = e;
  62.       e->next = NULL;
  63.    }
  64. }
  65.  
  66. /***************************************************************/
  67. /*                                                             */
  68. /* DoAt                                                        */
  69. /* Creates an entry for an At reminder, puts it on the queue   */
  70. /* Updates the global variable NumAtsQueued                    */
  71. /*                                                             */
  72. /***************************************************************/
  73. #ifdef __STDC__
  74. int DoAt(int tim, int tdelta, int trep, char *body, enum Token_t type)
  75. #else
  76. int DoAt(tim, tdelta, trep, body, type)
  77. int tim, tdelta, trep;
  78. char *body;
  79. enum Token_t type;
  80. #endif
  81. {
  82.    AtEntry *e;
  83.    int curtime;
  84.  
  85.    curtime = (int) (SystemTime() / 60);
  86.    
  87.    /* If the trigger time is in the past, don't add to the at queue */     
  88.    if (tim < curtime) return 0;
  89.  
  90.    /* Allocate space for the entry */
  91.    e = (AtEntry *) malloc(sizeof(AtEntry));
  92.    if (e == (AtEntry *) NULL) {
  93.       Eprint("Can't malloc memory for AT!\n");
  94.       return 1;
  95.    }
  96.    e->text = malloc(strlen(body)+1);
  97.    if (e->text == NULL) {
  98.       Eprint("Can't malloc memory for body of AT!\n");
  99.       return 1;
  100.    }
  101.    strcpy(e->text, body);
  102.  
  103.    /* Find out the next trigger time */
  104.    e->firsttime = FindNextTriggerTime(tim, trep, tdelta, curtime);
  105.    e->repeat    = trep;
  106.    e->type      = type;
  107.    e->time      = tim;
  108.    e->delta     = tdelta;
  109.    AddEntry(e);
  110.    NumAtsQueued++;
  111.    return 0;
  112. }
  113.  
  114. /***************************************************************/
  115. /*                                                             */
  116. /* int FindNextTriggerTime                                     */
  117. /*                                                             */
  118. /* Returns the next time a queued AT should be triggered.      */
  119. /* Returns -1 if the AT has expired.                           */
  120. /*                                                             */
  121. /***************************************************************/
  122. #ifdef __STDC__
  123. int FindNextTriggerTime(int tim, int rep, int delta, int curtime)
  124. #else
  125. int FindNextTriggerTime(tim, rep, delta, curtime)
  126. int tim, rep, delta, curtime;
  127. #endif
  128. {
  129.    int trigger = tim;
  130.    
  131.    if (delta <= 0)
  132.       if (trigger < curtime) return -1; else return trigger;
  133.    
  134.    trigger -= delta;
  135.    if (rep == -1) rep = delta;
  136.  
  137.    if (trigger < curtime) trigger += ((curtime - trigger) / rep) * rep;
  138.    if (trigger < curtime) trigger += rep;
  139.    if (trigger > tim) trigger = tim;
  140.    if (trigger < curtime) return -1; else return trigger;
  141. }
  142.  
  143. /***************************************************************/
  144. /*                                                             */
  145. /* HandleQueuedAts                                             */
  146. /*                                                             */
  147. /* Handles all the queued AT reminders.  Sits in a sleep loop  */
  148. /* to trigger reminders.                                       */
  149. /*                                                             */
  150. /***************************************************************/
  151. #ifdef __STDC__
  152. void HandleQueuedAts(void)
  153. #else
  154. void HandleQueuedAts()
  155. #endif
  156. {
  157.    AtEntry *e;
  158.    long TimeToSleep;
  159.    unsigned SleepTime;
  160.    long now;
  161.  
  162.    signal(SIGINT, SigIntHandler);
  163.  
  164.    while (e = AtQueue.next) {
  165.       now = SystemTime();
  166.       TimeToSleep = (long) e->firsttime * 60L - now;
  167.       if (TimeToSleep < 0L) TimeToSleep = 0L;
  168.  
  169.       /* Be paranoid and assume that unsigneds are only two bytes long -
  170.          therefore, do the sleeping in 30000-second chunks. */
  171.  
  172.       while (TimeToSleep) {
  173.          if (TimeToSleep > 30000L) SleepTime = 30000;
  174.                               else SleepTime = (unsigned) TimeToSleep;
  175.          sleep(SleepTime);
  176.          TimeToSleep -= (long) SleepTime;
  177.       }
  178.  
  179.       /* Over here, we trigger the reminder */
  180.       DoSubst(e->text, WorkBuf, CurDay, CurMon, CurYear, JulianToday, e->type, e->time, 0);
  181.       if (e->type == Run_t) system(WorkBuf);
  182.       else printf("%s\n", WorkBuf);
  183.  
  184.       /* Remove the entry from the queue */
  185.       AtQueue.next = e->next;
  186.  
  187.       /* Check if this reminder should be re-triggered */
  188.       e->firsttime = FindNextTriggerTime(e->time, e->repeat, 
  189.                                         e->delta, e->firsttime + 1);
  190.  
  191.       if (e->firsttime != -1) AddEntry(e);
  192.       else {
  193.       /* Not to be added - free the memory */
  194.          free(e->text);
  195.          free(e);
  196.       }
  197.    }
  198. }
  199.  
  200. /***************************************************************/
  201. /*                                                             */
  202. /* SigIntHandler                                               */
  203. /*                                                             */
  204. /* For debugging purposes, when sent a SIGINT, we print the    */
  205. /* contents of the queue.                                      */
  206. /*                                                             */
  207. /***************************************************************/
  208. void SigIntHandler()
  209. {
  210.    AtEntry *e;
  211.  
  212.    printf("Contents of AT queue:\n");
  213.  
  214.    e = AtQueue.next;
  215.    while (e) {
  216.       printf("Trigger: %02d:%02d  Activate: %02d:%02d  Rep: %d  Delta: %d\n",
  217.               e->time / 60, e->time % 60, e->firsttime / 60, e->firsttime % 60,
  218.               e->repeat, e->delta);
  219.       printf("Text: %s %s\n\n", ((e->type == Msg_t) ? "MSG" : "RUN"), e->text);
  220.       e = e->next;
  221.    }
  222.    printf("\n");
  223. }
  224.