Added idletime to remote whois.
[srvx.git] / src / helpfile.c
index 2529408e72a7cde2b1e694baaf9f3dee6bea6bf4..532bcb8577c72dc145ec7459b537e527b71adfbe 100644 (file)
@@ -84,7 +84,7 @@ static struct language *language_alloc(const char *name)
  * lang is a two-letter code according to ISO-639-1 (or three-letter
  * code according to ISO-639-2 for languages not in ISO-639-1), and
  * COUNTRY is the ISO 3166 country code in all upper case.
- * 
+ *
  * See also:
  * http://www.loc.gov/standards/iso639-2/
  * http://www.loc.gov/standards/iso639-2/langhome.html
@@ -171,8 +171,10 @@ static struct language *language_read(const char *name)
 
     /* Open the directory stream; if we can't, fail. */
     snprintf(filename, sizeof(filename), "languages/%s", name);
-    if (!(dir = opendir(filename)))
+    if (!(dir = opendir(filename))) {
+        log_module(MAIN_LOG, LOG_ERROR, "Unable to open language directory languages/%s: %s", name, strerror(errno));
         return NULL;
+    }
     if (!(lang = dict_find(languages, name, NULL)))
         lang = language_alloc(name);
 
@@ -203,7 +205,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);
@@ -222,29 +224,30 @@ static struct language *language_read(const char *name)
 
 static void language_read_list(void)
 {
+    struct stat sbuf;
     struct dirent *dirent;
     DIR *dir;
+    char namebuf[MAXLEN];
 
     if (!(dir = opendir("languages")))
         return;
     while ((dirent = readdir(dir))) {
         if (dirent->d_name[0] == '.')
             continue;
-#ifdef HAVE_DIRENT_D_TYPE
-        if (dirent->d_type != DT_DIR)
+        snprintf(namebuf, sizeof(namebuf), "languages/%s", dirent->d_name);
+        if (!strcmp(dirent->d_name, "strings.db")) {
             continue;
-#else
-        {
-            char namebuf[MAXLEN];
-            struct stat sbuf;
-            snprintf(namebuf, sizeof(namebuf), "languages/%s", dirent->d_name);
-            if (stat(namebuf, &sbuf) < 0)
-                continue;
-            if (!S_ISDIR(sbuf.st_mode))
-                continue;
         }
-#endif
-        language_alloc(dirent->d_name);
+        if (stat(namebuf, &sbuf) < 0) {
+            log_module(MAIN_LOG, LOG_INFO, "Skipping language entry '%s' (unable to stat).", dirent->d_name);
+            continue;
+        }
+        if (!S_ISDIR(sbuf.st_mode)) {
+            log_module(MAIN_LOG, LOG_INFO, "Skipping language entry '%s' (not directory).", dirent->d_name);
+            continue;
+        }
+        if (!dict_find(languages, dirent->d_name, NULL))
+            language_alloc(dirent->d_name);
     }
     closedir(dir);
 }
@@ -425,7 +428,7 @@ vsend_message(const char *dest, struct userNode *src, struct handle_info *handle
         size = sizeof(line);
         use_color = 1;
     }
-    if (!size)
+    if (!size || !(msg_type & MSG_TYPE_MULTILINE))
         size = DEFAULT_LINE_SIZE;
     switch (msg_type & 3) {
         case 0:
@@ -660,7 +663,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);
@@ -672,7 +675,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);
@@ -806,7 +809,7 @@ helpfile_eval_identifier(const char *start, const char **end)
         *end = start + 5;
         return 0;
     } else {
-        log_module(MAIN_LOG, LOG_FATAL, "Unexpected helpfile identifier '%.*s'.", *end-start, start);
+        log_module(MAIN_LOG, LOG_FATAL, "Unexpected helpfile identifier '%.*s'.", (int)(*end-start), start);
         return -1;
     }
 }
@@ -838,7 +841,7 @@ helpfile_eval_atomicexpr(const char *start, const char **end)
     while (isspace(*sep) && (sep < *end))
         sep++;
     if ((sep == *end) || (sep[0] != ')')) {
-        log_module(MAIN_LOG, LOG_FATAL, "Expected close parenthesis at '%.*s'.", *end-sep, sep);
+        log_module(MAIN_LOG, LOG_FATAL, "Expected close parenthesis at '%.*s'.", (int)(*end-sep), sep);
         return -1;
     }
 
@@ -875,7 +878,7 @@ helpfile_eval_expr(const char *start, const char **end)
         sep += len;
     }
     if (op == OP_INVALID) {
-        log_module(MAIN_LOG, LOG_FATAL, "Unrecognized helpfile operator at '%.*s'.", *end-sep, sep);
+        log_module(MAIN_LOG, LOG_FATAL, "Unrecognized helpfile operator at '%.*s'.", (int)(*end-sep), sep);
         return -1;
     }
 
@@ -889,7 +892,7 @@ helpfile_eval_expr(const char *start, const char **end)
     while (isspace(*sep2) && (sep2 < *end))
         sep2++;
     if (sep2 != *end) {
-        log_module(MAIN_LOG, LOG_FATAL, "Trailing garbage in helpfile expression: '%.*s'.", *end-sep2, sep2);
+        log_module(MAIN_LOG, LOG_FATAL, "Trailing garbage in helpfile expression: '%.*s'.", (int)(*end-sep2), sep2);
         return -1;
     }
 
@@ -916,7 +919,7 @@ helpfile_eval_condition(const char *start, const char **end)
     for (term = start; isalnum(*term) && (term < *end); ++term) ;
     if (term != start) {
         if ((term + 2 >= *end) || (term[0] != ':') || (term[1] != ' ')) {
-            log_module(MAIN_LOG, LOG_FATAL, "In helpfile condition '%.*s' expected prefix to end with ': '.", *end-start, start);
+            log_module(MAIN_LOG, LOG_FATAL, "In helpfile condition '%.*s' expected prefix to end with ': '.", (int)(*end-start), start);
             return -1;
         }
         start = term + 2;
@@ -1034,10 +1037,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);
 }