diff --git a/ChangeLog b/ChangeLog index b66ac3ef..d2fc924e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -46,6 +46,7 @@ NeoStats ChangeLog - Anything we add/remove/fix/change is in here (even our rant - Statserv HTML fix for clientversions when its empty (F) - Added support for numeric to config file (M) - Added defines for parameter used in do_exit and ported calls accordingly (M) + - Improvements to return values and error checking (M) * NeoStats * Fish * Version 2.5.5 - Module API version number diff --git a/chans.c b/chans.c index 6461612a..4fa6e1ef 100644 --- a/chans.c +++ b/chans.c @@ -35,11 +35,13 @@ */ -void +int init_chan_hash () { ch = hash_create (C_TABLE_SIZE, 0, 0); - + if(!ch) + return NS_FAILURE; + return NS_SUCCESS; } /** @brief Process the Channel TS Time diff --git a/conf.c b/conf.c index 816a947d..1800a574 100644 --- a/conf.c +++ b/conf.c @@ -34,9 +34,6 @@ static void cb_Module (char *, int); /** @brief The list of modules to load */ static void *load_mods[NUM_MODULES]; -/** @brief Hrm? - */ -static int done_mods; /** @brief Core Configuration Items * @@ -116,7 +113,7 @@ ConfLoad () printf ("* *\n"); printf ("* NeoStats NOT Started *\n"); printf ("***************************************************\n"); - return -1; + return NS_FAILURE; } printf ("Sucessfully Loaded Config File, Now Booting NeoStats\n"); #ifdef EXTAUTH @@ -130,8 +127,7 @@ ConfLoad () if (GetConf ((void *) &me.pingtime, CFGINT, "PingServerTime") <= 0) { me.pingtime = 120; } - done_mods = 0; - return 0; + return NS_SUCCESS; } diff --git a/dl.c b/dl.c index a3836ea5..61ccb38a 100644 --- a/dl.c +++ b/dl.c @@ -53,15 +53,26 @@ struct { * * @return none */ -void +int __init_mod_list () { SET_SEGV_LOCATION(); mh = hash_create (NUM_MODULES, 0, 0); + if(!mh) + return NS_FAILURE; bh = hash_create (B_TABLE_SIZE, 0, 0); + if(!bh) + return NS_FAILURE; th = hash_create (T_TABLE_SIZE, 0, 0); + if(!th) + return NS_FAILURE; bch = hash_create (C_TABLE_SIZE, 0, 0); + if(!bch) + return NS_FAILURE; sockh = hash_create (me.maxsocks, 0, 0); + if(!sockh) + return NS_FAILURE; + return NS_SUCCESS; } /** @brief create new timer diff --git a/dl.h b/dl.h index 6a997757..8386a8d8 100644 --- a/dl.h +++ b/dl.h @@ -187,7 +187,7 @@ hash_t *mh; /* * Prototypes */ -void __init_mod_list (void); +int __init_mod_list (void); int load_module (char *path, User * u); int unload_module (char *module_name, User * u); int add_ld_path (char *path); diff --git a/dns.c b/dns.c index 9b66f40a..541317f9 100644 --- a/dns.c +++ b/dns.c @@ -135,7 +135,7 @@ init_dns () SET_SEGV_LOCATION(); dnslist = list_create (DNS_QUEUE_SIZE); if (!dnslist) - return 0; + return NS_FAILURE; #ifndef DEBUG adnsstart = adns_init (&ads, adns_if_noerrprint | adns_if_noautosys, 0); #else @@ -144,9 +144,9 @@ init_dns () if (adnsstart) { printf ("ADNS init failed: %s\n", strerror (adnsstart)); nlog (LOG_CRITICAL, LOG_CORE, "ADNS init failed: %s", strerror (adnsstart)); - return 0; + return NS_FAILURE; } - return 1; + return NS_SUCCESS; } diff --git a/log.c b/log.c index ebc222c3..8b893787 100644 --- a/log.c +++ b/log.c @@ -68,9 +68,9 @@ init_logs () logs = hash_create (-1, 0, 0); if (!logs) { printf ("ERROR: Can't initialize log subsystem. Exiting!"); - return -1; + return NS_FAILURE; } - return 0; + return NS_SUCCESS; } /** @brief Occasionally flush log files out @@ -168,7 +168,7 @@ nlog (int level, int scope, char *fmt, ...) } } void -ResetLogs () +reset_logs () { char tmp[255], tmp2[255]; time_t t = time (NULL); @@ -224,5 +224,5 @@ nassert_fail (const char *expr, const char *file, const int line, const char *in } #endif nlog (LOG_CRITICAL, LOG_CORE, "Shutting Down!"); - exit (-1); + exit (EXIT_FAILURE); } diff --git a/log.h b/log.h index 01de61f5..261eeaa6 100644 --- a/log.h +++ b/log.h @@ -89,7 +89,7 @@ extern void nassert_fail (const char *expr, const char *file, const int line, co extern void nlog (int level, int scope, char *fmt, ...); void *close_logs (); int init_logs (); -void ResetLogs (); +void reset_logs (); /* Configurable log filename format string */ extern char LogFileNameFormat[MAX_LOGFILENAME]; diff --git a/main.c b/main.c index 9dfaf5e8..033a72cd 100644 --- a/main.c +++ b/main.c @@ -61,9 +61,6 @@ const char version[] = "(IRCU)"; const char version[] = "(B)"; #endif - - - /*! Date when we were compiled */ const char version_date[] = __DATE__; /*! Time we were compiled */ @@ -74,7 +71,6 @@ static void start (void); static void setup_signals (void); static int get_options (int argc, char **argv); - /*! have we forked */ int forked = 0; @@ -93,20 +89,20 @@ main (int argc, char *argv[]) { FILE *fp; /* get our commandline options */ - if(get_options (argc, argv)<0) - exit(-1); + if(get_options (argc, argv)!=NS_SUCCESS) + return EXIT_FAILURE; /* Change to the working Directory */ if (chdir (NEO_PREFIX) < 0) { printf ("NeoStats Could not change to %s\n", NEO_PREFIX); printf ("Did you 'make install' after compiling?\n"); printf ("Error Was: %s\n", strerror (errno)); - exit (-1); + return EXIT_FAILURE; } /* before we do anything, make sure logging is setup */ - if(init_logs ()<0) - exit(-1); + if(init_logs () != NS_SUCCESS) + return EXIT_FAILURE; /* our crash trace variables */ SET_SEGV_LOCATION(); @@ -146,29 +142,33 @@ main (int argc, char *argv[]) remove (RECV_LOG); /* initilze our Module subsystem */ - __init_mod_list (); + if(__init_mod_list () != NS_SUCCESS) + return EXIT_FAILURE; /* prepare to catch errors */ setup_signals (); /* load the config files */ - if(ConfLoad ()<0) - exit(-1); + if(ConfLoad () != NS_SUCCESS) + return EXIT_FAILURE; + if (me.die) { printf ("\n-----> ERROR: Read the README file then edit %s! <-----\n\n",CONFIG_NAME); nlog (LOG_CRITICAL, LOG_CORE, "Read the README file and edit your %s",CONFIG_NAME); - sleep (1); - close (servsock); - /* we are exiting the parent, not the program, don't call do_exit() */ - exit (0); + /* we are exiting the parent, not the program, so just return */ + return EXIT_FAILURE; } /* initialize the rest of the subsystems */ TimerReset (); - init_dns (); - init_server_hash (); - init_user_hash (); - init_chan_hash (); + if(init_dns () != NS_SUCCESS) + return EXIT_FAILURE; + if(init_server_hash () != NS_SUCCESS) + return EXIT_FAILURE; + if(init_user_hash () != NS_SUCCESS) + return EXIT_FAILURE; + if(init_chan_hash () != NS_SUCCESS) + return EXIT_FAILURE; init_ircd (); @@ -181,7 +181,7 @@ main (int argc, char *argv[]) /* Error check fork() */ if (forked<0) { perror("fork"); - exit(1); /* fork error */ + return EXIT_FAILURE; /* fork error */ } #endif /* we are the parent */ @@ -195,13 +195,13 @@ main (int argc, char *argv[]) printf ("NeoStats %d.%d.%d%s Successfully Launched into Background\n", MAJOR, MINOR, REV, version); printf ("PID: %i - Wrote to neostats.pid\n", forked); } - exit(0); /* parent exits */ + return EXIT_SUCCESS; /* parent exits */ } #ifndef DEBUG /* child (daemon) continues */ /* reopen logs for child */ - if(init_logs ()<0) - exit(-1); + if(init_logs () != NS_SUCCESS) + return EXIT_FAILURE; /* detach from parent process */ if (setpgid (0, 0) < 0) { nlog (LOG_WARNING, LOG_CORE, "setpgid() failed"); @@ -216,7 +216,10 @@ main (int argc, char *argv[]) /* we are ready to start now Duh! */ start (); - return 1; + /* We should never reach here but the compiler does not realise and may + complain about not all paths control returning values without the return + Since it should never happen, treat as an error condition! */ + return EXIT_FAILURE; } /** @brief Process Commandline Options @@ -251,7 +254,7 @@ get_options (int argc, char **argv) printf (" -n (Do not load any modules on startup)\n"); printf (" -q (Quiet start - for cron scripts)\n"); printf (" -f (Do not fork into background\n"); - return (-1); + return NS_FAILURE; case 'v': printf ("NeoStats Version %d.%d.%d%s\n", MAJOR, MINOR, REV, version); printf ("Compiled: %s at %s\n", version_date, version_time); @@ -266,7 +269,7 @@ get_options (int argc, char **argv) printf ("(B) - Bahamut IRCd\n"); printf ("(IRCu) - IRCu (P10) IRCd\n"); printf ("\nNeoStats: http://www.neostats.net\n"); - return (-1); + return NS_FAILURE; case 'r': printf ("recv.log enabled. Watch your DiskSpace\n"); config.recvlog = 1; @@ -281,7 +284,7 @@ get_options (int argc, char **argv) dbg = atoi (optarg); if ((dbg > 10) || (dbg < 1)) { printf ("Invalid Debug Level %d\n", dbg); - return (-1); + return NS_FAILURE; } config.debug = dbg; break; @@ -292,7 +295,7 @@ get_options (int argc, char **argv) printf ("Unknown command line switch %c\n", optopt); } } - return(0); + return NS_SUCCESS; } @@ -310,7 +313,7 @@ RETSIGTYPE serv_die () { #ifdef VALGRIND - exit(1); + exit(NS_SUCCESS); #else /* VALGRIND */ User *u; u = finduser (s_Services); @@ -444,29 +447,32 @@ setup_signals (void) struct sigaction act; act.sa_handler = SIG_IGN; act.sa_flags = 0; + + /* SIGPIPE/SIGALRM */ (void) sigemptyset (&act.sa_mask); (void) sigaddset (&act.sa_mask, SIGPIPE); (void) sigaddset (&act.sa_mask, SIGALRM); (void) sigaction (SIGPIPE, &act, NULL); (void) sigaction (SIGALRM, &act, NULL); + /* SIGHUP */ act.sa_handler = conf_rehash; (void) sigemptyset (&act.sa_mask); (void) sigaddset (&act.sa_mask, SIGHUP); (void) sigaction (SIGHUP, &act, NULL); + /* SIGTERM/SIGINT */ act.sa_handler = serv_die; (void) sigaddset (&act.sa_mask, SIGTERM); (void) sigaction (SIGTERM, &act, NULL); (void) sigaddset (&act.sa_mask, SIGINT); (void) sigaction (SIGINT, &act, NULL); -/* handling of SIGSEGV as well -sts */ + /* SIGSEGV as well -sts */ act.sa_handler = serv_segv; (void) sigaddset (&act.sa_mask, SIGSEGV); (void) sigaction (SIGSEGV, &act, NULL); - (void) signal (SIGHUP, conf_rehash); (void) signal (SIGTERM, serv_die); (void) signal (SIGSEGV, serv_segv); @@ -498,24 +504,22 @@ start (void) if (servsock <= 0) { nlog (LOG_WARNING, LOG_CORE, "Unable to connect to %s", me.uplink); } else { - attempts = 0; login (); read_loop (); + close (servsock); } - if(me.r_time>0) - nlog (LOG_NOTICE, LOG_CORE, "Reconnecting to the server in %d seconds (Attempt %i)", me.r_time, attempts); - else - nlog (LOG_NOTICE, LOG_CORE, "Reconnect time is zero, shutting down"); - close (servsock); unload_modules(NULL); if(me.r_time>0) { + nlog (LOG_NOTICE, LOG_CORE, "Reconnecting to the server in %d seconds (Attempt %i)", me.r_time, attempts); sleep (me.r_time); do_exit (NS_EXIT_RESTART); } - else + else { + nlog (LOG_NOTICE, LOG_CORE, "Reconnect time is zero, shutting down"); do_exit (NS_EXIT_NORMAL); + } } /** @brief Login to IRC @@ -534,6 +538,42 @@ login (void) sprotocol_cmd ("TOKEN CLIENT"); } +/** @brief before exiting call this function. It flushes log files and tidy's up. + * + * Cleans up before exiting + * @parm segv 1 = we are exiting because of a segv fault, 0, we are not. + * if 1, we don't prompt to save data + */ +void +do_exit (int segv) +{ + /* Initialise exit code to OK */ + int exit_code=EXIT_SUCCESS; + + switch (segv) { + case NS_EXIT_NORMAL: + nlog (LOG_CRITICAL, LOG_CORE, "Normal shut down subsystems"); + break; + case NS_EXIT_RESTART: + nlog (LOG_CRITICAL, LOG_CORE, "Restarting NeoStats subsystems"); + break; + case NS_EXIT_SEGFAULT: + nlog (LOG_CRITICAL, LOG_CORE, "Shutting down subsystems without saving data due to core"); + exit_code=EXIT_FAILURE; /* exit code to error */ + break; + } + kp_flush(); + close_logs (); + if (segv == NS_EXIT_RESTART) { + execve ("./neostats", NULL, NULL); + exit_code=EXIT_FAILURE; /* exit code to error */ + } + remove ("neostats.pid"); + exit (exit_code); +} + +/* @todo Everything below here wants moving into a different file */ + /** @brief Our Own implementation of Malloc. * * Allocates memory for internal variables. Usefull for Memory Debugging @@ -677,42 +717,6 @@ FreeList (char **List, int C) C = 0; } -/** @brief before exiting call this function. It flushes log files and tidy's up. - * - * Cleans up before exiting - * @parm segv 1 = we are exiting because of a segv fault, 0, we are not. - * if 1, we don't prompt to save data - */ -void -do_exit (int segv) -{ - /* Initialise exit code to OK */ - int exit_code=1; - - switch (segv) { - case 0: - nlog (LOG_CRITICAL, LOG_CORE, "Normal shut down subsystems"); - break; - case 2: - nlog (LOG_CRITICAL, LOG_CORE, "Restarting NeoStats subsystems"); - break; - case 1: - nlog (LOG_CRITICAL, LOG_CORE, "Shutting down subsystems without saving data due to core"); - /* exit code to error */ - exit_code=-1; - break; - } - kp_flush(); - close_logs (); - if (segv == 2) { - execve ("./neostats", NULL, NULL); - /* exit code to error */ - exit_code=-2; - } - remove ("neostats.pid"); - exit (exit_code); -} - /* this came from eggdrop sources */ /* Remove the color control codes that mIRC,pIRCh etc use to make * their client seem so fecking cool! (Sorry, Khaled, you are a nice diff --git a/server.c b/server.c index 4a919c23..e6bdf8dd 100644 --- a/server.c +++ b/server.c @@ -148,15 +148,16 @@ ServerDump () sendcoders ("End of Listing."); } -void +int init_server_hash () { sh = hash_create (S_TABLE_SIZE, 0, 0); if (!sh) { nlog (LOG_CRITICAL, LOG_CORE, "Create Server Hash Failed\n"); - do_exit (NS_EXIT_SEGFAULT); + return NS_FAILURE; } AddServer (me.name, NULL, 0); + return NS_SUCCESS; } void diff --git a/stats.h b/stats.h index d1342fd1..56ea4cdb 100644 --- a/stats.h +++ b/stats.h @@ -108,6 +108,21 @@ #define bzero(x, y) memset(x, '\0', y); #define is_synced me.synced +/* Early creation of unified return values and error system */ +/* These are program exit codes usually defined in stdlib.h but + if not found will be defined here */ +#ifndef EXIT_FAILURE +#define EXIT_FAILURE 1 +#endif /* EXIT_FAILURE */ +#ifndef EXIT_SUCCESS +#define EXIT_SUCCESS 0 +#endif /* EXIT_SUCCESS */ + +#define NS_SUCCESS 1 +#define NS_FAILURE -1 + +#define NS_ERROR_xxx -2 + /* do_exit call exit type definitions */ enum { NS_EXIT_NORMAL=0, @@ -287,12 +302,12 @@ void rehash (void); int init_modules (void); /* main.c */ +void do_exit (int exitcode); void *smalloc (long size); char *sstrdup (const char * s); char *strlower (char * s); void AddStringToList (char ***List, char S[], int *C); void FreeList (char **List, int C); -void do_exit (int exitcode); void strip_mirc_codes(char *text); char *sctime (time_t t); char *sftime (time_t t); @@ -333,7 +348,7 @@ User *finduser (const char *nick); void UserDump (char *nick); void part_u_chan (list_t *list, lnode_t *node, void *v); void UserMode (const char *nick, const char *modes, int smode); -void init_user_hash (void); +int init_user_hash (void); int UserLevel (User *u); void Do_Away (User *u, const char *awaymsg); void KillUser (const char *nick); @@ -343,7 +358,7 @@ void AddServer (char *name, char *uplink, int hops); void DelServer (char *name); Server *findserver (const char *name); void ServerDump (void); -void init_server_hash (void); +int init_server_hash (void); /* ns_help.c */ extern const char *ns_help[]; @@ -389,7 +404,7 @@ void kick_chan (User *, char *, User *); void Change_Chan_Ts (Chans * c, time_t tstime); int CheckChanMode (Chans * c, long mode); int IsChanMember(Chans *c, User *u); -void init_chan_hash (void); +int init_chan_hash (void); /* dns.c */ int dns_lookup (char *str, adns_rrtype type, void (*callback) (char *data, adns_answer * a), char *data); diff --git a/timer.c b/timer.c index 20e0c39d..5ddcf65e 100644 --- a/timer.c +++ b/timer.c @@ -28,12 +28,8 @@ #include "log.h" #include "conf.h" -static time_t last_stats_save; -static time_t last_lag_check; -static time_t last_cache_save; static int midnight = 0; - void chk () { @@ -94,24 +90,11 @@ chk () } } -void -TimerReset () -{ - time_t current = time (NULL); - last_stats_save = current; - last_lag_check = current; - last_cache_save = current; -} - - - - - void TimerMidnight () { nlog (LOG_DEBUG1, LOG_CORE, "Its midnight!!! -> %s", sctime (time (NULL))); - ResetLogs (); + reset_logs (); } int diff --git a/users.c b/users.c index dea38cb9..41da51ae 100644 --- a/users.c +++ b/users.c @@ -260,11 +260,13 @@ finduser (const char *nick) } -void +int init_user_hash () { uh = hash_create (U_TABLE_SIZE, 0, 0); - + if(!uh) + return NS_FAILURE; + return NS_SUCCESS; } void