Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

timer.c

Go to the documentation of this file.
00001 /* $Id: timer.c,v 1.2 2003/08/03 00:04:29 Mysid Exp $ */
00002 
00003 /*
00004  * Copyright (c) 1996-1997 Chip Norkus
00005  * Copyright (c) 1997 Max Byrd
00006  * Copyright (c) 1997 Greg Poma
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions
00011  * are met:
00012  * 1. Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  * 2. Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the
00016  *    documentation and/or other materials provided with the distribution.
00017  * 3. Neither the name of the authors nor the names of its contributors
00018  *    may be used to endorse or promote products derived from this software
00019  *    without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
00022  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
00025  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00026  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00027  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00028  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00030  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00031  * SUCH DAMAGE.
00032  */
00033 
00040 #include "services.h"
00041 #include "mass.h"
00042 #include <time.h>
00043 
00047 struct t_table
00048 {
00049     char *name;     
00050 
00051     void (*func) (char *);  
00052     /* void (*func) (void *); */
00053 };
00054 
00055 extern void autoremoveakill(char *mask);
00056 extern void killide(char *);
00057 extern void delTimedGhost(char *);
00058 extern void deleteTimedGhostChannel(char *);
00059 extern void flushLogs(char *);
00060 
00061 /* This is used to map timer addressed to the function names */
00062 // *INDENT-OFF*
00063 
00064 static struct t_table tt[] = {
00065   { "autoremoveakill",         autoremoveakill },
00066   { "killide",                 killide },
00067   { "delTimedGhost",           delTimedGhost },
00068   { "deleteTimedGhostChannel", deleteTimedGhostChannel },
00069   { "timed_akill_queue",       timed_akill_queue },
00070   { "timed_advert_maint",      timed_advert_maint },
00071   { "sync_cfg",                sync_cfg },
00072   { "expireNicks",             expireNicks },
00073   { "expireChans",             expireChans },
00074   { "checkTusers",             checkTusers },
00075   { "flushLogs",               flushLogs }
00076 };
00077 
00078 static int      curtid = 0;
00079 
00081 struct t_chain {
00083     struct t_chain *next;
00084 
00086     struct t_chain *prev;
00087 
00089     time_t          run;
00090 
00092     time_t          tid;
00093 
00095     void            (*func) (char *);
00096 
00098     char           *args;
00099 };
00100 
00101 // *INDENT-ON*
00102 
00106 static struct t_chain *firstTimerItem = NULL;
00107 
00124 int
00125 timer(long seconds, void (*func) (char *), void *args)
00126 {
00127     struct t_chain *tc, *temp;
00128     time_t curtime;
00129 
00130     time_t timetorun;
00131 
00132     curtime = time(NULL);
00133 
00134     if (seconds <= 0) {
00135         (void)func((char *)args);
00136         return 0;
00137     }
00138     timetorun = curtime + seconds;
00139 
00140     tc = (struct t_chain *)oalloc(sizeof(struct t_chain));
00141     tc->func = func;
00142     tc->run = timetorun;
00143     tc->args = (char *)args;
00144     curtid++;
00145     if (!curtid) {
00146         sSend
00147             ("%s GOPER :Timer ID overrun!  Services may be unstable until a restart.",
00148              myname);
00149         curtid++;
00150     }
00151     tc->tid = curtid;
00152 
00153     /*
00154      * If there isn't any timers 
00155      */
00156     if (firstTimerItem == NULL) {
00157         firstTimerItem = tc;
00158         tc->next = NULL;
00159         tc->prev = NULL;
00160         return tc->tid;
00161     }
00162     if (timetorun < firstTimerItem->run) {
00163         tc->next = firstTimerItem;
00164         tc->prev = NULL;
00165         firstTimerItem->prev = tc;
00166         firstTimerItem = tc;
00167         return tc->tid;
00168     }
00169     for (temp = firstTimerItem; temp->next; temp = temp->next) {
00170         if (temp->next) {
00171             if (temp->next->run <= timetorun)
00172                 continue;
00173         }
00174         tc->next = temp->next;
00175         temp->next = tc;
00176         tc->prev = temp;
00177         if (tc->next)
00178             tc->next->prev = tc;
00179         return tc->tid;
00180     }
00181 
00182 /*
00183  * Last entry 
00184  */
00185     tc->next = NULL;
00186     tc->prev = temp;
00187     temp->next = tc;
00188 
00189     return tc->tid;
00190 }
00191 
00199 int
00200 cancel_timer(int tid)
00201 {
00202     struct t_chain *temp;
00203     time_t curtime;
00204 
00205     curtime = time(NULL);
00206 
00207     if (!firstTimerItem)
00208         return -1;
00209 
00210     for (temp = firstTimerItem; temp; temp = temp->next) {
00211         if (temp->tid == tid) { /* match */
00212             if (temp->prev)
00213                 temp->prev->next = temp->next;
00214             if (temp->next)
00215                 temp->next->prev = temp->prev;
00216             if (temp == firstTimerItem)
00217                 firstTimerItem = temp->next;
00218 
00219             FREE(temp);
00220             return 0;
00221         }
00222     }
00223     return -1;
00224 }
00225 
00234 void
00235 timeralarm(void)
00236 {
00237     struct t_chain *tc;
00238     time_t curtime;
00239 
00240     curtime = time(NULL);
00241 
00242     /*
00243      * This is called when sigalarm is raised.. first, reset the signal 
00244      */
00245     tc = firstTimerItem;
00246 
00247     if (firstTimerItem == NULL)
00248         return;
00249     while (firstTimerItem->run <= curtime) {
00250         firstTimerItem->func(firstTimerItem->args);
00251         firstTimerItem = firstTimerItem->next;
00252         FREE(firstTimerItem->prev);
00253         firstTimerItem->prev = NULL;
00254     }
00255 }
00256 
00266 void
00267 dumptimer(char *from)
00268 {
00269     struct t_chain *tc;
00270     char temp[IRCBUF] = "\0";
00271     int i, num;
00272     time_t curtime;
00273 
00274     curtime = time(NULL);
00275 
00276     if (!firstTimerItem) {
00277         sSend(":%s NOTICE %s :No timers right now!", OperServ, from);
00278         return;
00279     }
00280     num = sizeof(tt) / sizeof(struct t_table);
00281     sSend(":%s NOTICE %s :tid secondsleft function             args",
00282           OperServ, from);
00283     for (tc = firstTimerItem; tc; tc = tc->next) {
00284         for (i = 0; i < num; i++) {
00285             if (tc->func == tt[i].func) {
00286                 strcpy(temp, tt[i].name);
00287                 break;
00288             } else
00289                 (*temp = '\0');
00290         }
00291         if (*temp == '\0')
00292             sprintf(temp, "%p", tc->func);
00293         sSend(":%s NOTICE %s :%-4ld %-11ld %-20s %s", OperServ, from,
00294               tc->tid, tc->run - curtime, temp, tc->args);
00295     }
00296 }

Generated at Sat Oct 25 20:56:10 2003 for Services using Doxygen.
Services Copyr. 1996-2001 Chip Norkus, Max Byrd, Greg Poma, Michael Graff, James Hess, Dafydd James. All rights reserved See LICENSE for licensing information.