openenvutils/commandshell/shell/src/builtins/sched.c
changeset 0 2e3d3ce01487
child 1 0fdb7f6b0309
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 // sched.c - execute commands at scheduled times
       
     2 //
       
     3 // © Portions Copyright (c) Symbian Software Ltd 2007. All rights reserved.
       
     4 //
       
     5 /*
       
     6  * This file is part of zsh, the Z shell.
       
     7  *
       
     8  * Copyright (c) 1992-1997 Paul Falstad
       
     9  * All rights reserved.
       
    10  *
       
    11  * Permission is hereby granted, without written agreement and without
       
    12  * license or royalty fees, to use, copy, modify, and distribute this
       
    13  * software and to distribute modified versions of this software for any
       
    14  * purpose, provided that the above copyright notice and the following
       
    15  * two paragraphs appear in all copies of this software.
       
    16  *
       
    17  * In no event shall Paul Falstad or the Zsh Development Group be liable
       
    18  * to any party for direct, indirect, special, incidental, or consequential
       
    19  * damages arising out of the use of this software and its documentation,
       
    20  * even if Paul Falstad and the Zsh Development Group have been advised of
       
    21  * the possibility of such damage.
       
    22  *
       
    23  * Paul Falstad and the Zsh Development Group specifically disclaim any
       
    24  * warranties, including, but not limited to, the implied warranties of
       
    25  * merchantability and fitness for a particular purpose.  The software
       
    26  * provided hereunder is on an "as is" basis, and Paul Falstad and the
       
    27  * Zsh Development Group have no obligation to provide maintenance,
       
    28  * support, updates, enhancements, or modifications.
       
    29  *
       
    30  */
       
    31 #include "sched.mdh"
       
    32 #include "sched.pro"
       
    33 
       
    34 #ifdef __SYMBIAN32__
       
    35 #ifdef __WINSCW__
       
    36 #pragma warn_unusedarg off
       
    37 #pragma warn_possunwant off
       
    38 #endif//__WINSCW__
       
    39 #endif//__SYMBIAN32__
       
    40 
       
    41 /* node in sched list */
       
    42 
       
    43 typedef struct schedcmd  *Schedcmd;
       
    44 
       
    45 struct schedcmd {
       
    46     struct schedcmd *next;
       
    47     char *cmd;			/* command to run */
       
    48     time_t time;		/* when to run it */
       
    49 };
       
    50 
       
    51 /* the list of sched jobs pending */
       
    52  
       
    53 static struct schedcmd *schedcmds;
       
    54 
       
    55 /**/
       
    56 static int
       
    57 bin_sched(UNUSED(char *nam), char **argv, UNUSED(Options ops), UNUSED(int func))
       
    58 {
       
    59     char *s = *argv++;
       
    60     time_t t;
       
    61     long h, m;
       
    62     struct tm *tm;
       
    63     struct schedcmd *sch, *sch2, *schl;
       
    64     int sn;
       
    65 
       
    66     /* If the argument begins with a -, remove the specified item from the
       
    67     schedule. */
       
    68     if (s && *s == '-') {
       
    69 	sn = atoi(s + 1);
       
    70 
       
    71 	if (!sn) {
       
    72 	    zwarnnam("sched", "usage for delete: sched -<item#>.", NULL, 0);
       
    73 	    return 1;
       
    74 	}
       
    75 	for (schl = (struct schedcmd *)&schedcmds, sch = schedcmds, sn--;
       
    76 	     sch && sn; sch = (schl = sch)->next, sn--);
       
    77 	if (!sch) {
       
    78 	    zwarnnam("sched", "not that many entries", NULL, 0);
       
    79 	    return 1;
       
    80 	}
       
    81 	schl->next = sch->next;
       
    82 	zsfree(sch->cmd);
       
    83 	zfree(sch, sizeof(struct schedcmd));
       
    84 
       
    85 	return 0;
       
    86     }
       
    87 
       
    88     /* given no arguments, display the schedule list */
       
    89     if (!s) {
       
    90 	char tbuf[40];
       
    91 
       
    92 	for (sn = 1, sch = schedcmds; sch; sch = sch->next, sn++) {
       
    93 	    t = sch->time;
       
    94 	    tm = localtime(&t);
       
    95 	    ztrftime(tbuf, 20, "%a %b %e %k:%M:%S", tm);
       
    96 	    printf("%3d %s %s\n", sn, tbuf, sch->cmd);
       
    97 	}
       
    98 	return 0;
       
    99     } else if (!*argv) {
       
   100 	/* other than the two cases above, sched *
       
   101 	 *requires at least two arguments        */
       
   102 	zwarnnam("sched", "not enough arguments", NULL, 0);
       
   103 	return 1;
       
   104     }
       
   105 
       
   106     /* The first argument specifies the time to schedule the command for.  The
       
   107     remaining arguments form the command. */
       
   108     if (*s == '+') {
       
   109 	/* + introduces a relative time.  The rest of the argument is an
       
   110 	hour:minute offset from the current time.  Once the hour and minute
       
   111 	numbers have been extracted, and the format verified, the resulting
       
   112 	offset is simply added to the current time. */
       
   113 	h = zstrtol(s + 1, &s, 10);
       
   114 	if (*s != ':') {
       
   115 	    zwarnnam("sched", "bad time specifier", NULL, 0);
       
   116 	    return 1;
       
   117 	}
       
   118 	m = zstrtol(s + 1, &s, 10);
       
   119 	if (*s) {
       
   120 	    zwarnnam("sched", "bad time specifier", NULL, 0);
       
   121 	    return 1;
       
   122 	}
       
   123 	t = time(NULL) + h * 3600 + m * 60;
       
   124     } else {
       
   125 	/* If there is no +, an absolute time of day must have been given.
       
   126 	This is in hour:minute format, optionally followed by a string starting
       
   127 	with `a' or `p' (for a.m. or p.m.).  Characters after the `a' or `p'
       
   128 	are ignored. */
       
   129 	h = zstrtol(s, &s, 10);
       
   130 	if (*s != ':') {
       
   131 	    zwarnnam("sched", "bad time specifier", NULL, 0);
       
   132 	    return 1;
       
   133 	}
       
   134 	m = zstrtol(s + 1, &s, 10);
       
   135 	if (*s && *s != 'a' && *s != 'A' && *s != 'p' && *s != 'P') {
       
   136 	    zwarnnam("sched", "bad time specifier", NULL, 0);
       
   137 	    return 1;
       
   138 	}
       
   139 	t = time(NULL);
       
   140 	tm = localtime(&t);
       
   141 	t -= tm->tm_sec + tm->tm_min * 60 + tm->tm_hour * 3600;
       
   142 	if (*s == 'p' || *s == 'P')
       
   143 	    h += 12;
       
   144 	t += h * 3600 + m * 60;
       
   145 	/* If the specified time is before the current time, it must refer to
       
   146 	tomorrow. */
       
   147 	if (t < time(NULL))
       
   148 	    t += 3600 * 24;
       
   149     }
       
   150     /* The time has been calculated; now add the new entry to the linked list
       
   151     of scheduled commands. */
       
   152     sch = (struct schedcmd *) zshcalloc(sizeof *sch);
       
   153     sch->time = t;
       
   154     sch->cmd = zjoin(argv, ' ', 0);
       
   155     sch->next = NULL;
       
   156     for (sch2 = (struct schedcmd *)&schedcmds; sch2->next; sch2 = sch2->next);
       
   157     sch2->next = sch;
       
   158     return 0;
       
   159 }
       
   160 
       
   161 /* Check scheduled commands; call this function from time to time. */
       
   162 
       
   163 /**/
       
   164 static void
       
   165 checksched(void)
       
   166 {
       
   167     time_t t;
       
   168     struct schedcmd *sch, *schl;
       
   169 
       
   170     if(!schedcmds)
       
   171 	return;
       
   172     t = time(NULL);
       
   173     for (schl = (struct schedcmd *)&schedcmds, sch = schedcmds; sch;
       
   174 	 sch = (schl = sch)->next) {
       
   175 	if (sch->time <= t) {
       
   176 	    execstring(sch->cmd, 0, 0);
       
   177 	    schl->next = sch->next;
       
   178 	    zsfree(sch->cmd);
       
   179 	    zfree(sch, sizeof(struct schedcmd));
       
   180 	    sch = schl;
       
   181 	}
       
   182     }
       
   183 }
       
   184 
       
   185 static void (*p_checksched) _((void)) = checksched;
       
   186 static struct linknode n_checksched = { NULL, NULL, &p_checksched };
       
   187 
       
   188 static struct builtin bintab[] = {
       
   189     BUILTIN("sched", 0, bin_sched, 0, -1, 0, NULL, NULL),
       
   190 };
       
   191 
       
   192 /**/
       
   193 int
       
   194 setup_(UNUSED(Module m))
       
   195 {
       
   196     return 0;
       
   197 }
       
   198 
       
   199 /**/
       
   200 int
       
   201 boot_(Module m)
       
   202 {
       
   203     if(!addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)))
       
   204 	return 1;
       
   205     uaddlinknode(prepromptfns, &n_checksched);
       
   206     return 0;
       
   207 }
       
   208 
       
   209 /**/
       
   210 int
       
   211 cleanup_(Module m)
       
   212 {
       
   213     struct schedcmd *sch, *schn;
       
   214 
       
   215     for (sch = schedcmds; sch; sch = schn) {
       
   216 	schn = sch->next;
       
   217 	zsfree(sch->cmd);
       
   218 	zfree(sch, sizeof(*sch));
       
   219     }
       
   220     uremnode(prepromptfns, &n_checksched);
       
   221     deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
       
   222     return 0;
       
   223 }
       
   224 
       
   225 /**/
       
   226 int
       
   227 finish_(UNUSED(Module m))
       
   228 {
       
   229     return 0;
       
   230 }