X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2Fhelpfile.c;h=aaf0d80ab961eed5048225f3d241f536ff4a106b;hb=80d9ed728be4b02ac483f3339cbb184f6602d15b;hp=38a61ec6877d03c8e511e4bba9ec2f26a9a4f632;hpb=51982054ac8f75d5c0ff61a6086c0163118a51c4;p=srvx.git diff --git a/src/helpfile.c b/src/helpfile.c index 38a61ec..aaf0d80 100644 --- a/src/helpfile.c +++ b/src/helpfile.c @@ -23,6 +23,7 @@ #include "log.h" #include "modcmd.h" #include "nickserv.h" +#include "spamserv.h" #if defined(HAVE_DIRENT_H) #include @@ -38,10 +39,10 @@ static const struct message_entry msgtab[] = { { NULL, NULL } }; -#define DEFAULT_LINE_SIZE MAX_LINE_SIZE +#define DEFAULT_LINE_SIZE MAX_LINE_SIZE #define DEFAULT_TABLE_SIZE 80 -extern struct userNode *global, *chanserv, *opserv, *nickserv; +extern struct userNode *global, *chanserv, *opserv, *nickserv, *spamserv; struct userNode *message_dest; struct userNode *message_source; struct language *lang_C; @@ -205,7 +206,7 @@ static struct language *language_read(const char *name) /* Read all the translations from the directory. */ while ((dirent = readdir(dir))) { snprintf(filename, sizeof(filename), "languages/%s/%s", name, dirent->d_name); - if (!strcmp(dirent->d_name,"parent")) { + if (!strcmp(dirent->d_name, "parent")) { continue; } else if (!strcmp(dirent->d_name, "strings.db")) { dict = parse_database(filename); @@ -235,6 +236,9 @@ static void language_read_list(void) if (dirent->d_name[0] == '.') continue; snprintf(namebuf, sizeof(namebuf), "languages/%s", dirent->d_name); + if (!strcmp(dirent->d_name, "strings.db")) { + continue; + } if (stat(namebuf, &sbuf) < 0) { log_module(MAIN_LOG, LOG_INFO, "Skipping language entry '%s' (unable to stat).", dirent->d_name); continue; @@ -243,7 +247,8 @@ static void language_read_list(void) log_module(MAIN_LOG, LOG_INFO, "Skipping language entry '%s' (not directory).", dirent->d_name); continue; } - language_alloc(dirent->d_name); + if (!dict_find(languages, dirent->d_name, NULL)) + language_alloc(dirent->d_name); } closedir(dir); } @@ -389,7 +394,7 @@ vsend_message(const char *dest, struct userNode *src, struct handle_info *handle void (*irc_send)(struct userNode *from, const char *to, const char *msg); static struct string_buffer input; unsigned int size, ipos, pos, length, chars_sent, use_color; - unsigned int expand_pos, expand_ipos, newline_ipos; + unsigned int expand_ipos, newline_ipos; char line[MAX_LINE_SIZE]; if (IsChannelName(dest) || *dest == '$') { @@ -415,8 +420,8 @@ vsend_message(const char *dest, struct userNode *src, struct handle_info *handle /* figure out how to send the messages */ if (handle) { - msg_type |= (HANDLE_FLAGGED(handle, USE_PRIVMSG) ? 1 : 0); - use_color = HANDLE_FLAGGED(handle, MIRC_COLOR); + msg_type |= (HANDLE_FLAGGED(handle, USE_PRIVMSG) ? 1 : 0); + use_color = HANDLE_FLAGGED(handle, MIRC_COLOR); size = handle->screen_width; if (size > sizeof(line)) size = sizeof(line); @@ -443,23 +448,23 @@ vsend_message(const char *dest, struct userNode *src, struct handle_info *handle * that requires a very big intermediate buffer. */ expand_ipos = newline_ipos = ipos = 0; - expand_pos = pos = 0; + pos = 0; chars_sent = 0; while (input.list[ipos]) { - char ch, *value, *free_value; + char ch, *value, *free_value; while ((ch = input.list[ipos]) && (ch != '$') && (ch != '\n') && (pos < size)) { - line[pos++] = ch; + line[pos++] = ch; ipos++; - } + } - if (!input.list[ipos]) + if (!input.list[ipos]) goto send_line; if (input.list[ipos] == '\n') { ipos++; goto send_line; } - if (pos == size) { + if (pos == size) { unsigned int new_ipos; /* Scan backwards for a space in the input, until we hit * either the last newline or the last variable expansion. @@ -484,53 +489,65 @@ vsend_message(const char *dest, struct userNode *src, struct handle_info *handle ipos = new_ipos; while (input.list[ipos] == ' ') ipos++; - goto send_line; - } + goto send_line; + } free_value = 0; - switch (input.list[++ipos]) { + switch (input.list[++ipos]) { /* Literal '$' or end of string. */ - case 0: - ipos--; - case '$': - value = "$"; - break; - /* The following two expand to mIRC color codes if enabled - by the user. */ - case 'b': - value = use_color ? "\002" : ""; - break; - case 'o': - value = use_color ? "\017" : ""; - break; + case 0: + ipos--; + case '$': + value = "$"; + break; + /* The following two expand to mIRC color codes if enabled + by the user. */ + case 'b': + value = use_color ? "\002" : ""; + break; + case 'o': + value = use_color ? "\017" : ""; + break; case 'r': value = use_color ? "\026" : ""; break; - case 'u': - value = use_color ? "\037" : ""; - break; - /* Service nicks. */ + case 'u': + value = use_color ? "\037" : ""; + break; + /* Service nicks. */ case 'S': value = src->nick; break; - case 'G': - value = global ? global->nick : "Global"; - break; - case 'C': - value = chanserv ? chanserv->nick : "ChanServ"; - break; - case 'O': - value = opserv ? opserv->nick : "OpServ"; - break; - case 'N': + case 'G': + value = global ? global->nick : "Global"; + break; + case 'C': + value = chanserv ? chanserv->nick : "ChanServ"; + break; + case 'O': + value = opserv ? opserv->nick : "OpServ"; + break; + case 'N': value = nickserv ? nickserv->nick : "NickServ"; break; + case 'X': + value = spamserv ? spamserv->nick : "SpamServ"; + break; case 's': value = self->name; break; - case 'H': - value = handle ? handle->handle : "Account"; - break; + case 'A': + value = handle ? handle->handle : "Account"; + break; + case 'U': + value = message_dest ? message_dest->nick : "Nick"; + break; + case 'I': + value = message_dest ? (IsFakeIdent(message_dest) ? message_dest->fakeident : message_dest->ident) : "Ident"; + break; + case 'H': + value = message_dest ? (IsFakeHost(message_dest) ? message_dest->fakehost : message_dest->hostname) : "Hostname"; + break; #define SEND_LINE(TRUNCED) do { \ line[pos] = 0; \ if (pos > 0) { \ @@ -543,9 +560,9 @@ vsend_message(const char *dest, struct userNode *src, struct handle_info *handle newline_ipos = ipos; \ if (!(msg_type & MSG_TYPE_MULTILINE)) return chars_sent; \ } while (0) - /* Custom expansion handled by helpfile-specific function. */ - case '{': - case '(': { + /* Custom expansion handled by helpfile-specific function. */ + case '{': + case '(': { struct helpfile_expansion exp; char *name_end = input.list + ipos + 1, *colon = NULL; @@ -585,20 +602,20 @@ vsend_message(const char *dest, struct userNode *src, struct handle_info *handle break; default: value = ""; - log_module(MAIN_LOG, LOG_ERROR, "Invalid exp.type %d from expansion function %p.", exp.type, expand_f); + log_module(MAIN_LOG, LOG_ERROR, "Invalid exp.type %d from expansion function %p.", exp.type, (void*)expand_f); break; } ipos = name_end - input.list; break; } - default: + default: fallthrough: value = alloca(3); value[0] = '$'; value[1] = input.list[ipos]; value[2] = 0; - } - ipos++; + } + ipos++; while ((pos + strlen(value) > size) || strchr(value, '\n')) { unsigned int avail; avail = size - pos - 1; @@ -635,17 +652,15 @@ vsend_message(const char *dest, struct userNode *src, struct handle_info *handle } } length = strlen(value); - memcpy(line + pos, value, length); + memcpy(line + pos, value, length); if (free_value) free(free_value); - pos += length; + pos += length; if ((pos < size-1) && input.list[ipos]) { - expand_pos = pos; expand_ipos = ipos; continue; } send_line: - expand_pos = pos; expand_ipos = ipos; SEND_LINE(0); #undef SEND_LINE @@ -659,7 +674,7 @@ send_message(struct userNode *dest, struct userNode *src, const char *format, .. int res; va_list ap; - if (IsLocal(dest)) return 0; + if (IsLocal(dest) && !IsDummy(dest)) return 0; va_start(ap, format); res = vsend_message(dest->nick, src, dest->handle_info, 0, NULL, format, ap); va_end(ap); @@ -671,7 +686,7 @@ send_message_type(int msg_type, struct userNode *dest, struct userNode *src, con int res; va_list ap; - if (IsLocal(dest)) return 0; + if (IsLocal(dest) && !IsDummy(dest)) return 0; va_start(ap, format); res = vsend_message(dest->nick, src, dest->handle_info, msg_type, NULL, format, ap); va_end(ap); @@ -729,7 +744,7 @@ send_help(struct userNode *dest, struct userNode *src, struct helpfile *hf, cons if (!rec) return send_message(dest, src, "MSG_TOPIC_UNKNOWN"); if (rec->type != RECDB_QSTRING) - return send_message(dest, src, "HFMSG_HELP_NOT_STRING"); + return send_message(dest, src, "HFMSG_HELP_NOT_STRING"); return _send_help(dest, src, hf->expand, rec->d.qstring); } @@ -933,25 +948,25 @@ unlistify_help(const char *key, void *data, void *extra) switch (rd->type) { case RECDB_QSTRING: - dict_insert(newdb, strdup(key), alloc_record_data_qstring(GET_RECORD_QSTRING(rd))); - return 0; + dict_insert(newdb, strdup(key), alloc_record_data_qstring(GET_RECORD_QSTRING(rd))); + return 0; case RECDB_STRING_LIST: { - struct string_list *slist = GET_RECORD_STRING_LIST(rd); - char *dest; - unsigned int totlen, len, i; - - for (i=totlen=0; iused; i++) - totlen = totlen + strlen(slist->list[i]) + 1; - dest = alloca(totlen+1); - for (i=totlen=0; iused; i++) { - len = strlen(slist->list[i]); - memcpy(dest+totlen, slist->list[i], len); - dest[totlen+len] = '\n'; - totlen = totlen + len + 1; - } - dest[totlen] = 0; - dict_insert(newdb, strdup(key), alloc_record_data_qstring(dest)); - return 0; + struct string_list *slist = GET_RECORD_STRING_LIST(rd); + char *dest; + unsigned int totlen, len, i; + + for (i=totlen=0; iused; i++) + totlen = totlen + strlen(slist->list[i]) + 1; + dest = alloca(totlen+1); + for (i=totlen=0; iused; i++) { + len = strlen(slist->list[i]); + memcpy(dest+totlen, slist->list[i], len); + dest[totlen+len] = '\n'; + totlen = totlen + len + 1; + } + dest[totlen] = 0; + dict_insert(newdb, strdup(key), alloc_record_data_qstring(dest)); + return 0; } case RECDB_OBJECT: { dict_iterator_t it; @@ -981,7 +996,7 @@ unlistify_help(const char *key, void *data, void *extra) return 0; } default: - return 1; + return 1; } } @@ -1002,8 +1017,8 @@ open_helpfile(const char *fname, expand_func_t expand) dict_insert(language_find("C")->helpfiles, hf->name, hf); } if (db) { - dict_foreach(db, unlistify_help, hf->db); - free_database(db); + dict_foreach(db, unlistify_help, hf->db); + free_database(db); } return hf; } @@ -1033,10 +1048,27 @@ void helpfile_init(void) language_read_list(); } -void helpfile_finalize(void) +static void helpfile_read_languages(void) { dict_iterator_t it; + dict_t dict; + + language_read_list(); for (it = dict_first(languages); it; it = iter_next(it)) language_read(iter_key(it)); + + /* If the user has a strings.db in their languages directory, + * allow that to override C language strings. + */ + dict = parse_database("languages/strings.db"); + if (dict) { + language_set_messages(lang_C, dict); + free_database(dict); + } +} + +void helpfile_finalize(void) +{ + conf_register_reload(helpfile_read_languages); reg_exit_func(language_cleanup); }