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

help.c

Go to the documentation of this file.
00001 
00013 /*
00014  * Copyright (c) 1996-1997 Chip Norkus
00015  * Copyright (c) 1997 Max Byrd
00016  * Copyright (c) 1997 Greg Poma
00017  * All rights reserved.
00018  *
00019  * Redistribution and use in source and binary forms, with or without
00020  * modification, are permitted provided that the following conditions
00021  * are met:
00022  * 1. Redistributions of source code must retain the above copyright
00023  *    notice, this list of conditions and the following disclaimer.
00024  * 2. Redistributions in binary form must reproduce the above copyright
00025  *    notice, this list of conditions and the following disclaimer in the
00026  *    documentation and/or other materials provided with the distribution.
00027  * 3. Neither the name of the authors nor the names of its contributors
00028  *    may be used to endorse or promote products derived from this software
00029  *    without specific prior written permission.
00030  *
00031  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
00032  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00033  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00034  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
00035  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
00036  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00037  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00038  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00039  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00040  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00041  * SUCH DAMAGE.
00042  */
00043 
00044 #include "services.h"
00045 #include "macro.h"
00046 
00048 help_cache *firsthelpcache;
00049 
00051 help_cache *lasthelpcache;
00052 
00060 void
00061 motd(char *to)
00062 {
00063     FILE *fp;
00064     char buffer[81];
00065     fp = fopen("services.motd", "r");
00066     if (fp == NULL) {
00067         sSend(":%s 422 %s :No MOTD File found", myname, to);
00068         return;
00069     }
00070 
00071     sSend(":%s 375 %s :SorceryNet Services Data:", myname, to);
00072 
00073     while (fgets(buffer, 81, fp)) {
00074         sSend(":%s 372 %s :%s", myname, to, buffer);
00075     }
00076     sSend
00077         (":%s 372 %s :# Most users online at one time: %lu     Registered nicks: %lu",
00078          myname, to, mostusers + 5, mostnicks);
00079     /* Liam: why the +5 ? nickserv, memo, chan, oper, game, info = 6;
00080      * this count also shouldn't include enforcers really.
00081      * Not that it matters much.
00082      */
00083     sSend(":%s 372 %s :# Registered channels: %lu", myname, to, mostchans);
00084     sSend
00085         (":%s 372 %s :#####################################################################",
00086          myname, to);
00087     sSend(":%s 376 %s :End of services MOTD", myname, to);
00088 
00089     fclose(fp);
00090 
00091 }
00092 
00100 void
00101 help(char *to, char *service, char **args, int numargs)
00102 {
00103     int i = 1;
00104     off_t topoff;
00105     size_t totallen = 0;
00106     char buffer[sizeof(HELP_PATH) + HELPTOPICBUF + NICKLEN + 255], *p;
00107     FILE *fp;
00108     help_line *helpline;
00109     help_cache *helpcache;
00110 
00111 #if (HELPTOPICBUF > 100)
00112     /* compile-time sanity check -- Liam*/
00113     
00114     you need to run configure and recompile;
00115 #endif
00116 
00117     /* If you configured services with a really long help path, 
00118      * we could overflow buffer, since MAX_PATH is often 4096 these
00119      * days, and IRCBUF is likely 512 or 513 - Liam
00120      */
00121     if (sizeof(HELP_PATH) + strlen(service) + HELPTOPICBUF >= IRCBUF) {
00122         sSend(":%s NOTICE %s :HELP_PATH is too long!", service, to);
00123         return;
00124     }
00125 
00126     sprintf(buffer, "%s/%s/", HELP_PATH, service);
00127     topoff = strlen(buffer);
00128 
00129     if (numargs > 5) {
00130         sSend(":%s NOTICE %s :Too Many Arguments", service, to);
00131         return;
00132     }
00133 
00134     if (numargs <= 1)
00135         strcat(buffer, "index");
00136     else {
00137         totallen = 0;
00138 
00139         for (; i < numargs; i++) {
00140             if ((strlen(args[i]) + totallen) > HELPTOPICBUF) {
00141                 sSend
00142                     (":%s NOTICE %s :Sorry, but the maximum length of a help command line is %d characters.",
00143                      service, to, HELPTOPICBUF);
00144                 if (*(buffer + topoff))
00145                     sSend(":%s NOTICE %s :No help was available on \"%s\"",
00146                           service, to, buffer + topoff);
00147                 return;
00148             }
00149             if (i > 1)
00150                 strcat(buffer, "-");
00151             strcat(buffer, args[i]);
00152             totallen += (strlen(args[i]) + 1);
00153         }
00154     }
00155 
00156     for (p = buffer + topoff; *p; p++)
00157         if (*p == '.' || *p == '/' || iscntrl(*p) || !isprint(*p))
00158             *p = '_';
00159     for (p = buffer; *p; p++)
00160         (*p) = (tolower(*p));
00161 
00162     helpcache = check_help_cache(buffer);
00163 
00164     if (helpcache != NULL) {    /* Woohoo! It's cached */
00165         for (helpline = helpcache->first->next; helpline;
00166              helpline =
00167              helpline->next) sSend(":%s NOTICE %s :%s", service, to,
00168                                    helpline->line);
00169         return;
00170     }
00171 
00172     {
00173         char *fopenbuf = (char *)oalloc(strlen(buffer) + sizeof ".help" + 1);
00174 
00175         strcpy(fopenbuf, buffer);
00176         strcat(fopenbuf, ".help");
00177 
00178         fp = fopen(fopenbuf, "r");
00179         FREE(fopenbuf);
00180     }
00181 
00182     if (fp == NULL) {
00183         if (numargs != 0) {
00184             buffer[0] = 0;
00185             parse_str(args, numargs, 1, buffer, IRCBUF);
00186             sSend(":%s NOTICE %s :No help is available about \"%s\"",
00187                   service, to, buffer);
00188         } else {
00189             sSend(":%s NOTICE %s :Helpfiles for %s are still "
00190                   "in development", service, to, service);
00191         }
00192         return;
00193     }
00194 
00195     /* Okay -- the file isn't cached.. we'll do it here */
00196     helpcache = (help_cache *) oalloc(sizeof(help_cache));
00197     if (firsthelpcache == NULL)
00198         firsthelpcache = helpcache;
00199     if (lasthelpcache != NULL)
00200         lasthelpcache->next = helpcache;
00201     lasthelpcache = helpcache;
00202     helpcache->name = (char *)oalloc(strlen(buffer) + 1);
00203     strcpy(helpcache->name, buffer);
00204 
00205     helpcache->first = helpline = (help_line *) oalloc(sizeof(help_line));
00206 
00207     while (fgets(buffer, 80, fp)) {
00208         if (!buffer[0])
00209             continue;
00210         buffer[strlen(buffer) - 1] = '\0';
00211 
00212         if (!buffer[0]) {
00213             buffer[0] = ' ';
00214             buffer[1] = '\0';
00215         }
00216 
00217         helpline->next = (help_line *) oalloc(sizeof(help_line));
00218         helpline = helpline->next;
00219         sSend(":%s NOTICE %s :%s", service, to, buffer);
00220         strcpy(helpline->line, buffer); /* This is safe -- limited to 80 already */
00221         /* safe but a little ineffient of memory;
00222          * better to allocate the strings as needed, and not
00223          * to allocate one more than we need each time. - Liam
00224          * */
00225     }
00226 
00227     fclose(fp);
00228 }
00229 
00236 help_cache *
00237 check_help_cache(char *filename)
00238 {
00239     help_cache *t_cache;
00240 
00241     for (t_cache = firsthelpcache; t_cache; t_cache = t_cache->next) {
00242         if (strcmp(t_cache->name, filename) == 0) {
00243             return t_cache;
00244         }
00245     }
00246 
00247     return NULL;
00248 }
00249 
00253 void
00254 flush_help_cache(void)
00255 {
00256     help_cache *t_cache;
00257     help_cache *t_cache2;
00258     help_line *t_line;
00259     help_line *t_line2;
00260 
00261     for (t_cache = firsthelpcache; t_cache;) {
00262         if (t_cache == NULL)
00263             return;
00264         t_cache2 = t_cache->next;
00265         for (t_line = t_cache->first; t_line;) {
00266             t_line2 = t_line->next;
00267             FREE(t_line);
00268             t_line = t_line2;
00269         }
00270 
00271         FREE(t_cache->name);
00272         FREE(t_cache);
00273         t_cache = t_cache2;
00274     }
00275     firsthelpcache = NULL;
00276     lasthelpcache = NULL;
00277 }

Generated at Sat Oct 25 20:56:07 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.