src/help.c

Go to the documentation of this file.
00001 /*
00002  * help.c -- commands for giving help 
00003  */
00004 
00005 #include "copyright.h"
00006 #include "config.h"
00007 
00008 #include <fcntl.h>
00009 
00010 #include "mudconf.h"
00011 #include "config.h"
00012 #include "db.h"
00013 #include "interface.h"
00014 #include "externs.h"
00015 #include "help.h"
00016 #include "htab.h"
00017 #include "alloc.h"
00018 
00019 /*
00020  * Pointers to this struct is what gets stored in the help_htab's 
00021  */
00022 struct help_entry {
00023         int pos;                                        /*
00024                                                                  * Position, copied from help_indx 
00025                                                                  */
00026         char original;                          /*
00027                                                                  * 1 for the longest name for a topic. 0 for
00028                                                                  * * * * abbreviations 
00029                                                                  */
00030         char *key;                                      /*
00031                                                                  * The key this is stored under. 
00032                                                                  */
00033 };
00034 
00035 int helpindex_read(HASHTAB * htab, char *filename)
00036 {
00037         help_indx entry;
00038         char *p;
00039         int count;
00040         FILE *fp;
00041         struct help_entry *htab_entry;
00042 
00043         /*
00044          * Let's clean out our hash table, before we throw it away. 
00045          */
00046         for(htab_entry = (struct help_entry *) hash_firstentry(htab);
00047                 htab_entry; htab_entry = (struct help_entry *) hash_nextentry(htab)) {
00048                 free(htab_entry->key);
00049                 free(htab_entry);
00050         }
00051 
00052         hashflush(htab, 0);
00053         if((fp = fopen(filename, "r")) == NULL) {
00054                 STARTLOG(LOG_PROBLEMS, "HLP", "RINDX") {
00055                         p = alloc_lbuf("helpindex_read.LOG");
00056                         sprintf(p, "Can't open %s for reading.", filename);
00057                         log_text(p);
00058                         free_lbuf(p);
00059                         ENDLOG;
00060                 }
00061                 return -1;
00062         }
00063         count = 0;
00064         while ((fread((char *) &entry, sizeof(help_indx), 1, fp)) == 1) {
00065 
00066                 /*
00067                  * Lowercase the entry and add all leftmost substrings. * * * 
00068                  * 
00069                  * * Substrings already added will be rejected by hashadd. 
00070                  */
00071                 for(p = entry.topic; *p; p++)
00072                         *p = ToLower(*p);
00073 
00074                 htab_entry = (struct help_entry *) malloc(sizeof(struct help_entry));
00075 
00076                 htab_entry->pos = entry.pos;
00077                 htab_entry->original = 1;       /*
00078                                                                          * First is the longest 
00079                                                                          */
00080                 htab_entry->key = (char *) malloc(strlen(entry.topic) + 1);
00081                 StringCopy(htab_entry->key, entry.topic);
00082                 while (p > entry.topic) {
00083                         p--;
00084                         if(!isspace(*p)) {
00085                                 if((hashadd(entry.topic, (int *) htab_entry, htab)) == 0)
00086                                         count++;
00087                                 else {
00088                                         free(htab_entry->key);
00089                                         free(htab_entry);
00090                                 }
00091                         } else {
00092                                 free(htab_entry->key);
00093                                 free(htab_entry);
00094                         }
00095                         *p = '\0';
00096                         htab_entry =
00097                                 (struct help_entry *) malloc(sizeof(struct help_entry));
00098 
00099                         htab_entry->pos = entry.pos;
00100                         htab_entry->original = 0;
00101                         htab_entry->key = (char *) malloc(strlen(entry.topic) + 1);
00102                         StringCopy(htab_entry->key, entry.topic);
00103                 }
00104                 free(htab_entry->key);
00105                 free(htab_entry);
00106         }
00107         fclose(fp);
00108         hashreset(htab);
00109         return count;
00110 }
00111 
00112 void helpindex_load(dbref player)
00113 {
00114         int news, help, whelp;
00115         int phelp, wnhelp;
00116 
00117         phelp = helpindex_read(&mudstate.plushelp_htab, mudconf.plushelp_indx);
00118         wnhelp = helpindex_read(&mudstate.wiznews_htab, mudconf.wiznews_indx);
00119         news = helpindex_read(&mudstate.news_htab, mudconf.news_indx);
00120         help = helpindex_read(&mudstate.help_htab, mudconf.help_indx);
00121         whelp = helpindex_read(&mudstate.wizhelp_htab, mudconf.whelp_indx);
00122         if((player != NOTHING) && !Quiet(player))
00123                 notify_printf(player,
00124                                           "Index entries: News...%d  Help...%d  Wizhelp...%d  +Help...%d  Wiznews...%d",
00125                                           news, help, whelp, phelp, wnhelp);
00126 }
00127 
00128 void helpindex_init(void)
00129 {
00130         hashinit(&mudstate.news_htab, 30 * HASH_FACTOR);
00131         hashinit(&mudstate.help_htab, 400 * HASH_FACTOR);
00132         hashinit(&mudstate.wizhelp_htab, 400 * HASH_FACTOR);
00133         hashinit(&mudstate.plushelp_htab, 400 * HASH_FACTOR);
00134         hashinit(&mudstate.wiznews_htab, 400 * HASH_FACTOR);
00135 
00136         helpindex_load(NOTHING);
00137 }
00138 
00139 void help_write(dbref player, char *topic, HASHTAB * htab, char *filename,
00140                                 int eval)
00141 {
00142         FILE *fp;
00143         char *p, *line, *bp, *str, *result;
00144         int offset;
00145         struct help_entry *htab_entry;
00146         char matched;
00147         char *topic_list = NULL, *buffp;
00148 
00149         if(*topic == '\0')
00150                 topic = (char *) "help";
00151         else
00152                 for(p = topic; *p; p++)
00153                         *p = ToLower(*p);
00154         htab_entry = (struct help_entry *) hashfind(topic, htab);
00155         if(htab_entry)
00156                 offset = htab_entry->pos;
00157         else {
00158                 matched = 0;
00159                 for(htab_entry = (struct help_entry *) hash_firstentry(htab);
00160                         htab_entry != NULL;
00161                         htab_entry = (struct help_entry *) hash_nextentry(htab)) {
00162                         if(htab_entry->original && quick_wild(topic, htab_entry->key)) {
00163                                 if(matched == 0) {
00164                                         matched = 1;
00165                                         topic_list = alloc_lbuf("help_write");
00166                                         buffp = topic_list;
00167                                 }
00168                                 safe_str(htab_entry->key, topic_list, &buffp);
00169                                 safe_str((char *) "  ", topic_list, &buffp);
00170                         }
00171                 }
00172                 if(matched == 0)
00173                         notify_printf(player, "No entry for '%s'.", topic);
00174                 else {
00175                         notify_printf(player,
00176                                                   "Here are the entries which match '%s':", topic);
00177                         *buffp = '\0';
00178                         notify(player, topic_list);
00179                         free_lbuf(topic_list);
00180                 }
00181                 return;
00182         }
00183         if((fp = fopen(filename, "r")) == NULL) {
00184                 notify(player, "Sorry, that function is temporarily unavailable.");
00185                 STARTLOG(LOG_PROBLEMS, "HLP", "OPEN") {
00186                         line = alloc_lbuf("help_write.LOG.open");
00187                         sprintf(line, "Can't open %s for reading.", filename);
00188                         log_text(line);
00189                         free_lbuf(line);
00190                         ENDLOG;
00191                 }
00192                 return;
00193         }
00194         if(fseek(fp, offset, 0) < 0L) {
00195                 notify(player, "Sorry, that function is temporarily unavailable.");
00196                 STARTLOG(LOG_PROBLEMS, "HLP", "SEEK") {
00197                         line = alloc_lbuf("help_write.LOG.seek");
00198                         sprintf(line, "Seek error in file %s.", filename);
00199                         log_text(line);
00200                         free_lbuf(line);
00201                         ENDLOG;
00202                 }
00203                 fclose(fp);
00204 
00205                 return;
00206         }
00207         line = alloc_lbuf("help_write");
00208         result = alloc_lbuf("help_write.2");
00209         for(;;) {
00210                 if(fgets(line, LBUF_SIZE - 1, fp) == NULL)
00211                         break;
00212                 if(line[0] == '&')
00213                         break;
00214                 for(p = line; *p != '\0'; p++)
00215                         if(*p == '\n')
00216                                 *p = '\0';
00217                 if(eval) {
00218                         str = line;
00219                         bp = result;
00220                         exec(result, &bp, 0, player, player,
00221                                  EV_NO_COMPRESS | EV_FIGNORE | EV_EVAL, &str,
00222                                  (char **) NULL, 0);
00223                         *bp = '\0';
00224                         notify(player, result);
00225                 } else
00226                         notify(player, line);
00227         }
00228         fclose(fp);
00229         free_lbuf(line);
00230         free_lbuf(result);
00231 }
00232 
00233 /*
00234  * ---------------------------------------------------------------------------
00235  * * do_help: display information from new-format news and help files
00236  */
00237 
00238 void do_help(dbref player, dbref cause, int key, char *message)
00239 {
00240         char *buf;
00241 
00242         switch (key) {
00243         case HELP_HELP:
00244                 help_write(player, message, &mudstate.help_htab, mudconf.help_file,
00245                                    0);
00246                 break;
00247         case HELP_NEWS:
00248                 help_write(player, message, &mudstate.news_htab, mudconf.news_file,
00249                                    EVAL_ALL_NEWS);
00250                 break;
00251         case HELP_WIZHELP:
00252                 help_write(player, message, &mudstate.wizhelp_htab,
00253                                    mudconf.whelp_file, 0);
00254                 break;
00255         case HELP_PLUSHELP:
00256                 help_write(player, message, &mudstate.plushelp_htab,
00257                                    mudconf.plushelp_file, 1);
00258                 break;
00259         case HELP_WIZNEWS:
00260 #ifdef DO_PARSE_WIZNEWS
00261                 help_write(player, message, &mudstate.wiznews_htab,
00262                                    mudconf.wiznews_file, 1);
00263 #else
00264                 help_write(player, message, &mudstate.wiznews_htab,
00265                                    mudconf.wiznews_file, 0);
00266 #endif
00267                 break;
00268         default:
00269                 STARTLOG(LOG_BUGS, "BUG", "HELP") {
00270                         buf = alloc_mbuf("do_help.LOG");
00271                         sprintf(buf, "Unknown help file number: %d", key);
00272                         log_text(buf);
00273                         free_mbuf(buf);
00274                         ENDLOG;
00275                 }
00276         }
00277 }

Generated on Mon May 28 04:25:24 2007 for BattletechMUX by  doxygen 1.4.7