/* help.c -- commands for giving help */ #include "autoconf.h" #include "copyright.h" #ifndef lint static char RCSid[] = "$Id: help.c,v 1.8 1995/03/21 00:00:29 ambar Exp $"; USE(RCSid); #endif #include "interface.h" #include "help.h" /* Pointers to this struct is what gets stored in the help_htab's */ struct help_entry { int pos; /* Position, copied from help_indx */ char original; /* 1 for the longest name for a topic. 0 for abbreviations */ char *key; /* The key this is stored under. */ }; int helpindex_read(htab, filename) HASHTAB *htab; char *filename; { help_indx entry; char *p; int count; FILE *fp; struct help_entry *htab_entry; /* Let's clean out our hash table, before we throw it away. */ for (htab_entry = (struct help_entry *) hash_firstentry(htab); htab_entry; htab_entry = (struct help_entry *) hash_nextentry(htab)) { free(htab_entry->key); free(htab_entry); } hashflush(htab, 0); if ((fp = tf_fopen(filename, O_RDONLY)) == NULL) { STARTLOG(LOG_PROBLEMS, "HLP", "RINDX") p = alloc_lbuf("helpindex_read.LOG"); sprintf(p, "Can't open %s for reading.", filename); log_text(p); free_lbuf(p); ENDLOG return -1; } count = 0; while ((fread((char *) &entry, sizeof(help_indx), 1, fp)) == 1) { /* Lowercase the entry and add all leftmost substrings. * Substrings already added will be rejected by hashadd. */ for (p = entry.topic; *p; p++) *p = ToLower(*p); htab_entry = (struct help_entry *) XMALLOC(sizeof(struct help_entry), "helpindex_read.1"); htab_entry->pos = entry.pos; htab_entry->original = 1; /* First is the longest */ htab_entry->key = (char *) XMALLOC(strlen(entry.topic) + 1, "helpindex_read.2"); strcpy(htab_entry->key, entry.topic); while (p > entry.topic) { p--; if (!isspace(*p) && (hashadd(entry.topic, (int *) htab_entry, htab) == 0)) { count++; } else { /* It didn't make it into the hash table */ free(htab_entry->key); free(htab_entry); } *p = '\0'; htab_entry = (struct help_entry *) XMALLOC(sizeof(struct help_entry), "helpindex_read.3"); htab_entry->pos = entry.pos; htab_entry->original = 0; htab_entry->key = strsave(entry.topic); } free(htab_entry->key); free(htab_entry); } tf_fclose(fp); hashreset(htab); return count; } void helpindex_load(player) dbref player; { int news, help, whelp; news = helpindex_read(&mudstate.news_htab, mudconf.news_indx); help = helpindex_read(&mudstate.help_htab, mudconf.help_indx); whelp = helpindex_read(&mudstate.wizhelp_htab, mudconf.whelp_indx); if ((player != NOTHING) && !Quiet(player)) notify(player, tprintf("Index entries: News...%d Help...%d Wizhelp...%d", news, help, whelp)); } void NDECL(helpindex_init) { hashinit(&mudstate.news_htab, 17); hashinit(&mudstate.help_htab, 37); hashinit(&mudstate.wizhelp_htab, 37); helpindex_load(NOTHING); } void help_write(player, topic, htab, filename) dbref player; char *topic, *filename; HASHTAB *htab; { FILE *fp; char *p, *line; int offset; struct help_entry *htab_entry; char matched; char *topic_list, *buffp; if (*topic == '\0') topic = (char *) "help"; else for (p = topic; *p; p++) *p = ToLower(*p); htab_entry = (struct help_entry *) hashfind(topic, htab); if (htab_entry) offset = htab_entry->pos; else { matched = 0; for (htab_entry = (struct help_entry *) hash_firstentry(htab); htab_entry != NULL; htab_entry = (struct help_entry *) hash_nextentry(htab)) { if (htab_entry->original && quick_wild(topic, htab_entry->key)) { if (matched == 0) { matched = 1; topic_list = alloc_lbuf("help_write"); buffp = topic_list; } safe_str(htab_entry->key, topic_list, &buffp); safe_str((char *) " ", topic_list, &buffp); } } if (matched == 0) notify(player, tprintf("No entry for '%s'.", topic)); else { notify(player, tprintf("Here are the entries which match '%s':", topic)); *buffp = '\0'; notify(player, topic_list); free_lbuf(topic_list); } return; } if ((fp = tf_fopen(filename, O_RDONLY)) == NULL) { notify(player, "Sorry, that function is temporarily unavailable."); STARTLOG(LOG_PROBLEMS, "HLP", "OPEN") line = alloc_lbuf("help_write.LOG.open"); sprintf(line, "Can't open %s for reading.", filename); log_text(line); free_lbuf(line); ENDLOG return; } if (fseek(fp, offset, 0) < 0L) { notify(player, "Sorry, that function is temporarily unavailable."); STARTLOG(LOG_PROBLEMS, "HLP", "SEEK") line = alloc_lbuf("help_write.LOG.seek"); sprintf(line, "Seek error in file %s.", filename); log_text(line); free_lbuf(line); ENDLOG tf_fclose(fp); return; } line = alloc_lbuf("help_write"); for (;;) { if (fgets(line, LBUF_SIZE - 1, fp) == NULL) break; if (line[0] == '&') break; for (p = line; *p != '\0'; p++) if (*p == '\n') *p = '\0'; notify(player, line); } free_lbuf(line); tf_fclose(fp); } /* --------------------------------------------------------------------------- * do_help: display information from new-format news and help files */ void do_help(player, cause, key, message) dbref player, cause; int key; char *message; { char *buf; switch (key) { case HELP_HELP: help_write(player, message, &mudstate.help_htab, mudconf.help_file); break; case HELP_NEWS: help_write(player, message, &mudstate.news_htab, mudconf.news_file); break; case HELP_WIZHELP: help_write(player, message, &mudstate.wizhelp_htab, mudconf.whelp_file); break; default: STARTLOG(LOG_BUGS, "BUG", "HELP") buf = alloc_mbuf("do_help.LOG"); sprintf(buf, "Unknown help file number: %d", key); log_text(buf); free_mbuf(buf); ENDLOG } }