diff options
-rw-r--r-- | usr/src/cmd/cron/cron.c | 135 | ||||
-rw-r--r-- | usr/src/cmd/cron/elm.c | 341 |
2 files changed, 299 insertions, 177 deletions
diff --git a/usr/src/cmd/cron/cron.c b/usr/src/cmd/cron/cron.c index 44dab11419..2abcdc3d36 100644 --- a/usr/src/cmd/cron/cron.c +++ b/usr/src/cmd/cron/cron.c @@ -29,7 +29,6 @@ /* Copyright (c) 1987, 1988 Microsoft Corporation */ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" #ifdef lint /* make lint happy */ @@ -287,6 +286,7 @@ static void rm_ctevents(struct usr *); static void cleanup(struct runinfo *rn, int r); static void crabort(char *, int); static void msg(char *fmt, ...); +static void ignore_msg(char *, char *, struct event *); static void logit(int, struct runinfo *, int); static void parsqdef(char *); static void defaults(); @@ -333,6 +333,7 @@ static int set_user_cred(const struct usr *, struct project *); * it's original intended use. */ static time_t last_time, init_time, t_old; +static int reset_needed; /* set to 1 when cron(1M) needs to re-initialize */ static int accept_sigcld, notifypipe[2]; static sigset_t defmask, childmask; @@ -390,7 +391,7 @@ static void process_anc_files(int); * functions in elm.c */ extern void el_init(int, time_t, time_t, int); -extern void el_add(void *, time_t, int); +extern int el_add(void *, time_t, int); extern void el_remove(int, int); extern int el_empty(void); extern void *el_first(void); @@ -415,13 +416,17 @@ main(int argc, char *argv[]) struct sigaction act; /* - * reset is set to 1 via the return from ex() should ex() find - * that the event to be executed is being run at the wrong time. + * reset_needed is set to 1 whenever el_add() finds out that a cron + * job is scheduled to be run before the time when cron(1M) daemon + * initialized. + * Other cases where a reset is needed is when ex() finds that the + * event to be executed is being run at the wrong time, or when idle() + * determines that time was reset. * We immediately return to the top of the while (TRUE) loop in - * main() where the event list is cleared and rebuilt, and reset + * main() where the event list is cleared and rebuilt, and reset_needed * is set back to 0. */ - int reset = 0; + reset_needed = 0; /* * Only the privileged user can run this command. @@ -477,13 +482,14 @@ begin: */ (void) fcntl(notifypipe[0], F_SETFL, O_WRONLY|O_NONBLOCK); - t_old = time(NULL); + t_old = init_time; last_time = t_old; for (;;) { /* MAIN LOOP */ t = time(NULL); - if ((t_old > t) || (t-last_time > CUSHION) || reset) { - reset = 0; + if ((t_old > t) || (t-last_time > CUSHION) || reset_needed) { + reset_needed = 0; /* the time was set backwards or forward */ + msg("time was reset, re-initializing"); el_delete(); u = uhead; while (u != NULL) { @@ -502,6 +508,13 @@ begin: initialize(0); t = time(NULL); last_time = t; + /* + * reset_needed might have been set in the functions + * call path from initialize() + */ + if (reset_needed) { + continue; + } } t_old = t; @@ -519,8 +532,14 @@ begin: #endif } if (ne_time > 0) { - if ((reset = idle(ne_time)) != 0) + /* + * reset_needed may be set in the functions call path + * from idle() + */ + if (idle(ne_time) || reset_needed) { + reset_needed = 1; continue; + } } if (stat(QUEDEFS, &buf)) { @@ -532,8 +551,14 @@ begin: last_time = next_event->time; /* save execution time */ - if (reset = ex(next_event)) + /* + * reset_needed may be set in the functions call path + * from ex() + */ + if (ex(next_event) || reset_needed) { + reset_needed = 1; continue; + } switch (next_event->etype) { case CRONEVENT: @@ -581,8 +606,15 @@ begin: next_event->cmd, next_event->time, timebuf); #endif - el_add(next_event, next_event->time, - (next_event->u)->ctid); + switch (el_add(next_event, next_event->time, + (next_event->u)->ctid)) { + case -1: + ignore_msg("main", "cron", next_event); + break; + case -2: /* event time lower than init time */ + reset_needed = 1; + break; + } break; default: /* remove at or batch job from system */ @@ -620,8 +652,6 @@ initialize(int firstpass) #ifdef DEBUG (void) fprintf(stderr, "in initialize\n"); #endif - init_time = time(NULL); - el_init(8, init_time, (time_t)(60*60*24), 10); if (firstpass) { /* for mail(1), make sure messages come from root */ if (putenv("LOGNAME=root") != 0) { @@ -660,6 +690,9 @@ initialize(int firstpass) crabort("cannot open fifo queue", REMOVE_FIFO|CONSOLE_MSG); } + init_time = time(NULL); + el_init(8, init_time, (time_t)(60*60*24), 10); + /* * read directories, create users list, and add events to the * main event list. Only zero user list on firstpass. @@ -1031,7 +1064,9 @@ add_atevent(struct usr *u, char *job, time_t tim, int jobtype) (void) fprintf(stderr, "add_atevent: user=%s, job=%s, time=%ld\n", u->name, e->cmd, e->time); #endif - el_add(e, e->time, e->of.at.eventid); + if (el_add(e, e->time, e->of.at.eventid) < 0) { + ignore_msg("add_atevent", "at", e); + } } void @@ -1151,7 +1186,14 @@ again: /* set the time for the first occurance of this event */ e->time = next_time(e, reftime); /* finally, add this event to the main event list */ - el_add(e, e->time, u->ctid); + switch (el_add(e, e->time, u->ctid)) { + case -1: + ignore_msg("readcron", "cron", e); + break; + case -2: /* event time lower than init time */ + reset_needed = 1; + break; + } cte_valid(); #ifdef DEBUG cftime(timebuf, "%C", &e->time); @@ -2128,12 +2170,21 @@ ex(struct event *e) if (next_event->etype == CRONEVENT) { msg("correcting cron event\n"); next_event->time = next_time(next_event, dhltime); - el_add(next_event, next_event->time, - (next_event->u)->ctid); + switch (el_add(next_event, next_event->time, + (next_event->u)->ctid)) { + case -1: + ignore_msg("ex", "cron", next_event); + break; + case -2: /* event time lower than init time */ + reset_needed = 1; + break; + } } else { /* etype == ATEVENT */ msg("correcting batch event\n"); - el_add(next_event, next_event->time, - next_event->of.at.eventid); + if (el_add(next_event, next_event->time, + next_event->of.at.eventid) < 0) { + ignore_msg("ex", "at", next_event); + } } delayed++; t_old = time(NULL); @@ -2687,12 +2738,22 @@ process_msg(struct message *pmsg, time_t reftime) break; } if (next_event != NULL) { - if (next_event->etype == CRONEVENT) - el_add(next_event, next_event->time, - (next_event->u)->ctid); - else /* etype == ATEVENT */ - el_add(next_event, next_event->time, - next_event->of.at.eventid); + if (next_event->etype == CRONEVENT) { + switch (el_add(next_event, next_event->time, + (next_event->u)->ctid)) { + case -1: + ignore_msg("process_msg", "cron", next_event); + break; + case -2: /* event time lower than init time */ + reset_needed = 1; + break; + } + } else { /* etype == ATEVENT */ + if (el_add(next_event, next_event->time, + next_event->of.at.eventid) < 0) { + ignore_msg("process_msg", "at", next_event); + } + } next_event = NULL; } (void) fflush(stdout); @@ -2836,6 +2897,16 @@ msg(char *fmt, ...) } static void +ignore_msg(char *func_name, char *job_type, struct event *event) +{ + msg("%s: ignoring %s job (user: %s, cmd: %s, time: %ld)", + func_name, job_type, + event->u->name ? event->u->name : "unknown", + event->cmd ? event->cmd : "unknown", + event->time); +} + +static void logit(int cc, struct runinfo *rp, int rc) { time_t t; @@ -2869,7 +2940,15 @@ resched(int delay) next_event->time = next_time(next_event, (time_t)0); if (nt < next_event->time) next_event->time = nt; - el_add(next_event, next_event->time, (next_event->u)->ctid); + switch (el_add(next_event, next_event->time, + (next_event->u)->ctid)) { + case -1: + ignore_msg("resched", "cron", next_event); + break; + case -2: /* event time lower than init time */ + reset_needed = 1; + break; + } delayed = 1; msg("rescheduling a cron job"); return; diff --git a/usr/src/cmd/cron/elm.c b/usr/src/cmd/cron/elm.c index 157b0e00f8..a61ced60ad 100644 --- a/usr/src/cmd/cron/elm.c +++ b/usr/src/cmd/cron/elm.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,29 +29,32 @@ -#pragma ident "%Z%%M% %I% %E% SMI" -/************************************************************************** - *** General-Purpose Event List Manager *** - ************************************************************************** - - description: These routines maintain a time-ordered list of events. - functions available: - init : Creates and initializes the data structure. - See the reference for parameters to init. - add(&event,time,id) : Adds an event to the list. - remove(id) : Removes events (with appropriate id). - empty : Returns true if the list is empty, false otherwise. - first : Removes the element at the head of the list. - Returns a pointer to the event. - delete : Frees up all allocated storage associated - with the event list. - reference: Franta, W. R. and Maly, K., - "An efficient data structure for the - simulation event set ", CACM Vol. 20(8), - Aug 1977, pp. 596-602. - machine dependant: the constant INFINITY - - *************************************************************************/ +/* ********************************************************************** */ +/* * General-Purpose Event List Manager * */ +/* ********************************************************************** */ +/* + * description: These routines maintain a time-ordered list of events. + * functions available: + * init : Creates and initializes the data structure. + * See the reference for parameters to init. + * add(&event, time, id) : Adds an event to the list. + * Returns: 0 if success, + * -2 if event time is lower + * than Lower Bound time LB + * -1 else + * remove(id) : Removes events (with appropriate id). + * empty : Returns true if the list is empty, false otherwise. + * first : Removes the element at the head of the list. + * Returns a pointer to the event. + * delete : Frees up all allocated storage associated + * with the event list. + * reference: Franta, W. R. and Maly, K., + * "An efficient data structure for the + * simulation event set ", CACM Vol. 20(8), + * Aug 1977, pp. 596-602. + * machine dependant: the constant INFINITY + */ +/* ********************************************************************** */ #include <sys/types.h> @@ -61,9 +63,9 @@ extern void *xmalloc(size_t); #define INFINITY 2147483647L /* upper bound on time */ -#define NULL 0 /* a null pointer */ -#define TRUE 1 -#define FALSE 0 +#define NULL 0 /* a null pointer */ +#define TRUE 1 +#define FALSE 0 /* the following parameters are set in init */ static int DU; /* number of time intervals */ @@ -71,18 +73,20 @@ static time_t LB; /* lower bound on time */ static time_t DT; /* width of interval */ static int NLIM; /* max notices per sublist */ -/* a notice points to an event. a notice has the following fields: - time = time of the event. - id = identifier for an event or class of events that may need - to be removed (other than at the front of the list). - event = pointer to the event. - isdummy = tells whether this notice points to a real event or - is just a dummy notice (one that is used to "mark off" - the time intervals that the user specifies in init). - key = points back to the key that points to this notice, - if there is one. - left = points to the notice immediately preceding this one. - right = points to the notice immediately following this one. */ +/* + * a notice points to an event. a notice has the following fields: + * time = time of the event. + * id = identifier for an event or class of events that may need + * to be removed (other than at the front of the list). + * event = pointer to the event. + * isdummy = tells whether this notice points to a real event or + * is just a dummy notice (one that is used to "mark off" + * the time intervals that the user specifies in init). + * key = points back to the key that points to this notice, + * if there is one. + * left = points to the notice immediately preceding this one. + * right = points to the notice immediately following this one. + */ struct notice { time_t time; int id; void *event; @@ -92,45 +96,51 @@ struct notice { time_t time; struct notice *right; }; /* current points to the front of the list of notices (events) */ -struct notice *current=NULL; - -/* a key points to a sublist of notices. a key has the following fields: - time = max time of notices in sublist. - numnote = number of notices in sublist. - notice = pointer to the notice with max time. - left = points to the key immediately preceding this one. - right = points to the key immediately following this one. */ +struct notice *current = NULL; + +/* + * a key points to a sublist of notices. a key has the following fields: + * time = max time of notices in sublist. + * numnote = number of notices in sublist. + * notice = pointer to the notice with max time. + * left = points to the key immediately preceding this one. + * right = points to the key immediately following this one. + */ struct key { time_t time; int numnote; struct notice *notice; struct key *left; struct key *right; }; -/* the index list breaks the keys into time intervals as specified in init. - the index is "shifted" one time interval whenever el_first returns an - event with a time greater than the max time of the first interval - (eg. with intervals of a day which span one week (MTWTFSS), - if el_first finds the next event is on tuesday, then - the intervals of the event list get shifted (TWTFSSM). */ +/* + * the index list breaks the keys into time intervals as specified in init. + * the index is "shifted" one time interval whenever el_first returns an + * event with a time greater than the max time of the first interval + * (eg. with intervals of a day which span one week (MTWTFSS), + * if el_first finds the next event is on tuesday, then + * the intervals of the event list get shifted (TWTFSSM). + */ struct index { struct key *key; struct index *right; }; -static struct index *index=NULL; /* index pts to the front of the index list */ +/* index pts to the front of the index list */ +static struct index *index = NULL; -/***********************/ +/* ******************* */ void -el_init(du,lb,dt,nlim) -/***********************/ +el_init(du, lb, dt, nlim) +/* ******************* */ int du, nlim; time_t lb, dt; { int i; time_t t; - struct index *indprev,*ind; + struct index *indprev, *ind; struct key *kprev, *k; struct notice *nprev, *n; - if ((du<1) || (dt<1) || (nlim<1)) return; + if ((du < 1) || (dt < 1) || (nlim < 1)) + return; DU = du + 1; LB = lb; DT = dt; @@ -141,13 +151,13 @@ time_t lb, dt; */ /* create first dummy notice */ - n= (struct notice *) xmalloc(sizeof(struct notice)); + n = (struct notice *)xmalloc(sizeof (struct notice)); n->time = LB; n->isdummy = TRUE; n->left = NULL; nprev = n; /* create first dummy key */ - k= (struct key *) xmalloc(sizeof(struct key)); + k = (struct key *)xmalloc(sizeof (struct key)); k->time = LB; k->numnote = 1; k->notice = n; @@ -159,15 +169,15 @@ time_t lb, dt; indprev = NULL; /* create dummy notices, dummy keys, and index elements */ t = LB; - for (i=1; i<DU; i++) { + for (i = 1; i < DU; i++) { t = t + DT; - n = (struct notice *) xmalloc(sizeof(struct notice)); + n = (struct notice *)xmalloc(sizeof (struct notice)); n->time = t; n->isdummy = TRUE; n->left = nprev; nprev->right = n; nprev = n; - k = (struct key *) xmalloc(sizeof(struct key)); + k = (struct key *)xmalloc(sizeof (struct key)); k->time = t; k->numnote = 1; k->notice = n; @@ -175,20 +185,22 @@ time_t lb, dt; kprev->right = k; kprev = k; n->key = k; - ind = (struct index *) xmalloc(sizeof(struct index)); + ind = (struct index *)xmalloc(sizeof (struct index)); ind->key = k; - if (indprev == NULL) index = ind; - else indprev->right = ind; + if (indprev == NULL) + index = ind; + else + indprev->right = ind; indprev = ind; } /* create last dummy notice */ - n = (struct notice *) xmalloc(sizeof(struct notice)); + n = (struct notice *)xmalloc(sizeof (struct notice)); n->time = INFINITY; n->isdummy = TRUE; n->left = nprev; n->right = NULL; nprev->right = n; /* create last dummy key */ - k = (struct key *) xmalloc(sizeof(struct key)); + k = (struct key *)xmalloc(sizeof (struct key)); k->time = INFINITY; k->numnote = 1; k->notice = n; @@ -197,37 +209,48 @@ time_t lb, dt; kprev->right = k; n->key = k; /* create last index element */ - ind = (struct index *) xmalloc(sizeof(struct index)); + ind = (struct index *)xmalloc(sizeof (struct index)); ind->key = k; ind->right = NULL; indprev->right = ind; - + current = NULL; } -/**************************/ -void -el_add(event,time,id) -/**************************/ +/* ********************** */ +int +el_add(event, time, id) +/* ********************** */ void *event; int id; time_t time; { -/* add works slightly differently than in the reference. if the - sublist to be inserted into is full (numnote = NLIM), - the sublist is split in half. thus the size of the sublists - in this implementation normally ranges from NLIM/2 to NLIM. */ + /* + * add works slightly differently than in the reference. if the + * sublist to be inserted into is full (numnote = NLIM), + * the sublist is split in half. thus the size of the sublists + * in this implementation normally ranges from NLIM/2 to NLIM. + */ struct index *ind; - struct key *k,*k2; - struct notice *n,*n2; + struct key *k, *k2; + struct notice *n, *n2; int i; - if ((index==NULL) || (time<LB)) return; + /* + * time may be 0 when set by next_time() on error or an + * invalid time specification of job + */ + if ((index == NULL) || (time <= 0)) { + return (-1); + } + if (time < LB) { + return (-2); + } /* allocate new notice */ - n = (struct notice *) xmalloc(sizeof(struct notice)); + n = (struct notice *)xmalloc(sizeof (struct notice)); n->time = time; n->id = id; n->event = event; @@ -237,7 +260,7 @@ time_t time; /* find the right interval */ ind = index; while ((ind->key)->time <= time) ind = ind->right; - + /* find the right key */ k = (ind->key)->left; while (k->time > time) k = k->left; @@ -248,9 +271,9 @@ time_t time; /* k's sublist is full, so split it */ k->numnote = NLIM / 2; n2 = k->notice; - for (i=1; i<=NLIM/2; i++) n2 = n2->left; + for (i = 1; i <= NLIM/2; i++) n2 = n2->left; /* create a key which will point to notice n2 */ - k2 = (struct key *) xmalloc(sizeof(struct key)); + k2 = (struct key *)xmalloc(sizeof (struct key)); k2->time = n2->time; k2->numnote = NLIM - NLIM/2; k2->notice = n2; @@ -262,8 +285,10 @@ time_t time; /* which of the new sublists will hold the new notice? */ if (k2->time > time) k = k2; } - /* the new notice n is ready to be inserted - k points to the appropriate sublist */ + /* + * the new notice n is ready to be inserted + * k points to the appropriate sublist + */ k->numnote = k->numnote + 1; n2 = k->notice; while (n2->time > time) n2 = n2->left; @@ -272,38 +297,45 @@ time_t time; (n2->right)->left = n; n2->right = n; - if ( (current == NULL) || (current->time > time) ) current = n; + if ((current == NULL) || (current->time > time)) + current = n; + + return (0); } -/************************/ +/* ******************** */ void -el_remove(id,flag) -/************************/ -int id,flag; +el_remove(id, flag) +/* ******************** */ +int id, flag; { -/* remove finds notices n that need to be removed by traversing thru - the notice list. if n is the sole element of a sublist, the - sublist is deleted. if not, an adjacent sublist is merged with - n's sublist, if that is possible. after these checks, n is removed. */ + /* + * remove finds notices n that need to be removed by traversing thru + * the notice list. if n is the sole element of a sublist, the + * sublist is deleted. if not, an adjacent sublist is merged with + * n's sublist, if that is possible. after these checks, n is removed. + */ - struct notice *n,*n2; - struct key *k,*kl,*kr; + struct notice *n, *n2; + struct key *k, *kl, *kr; - if ((index==NULL) || (current==NULL)) return; + if ((index == NULL) || (current == NULL)) + return; n = current; - while ( n != NULL) { - while ( (n!=NULL) && ((n->isdummy)||(n->id!=id)) ) n = n->right; + while (n != NULL) { + while ((n != NULL) && ((n->isdummy) || (n->id != id))) + n = n->right; if (n != NULL) { /* n should be deleted */ - if ( (n->key!=NULL) && ((n->key)->numnote==1) ) { + if ((n->key != NULL) && ((n->key)->numnote == 1)) { /* n = sole element of a sublist */ k = n->key; (k->left)->right = k->right; (k->right)->left = k->left; - free(k); } - else { if (n->key != NULL) { + free(k); + } else { if (n->key != NULL) { /* n has a key pointing to it */ (n->left)->key = n->key; (n->key)->time = (n->left)->time; @@ -313,20 +345,23 @@ int id,flag; while (n2->key == NULL) n2 = n2->right; k = n2->key; k->numnote = k->numnote - 1; - /* check if two adjacent sublists can be merged - first check left, then check right */ + /* + * check if two adjacent sublists can be merged + * first check left, then check right + */ kl = k->left; kr = k->right; - if ( (!(kl->notice)->isdummy) && - ((kl->numnote+k->numnote)<=NLIM) ) { + if ((!(kl->notice)->isdummy) && + ((kl->numnote+k->numnote) <= NLIM)) { /* delete the key to the left */ (kl->notice)->key = NULL; k->numnote += kl->numnote; (kl->left)->right = k; k->left = kl->left; - free(kl); } - else if ( (!(k->notice)->isdummy) && - ((kr->numnote+k->numnote)<=NLIM) ) { + free(kl); + } else if ((!(k->notice)->isdummy) && + ((kr->numnote+k->numnote) + <= NLIM)) { /* delete this key */ (k->notice)->key = NULL; kr->numnote += k->numnote; @@ -347,33 +382,36 @@ int id,flag; k = (index->key)->left; while (k->left != NULL) k = k->left; n = (k->notice)->right; - while ((n!=NULL) && (n->isdummy)) n = n->right; + while ((n != NULL) && (n->isdummy)) n = n->right; current = n; } -/*************************/ +/* ********************* */ int el_empty(void) -/*************************/ +/* ********************* */ { - if (current == NULL) return(1); - else return(0); + if (current == NULL) + return (1); + else + return (0); } -/*************************/ +/* ********************* */ void * el_first(void) -/*************************/ +/* ********************* */ { - struct notice *n,*fn; - struct key *k,*fk; - struct index *ind,*fi; - int ctr,*val; + struct notice *n, *fn; + struct key *k, *fk; + struct index *ind, *fi; + int ctr, *val; time_t next_int; - if ((index==NULL) || (current==NULL)) return(NULL); + if ((index == NULL) || (current == NULL)) + return (NULL); while ((index->key)->time < current->time) { if (DU == 2) { @@ -382,10 +420,12 @@ el_first(void) k->time += DT; (k->notice)->time += DT; continue; } - /* remove the notice, key, and index corresponding - to the first time interval. Then split the - overflow interval into a normal interval - plus an overflow interval. */ + /* + * remove the notice, key, and index corresponding + * to the first time interval. Then split the + * overflow interval into a normal interval + * plus an overflow interval. + */ fi = index; fk = fi->key; fn = fk->notice; @@ -408,10 +448,12 @@ el_first(void) ctr++; n = n->left; } n = n->right; - /* n points to first notice of the new overflow interval - ctr tells how many notices are in the first sublist - of the new overflow interval - insert the new index element */ + /* + * n points to first notice of the new overflow interval + * ctr tells how many notices are in the first sublist + * of the new overflow interval + * insert the new index element + */ fi->right = ind->right; ind->right = fi; /* insert the new dummy key */ @@ -434,52 +476,53 @@ el_first(void) (current->right)->left = current->left; /* now update the numnote field in the appropriate key */ n = current; - while ( n->key == NULL ) n = n->right; + while (n->key == NULL) n = n->right; k = n->key; k->numnote = k->numnote - 1; /* if numnote = 0 then this key must be removed */ if (k->numnote == 0) { (k->left)->right = k->right; - (k->right)->left = k->left; + (k->right)->left = k->left; free(k); } /* now set current to be the head of the list */ fn = current->right; - while ( (fn != NULL) && (fn->isdummy) ) + while ((fn != NULL) && (fn->isdummy)) fn = fn->right; val = current->event; free(current); current = fn; - return(val); + return (val); } -/******************/ +/* ************** */ void el_delete(void) -/******************/ +/* ************** */ { /* el_delete frees up all the space associated with the event list */ - - struct index *ind,*ind2; - struct key *k,*k2; - struct notice *n,*n2; - if (index==NULL) return; + struct index *ind, *ind2; + struct key *k, *k2; + struct notice *n, *n2; + + if (index == NULL) + return; ind = index; k = ind->key; while (k->left != NULL) k = k->left; n = k->notice; - while (n!=NULL) { + while (n != NULL) { n2 = n->right; free(n); n = n2; } - while (k!=NULL) { + while (k != NULL) { k2 = k->right; free(k); k = k2; } - while (ind!=NULL) { + while (ind != NULL) { ind2 = ind->right; free(ind); ind = ind2; } |