home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / AT.C < prev    next >
C/C++ Source or Header  |  1994-04-17  |  10KB  |  380 lines

  1. /*      Timed execution routine. Starts a timer and executes a sequence
  2.  *  of commands when expired.
  3.  *
  4.  *  Added by IW0CNB - Feb 1992
  5.  *  'at mm' format added by WG7J - 920805
  6.  *
  7.  *      Added by WA7TAS Oct 1992:
  8.  *
  9.  *         'at k' command
  10.  *
  11.  *         Repeating AT command
  12.  *           - bug fix June 2, 1993
  13.  *           - merged changes into Johan's new code June 14, 1993
  14.  *
  15.  */
  16. #include <time.h>
  17. #ifdef MSDOS
  18. #include <dos.h>
  19. #endif
  20. #include "global.h"
  21. #ifdef ATCMD
  22. #include "timer.h"
  23. #include "proc.h"
  24. #include "cmdparse.h"
  25. #include "socket.h"
  26.   
  27. void atcmd __ARGS((char *command));
  28.   
  29. /* List of events; We keep note of all timer processes generated by the
  30.  * at command.
  31.  */
  32. struct at_list {
  33.     struct at_list *next;   /* Linked-list pointer */
  34.     struct timer *at_timer;
  35.     char   recur[10];   /* used in recursive 'at' commands*/
  36.     unsigned int id;    /* numerical 'id' of this 'at' */
  37. };
  38.   
  39. #define NULLATLIST  (struct at_list *)0
  40.   
  41. static struct at_list *Head_loe = NULLATLIST;   /* Head of List Of Events */
  42. static int id=1;        /* next 'at' assigned gets this number */
  43.   
  44. int
  45. doat(argc,argv,p)
  46. int argc;
  47. char *argv[];
  48. void *p;
  49. {
  50.     struct date *exp_date;
  51.     struct time *exp_time;
  52.     struct timer *t;
  53.   
  54.     char *cp,*dp;
  55.     unsigned int tid;
  56.     int i,notf;
  57.     time_t nowtime;
  58.     unsigned long time1;
  59.     struct tm tm;
  60.     extern struct timer *Timers;
  61.     struct at_list *loe,*pp;    /* List of events */
  62.     char *Errmsg = "Usage:\nat yymmddhhmm <cmd>\nat hhmm <cmd>\nat mm <cmd>\nat now+hhmm <cmd>\nat k <id num> <id num> ...\n";
  63.   
  64.     if(argc < 2){       /* Print list of pending at commands */
  65.         tputs("List of events:\n");
  66.   
  67.         for(t = Timers;t != NULLTIMER;t = t->next){
  68.             if(t->func == (void (*)())atcmd){
  69.                 loe=Head_loe;
  70.                 while(loe!=NULLATLIST) {
  71.                     if(loe->at_timer == t) break;
  72.                     loe=loe->next;
  73.                 }
  74.                 time(&nowtime);
  75.                 nowtime = (time_t)(read_timer(t) / 1000L + (unsigned long)nowtime);
  76.                 cp = ctime(&nowtime);
  77.                 rip(cp);
  78.                 dp = strchr(t->arg,'|');
  79.                 *dp = 0;
  80.                 tprintf("At: %s - ID: %5u - Command: %s\n",cp,loe->id,t->arg);
  81.                 *dp = '|';
  82.             }
  83.         }
  84.         return 0;
  85.     }
  86.   
  87.     if(argc < 3){
  88.         tputs(Errmsg);
  89.         return 0;
  90.     }
  91.   
  92.     if(argv[1][0]=='k') {
  93.         i=2;
  94.         while(i<argc) {
  95.             tid=atoi(argv[i]);
  96.             if(strlen(argv[i])>5 || tid==0 || atol(argv[i])>65535L) {
  97.                 tprintf("Invalid ID #.\n");
  98.                 return 0;
  99.             }
  100.             loe=Head_loe;
  101.             notf=1;
  102.             pp = NULL;
  103.             while(loe!=NULLATLIST) {
  104.                 if(loe->id==tid) {
  105.                     stop_timer(loe->at_timer);
  106.                     free(loe->at_timer->arg);
  107.                     free(loe->at_timer);
  108.                     if(loe == Head_loe) {
  109.                         Head_loe=loe->next;
  110.                     }
  111.                     else {
  112.                         pp->next=loe->next;
  113.                     }
  114.                     free(loe);
  115.                     tprintf("at id: %u--Killed.\n",tid);
  116.                     notf=0;
  117.                     break;
  118.                 }
  119.                 pp=loe;
  120.                 loe=loe->next;
  121.             }
  122.             if(notf) tprintf("  ID %u not found.\n",tid);
  123.             i++;
  124.         }
  125.         return 0;
  126.     }
  127.     exp_date = (struct date *)mallocw(sizeof(struct date));
  128.     exp_time = (struct time *)mallocw(sizeof(struct time));
  129.   
  130.     cp=mallocw(5);
  131.   
  132.     switch(strlen(argv[1])){
  133.         case 10: /* Full date and time given */
  134.             cp[0]=argv[1][0];
  135.             cp[1]=argv[1][1];
  136.             cp[2]='\0';
  137.   
  138.             exp_date->da_year = 1900 + atoi(cp);
  139.             if(exp_date->da_year > 1999) goto error;
  140.   
  141.             cp[0]=argv[1][2];
  142.             cp[1]=argv[1][3];
  143.             cp[2]='\0';
  144.   
  145.             exp_date->da_mon = (char)atoi(cp);
  146.             if(exp_date->da_mon > 12) goto error;
  147.   
  148.             cp[0]=argv[1][4];
  149.             cp[1]=argv[1][5];
  150.             cp[2]='\0';
  151.   
  152.             exp_date->da_day = (char)atoi(cp);
  153.             if(exp_date->da_day > 31) goto error;
  154.   
  155.             cp[0]=argv[1][6];
  156.             cp[1]=argv[1][7];
  157.             cp[2]='\0';
  158.   
  159.             exp_time->ti_hour = (char)atoi(cp);
  160.             if(exp_time->ti_hour > 23) goto error;
  161.   
  162.             cp[0]=argv[1][8];
  163.             cp[1]=argv[1][9];
  164.             cp[2]='\0';
  165.   
  166.             exp_time->ti_min = (char)atoi(cp);
  167.             if(exp_time->ti_min > 59) goto error;
  168.   
  169.             exp_time->ti_sec = 0;
  170.             exp_time->ti_hund = 0;
  171.   
  172.             time(&nowtime);
  173.             time1 = (unsigned long)dostounix(exp_date,exp_time);
  174.             if(time1 < (unsigned long)nowtime) goto error;
  175.   
  176.             break;
  177.   
  178.         case 4:  /* Only time given, so apply current date */
  179.             getdate(exp_date);
  180.             cp[0]=argv[1][0];
  181.             cp[1]=argv[1][1];
  182.             cp[2]='\0';
  183.   
  184.             exp_time->ti_hour = (char)atoi(cp);
  185.             if(exp_time->ti_hour > 23) goto error;
  186.   
  187.             cp[0]=argv[1][2];
  188.             cp[1]=argv[1][3];
  189.             cp[2]='\0';
  190.   
  191.             exp_time->ti_min = (char)atoi(cp);
  192.             if(exp_time->ti_min > 59) goto error;
  193.   
  194.             exp_time->ti_sec = 0;
  195.             exp_time->ti_hund = 0;
  196.   
  197.             time(&nowtime);
  198.             time1 = (unsigned long)dostounix(exp_date,exp_time);
  199.             if(time1 <= (unsigned long)nowtime){ /* Requested time has passed */
  200.                 time1 += 86400L;        /* So book him for tomorrow */
  201.             }
  202.             break;
  203.   
  204.   
  205.         case 2:  /* Only minutes given, so apply current time & date - WG7J */
  206.             tm.tm_min = (char)atoi(argv[1]);
  207.             if(tm.tm_min > 59) goto error;
  208.   
  209.         /* get today's date */
  210.             getdate(exp_date);
  211.             tm.tm_year = exp_date->da_year - 1900;
  212.             tm.tm_mday = exp_date->da_day;
  213.             tm.tm_mon = exp_date->da_mon - 1;
  214.   
  215.         /* get current time */
  216.             gettime(exp_time);
  217.             tm.tm_hour = exp_time->ti_hour;
  218.         /* if we're already past the minute, do it next hour ! */
  219.             if(exp_time->ti_min > tm.tm_min)
  220.                 tm.tm_hour++;
  221.   
  222.         /* now adjust this for day boundaries, etc. */
  223.             tm.tm_sec = 0;
  224.             tm.tm_isdst = 0;
  225.             time1 = mktime(&tm);
  226.             time(&nowtime);
  227.             break;
  228.   
  229.         case 8:  /* now+hhmm given */
  230.             strncpy(cp,argv[1],4);
  231.             cp[4]='\0';
  232.             if(strcmp(cp,"now+") != 0) goto error;
  233.   
  234.             cp[0]=argv[1][4];
  235.             cp[1]=argv[1][5];
  236.             cp[2]='\0';
  237.   
  238.             time1=(unsigned long)atoi(cp)*3600L;
  239.   
  240.             cp[0]=argv[1][6];
  241.             cp[1]=argv[1][7];
  242.             cp[2]='\0';
  243.   
  244.             time1+=(unsigned long)atoi(cp)*60L;
  245.             time(&nowtime);
  246.             time1+=(unsigned long)nowtime;
  247.             break;
  248.   
  249.         default:
  250.             error:      tprintf(Errmsg);
  251.             free(exp_date);
  252.             free(exp_time);
  253.             free(cp);
  254.             return 0;
  255.   
  256.     } /* switch */
  257.   
  258.     free(cp);
  259.     free(exp_time);
  260.     free(exp_date);
  261.   
  262.     t=(struct timer *)mallocw(sizeof(struct timer));
  263.   
  264.     set_timer(t,(time1 - (unsigned long)nowtime) * 1000L);
  265.     t->state=TIMER_RUN;
  266.     t->func=(void (*)())atcmd;
  267.     t->arg=(char *)mallocw(strlen(argv[2])+12); /*crh*/
  268.     sprintf(t->arg,"%s|%d",argv[2],id);
  269.   
  270.     /* Add the new timer to the head of List Of Events */
  271.     loe=(struct at_list *)mallocw(sizeof(struct at_list));
  272. /*
  273.  * if timer is recursive, set at_list->recur and tack
  274.  *  the '+' character to the end of the timer argument
  275.  */
  276.     loe->recur[0]=0;
  277.     if(argv[2][strlen(argv[2])-1] == '+') {
  278.         strcpy(loe->recur,argv[1]);
  279.         strcat(t->arg,"+");
  280.     }
  281.     loe->at_timer=t;
  282.     loe->id=id++;
  283. /*
  284.  * start the timer
  285.  */
  286.     start_timer(t);
  287. /*
  288.  * an id of 0 is invalid
  289.  */
  290.     if(id==0) id=1;
  291.     loe->next=Head_loe;
  292.     Head_loe=loe;
  293.   
  294.     return 0;
  295. }
  296.   
  297. struct proc *Aproc;
  298.   
  299. /* Process that actually handles 'at' execution */
  300. void
  301. atproc(int i,void *p1,void *p2)
  302. {
  303.     extern struct cmds DFAR Cmds[];
  304.     char *command;
  305.     struct at_list *loe, *p;
  306.     int recur, id;
  307.     char *pp;
  308.     char cmd[80];
  309.   
  310.     command =  (char *)p1;
  311.   
  312.     log(-1,"AT command: %s",command);
  313.   
  314. /*
  315.  * check for recursion
  316.  */
  317.     if(command[strlen(command)-1] == '+')
  318.         recur=1;
  319.     else
  320.         recur=0;
  321. /*
  322.  * locate id in command string
  323.  */
  324.     pp = strchr(command,'|');
  325.     *pp++ = 0;
  326.     id = atoi(pp);
  327.   
  328.     /* Free up memory for expired at commands */
  329.     p=Head_loe;
  330.     loe=Head_loe;
  331.     while(loe != NULLATLIST){
  332.         if(loe->at_timer->state == TIMER_EXPIRE){
  333.             if(loe->id != id) continue; /* is this the proper entry? */
  334.             if(recur) {
  335.                 strcpy(cmd,"at ");
  336.                 strcat(cmd,loe->recur);
  337.                 strcat(cmd," \"");
  338.                 strcat(cmd,command);
  339.                 strcat(cmd,"\"");
  340.                 command[strlen(command)-1]=0;
  341.             }
  342.             free(loe->at_timer);    /* Free timer */
  343.             if(loe == Head_loe){
  344.                 Head_loe=loe->next;
  345.                 p=loe->next;
  346.                 free(loe);
  347.                 loe=p;
  348.                 p=Head_loe;
  349.             } else {
  350.                 p->next=loe->next;
  351.                 free(loe);
  352.                 loe=p->next;
  353.             }
  354.             break;  /* exit while loop */
  355.         } else {    /* Not expired, go on */
  356.             if(loe != Head_loe) p=p->next;
  357.             loe=loe->next;
  358.         }
  359.     }
  360.   
  361.     cmdparse(Cmds,command,NULL);    /* Go with requested command */
  362.   
  363.     if(recur) cmdparse(Cmds,cmd,NULL);
  364.   
  365.     free(command);
  366.   
  367. }
  368.   
  369. struct proc *Aproc;
  370.   
  371. /* Function to be called on timer expiration to execute a command */
  372. void
  373. atcmd(command)
  374. char *command;
  375. {
  376.     Aproc = newproc("AT handler",1024,atproc,0,(void *)command,NULL,0);
  377. }
  378. #endif /* ATCMD */
  379.   
  380.