diff -uNr ircservices-5.0.23/Changes ircservices-5.0.24/Changes --- ircservices-5.0.23/Changes 2003-11-03 18:06:18 +0900 +++ ircservices-5.0.24/Changes 2003-11-11 16:06:32 +0900 @@ -1,5 +1,19 @@ Version 5.0 ----------- +2003/11/11 .24 Fixed a warning in convert-db compilation. +2003/11/11 Fixed bugs in convert-db causing some nickname and channel + settings (timezone, language, channel and memo limits) + to not be initialized properly. +2003/11/11 Added -tzfile, -no-timezones, and -reset-memo-limits + options to the Cygnus database converter in convert-db. +2003/11/05 Databases can now be exported in XML from the command line + (-export option). +2003/11/05 GCC versions earlier than 3.2 (except 2.95.3) are now + deprecated. Variadic macros workaround added for + problem reported by Ali Sor +2003/11/05 Channel last-used time is now updated properly for the + first user to enter the channel if the user has auto-op + privileges. Reported by 2003/11/01 .23 Fixed bug causing database contents to get lost for small databases on full filesystems. Reported by diff -uNr ircservices-5.0.23/configure ircservices-5.0.24/configure --- ircservices-5.0.23/configure 2003-10-20 15:53:10 +0900 +++ ircservices-5.0.24/configure 2003-11-05 15:46:59 +0900 @@ -178,7 +178,7 @@ # Variable initialization. -MY_CONFIG_VERSION=5 +MY_CONFIG_VERSION=6 CONFIG_VERSION= PROGRAM=ircservices @@ -196,6 +196,7 @@ CC_LFLAGS=bonkle CC_LIBS=bonkle EXE_SUFFIX=bonkle +NO_VARARG_MACROS= CLEAN_COMPILE=y MEMCHECKS= @@ -245,6 +246,7 @@ MISSING=bonkle FORCED_GCC_2_96= +WARNED_OLD_GCC= ########################################################################### @@ -511,6 +513,10 @@ # socklen_t test broken on FreeBSD HAVE_SOCKLEN_T= fi + if [ $CONFIG_VERSION -lt 6 ] ; then + # deprecated GCC < 3.2, so recheck compiler + CC= + fi if [ "$USE_DYNAMIC_MODULES" ] ; then STATIC_MODULES= RANLIB= @@ -710,7 +716,7 @@ log "/usr/bin/test works" echo "medium." else - log "neither test nor /bin/test work!" + log "neither test nor /bin/test nor /usr/bin/test work!" echo "low." echo " Warning: Compilation may fail unless you pass a saner shell to make:" echo " make [or gmake] SHELL=/usr/local/bin/bash ..." @@ -744,10 +750,9 @@ EOT if [ "$FORCE_GCC_2_96" ] ; then cat <&1 | fgrep 2.96 >/dev/null ; then + version=`gcc --version 2>&1 | head -1 | sed 's/.*[^0-9.]\([0-9][0-9.]*\).*/\1/'` + vmajor=`echo "x.$version.0" | cut -d. -f2` + vminor=`echo "x.$version.0" | cut -d. -f3` + if test "x$version" = x || (echo "x$vmajor" | cut -c2- | grep '[^0-9]' >/dev/null 2>&1) || (echo "x$vminor" | cut -c2- | grep '[^0-9]' >/dev/null 2>&1) ; then + log "unparseable version string: $version" + cat <$CONFTMP/test.c <>config.h.new <>config.h.new <
  • GCC -[www.gnu.org] (the GNU C compiler). -Services currently uses some extensions to the C language provided by GCC, -and is unlikely to compile on other compilers. Warning: GCC version -2.96, provided in some Red Hat and related Linux distributions, has bugs -which cause Services to be compiled incorrectly (see -FAQ B.1 for details); early versions in the 3.x -series were also reported to have problems. Please use either version -2.95.3 or version 3.2 or later to compile Services. +[www.gnu.org] (the GNU C compiler), either +version 2.95.3, or version 3.2 or later. Services currently uses some +extensions to the C language provided by GCC, and is unlikely to compile on +other compilers; Services also takes advantage of recent additions to the C +standard (often referred to as "C99"), in particular "variadic macros", +which are not supported by older versions of GCC. This version of Services +may compile with such older versions, albeit with less specific error +messages in some circumstances, but support for them is planned to be +removed completely in a future version. Also note that early versions in +the 3.x series were reported to have problems, and should not be used. + +

    Warning: GCC version 2.96, provided in some Red Hat and related +Linux distributions, has bugs which cause Services to be compiled +incorrectly (see FAQ B.1 for details). Do not +use this compiler to compile Services in any circumstances.

  • GNU make [www.gnu.org], version 3.79 or diff -uNr ircservices-5.0.23/docs/5.html ircservices-5.0.24/docs/5.html --- ircservices-5.0.23/docs/5.html 2003-10-27 12:34:21 +0900 +++ ircservices-5.0.24/docs/5.html 2003-11-11 15:48:27 +0900 @@ -29,13 +29,26 @@

    In order to facilitate processing of the Services databases by other programs, Services provides the ability to export the databases in XML format. This is accomplished through the misc/xml-export module -and the HTTP server built into Services. +and, optionally, the HTTP server built into +Services. -

    If the misc/xml-export module is loaded into Services, the HTTP -database access module (httpd/dbaccess) will display an "XML -database download" link. Clicking on the link will display the XML data -in your browser, which you can then save (for Netscape and Internet -Explorer, select "Save as..." from the browser's File menu). +

    The misc/xml-export module adds an extra command-line option, +-export, to Services. Since the command line is parsed before +Services connects to the network, the module must be specified in your +ircservices.conf file to enable this option. The option has the +format "-export" or "-export=filename", where +filename is the name of the file to write the XML data to; +if it does not begin with a slash, it is taken relative to the Services +data directory (the directory containing the database and log files). If +filename is not given or is a single hyphen ("-"), +the data will be printed on standard output. When the export completes, +Services will terminate, and will not connect to the IRC network. + +

    Additionally, if the misc/xml-export module is loaded into +Services, the HTTP database access module (httpd/dbaccess) will +display an "XML database download" link. Clicking on the link will display +the XML data in your browser, which you can then save (for Netscape and +Internet Explorer, select "Save as..." from the browser's File menu). Alternatively, you can download the link directly without displaying it in your browser; in Netscape, hold shift while clicking on the link, and in Internet Explorer, right-click on the link and select "Save target as..." @@ -44,10 +57,14 @@

    The format of the exported XML data is discussed in Appendix B. No DTD is currently available. -

    Note: Services will not respond to any network activity while you +

    Notes: Services will not respond to any network activity while you are downloading the database. If you have a large database, this can make Services appear to "freeze" with respect to the IRC network, and it may -even get disconnected from the network in extreme cases. +even get disconnected from the network in extreme cases. Additionally, be +aware that the data may change after you have downloaded it; if you want to +avoid this, for example when exporting data to move it to another machine +or network, use the command-line option -export rather than the +HTTP server interface.

    Note to Internet Explorer users: Some versions of Internet Explorer have a bug which can prevent the XML data from being displayed or @@ -77,9 +94,10 @@

    Just as it can export data in XML format, Services can also read in XML data and import (merge) it into its databases. Importing is handled by the -misc/xml-import module. Unlike exporting, however, importing is -done via the command line. For this reason, the misc/xml-import -module must be loaded at startup (loading it via an OperServ +misc/xml-import module. Unlike exporting, however, importing +cannot be done via the HTTP server; it is always done through the command +line. For this reason, the misc/xml-import module must be loaded +at startup (loading it via an OperServ REHASH or a SIGHUP signal will have no effect). @@ -153,7 +171,7 @@

    The full syntax for convert-db is as follows:

    - convert-db [-v] [+program-name] pathname + convert-db [-v] [+program-name] [options . . . ] pathname
    The options and parameters are:
      @@ -162,6 +180,8 @@ used to create the data files. A list of possible program-name values is given in table 5-1 below. program-name values are not case sensitive. +
    • options: Additional options specific to each type of + data file controlling details of the data conversion; see below.
    • pathname: Specifies the pathname of the directory containing the database files.
    @@ -219,6 +239,24 @@

    Back to top +

    Additional options are available for the following data file types: +

    +
    cygnus +
      +
    • -tzfile=filename: Specifies an alternative time + zone file to use when loading nickname time zone data. + convert-db defaults to the deata from the + cygnus.zone file distributed with Cygnus 0.2.0; if you + have modified this file or created your own time zone list, you + will need to use this option to get nickname time zones converted + correctly. +
    • -no-timezones: Causes all nickname time zone settings to + be reset to default (the time zone Services runs in). +
    • -reset-memo-limits: Causes all nickname memo limits to be + reset to default; see the notes on Cygnus database conversion. +
    +
    +

    5-3-2. Notes on converting databases from particular programs

    @@ -317,10 +355,15 @@
  • Nicknames will retain their memo limit settings in the converted data; however, they will not be affected by changes to the MSMaxMemos - setting. -
  • If you have modified the timezone list used by Cygnus + setting. (Memo limits can be reset to the default, which follows + the MSMaxMemos setting, with the -reset-memo-limits + option.) +
  • If you have modified the time zone list used by Cygnus (cygnus.zone), nickname time zones will not be transferred - correctly. + correctly by default. Use the -tzfile= option to ensure + that time zones are loaded from your time zone file, or use the + -no-timezones option to reset all time zone settings to + default.
  • Authentication for channels is not supported; authentication codes and "verify" information will be discarded.
  • Channel access list entries in IRC Services must always be registered diff -uNr ircservices-5.0.23/modules/chanserv/check.c ircservices-5.0.24/modules/chanserv/check.c --- ircservices-5.0.23/modules/chanserv/check.c 2003-11-03 18:10:36 +0900 +++ ircservices-5.0.24/modules/chanserv/check.c 2003-11-11 16:09:43 +0900 @@ -187,14 +187,21 @@ if ((modes & CUMODE_o) && !(ci->flags & CI_LEAVEOPS) && is_servermode - && (time(NULL)-start_time >= CSRestrictDelay - || !check_access_if_idented(user, ci, CA_AUTOOP)) - && !check_access(user, ci, CA_AUTOOP) ) { - notice_lang(s_ChanServ, user, CHAN_IS_REGISTERED, s_ChanServ); - u->flags |= CUFLAG_DEOPPED; - set_cmode(s_ChanServ, c, "-o", user->nick); - modes &= ~CUMODE_o; + if ((time(NULL)-start_time >= CSRestrictDelay + || !check_access_if_idented(user, ci, CA_AUTOOP)) + && !check_access(user, ci, CA_AUTOOP) + ) { + notice_lang(s_ChanServ, user, CHAN_IS_REGISTERED, s_ChanServ); + u->flags |= CUFLAG_DEOPPED; + set_cmode(s_ChanServ, c, "-o", user->nick); + modes &= ~CUMODE_o; + } else if (check_access(user, ci, CA_AUTOOP)) { + /* The user's an autoop user; update the last-used time here, + * because it won't get updated below (they're already opped) */ + ci->last_used = time(NULL); + put_channelinfo(ci); + } } /* Adjust modes based on channel access */ diff -uNr ircservices-5.0.23/modules/misc/xml-export.c ircservices-5.0.24/modules/misc/xml-export.c --- ircservices-5.0.23/modules/misc/xml-export.c 2003-11-03 18:10:36 +0900 +++ ircservices-5.0.24/modules/misc/xml-export.c 2003-11-11 16:09:43 +0900 @@ -431,6 +431,35 @@ } /*************************************************************************/ +/*************************************************************************/ + +#ifndef CONVERT_DB + +/* Command-line option callback. */ + +static int do_command_line(const char *option, const char *value) +{ + FILE *f; + + if (!option || strcmp(option, "export") != 0) + return 0; + if (!value || !*value || strcmp(value,"-") == 0) { + f = stdout; + } else { + f = fopen(value, "w"); + if (!f) { + perror(value); + return 2; + } + } + if (!xml_export((xml_writefunc_t)fprintf, f)) + return 2; + return 3; +} + +#endif /* CONVERT_DB */ + +/*************************************************************************/ /***************************** Module stuff ******************************/ /*************************************************************************/ @@ -450,6 +479,12 @@ { module = module_; + if (!add_callback(NULL, "command line", do_command_line)) { + module_log("Unable to add callback"); + exit_module(0); + return 0; + } + return 1; } diff -uNr ircservices-5.0.23/modules/misc/xml-import.c ircservices-5.0.24/modules/misc/xml-import.c --- ircservices-5.0.23/modules/misc/xml-import.c 2003-11-03 18:10:36 +0900 +++ ircservices-5.0.24/modules/misc/xml-import.c 2003-11-11 16:09:43 +0900 @@ -2615,6 +2615,7 @@ if (!add_callback(NULL, "command line", do_command_line)) { module_log("Unable to add callback"); exit_module(0); + return 0; } return 1; diff -uNr ircservices-5.0.23/modules/nickserv/autojoin.c ircservices-5.0.24/modules/nickserv/autojoin.c --- ircservices-5.0.23/modules/nickserv/autojoin.c 2003-11-03 18:10:36 +0900 +++ ircservices-5.0.24/modules/nickserv/autojoin.c 2003-11-11 16:09:43 +0900 @@ -169,14 +169,14 @@ } ARRAY_SEARCH_PLAIN(ngi->ajoin, chan, strcmp, i); if (i == ngi->ajoin_count) - ARRAY_SEARCH_PLAIN(ngi->ajoin, chan, stricmp, i); + ARRAY_SEARCH_PLAIN(ngi->ajoin, chan, irc_stricmp, i); if (i == ngi->ajoin_count) { notice_lang(s_NickServ, u, NICK_AJOIN_NOT_FOUND, chan); return; } - notice_lang(s_NickServ, u, NICK_AJOIN_DELETED, chan); free(ngi->ajoin[i]); ARRAY_REMOVE(ngi->ajoin, i); + notice_lang(s_NickServ, u, NICK_AJOIN_DELETED, chan); } else if (stricmp(cmd, "LIST") == 0) { if (!ngi->ajoin_count) { diff -uNr ircservices-5.0.23/tools/convert-cygnus.c ircservices-5.0.24/tools/convert-cygnus.c --- ircservices-5.0.23/tools/convert-cygnus.c 2003-11-03 18:10:36 +0900 +++ ircservices-5.0.24/tools/convert-cygnus.c 2003-11-11 16:09:43 +0900 @@ -23,6 +23,18 @@ * checking and store the result in the variable `var'; if the value is not * a valid integer, a message is printed to stderr and the current time is * used instead. `errfmt' must be a string literal. */ +#ifdef NO_VARARG_MACROS +#define CVT_TIME(var,str) do { \ + unsigned long time_l = strtoul(str, (char **)&str, 10); \ + if (str && *str) { \ + fprintf(stderr, "%s:%d: time is not a valid number;" \ + " setting to current time\n", fname, line); \ + var = time(NULL); \ + } else { \ + var = time_l; \ + } \ +} while (0) +#else /* vararg macros */ #define CVT_TIME(var,str,errfmt,...) do { \ unsigned long time_l = strtoul(str, (char **)&str, 10); \ if (str && *str) { \ @@ -33,9 +45,22 @@ var = time_l; \ } \ } while (0) +#endif /* The same thing, but defaulting to zero instead of the current time * (good for expirations). */ +#ifdef NO_VARARG_MACROS +#define CVT_TIME_0(var,str) do { \ + unsigned long time_l = strtoul(str, (char **)&str, 10); \ + if (str && *str) { \ + fprintf(stderr, "%s:%d: time is not a valid number;" \ + " setting to zero\n", fname, line); \ + var = time(NULL); \ + } else { \ + var = time_l; \ + } \ +} while (0) +#else /* vararg macros */ #define CVT_TIME_0(var,str,errfmt,...) do { \ unsigned long time_l = strtoul(str, (char **)&str, 10); \ if (str && *str) { \ @@ -46,6 +71,12 @@ var = time_l; \ } \ } while (0) +#endif + +/*************************************************************************/ + +/* Reset memo limits to default? (-reset-memo-limits option) */ +static int reset_memo_limits = 0; /*************************************************************************/ @@ -243,11 +274,18 @@ pass[sizeof(ngi->pass)-1] = 0; } strscpy(ngi->pass, pass, sizeof(ngi->pass)); +#ifdef NO_VARARG_MACROS + CVT_TIME(ni->time_registered, reg); + CVT_TIME(ni->last_seen, seen); +#else CVT_TIME(ni->time_registered, reg, "Registration time for `%s'", ni->nick); CVT_TIME(ni->last_seen, seen, "Last-seen time for `%s'", ni->nick); +#endif tmp = strtol(memolimit, (char **)&memolimit, 10); - if (memolimit && *memolimit) { + if (reset_memo_limits) { + ngi->memos.memomax = MEMOMAX_DEFAULT; + } else if (memolimit && *memolimit) { fprintf(stderr, "%s:%d: Memo limit for `%s' is not a valid" " number; setting to default\n", fname, line, ni->nick); @@ -265,7 +303,7 @@ " valid number; setting to default\n", fname, line, ni->nick); ngi->timezone = TIMEZONE_DEFAULT; - } else if (tmp == 0) { + } else if (tmp == 0 || ntimezones <= 0) { ngi->timezone = TIMEZONE_DEFAULT; } else if (tmp < 1 || tmp > ntimezones) { fprintf(stderr, "%s:%d: Timezone index for `%s' is out of" @@ -414,7 +452,11 @@ " ignoring memo\n", fname, line); break; } +#ifdef NO_VARARG_MACROS + CVT_TIME(rtime, time_s); +#else CVT_TIME(rtime, time_s, "Memo timestamp"); +#endif if (strlen(sender) > NICKMAX-1) { fprintf(stderr, "%s:%d: Truncating sender nickname `%s'" " (exceeds NICKMAX-1 characters)\n", fname, line, @@ -732,9 +774,14 @@ pass[sizeof(ci->founderpass)-1] = 0; } strscpy(ci->founderpass, pass, sizeof(ci->founderpass)); +#ifdef NO_VARARG_MACROS + CVT_TIME(ci->time_registered, reg); + CVT_TIME(ci->last_used, used); +#else CVT_TIME(ci->time_registered, reg, "Registration time for `%s'", ci->name); CVT_TIME(ci->last_used, used, "Last-used time for `%s'", ci->name); +#endif lockon = strtol(lockon_s, (char **)&lockon_s, 10); if (lockon_s && *lockon_s) { fprintf(stderr, "%s:%d: Locked-on mode value for `%s' is not" @@ -767,6 +814,7 @@ " range; clearing\n", fname, line, ci->name); tmp = 0; } + ci->memos.memomax = MEMOMAX_DEFAULT; /* Now set flags */ ci->flags = 0; if (tmp) @@ -876,8 +924,12 @@ } if (reason && !*reason) reason = NULL; +#ifdef NO_VARARG_MACROS + CVT_TIME(stime, time_s); +#else CVT_TIME(stime, time_s, "%s autokick `%s': Set time", ci->name, mask); +#endif ARRAY_EXTEND(ci->akick); ci->akick[ci->akick_count-1].mask = sstrdup(mask); ci->akick[ci->akick_count-1].reason = reason ? sstrdup(reason) @@ -957,8 +1009,12 @@ fname, line); break; } +#ifdef NO_VARARG_MACROS + CVT_TIME(ci->last_topic_time, time_s); +#else CVT_TIME(ci->last_topic_time, time_s, "%s topic: Set time", ci->name); +#endif strscpy(ci->last_topic_setter, nick, sizeof(ci->last_topic_setter)); ci->last_topic = sstrdup(topic); @@ -1159,9 +1215,14 @@ md->mask = sstrdup(mask); md->reason = sstrdup(reason); strscpy(md->who, setter, sizeof(md->who)); +#ifdef NO_VARARG_MACROS + CVT_TIME(md->time, set); + CVT_TIME_0(md->expires, expires); +#else CVT_TIME(md->time, set, "Autokill `%s' set-time value", mask); CVT_TIME_0(md->expires, expires, "Autokill `%s' expires value", mask); +#endif if (md->expires) md->expires += md->time; md->lastused = 0; @@ -1295,10 +1356,85 @@ return NULL; } -static void load_cygnus(const char *sourcedir, int verbose) +static void load_cygnus(const char *sourcedir, int verbose, int ac, char **av) { + int i; + timezones = (int *)default_timezones; ntimezones = lenof(default_timezones); + reset_memo_limits = 0; + for (i = 1; i < ac; i++) { + if (strncmp(av[i],"-tzfile=",8) == 0) { + const char *filename = av[i]+8; + FILE *f = fopen(filename, "r"); + if (!f) { + fprintf(stderr, "Cannot open time zone file `%s': %s\n", + filename, strerror(errno)); + } else { + char buf[BUFSIZE]; + fprintf(stderr, "Using time zone file `%s'.\n", filename); + ntimezones = 0; + while (fgets(buf, sizeof(buf), f)) { + int n = atoi(buf); + if (n > ntimezones) + ntimezones = n; + } + if (ntimezones <= 0) { + fprintf(stderr, "Warning: time zone file `%s' is empty\n", + filename); + timezones = NULL; + } else { + int line = 0; + timezones = smalloc(sizeof(*timezones) * ntimezones); + memset(timezones, -1, sizeof(timezones)); + fseek(f, 0, SEEK_SET); + while (fgets(buf, sizeof(buf), f)) { + char *nstr, *ofsstr; + int n, ofs; + line++; + nstr = strtok(buf, " \t\r\n"); + (void) strtok(NULL, " \t\r\n"); + (void) strtok(NULL, " \t\r\n"); + ofsstr = strtok(NULL, " \t\r\n"); + if (!nstr || !ofsstr) { + fprintf(stderr, "Warning: invalid format in time" + " zone file `%s' line %d\n", + filename, line); + continue; + } + n = strtol(nstr, &nstr, 10); + ofs = strtol(ofsstr, &ofsstr, 10); + if ((nstr && *nstr) || (ofsstr && *ofsstr)) { + fprintf(stderr, "Warning: invalid format in time" + " zone file `%s' line %d\n", + filename, line); + } else if (n < 1 || n > ntimezones) { + fprintf(stderr, "Warning: invalid time zone index" + " in time zone file `%s' line %d\n", + filename, line); + } else if (ofs < -12*60*60 || ofs > 13*60*60) { + fprintf(stderr, "Warning: time zone offset out of" + " range in time zone file `%s' line %d\n", + filename, line); + } else { + timezones[n-1] = ofs/60; + } + } + } + } + } else if (strcmp(av[i],"-no-timezones") == 0) { + ntimezones = 0; + if (timezones != default_timezones) + free(timezones); + timezones = NULL; + } else if (strcmp(av[i],"-reset-memo-limits") == 0) { + reset_memo_limits = 1; + } else { + fprintf(stderr, "Unrecognized option %s\n", av[i]); + usage(av[0]); + } + } + if (verbose) fprintf(stderr, "Loading nickserv.db...\n"); cyg_load_nick(sourcedir); diff -uNr ircservices-5.0.23/tools/convert-db.c ircservices-5.0.24/tools/convert-db.c --- ircservices-5.0.23/tools/convert-db.c 2003-11-03 18:10:36 +0900 +++ ircservices-5.0.24/tools/convert-db.c 2003-11-11 16:09:43 +0900 @@ -113,24 +113,20 @@ NickInfo *makenick(const char *nick, NickGroupInfo **nickgroup_ret) { - NickInfo *ni; - NickGroupInfo *ngi; - -#ifdef CLEAN_COMPILE - ngi = NULL; -#endif + NickInfo *ni = scalloc(sizeof(*ni), 1); + strscpy(ni->nick, nick, sizeof(ni->nick)); if (nickgroup_ret) { - ngi = scalloc(sizeof(*ngi), 1); + NickGroupInfo *ngi = scalloc(sizeof(*ngi), 1); do { /* We assume that eventually we'll find one that's not in use */ ngi->id = rand() + rand(); if (ngi->id == 0) ngi->id = 1; } while (get_nickgroupinfo(ngi->id)); - } - ni = scalloc(sizeof(*ni), 1); - strscpy(ni->nick, nick, sizeof(ni->nick)); - if (nickgroup_ret) { + ngi->memos.memomax = MEMOMAX_DEFAULT; + ngi->channelmax = CHANMAX_DEFAULT; + ngi->language = LANG_DEFAULT; + ngi->timezone = TIMEZONE_DEFAULT; ni->nickgroup = ngi->id; ARRAY_EXTEND(ngi->nicks); strscpy(ngi->nicks[0], nick, sizeof(ngi->nicks[0])); @@ -178,21 +174,6 @@ /*************************************************************************/ -/* Create a new NickGroupInfo, assign it an ID, and set default values. */ - -NickGroupInfo *new_nickgroupinfo(void) -{ - static uint32 id = 1; - NickGroupInfo *ngi = scalloc(sizeof(*ngi), 1); - ngi->id = id++; - ngi->memos.memomax = MEMOMAX_DEFAULT; - ngi->channelmax = CHANMAX_DEFAULT; - ngi->language = LANG_DEFAULT; - return ngi; -} - -/*************************************************************************/ - /* Retrieve the NickGroupInfo structure for the given nick. Returns NULL * if the nick does not exist or is forbidden (i.e. has no NickGroupInfo). */ @@ -506,14 +487,16 @@ /****************************** Main program *****************************/ /*************************************************************************/ -static void usage(const char *progname) +void usage(const char *progname) { int i; - fprintf(stderr, "Usage: %s [-v] [+program-name] sourcedir\n" + fprintf(stderr, "Usage: %s [-v] [+program-name] [options...] sourcedir\n" "The following program names are known:\n", progname); for (i = 0; dbtypes[i]; i++) fprintf(stderr, " %s\n", dbtypes[i]->id); + fprintf(stderr, + "See the manual for options available for each database type.\n"); exit(1); } @@ -521,22 +504,26 @@ int main(int ac, char **av) { + int newac = 0; /* For passing to processing function */ + char **newav; char *sourcedir = NULL; /* Source data file directory */ int verbose = 0; /* Verbose output? */ - void (*load)(const char *, int) = NULL; + void (*load)(const char *, int, int, char **) = NULL; int i; char oldpath[PATH_MAX+1], newpath[PATH_MAX+1]; /* Parse command-line parameters */ + newac = 1; + newav = malloc(sizeof(*newav) * ac); + newav[0] = av[0]; for (i = 1; i < ac; i++) { - if (av[i][0] == '-') { - if (av[i][1] == 'v') { - verbose++; - } else { - if (av[i][1] != 'h') - fprintf(stderr, "Unknown option -%c\n", av[i][1]); - usage(av[0]); - } + if (strcmp(av[i],"-v") == 0) { + verbose++; + } else if (strcmp(av[i],"-h") == 0 + || strcmp(av[i],"-?") == 0 + || strcmp(av[i],"-help") == 0 + || strcmp(av[i],"--help") == 0) { + usage(av[0]); } else if (av[i][0] == '+') { int j; for (j = 0; dbtypes[j]; j++) { @@ -549,6 +536,8 @@ fprintf(stderr, "Unknown database type `%s'\n", av[i]+1); usage(av[0]); } + } else if (av[i][0] == '-') { + newav[newac++] = av[i]; } else { if (sourcedir) { fprintf(stderr, "Only one source directory may be specified\n"); @@ -601,7 +590,7 @@ /* Actually load the databases. If an error occurs, load() will abort the * program for us */ - load(sourcedir, verbose); + load(sourcedir, verbose, newac, newav); /* Do sanity checks. */ sanity_checks(); diff -uNr ircservices-5.0.23/tools/convert-db.h ircservices-5.0.24/tools/convert-db.h --- ircservices-5.0.23/tools/convert-db.h 2003-11-03 18:10:36 +0900 +++ ircservices-5.0.24/tools/convert-db.h 2003-11-11 16:09:43 +0900 @@ -39,8 +39,11 @@ * "Found XYZ databases" message if databases are found, NULL if not */ const char *(*check)(const char *sourcedir); /* Routine to load databases from the given directory; prints an - * appropriate error message and calls exit(1) if an error occurs */ - void (*load)(const char *dir, int verbose); + * appropriate error message and calls exit(1) if an error occurs. + * ac/av are loaded with all option arguments passed to the program + * not parsed out by the main code; av[0] will contain the program + * name as usual */ + void (*load)(const char *dir, int verbose, int ac, char **av); } DBTypeInfo; extern DBTypeInfo @@ -95,10 +98,6 @@ int32 *version_ret); -/* Create a new NickGroupInfo, assign it an ID, and set default values. */ -#define new_nickgroupinfo my_new_nickgroupinfo -extern NickGroupInfo *new_nickgroupinfo(void); - /* Retrieve the NickGroupInfo structure for the given nick. Returns NULL * if the nick does not exist or is forbidden (i.e. has no NickGroupInfo). */ extern NickGroupInfo *get_nickgroupinfo_by_nick(const char *nick); @@ -153,4 +152,10 @@ /*************************************************************************/ +/* Miscellaneous externs. */ + +extern void usage(const char *progname); + +/*************************************************************************/ + #endif /* CONVERT_DB_H */ diff -uNr ircservices-5.0.23/tools/convert-epona.c ircservices-5.0.24/tools/convert-epona.c --- ircservices-5.0.23/tools/convert-epona.c 2003-11-03 18:10:36 +0900 +++ ircservices-5.0.24/tools/convert-epona.c 2003-11-11 16:09:43 +0900 @@ -620,8 +620,12 @@ return NULL; } -static void load_epona(const char *sourcedir, int verbose) +static void load_epona(const char *sourcedir, int verbose, int ac, char **av) { + if (ac > 1) { + fprintf(stderr, "Unrecognized option %s\n", av[1]); + usage(av[0]); + } if (verbose) fprintf(stderr, "Loading nick.db...\n"); epona_load_nick(sourcedir); diff -uNr ircservices-5.0.23/tools/convert-magick.c ircservices-5.0.24/tools/convert-magick.c --- ircservices-5.0.23/tools/convert-magick.c 2003-11-03 18:10:36 +0900 +++ ircservices-5.0.24/tools/convert-magick.c 2003-11-11 16:09:43 +0900 @@ -583,8 +583,13 @@ return NULL; } -static void load_magick_14b2(const char *sourcedir, int verbose) +static void load_magick_14b2(const char *sourcedir, int verbose, int ac, + char **av) { + if (ac > 1) { + fprintf(stderr, "Unrecognized option %s\n", av[1]); + usage(av[0]); + } if (verbose) fprintf(stderr, "Loading nick.db...\n"); m14_load_nick(sourcedir, 5); @@ -633,8 +638,13 @@ return NULL; } -static void load_wrecked_1_2(const char *sourcedir, int verbose) +static void load_wrecked_1_2(const char *sourcedir, int verbose, int ac, + char **av) { + if (ac > 1) { + fprintf(stderr, "Unrecognized option %s\n", av[1]); + usage(av[0]); + } if (verbose) fprintf(stderr, "Loading nick.db...\n"); m14_load_nick(sourcedir, 6); diff -uNr ircservices-5.0.23/tools/convert-ptlink.c ircservices-5.0.24/tools/convert-ptlink.c --- ircservices-5.0.23/tools/convert-ptlink.c 2003-11-03 18:10:36 +0900 +++ ircservices-5.0.24/tools/convert-ptlink.c 2003-11-11 16:09:43 +0900 @@ -597,8 +597,12 @@ return NULL; } -static void load_ptlink(const char *sourcedir, int verbose) +static void load_ptlink(const char *sourcedir, int verbose, int ac, char **av) { + if (ac > 1) { + fprintf(stderr, "Unrecognized option %s\n", av[1]); + usage(av[0]); + } if (verbose) fprintf(stderr, "Loading nick.db...\n"); ptlink_load_nick(sourcedir); diff -uNr ircservices-5.0.23/tools/convert-sirv.c ircservices-5.0.24/tools/convert-sirv.c --- ircservices-5.0.23/tools/convert-sirv.c 2003-11-03 18:10:36 +0900 +++ ircservices-5.0.24/tools/convert-sirv.c 2003-11-11 16:09:43 +0900 @@ -1039,8 +1039,12 @@ return NULL; } -static void load_auspice(const char *sourcedir, int verbose) +static void load_auspice(const char *sourcedir, int verbose, int ac, char **av) { + if (ac > 1) { + fprintf(stderr, "Unrecognized option %s\n", av[1]); + usage(av[0]); + } if (verbose) fprintf(stderr, "Loading nick.db...\n"); sirv_load_nick(sourcedir, TYPE_AUSPICE); @@ -1076,8 +1080,12 @@ return NULL; } -static void load_bolivia(const char *sourcedir, int verbose) +static void load_bolivia(const char *sourcedir, int verbose, int ac, char **av) { + if (ac > 1) { + fprintf(stderr, "Unrecognized option %s\n", av[1]); + usage(av[0]); + } if (verbose) fprintf(stderr, "Loading nick.db...\n"); sirv_load_nick(sourcedir, TYPE_BOLIVIA); @@ -1137,8 +1145,12 @@ return NULL; } -static void load_sirv(const char *sourcedir, int verbose) +static void load_sirv(const char *sourcedir, int verbose, int ac, char **av) { + if (ac > 1) { + fprintf(stderr, "Unrecognized option %s\n", av[1]); + usage(av[0]); + } if (verbose) fprintf(stderr, "Loading nick.db...\n"); sirv_load_nick(sourcedir, TYPE_SIRV); diff -uNr ircservices-5.0.23/tools/convert-trircd.c ircservices-5.0.24/tools/convert-trircd.c --- ircservices-5.0.23/tools/convert-trircd.c 2003-11-03 18:10:36 +0900 +++ ircservices-5.0.24/tools/convert-trircd.c 2003-11-11 16:09:43 +0900 @@ -772,8 +772,12 @@ return NULL; } -static void load_trircd(const char *sourcedir, int verbose) +static void load_trircd(const char *sourcedir, int verbose, int ac, char **av) { + if (ac > 1) { + fprintf(stderr, "Unrecognized option %s\n", av[1]); + usage(av[0]); + } if (verbose) fprintf(stderr, "Loading nick.db...\n"); trircd_load_nick(sourcedir); diff -uNr ircservices-5.0.23/tools/convert-ver8.c ircservices-5.0.24/tools/convert-ver8.c --- ircservices-5.0.23/tools/convert-ver8.c 2003-11-03 18:10:36 +0900 +++ ircservices-5.0.24/tools/convert-ver8.c 2003-11-11 16:09:43 +0900 @@ -620,8 +620,13 @@ return NULL; } -static void load_daylight(const char *sourcedir, int verbose) +static void load_daylight(const char *sourcedir, int verbose, int ac, + char **av) { + if (ac > 1) { + fprintf(stderr, "Unrecognized option %s\n", av[1]); + usage(av[0]); + } if (verbose) fprintf(stderr, "Loading nick.db...\n"); ver8_load_nick(sourcedir, TYPE_DAYLIGHT); @@ -657,8 +662,13 @@ return NULL; } -static void load_ircs_1_2(const char *sourcedir, int verbose) +static void load_ircs_1_2(const char *sourcedir, int verbose, int ac, + char **av) { + if (ac > 1) { + fprintf(stderr, "Unrecognized option %s\n", av[1]); + usage(av[0]); + } if (verbose) fprintf(stderr, "Loading nick.db...\n"); ver8_load_nick(sourcedir, TYPE_IRCS); diff -uNr ircservices-5.0.23/version.sh ircservices-5.0.24/version.sh --- ircservices-5.0.23/version.sh 2003-11-03 18:06:24 +0900 +++ ircservices-5.0.24/version.sh 2003-11-11 16:06:26 +0900 @@ -6,7 +6,7 @@ # $PROGRAM is the string returned as the first part of a /VERSION reply, # and must not contain spaces. It is not used anywhere else. PROGRAM=ircservices -VERSION=5.0.23 +VERSION=5.0.24 # Increment Services build number if [ -f version.c ] ; then