Imported Upstream version 2.6.1p1
[debian/amanda] / server-src / amindexd.c
index 951151bfd42bd39ac716cac90fb1522d8fae0f67..e1e1ba10b92ea5f3e8eed2fe00cff1afd4816850 100644 (file)
 #include "disk_history.h"
 #include "list_dir.h"
 #include "logfile.h"
-#include "token.h"
 #include "find.h"
 #include "tapefile.h"
 #include "util.h"
 #include "amandad.h"
 #include "pipespawn.h"
+#include "sockaddr-util.h"
+#include "amxml.h"
 
 #include <grp.h>
 
@@ -100,15 +101,12 @@ static char *amandad_auth = NULL;
 static FILE *cmdin;
 static FILE *cmdout;
 
-static void reply(int, char *, ...)
-    __attribute__ ((format (printf, 2, 3)));
-static void lreply(int, char *, ...)
-    __attribute__ ((format (printf, 2, 3)));
-static void fast_lreply(int, char *, ...)
-    __attribute__ ((format (printf, 2, 3)));
+static void reply(int, char *, ...) G_GNUC_PRINTF(2, 3);
+static void lreply(int, char *, ...) G_GNUC_PRINTF(2, 3);
+static void fast_lreply(int, char *, ...) G_GNUC_PRINTF(2, 3);
 static am_host_t *is_dump_host_valid(char *);
 static int is_disk_valid(char *);
-static int is_config_valid(char *);
+static int check_and_load_config(char *);
 static int build_disk_table(void);
 static int disk_history_list(void);
 static int is_dir_valid_opaque(char *);
@@ -133,8 +131,7 @@ remove_files(
     REMOVE_ITEM *prev;
 
     while(remove) {
-       dbprintf(("%s: removing index file: %s\n",
-                 debug_prefix_time(NULL), remove->filename));
+       dbprintf(_("removing index file: %s\n"), remove->filename);
        unlink(remove->filename);
        amfree(remove->filename);
        prev = remove;
@@ -159,7 +156,6 @@ uncompress_file(
     int indexfd;
     int nullfd;
     int debugfd;
-    int debugnullfd;
     char line[STR_SIZE];
     FILE *pipe_stream;
     pid_t pid_gzip;
@@ -185,12 +181,10 @@ uncompress_file(
         * Check that compressed file exists manually.
         */
        if (stat(filename_gz, &statbuf) < 0) {
-           *emsg = newvstralloc(*emsg, "Compressed file '",
-                               filename_gz,
-                               "' is inaccessable: ",
-                               strerror(errno),
-                               NULL);
-           dbprintf(("%s\n",*emsg));
+           *emsg = newvstrallocf(*emsg,
+                               _("Compressed file '%s' is inaccessable: %s"),
+                               filename_gz, strerror(errno));
+           dbprintf("%s\n",*emsg);
            amfree(filename);
            return NULL;
        }
@@ -201,28 +195,26 @@ uncompress_file(
 #  define PARAM_UNCOMPRESS_OPT skip_argument
 #endif
 
-       debugfd = dbfd();
-       debugnullfd = 0;
-       if(debugfd < 0) {
-           debugfd = open("/dev/null", O_WRONLY);
-           debugnullfd = 1;
-       }
-
        nullfd = open("/dev/null", O_RDONLY);
+
        indexfd = open(filename,O_WRONLY|O_CREAT, 0600);
        if (indexfd == -1) {
-           *emsg = newvstralloc(*emsg, "Can't open '",
-                                filename, "' for writting: ",
-                                strerror(errno),
-                                NULL);
-           dbprintf(("%s\n",*emsg));
+           *emsg = newvstrallocf(*emsg, _("Can't open '%s' for writting: %s"),
+                                filename, strerror(errno));
+           dbprintf("%s\n",*emsg);
            amfree(filename);
+           aclose(nullfd);
            return NULL;
        }
 
+       /* just use our stderr directly for the pipe's stderr; in 
+        * main() we send stderr to the debug file, or /dev/null
+        * if debugging is disabled */
+       debugfd = STDERR_FILENO;
+
        /* start the uncompress process */
        putenv(stralloc("LC_ALL=C"));
-       pid_gzip = pipespawn(UNCOMPRESS_PATH, STDOUT_PIPE,
+       pid_gzip = pipespawn(UNCOMPRESS_PATH, STDOUT_PIPE, 0,
                             &nullfd, &pipe_from_gzip, &debugfd,
                             UNCOMPRESS_PATH, PARAM_UNCOMPRESS_OPT,
                             filename_gz, NULL);
@@ -230,29 +222,28 @@ uncompress_file(
 
        pipe_stream = fdopen(pipe_from_gzip,"r");
        if(pipe_stream == NULL) {
-           *emsg = newvstralloc(*emsg, "Can't fdopen pipe from gzip: ",
-                                strerror(errno),
-                                NULL);
-           dbprintf(("%s\n",*emsg));
+           *emsg = newvstrallocf(*emsg, _("Can't fdopen pipe from gzip: %s"),
+                                strerror(errno));
+           dbprintf("%s\n",*emsg);
            amfree(filename);
+           aclose(indexfd);
            return NULL;
        }
 
        /* start the sort process */
-       pid_sort = pipespawn(SORT_PATH, STDIN_PIPE,
+       putenv(stralloc("LC_ALL=C"));
+       pid_sort = pipespawn(SORT_PATH, STDIN_PIPE, 0,
                             &pipe_to_sort, &indexfd, &debugfd,
                             SORT_PATH, NULL);
-       if (debugnullfd == 1)
-           aclose(debugfd);
        aclose(indexfd);
 
        /* send all ouput from uncompress process to sort process */
        /* clean the data with clean_backslash */
        while (fgets(line, STR_SIZE, pipe_stream) != NULL) {
            if (line[0] != '\0') {
-               if (index(line,'/')) {
+               if (strchr(line,'/')) {
                    clean_backslash(line);
-                   fullwrite(pipe_to_sort,line,strlen(line));
+                   full_write(pipe_to_sort,line,strlen(line));
                }
            }
        }
@@ -261,26 +252,26 @@ uncompress_file(
        aclose(pipe_to_sort);
        if (waitpid(pid_gzip, &wait_status, 0) < 0) {
            if (!WIFEXITED(wait_status)) {
-               dbprintf(("Uncompress exited with signal %d",
-                         WTERMSIG(wait_status)));
+               dbprintf(_("Uncompress exited with signal %d"),
+                         WTERMSIG(wait_status));
            } else if (WEXITSTATUS(wait_status) != 0) {
-               dbprintf(("Uncompress exited with status %d",
-                         WEXITSTATUS(wait_status)));
+               dbprintf(_("Uncompress exited with status %d"),
+                         WEXITSTATUS(wait_status));
            } else {
-               dbprintf(("Uncompres returned negative value: %s",
-                         strerror(errno)));
+               dbprintf(_("Uncompres returned negative value: %s"),
+                         strerror(errno));
            }
        }
-       if (waitpid(pid_sort, &wait_status, 0)) {
+       if (waitpid(pid_sort, &wait_status, 0) < 0) {
            if (!WIFEXITED(wait_status)) {
-               dbprintf(("Sort exited with signal %d",
-                         WTERMSIG(wait_status)));
+               dbprintf(_("Sort exited with signal %d"),
+                         WTERMSIG(wait_status));
            } else if (WEXITSTATUS(wait_status) != 0) {
-               dbprintf(("Sort exited with status %d",
-                         WEXITSTATUS(wait_status)));
+               dbprintf(_("Sort exited with status %d"),
+                         WEXITSTATUS(wait_status));
            } else {
-               dbprintf(("Sort returned negative value: %s",
-                         strerror(errno)));
+               dbprintf(_("Sort returned negative value: %s"),
+                         strerror(errno));
            }
        }
 
@@ -291,7 +282,7 @@ uncompress_file(
        uncompress_remove = remove_file;
     } else if(!S_ISREG((stat_filename.st_mode))) {
            amfree(*emsg);
-           *emsg = vstralloc("\"", filename, "\" is not a regular file", NULL);
+           *emsg = vstrallocf(_("\"%s\" is not a regular file"), filename);
            errno = -1;
            amfree(filename);
            amfree(cmd);
@@ -310,8 +301,7 @@ process_ls_dump(
     int                recursive,
     char **    emsg)
 {
-    char line[STR_SIZE];
-    char *old_line = NULL;
+    char line[STR_SIZE], old_line[STR_SIZE];
     char *filename = NULL;
     char *filename_gz;
     char *dir_slash = NULL;
@@ -320,6 +310,7 @@ process_ls_dump(
     int ch;
     size_t len_dir_slash;
 
+    old_line[0] = '\0';
     if (strcmp(dir, "/") == 0) {
        dir_slash = stralloc(dir);
     } else {
@@ -329,11 +320,12 @@ process_ls_dump(
     filename_gz = get_index_name(dump_hostname, dump_item->hostname, disk_name,
                                 dump_item->date, dump_item->level);
     if (filename_gz == NULL) {
-       *emsg = stralloc("index file not found");
+       *emsg = stralloc(_("index file not found"));
        amfree(filename_gz);
        return -1;
     }
-    if((filename = uncompress_file(filename_gz, emsg)) == NULL) {
+    filename = uncompress_file(filename_gz, emsg);
+    if(filename == NULL) {
        amfree(filename_gz);
        amfree(dir_slash);
        return -1;
@@ -342,8 +334,9 @@ process_ls_dump(
 
     if((fp = fopen(filename,"r"))==0) {
        amfree(*emsg);
-       *emsg = stralloc(strerror(errno));
+       *emsg = vstrallocf("%s", strerror(errno));
        amfree(dir_slash);
+        amfree(filename);
        return -1;
     }
 
@@ -364,16 +357,14 @@ process_ls_dump(
                    }
                    s[-1] = '\0';
                }
-               if(old_line == NULL || strcmp(line, old_line) != 0) {
+               if(strcmp(line, old_line) != 0) {
                    add_dir_list_item(dump_item, line);
-                   amfree(old_line);
-                   old_line = stralloc(line);
+                   strcpy(old_line, line);
                }
            }
        }
     }
     afclose(fp);
-    /*@i@*/ amfree(old_line);
     amfree(filename);
     amfree(dir_slash);
     return 0;
@@ -390,7 +381,7 @@ printf_arglist_function1(static void reply, int, n, char *, fmt)
 
     while(1) {
        arglist_start(args, fmt);
-       len = vsnprintf(reply_buffer, reply_buffer_size, fmt, args);
+       len = g_vsnprintf(reply_buffer, reply_buffer_size, fmt, args);
        arglist_end(args);
 
        if (len > -1 && (size_t)len < reply_buffer_size-1)
@@ -401,21 +392,19 @@ printf_arglist_function1(static void reply, int, n, char *, fmt)
        reply_buffer = alloc(reply_buffer_size);
     }
 
-    if (fprintf(cmdout,"%03d %s\r\n", n, reply_buffer) < 0)
+    if (g_fprintf(cmdout,"%03d %s\r\n", n, reply_buffer) < 0)
     {
-       dbprintf(("%s: ! error %d (%s) in printf\n",
-                 debug_prefix_time(NULL), errno, strerror(errno)));
+       dbprintf(_("! error %d (%s) in printf\n"), errno, strerror(errno));
        uncompress_remove = remove_files(uncompress_remove);
        exit(1);
     }
     if (fflush(cmdout) != 0)
     {
-       dbprintf(("%s: ! error %d (%s) in fflush\n",
-                 debug_prefix_time(NULL), errno, strerror(errno)));
+       dbprintf(_("! error %d (%s) in fflush\n"), errno, strerror(errno));
        uncompress_remove = remove_files(uncompress_remove);
        exit(1);
     }
-    dbprintf(("%s: < %03d %s\n", debug_prefix_time(NULL), n, reply_buffer));
+    dbprintf(_("< %03d %s\n"), n, reply_buffer);
 }
 
 /* send one line of a multi-line response */
@@ -429,7 +418,7 @@ printf_arglist_function1(static void lreply, int, n, char *, fmt)
 
     while(1) {
        arglist_start(args, fmt);
-       len = vsnprintf(reply_buffer, reply_buffer_size, fmt, args);
+       len = g_vsnprintf(reply_buffer, reply_buffer_size, fmt, args);
        arglist_end(args);
 
        if (len > -1 && (size_t)len < reply_buffer_size-1)
@@ -440,22 +429,22 @@ printf_arglist_function1(static void lreply, int, n, char *, fmt)
        reply_buffer = alloc(reply_buffer_size);
     }
 
-    if (fprintf(cmdout,"%03d-%s\r\n", n, reply_buffer) < 0)
+    if (g_fprintf(cmdout,"%03d-%s\r\n", n, reply_buffer) < 0)
     {
-       dbprintf(("%s: ! error %d (%s) in printf\n",
-                 debug_prefix_time(NULL), errno, strerror(errno)));
+       dbprintf(_("! error %d (%s) in printf\n"),
+                 errno, strerror(errno));
        uncompress_remove = remove_files(uncompress_remove);
        exit(1);
     }
     if (fflush(cmdout) != 0)
     {
-       dbprintf(("%s: ! error %d (%s) in fflush\n",
-                 debug_prefix_time(NULL), errno, strerror(errno)));
+       dbprintf(_("! error %d (%s) in fflush\n"),
+                 errno, strerror(errno));
        uncompress_remove = remove_files(uncompress_remove);
        exit(1);
     }
 
-    dbprintf(("%s: < %03d-%s\n", debug_prefix_time(NULL), n, reply_buffer));
+    dbprintf("< %03d-%s\n", n, reply_buffer);
 
 }
 
@@ -470,7 +459,7 @@ printf_arglist_function1(static void fast_lreply, int, n, char *, fmt)
 
     while(1) {
        arglist_start(args, fmt);
-       len = vsnprintf(reply_buffer, reply_buffer_size, fmt, args);
+       len = g_vsnprintf(reply_buffer, reply_buffer_size, fmt, args);
        arglist_end(args);
 
        if (len > -1 && (size_t)len < reply_buffer_size-1)
@@ -481,15 +470,15 @@ printf_arglist_function1(static void fast_lreply, int, n, char *, fmt)
        reply_buffer = alloc(reply_buffer_size);
     }
 
-    if (fprintf(cmdout,"%03d-%s\r\n", n, reply_buffer) < 0)
+    if (g_fprintf(cmdout,"%03d-%s\r\n", n, reply_buffer) < 0)
     {
-       dbprintf(("%s: ! error %d (%s) in printf\n",
-                 debug_prefix_time(NULL), errno, strerror(errno)));
+       dbprintf(_("! error %d (%s) in printf\n"),
+                 errno, strerror(errno));
        uncompress_remove = remove_files(uncompress_remove);
        exit(1);
     }
 
-    dbprintf(("%s: < %03d-%s\n", debug_prefix_time(NULL), n, reply_buffer));
+    dbprintf("< %03d-%s\n", n, reply_buffer);
 }
 
 /* see if hostname is valid */
@@ -504,15 +493,15 @@ is_dump_host_valid(
     am_host_t   *ihost;
     disk_t      *diskp;
 
-    if (config_name == NULL) {
-       reply(501, "Must set config before setting host.");
+    if (get_config_name() == NULL) {
+       reply(501, _("Must set config before setting host."));
        return NULL;
     }
 
     /* check that the config actually handles that host */
     ihost = lookup_host(host);
     if(ihost == NULL) {
-       reply(501, "Host %s is not in your disklist.", host);
+       reply(501, _("Host %s is not in your disklist."), host);
        return NULL;
     }
 
@@ -528,7 +517,8 @@ is_dump_host_valid(
        }
     }
 
-    reply(501, "No index records for host: %s. Have you enabled indexing?", host);
+    reply(501, _("No index records for host: %s. Have you enabled indexing?"),
+         host);
     return NULL;
 }
 
@@ -540,12 +530,12 @@ is_disk_valid(
     disk_t *idisk;
     char *qdisk;
 
-    if (config_name == NULL) {
-       reply(501, "Must set config,host before setting disk.");
+    if (get_config_name() == NULL) {
+       reply(501, _("Must set config,host before setting disk."));
        return -1;
     }
     else if (dump_hostname == NULL) {
-       reply(501, "Must set host before setting disk.");
+       reply(501, _("Must set host before setting disk."));
        return -1;
     }
 
@@ -553,7 +543,7 @@ is_disk_valid(
     idisk = lookup_disk(dump_hostname, disk);
     if(idisk == NULL) {
        qdisk = quote_string(disk);
-       reply(501, "Disk %s:%s is not in your disklist.", dump_hostname, qdisk);
+       reply(501, _("Disk %s:%s is not in your disklist."), dump_hostname, qdisk);
        amfree(qdisk);
        return -1;
     }
@@ -561,7 +551,7 @@ is_disk_valid(
     /* assume an index dir already */
     if (get_index_dir(dump_hostname, idisk->hostname, disk) == 0) {
        qdisk = quote_string(disk);
-       reply(501, "No index records for disk: %s. Invalid?", qdisk);
+       reply(501, _("No index records for disk: %s. Invalid?"), qdisk);
        amfree(qdisk);
        return -1;
     }
@@ -571,10 +561,9 @@ is_disk_valid(
 
 
 static int
-is_config_valid(
+check_and_load_config(
     char *     config)
 {
-    char *conffile;
     char *conf_diskfile;
     char *conf_tapelist;
     char *conf_indexdir;
@@ -582,58 +571,46 @@ is_config_valid(
 
     /* check that the config actually exists */
     if (config == NULL) {
-       reply(501, "Must set config first.");
+       reply(501, _("Must set config first."));
        return -1;
     }
 
-    /* read conffile */
-    conffile = stralloc2(config_dir, CONFFILE_NAME);
-    if (read_conffile(conffile)) {
-       reply(501, "Could not read config file %s!", conffile);
-       amfree(conffile);
+    /* (re-)initialize configuration with the new config name */
+    config_init(CONFIG_INIT_EXPLICIT_NAME, config);
+    if (config_errors(NULL) >= CFGERR_ERRORS) {
+       reply(501, _("Could not read config file for %s!"), config);
        return -1;
     }
-    amfree(conffile);
 
-    conf_diskfile = getconf_str(CNF_DISKFILE);
-    if (*conf_diskfile == '/') {
-       conf_diskfile = stralloc(conf_diskfile);
-    } else {
-       conf_diskfile = stralloc2(config_dir, conf_diskfile);
-    }
-    if (read_diskfile(conf_diskfile, &disk_list) < 0) {
-       reply(501, "Could not read disk file %s!", conf_diskfile);
-       amfree(conf_diskfile);
+    check_running_as(RUNNING_AS_DUMPUSER_PREFERRED);
+
+    conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
+    read_diskfile(conf_diskfile, &disk_list);
+    amfree(conf_diskfile);
+    if (config_errors(NULL) >= CFGERR_ERRORS) {
+       reply(501, _("Could not read disk file %s!"), conf_diskfile);
        return -1;
     }
-    amfree(conf_diskfile);
 
-    conf_tapelist = getconf_str(CNF_TAPELIST);
-    if (*conf_tapelist == '/') {
-       conf_tapelist = stralloc(conf_tapelist);
-    } else {
-       conf_tapelist = stralloc2(config_dir, conf_tapelist);
-    }
+    conf_tapelist = config_dir_relative(getconf_str(CNF_TAPELIST));
     if(read_tapelist(conf_tapelist)) {
-       reply(501, "Could not read tapelist file %s!", conf_tapelist);
+       reply(501, _("Could not read tapelist file %s!"), conf_tapelist);
        amfree(conf_tapelist);
        return -1;
     }
     amfree(conf_tapelist);
 
-    dbrename(config, DBG_SUBDIR_SERVER);
+    dbrename(get_config_name(), DBG_SUBDIR_SERVER);
 
-    output_find = find_dump(1, &disk_list);
-    sort_find_result("DLKHpB", &output_find);
+    output_find = find_dump(&disk_list);
+    /* the 'w' here sorts by write timestamp, so that the first instance of
+     * any particular datestamp/host/disk/level/part that we see is the one
+     * written earlier */
+    sort_find_result("DLKHpwB", &output_find);
 
-    conf_indexdir = getconf_str(CNF_INDEXDIR);
-    if(*conf_indexdir == '/') {
-       conf_indexdir = stralloc(conf_indexdir);
-    } else {
-       conf_indexdir = stralloc2(config_dir, conf_indexdir);
-    }
+    conf_indexdir = config_dir_relative(getconf_str(CNF_INDEXDIR));
     if (stat (conf_indexdir, &dir_stat) != 0 || !S_ISDIR(dir_stat.st_mode)) {
-       reply(501, "Index directory %s does not exist", conf_indexdir);
+       reply(501, _("Index directory %s does not exist"), conf_indexdir);
        amfree(conf_indexdir);
        return -1;
     }
@@ -653,16 +630,16 @@ build_disk_table(void)
     int last_partnum;
     find_result_t *find_output;
 
-    if (config_name == NULL) {
-       reply(590, "Must set config,host,disk before building disk table");
+    if (get_config_name() == NULL) {
+       reply(590, _("Must set config,host,disk before building disk table"));
        return -1;
     }
     else if (dump_hostname == NULL) {
-       reply(590, "Must set host,disk before building disk table");
+       reply(590, _("Must set host,disk before building disk table"));
        return -1;
     }
     else if (disk_name == NULL) {
-       reply(590, "Must set disk before building disk table");
+       reply(590, _("Must set disk before building disk table"));
        return -1;
     }
 
@@ -678,8 +655,30 @@ build_disk_table(void)
           strcmp(disk_name    , find_output->diskname) == 0 &&
           strcmp("OK"         , find_output->status)   == 0) {
            int partnum = -1;
-           if(strcmp("--", find_output->partnum)){
+           int maxpart = -1;
+           if (strcmp("1/1", find_output->partnum) == 0) {
+               partnum = -1;
+           } else if (strcmp("1/-1", find_output->partnum) == 0) {
+               if (find_output->next &&
+                   strcmp(dump_hostname, find_output->next->hostname) == 0 &&
+                   strcmp(disk_name, find_output->next->diskname) == 0 &&
+                   strcmp(find_output->timestamp,
+                          find_output->next->timestamp) == 0 &&
+                   strcmp("OK", find_output->next->status) == 0 &&
+                   strcmp("2/-1", find_output->next->partnum) == 0) {
+                   partnum = 1;
+               }
+               else {
+                   partnum = -1;
+               }
+           } else if (strcmp("--", find_output->partnum)) {
+               char *c;
                partnum = atoi(find_output->partnum);
+               c = strchr(find_output->partnum,'/');
+               if (c)
+                   maxpart = atoi(c+1);
+               else
+                   maxpart = -1;
            }
            /*
             * The sort order puts holding disk entries first.  We want to
@@ -693,20 +692,31 @@ build_disk_table(void)
               partnum == last_partnum && last_filenum == 0) {
                continue;
            }
+           /* ignore duplicate partnum */
+           if(last_timestamp &&
+              strcmp(find_output->timestamp, last_timestamp) == 0 &&
+              find_output->level == last_level && 
+              partnum == last_partnum) {
+               continue;
+           }
            last_timestamp = find_output->timestamp;
            last_filenum = find_output->filenum;
            last_level = find_output->level;
            last_partnum = partnum;
            date = amindexd_nicedate(find_output->timestamp);
            add_dump(find_output->hostname, date, find_output->level,
-                    find_output->label, find_output->filenum, partnum);
-           dbprintf(("%s: - %s %d %s " OFF_T_FMT " %d\n",
-                    debug_prefix_time(NULL), date, find_output->level, 
+                    find_output->label, find_output->filenum, partnum,
+                    maxpart);
+           dbprintf("- %s %d %s %lld %d %d\n",
+                    date, find_output->level, 
                     find_output->label,
-                    (OFF_T_FMT_TYPE)find_output->filenum,
-                    partnum));
+                    (long long)find_output->filenum,
+                    partnum, maxpart);
        }
     }
+
+    clean_dump();
+
     return 0;
 }
 
@@ -717,21 +727,21 @@ disk_history_list(void)
     DUMP_ITEM *item;
     char date[20];
 
-    if (config_name == NULL) {
-       reply(502, "Must set config,host,disk before listing history");
+    if (get_config_name() == NULL) {
+       reply(502, _("Must set config,host,disk before listing history"));
        return -1;
     }
     else if (dump_hostname == NULL) {
-       reply(502, "Must set host,disk before listing history");
+       reply(502, _("Must set host,disk before listing history"));
        return -1;
     }
     else if (disk_name == NULL) {
-       reply(502, "Must set disk before listing history");
+       reply(502, _("Must set disk before listing history"));
        return -1;
     }
 
-    lreply(200, " Dump history for config \"%s\" host \"%s\" disk %s",
-         config_name, dump_hostname, qdisk_name);
+    lreply(200, _(" Dump history for config \"%s\" host \"%s\" disk %s"),
+         get_config_name(), dump_hostname, qdisk_name);
 
     for (item=first_dump(); item!=NULL; item=next_dump(item)){
         char *tapelist_str = marshal_tapelist(item->tapes, 1);
@@ -745,14 +755,14 @@ disk_history_list(void)
            lreply(201, " %s %d %s", date, item->level, tapelist_str);
        }
        else{
-           lreply(201, " %s %d %s " OFF_T_FMT, date, item->level,
-               tapelist_str, (OFF_T_FMT_TYPE)item->file);
+           lreply(201, " %s %d %s %lld", date, item->level,
+               tapelist_str, (long long)item->file);
        }
        amfree(tapelist_str);
     }
 
-    reply(200, "Dump history for config \"%s\" host \"%s\" disk %s",
-         config_name, dump_hostname, qdisk_name);
+    reply(200, _("Dump history for config \"%s\" host \"%s\" disk %s"),
+         get_config_name(), dump_hostname, qdisk_name);
 
     return 0;
 }
@@ -777,20 +787,20 @@ is_dir_valid_opaque(
     size_t ldir_len;
     static char *emsg = NULL;
 
-    if (config_name == NULL || dump_hostname == NULL || disk_name == NULL) {
-       reply(502, "Must set config,host,disk before asking about directories");
+    if (get_config_name() == NULL || dump_hostname == NULL || disk_name == NULL) {
+       reply(502, _("Must set config,host,disk before asking about directories"));
        return -1;
     }
     else if (dump_hostname == NULL) {
-       reply(502, "Must set host,disk before asking about directories");
+       reply(502, _("Must set host,disk before asking about directories"));
        return -1;
     }
     else if (disk_name == NULL) {
-       reply(502, "Must set disk before asking about directories");
+       reply(502, _("Must set disk before asking about directories"));
        return -1;
     }
     else if (target_date == NULL) {
-       reply(502, "Must set date before asking about directories");
+       reply(502, _("Must set date before asking about directories"));
        return -1;
     }
     /* scan through till we find first dump on or before date */
@@ -801,7 +811,7 @@ is_dir_valid_opaque(
     if (item == NULL)
     {
        /* no dump for given date */
-       reply(500, "No dumps available on or before date \"%s\"", target_date);
+       reply(500, _("No dumps available on or before date \"%s\""), target_date);
        return -1;
     }
 
@@ -824,16 +834,16 @@ is_dir_valid_opaque(
            return -1;
        }
        if((filename = uncompress_file(filename_gz, &emsg)) == NULL) {
-           reply(599, "System error %s", emsg);
+           reply(599, _("System error %s"), emsg);
            amfree(filename_gz);
            amfree(emsg);
            amfree(ldir);
            return -1;
        }
        amfree(filename_gz);
-       dbprintf(("%s: f %s\n", debug_prefix_time(NULL), filename));
+       dbprintf("f %s\n", filename);
        if ((fp = fopen(filename, "r")) == NULL) {
-           reply(599, "System error %s", strerror(errno));
+           reply(599, _("System error %s"), strerror(errno));
            amfree(filename);
            amfree(ldir);
            return -1;
@@ -862,7 +872,7 @@ is_dir_valid_opaque(
 
     amfree(filename);
     amfree(ldir);
-    reply(500, "\"%s\" is an invalid directory", dir);
+    reply(500, _("\"%s\" is an invalid directory"), dir);
     return -1;
 }
 
@@ -885,20 +895,20 @@ opaque_ls(
 
     clear_dir_list();
 
-    if (config_name == NULL) {
-       reply(502, "Must set config,host,disk before listing a directory");
+    if (get_config_name() == NULL) {
+       reply(502, _("Must set config,host,disk before listing a directory"));
        return -1;
     }
     else if (dump_hostname == NULL) {
-       reply(502, "Must set host,disk before listing a directory");
+       reply(502, _("Must set host,disk before listing a directory"));
        return -1;
     }
     else if (disk_name == NULL) {
-       reply(502, "Must set disk before listing a directory");
+       reply(502, _("Must set disk before listing a directory"));
        return -1;
     }
     else if (target_date == NULL) {
-       reply(502, "Must set date before listing a directory");
+       reply(502, _("Must set date before listing a directory"));
        return -1;
     }
 
@@ -910,13 +920,13 @@ opaque_ls(
     if (dump_item == NULL)
     {
        /* no dump for given date */
-       reply(500, "No dumps available on or before date \"%s\"", target_date);
+       reply(500, _("No dumps available on or before date \"%s\""), target_date);
        return -1;
     }
 
     /* get data from that dump */
     if (process_ls_dump(dir, dump_item, recursive, &emsg) == -1) {
-       reply(599, "System error %s", emsg);
+       reply(599, _("System error %s"), emsg);
        amfree(emsg);
        return -1;
     }
@@ -929,7 +939,7 @@ opaque_ls(
        {
            last_level = dump_item->level;
            if (process_ls_dump(dir, dump_item, recursive, &emsg) == -1) {
-               reply(599, "System error %s", emsg);
+               reply(599, _("System error %s"), emsg);
                amfree(emsg);
                return -1;
            }
@@ -937,7 +947,7 @@ opaque_ls(
     }
 
     /* return the information to the caller */
-    lreply(200, " Opaque list of %s", dir);
+    lreply(200, _(" Opaque list of %s"), dir);
     for(level=0; level<=9; level++) {
        for (dir_item = get_dir_list(); dir_item != NULL; 
             dir_item = dir_item->next) {
@@ -946,8 +956,8 @@ opaque_ls(
                if (!am_has_feature(their_features, marshall_feature) &&
                    (num_entries(dir_item->dump->tapes) > 1 ||
                    dir_item->dump->tapes->numfiles > 1)) {
-                   fast_lreply(501, " ERROR: Split dumps not supported"
-                               " with old version of amrecover.");
+                   fast_lreply(501, _(" ERROR: Split dumps not supported"
+                               " with old version of amrecover."));
                    break;
                }
                else {
@@ -956,7 +966,7 @@ opaque_ls(
            }
        }
     }
-    reply(200, " Opaque list of %s", dir);
+    reply(200, _(" Opaque list of %s"), dir);
 
     clear_dir_list();
     return 0;
@@ -987,11 +997,11 @@ void opaque_ls_one(
                                     fe_amindexd_fileno_in_OLSD)) ||
        (recursive && am_has_feature(their_features,
                                    fe_amindexd_fileno_in_ORLD))) {
-       fast_lreply(201, " %s %d %s " OFF_T_FMT " %s",
+       fast_lreply(201, " %s %d %s %lld %s",
                    date,
                    dir_item->dump->level,
                    tapelist_str,
-                   (OFF_T_FMT_TYPE)dir_item->dump->file,
+                   (long long)dir_item->dump->file,
                    qpath);
     }
     else {
@@ -1017,39 +1027,36 @@ tapedev_is(void)
     char *result;
 
     /* check state okay to do this */
-    if (config_name == NULL) {
-       reply(501, "Must set config before asking about tapedev.");
+    if (get_config_name() == NULL) {
+       reply(501, _("Must set config before asking about tapedev."));
        return -1;
     }
 
     /* use amrecover_changer if possible */
     if ((result = getconf_str(CNF_AMRECOVER_CHANGER)) != NULL  &&
         *result != '\0') {
-       dbprintf(("%s: tapedev_is amrecover_changer: %s\n",
-                  debug_prefix_time(NULL), result));
-       reply(200, result);
+       dbprintf(_("tapedev_is amrecover_changer: %s\n"), result);
+       reply(200, "%s", result);
        return 0;
     }
 
     /* use changer if possible */
     if ((result = getconf_str(CNF_TPCHANGER)) != NULL  &&  *result != '\0') {
-       dbprintf(("%s: tapedev_is tpchanger: %s\n",
-                  debug_prefix_time(NULL), result));
-       reply(200, result);
+       dbprintf(_("tapedev_is tpchanger: %s\n"), result);
+       reply(200, "%s", result);
        return 0;
     }
 
     /* get tapedev value */
     if ((result = getconf_str(CNF_TAPEDEV)) != NULL  &&  *result != '\0') {
-       dbprintf(("%s: tapedev_is tapedev: %s\n",
-                  debug_prefix_time(NULL), result));
-       reply(200, result);
+       dbprintf(_("tapedev_is tapedev: %s\n"), result);
+       reply(200, "%s", result);
        return 0;
     }
 
-    dbprintf(("%s: No tapedev or tpchanger in config site.\n",
-              debug_prefix_time(NULL)));
-    reply(501, "Tapedev or tpchanger not set in config file.");
+    dbprintf(_("No tapedev or tpchanger in config site.\n"));
+
+    reply(501, _("Tapedev or tpchanger not set in config file."));
     return -1;
 }
 
@@ -1061,16 +1068,16 @@ are_dumps_compressed(void)
     disk_t *diskp;
 
     /* check state okay to do this */
-    if (config_name == NULL) {
-       reply(501, "Must set config,host,disk name before asking about dumps.");
+    if (get_config_name() == NULL) {
+       reply(501, _("Must set config,host,disk name before asking about dumps."));
        return -1;
     }
     else if (dump_hostname == NULL) {
-       reply(501, "Must set host,disk name before asking about dumps.");
+       reply(501, _("Must set host,disk name before asking about dumps."));
        return -1;
     }
     else if (disk_name == NULL) {
-       reply(501, "Must set disk name before asking about dumps.");
+       reply(501, _("Must set disk name before asking about dumps."));
        return -1;
     }
 
@@ -1083,7 +1090,7 @@ are_dumps_compressed(void)
     }
 
     if (diskp == NULL) {
-       reply(501, "Couldn't find host/disk in disk file.");
+       reply(501, _("Couldn't find host/disk in disk file."));
        return -1;
     }
 
@@ -1105,8 +1112,8 @@ main(
     char *s;
     int ch;
     char *cmd_undo, cmd_undo_ch;
-    socklen_t socklen;
-    struct sockaddr_storage his_addr;
+    socklen_t_equiv socklen;
+    sockaddr_union his_addr;
     char *arg = NULL;
     char *cmd;
     size_t len;
@@ -1114,6 +1121,16 @@ main(
     char *errstr = NULL;
     char *pgm = "amindexd";            /* in case argv[0] is not set */
     char his_hostname[MAX_HOSTNAME_LENGTH];
+    char *cfg_opt = NULL;
+
+    /*
+     * Configure program for internationalization:
+     *   1) Only set the message locale for now.
+     *   2) Set textdomain for all amanda related programs to "amanda"
+     *      We don't want to be forced to support dozens of message catalogs.
+     */  
+    setlocale(LC_MESSAGES, "C");
+    textdomain("amanda"); 
 
     safe_fd(DATA_FD_OFFSET, 2);
     safe_cd();
@@ -1137,43 +1154,18 @@ main(
     /* Don't die when child closes pipe */
     signal(SIGPIPE, SIG_IGN);
 
-#ifdef FORCE_USERID
-
-    /* we'd rather not run as root */
-
-    if(geteuid() == 0) {
-       if(client_uid == (uid_t) -1) {
-           error("error [cannot find user %s in passwd file]\n", CLIENT_LOGIN);
-           /*NOTREACHED*/
-       }
-
-       /*@ignore@*/
-       initgroups(CLIENT_LOGIN, client_gid);
-       /*@end@*/
-       setgid(client_gid);
-       setuid(client_uid);
-    }
-
-#endif /* FORCE_USERID */
-
     dbopen(DBG_SUBDIR_SERVER);
-    dbprintf(("%s: version %s\n", get_pname(), version()));
+    dbprintf(_("version %s\n"), version());
 
     if(argv == NULL) {
        error("argv == NULL\n");
     }
 
     if (! (argc >= 1 && argv[0] != NULL)) {
-       dbprintf(("%s: WARNING: argv[0] not defined: check inetd.conf\n",
-                 debug_prefix_time(NULL)));
+       dbprintf(_("WARNING: argv[0] not defined: check inetd.conf\n"));
     }
 
-    {
-       int db_fd = dbfd();
-       if(db_fd != -1) {
-           dup2(db_fd, 2);
-       }
-    }
+    debug_dup_stderr_to_debug();
 
     /* initialize */
 
@@ -1202,14 +1194,13 @@ main(
     }
 
     if (argc > 0) {
-       config_name = stralloc(*argv);
-       config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
+       cfg_opt = *argv;
        argc--;
        argv++;
     }
 
     if(gethostname(local_hostname, SIZEOF(local_hostname)-1) == -1) {
-       error("gethostname: %s", strerror(errno));
+       error(_("gethostname: %s"), strerror(errno));
        /*NOTREACHED*/
     }
     local_hostname[SIZEOF(local_hostname)-1] = '\0';
@@ -1226,7 +1217,7 @@ main(
            /* who are we talking to? */
            socklen = sizeof (his_addr);
            if (getpeername(0, (struct sockaddr *)&his_addr, &socklen) == -1)
-               error("getpeername: %s", strerror(errno));
+               error(_("getpeername: %s"), strerror(errno));
 
            /* Try a reverse (IP->hostname) resolution, and fail if it does
             * not work -- this is a basic security check */
@@ -1248,6 +1239,10 @@ main(
        /* read the REQ packet */
        for(; (line = agets(stdin)) != NULL; free(line)) {
            if(strncmp_const(line, "OPTIONS ") == 0) {
+                if (g_options != NULL) {
+                   dbprintf(_("REQ packet specified multiple OPTIONS.\n"));
+                    free_g_options(g_options);
+                }
                g_options = parse_g_options(line+8, 1);
                if(!g_options->hostname) {
                    g_options->hostname = alloc(MAX_HOSTNAME_LENGTH+1);
@@ -1260,16 +1255,16 @@ main(
 
        if(amandad_auth && g_options->auth) {
            if(strcasecmp(amandad_auth, g_options->auth) != 0) {
-               printf("ERROR recover program ask for auth=%s while amindexd is configured for '%s'\n",
+               g_printf(_("ERROR recover program ask for auth=%s while amindexd is configured for '%s'\n"),
                       g_options->auth, amandad_auth);
-               error("amindexd: ERROR recover program ask for auth=%s while amindexd is configured for '%s'",
+               error(_("amindexd: ERROR recover program ask for auth=%s while amindexd is configured for '%s'"),
                      g_options->auth, amandad_auth);
                /*NOTREACHED*/
            }
        }
        /* send the REP packet */
-       printf("CONNECT MESG %d\n", DATA_FD_OFFSET);
-       printf("\n");
+       g_printf("CONNECT MESG %d\n", DATA_FD_OFFSET);
+       g_printf("\n");
        fflush(stdin);
        fflush(stdout);
        fclose(stdin);
@@ -1297,11 +1292,11 @@ main(
     our_features = am_init_feature_set();
     their_features = am_set_default_feature_set();
 
-    if (config_name != NULL && is_config_valid(config_name) != -1) {
+    if (cfg_opt != NULL && check_and_load_config(cfg_opt) != -1) { /* load the config */
        return 1;
     }
 
-    reply(220, "%s AMANDA index server (%s) ready.", local_hostname,
+    reply(220, _("%s AMANDA index server (%s) ready."), local_hostname,
          version());
 
     user_validated = from_amandad;
@@ -1313,18 +1308,15 @@ main(
        while(1) {
            if((part = agets(cmdin)) == NULL) {
                if(errno != 0) {
-                   dbprintf(("%s: ? read error: %s\n",
-                             debug_prefix_time(NULL), strerror(errno)));
+                   dbprintf(_("? read error: %s\n"), strerror(errno));
                } else {
-                   dbprintf(("%s: ? unexpected EOF\n",
-                             debug_prefix_time(NULL)));
+                   dbprintf(_("? unexpected EOF\n"));
                }
                if(line) {
-                   dbprintf(("%s: ? unprocessed input:\n",
-                             debug_prefix_time(NULL)));
-                   dbprintf(("-----\n"));
-                   dbprintf(("? %s\n", line));
-                   dbprintf(("-----\n"));
+                   dbprintf(_("? unprocessed input:\n"));
+                   dbprintf("-----\n");
+                   dbprintf("? %s\n", line);
+                   dbprintf("-----\n");
                }
                amfree(line);
                amfree(part);
@@ -1350,7 +1342,7 @@ main(
            strappend(line, "\n");
        }
 
-       dbprintf(("%s: > %s\n", debug_prefix_time(NULL), line));
+       dbprintf("> %s\n", line);
 
        if (arg != NULL)
            amfree(arg);
@@ -1359,7 +1351,7 @@ main(
 
        skip_whitespace(s, ch);
        if(ch == '\0') {
-           reply(500, "Command not recognised/incorrect: %s", line);
+           reply(500, _("Command not recognised/incorrect: %s"), line);
            amfree(line);
            continue;
        }
@@ -1382,18 +1374,18 @@ main(
        if (!user_validated && strcmp(cmd, "SECURITY") == 0 && arg) {
            user_validated = amindexd_debug ||
                                check_security(
-                                       (struct sockaddr_storage *)&his_addr,
+                                       (sockaddr_union *)&his_addr,
                                        arg, 0, &errstr);
            if(user_validated) {
-               reply(200, "Access OK");
+               reply(200, _("Access OK"));
                amfree(line);
                continue;
            }
        }
        if (!user_validated) {  /* don't tell client the reason, just log it to debug log */
-           reply(500, "Access not allowed");
+           reply(500, _("Access not allowed"));
            if (errstr) {   
-               dbprintf(("%s: %s\n", debug_prefix_time(NULL), errstr));
+               dbprintf("%s\n", errstr);
            }
            break;
        }
@@ -1408,7 +1400,7 @@ main(
            if ((lhost = is_dump_host_valid(arg)) != NULL)
            {
                dump_hostname = newstralloc(dump_hostname, lhost->hostname);
-               reply(200, "Dump host set to %s.", dump_hostname);
+               reply(200, _("Dump host set to %s."), dump_hostname);
                amfree(qdisk_name);             /* invalidate any value */
                amfree(disk_name);              /* invalidate any value */
            }
@@ -1419,11 +1411,11 @@ main(
            int nbhost = 0,
                 found = 0;
            s[-1] = '\0';
-           if (config_name == NULL) {
-               reply(501, "Must set config before listhost");
+           if (get_config_name() == NULL) {
+               reply(501, _("Must set config before listhost"));
            }
            else {
-               lreply(200, " List hosts for config %s", config_name);
+               lreply(200, _(" List hosts for config %s"), get_config_name());
                for (disk = disk_list.head; disk!=NULL; disk = disk->next) {
                     found = 0;
                    for (diskdup = disk_list.head; diskdup!=disk; diskdup = diskdup->next) {
@@ -1438,10 +1430,10 @@ main(
                     }
                }
                if(nbhost > 0) {
-                   reply(200, " List hosts for config %s", config_name);
+                   reply(200, _(" List hosts for config %s"), get_config_name());
                }
                else {
-                   reply(200, "No hosts for config %s", config_name);
+                   reply(200, _("No hosts for config %s"), get_config_name());
                }
            }
            s[-1] = (char)ch;
@@ -1451,23 +1443,57 @@ main(
                disk_name = newstralloc(disk_name, arg);
                qdisk_name = quote_string(disk_name);
                if (build_disk_table() != -1) {
-                   reply(200, "Disk set to %s.", qdisk_name);
+                   reply(200, _("Disk set to %s."), qdisk_name);
                }
            }
            s[-1] = (char)ch;
+       } else if (strcmp(cmd, "DLE") == 0) {
+           disk_t *dp;
+           char *optionstr;
+           char *b64disk;
+           char *l, *ql;
+
+           dp = lookup_disk(dump_hostname, disk_name);
+           if (dp->line == 0) {
+               reply(200, "NODLE");
+           } else {
+               b64disk = amxml_format_tag("disk", dp->name);
+               optionstr = xml_optionstr(dp, their_features, NULL, 0);
+               l = vstralloc("<dle>\n",
+                             "  <program>", dp->program, "</program>\n", NULL);
+               if (dp->application) {
+                   char *xml_app = xml_application(dp->application,
+                                                   their_features);
+                   vstrextend(&l, xml_app, NULL);
+                   amfree(xml_app);
+               }
+               vstrextend(&l, "  ", b64disk, "\n", NULL);
+               if (dp->device) {
+                   char *b64device = amxml_format_tag("diskdevice", dp->device);
+                   vstrextend(&l, "  ", b64device, "\n", NULL);
+                   amfree(b64device);
+               }
+               vstrextend(&l, optionstr, "</dle>\n", NULL);
+               ql = quote_string(l);
+               reply(200, "%s", ql);
+               amfree(optionstr);
+               amfree(l);
+               amfree(ql);
+               amfree(b64disk);
+           }
        } else if (strcmp(cmd, "LISTDISK") == 0) {
            char *qname;
            disk_t *disk;
            int nbdisk = 0;
            s[-1] = '\0';
-           if (config_name == NULL) {
-               reply(501, "Must set config, host before listdisk");
+           if (get_config_name() == NULL) {
+               reply(501, _("Must set config, host before listdisk"));
            }
            else if (dump_hostname == NULL) {
-               reply(501, "Must set host before listdisk");
+               reply(501, _("Must set host before listdisk"));
            }
            else if(arg) {
-               lreply(200, " List of disk for device %s on host %s", arg,
+               lreply(200, _(" List of disk for device %s on host %s"), arg,
                       dump_hostname);
                for (disk = disk_list.head; disk!=NULL; disk = disk->next) {
 
@@ -1481,16 +1507,16 @@ main(
                    }
                }
                if(nbdisk > 0) {
-                   reply(200, "List of disk for device %s on host %s", arg,
+                   reply(200, _("List of disk for device %s on host %s"), arg,
                          dump_hostname);
                }
                else {
-                   reply(200, "No disk for device %s on host %s", arg,
+                   reply(200, _("No disk for device %s on host %s"), arg,
                          dump_hostname);
                }
            }
            else {
-               lreply(200, " List of disk for host %s", dump_hostname);
+               lreply(200, _(" List of disk for host %s"), dump_hostname);
                for (disk = disk_list.head; disk!=NULL; disk = disk->next) {
                    if(strcasecmp(disk->host->hostname, dump_hostname) == 0) {
                        qname = quote_string(disk->name);
@@ -1500,28 +1526,21 @@ main(
                    }
                }
                if(nbdisk > 0) {
-                   reply(200, "List of disk for host %s", dump_hostname);
+                   reply(200, _("List of disk for host %s"), dump_hostname);
                }
                else {
-                   reply(200, "No disk for host %s", dump_hostname);
+                   reply(200, _("No disk for host %s"), dump_hostname);
                }
            }
            s[-1] = (char)ch;
        } else if (strcmp(cmd, "SCNF") == 0 && arg) {
            s[-1] = '\0';
-           amfree(config_name);
-           amfree(config_dir);
-           config_name = newstralloc(config_name, arg);
-           config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
-           if (is_config_valid(arg) != -1) {
+           if (check_and_load_config(arg) != -1) {    /* try to load the new config */
                amfree(dump_hostname);          /* invalidate any value */
                amfree(qdisk_name);             /* invalidate any value */
                amfree(disk_name);              /* invalidate any value */
-               reply(200, "Config set to %s.", config_name);
-           } else {
-               amfree(config_name);
-               amfree(config_dir);
-           }
+               reply(200, _("Config set to %s."), get_config_name());
+           } /* check_and_load_config replies with any failure messages */
            s[-1] = (char)ch;
        } else if (strcmp(cmd, "FEATURES") == 0 && arg) {
            char *our_feature_string = NULL;
@@ -1533,6 +1552,10 @@ main(
            our_feature_string = am_feature_to_string(our_features);
            their_feature_string = newstralloc(their_feature_string, arg);
            their_features = am_string_to_feature(their_feature_string);
+           if (!their_features) {
+               g_warning("Invalid client feature set '%s'", their_feature_string);
+               their_features = am_set_default_feature_set();
+           }
            reply(200, "FEATURES %s", our_feature_string);
            amfree(our_feature_string);
            amfree(their_feature_string);
@@ -1540,13 +1563,13 @@ main(
        } else if (strcmp(cmd, "DATE") == 0 && arg) {
            s[-1] = '\0';
            target_date = newstralloc(target_date, arg);
-           reply(200, "Working date set to %s.", target_date);
+           reply(200, _("Working date set to %s."), target_date);
            s[-1] = (char)ch;
        } else if (strcmp(cmd, "DHST") == 0) {
            (void)disk_history_list();
        } else if (strcmp(cmd, "OISD") == 0 && arg) {
            if (is_dir_valid_opaque(arg) != -1) {
-               reply(200, "\"%s\" is a valid directory", arg);
+               reply(200, _("\"%s\" is a valid directory"), arg);
            }
        } else if (strcmp(cmd, "OLSD") == 0 && arg) {
            (void)opaque_ls(arg,0);
@@ -1558,7 +1581,7 @@ main(
            (void)are_dumps_compressed();
        } else {
            *cmd_undo = cmd_undo_ch;    /* restore the command line */
-           reply(500, "Command not recognised/incorrect: %s", cmd);
+           reply(500, _("Command not recognised/incorrect: %s"), cmd);
        }
        amfree(line);
     }
@@ -1566,7 +1589,7 @@ main(
     
     uncompress_remove = remove_files(uncompress_remove);
     free_find_result(&output_find);
-    reply(200, "Good bye.");
+    reply(200, _("Good bye."));
     dbclose();
     return 0;
 }
@@ -1589,7 +1612,7 @@ amindexd_nicedate(
     day   = numdate % 100;
 
     if(strlen(datestamp) <= 8) {
-       snprintf(nice, SIZEOF(nice), "%4d-%02d-%02d",
+       g_snprintf(nice, SIZEOF(nice), "%4d-%02d-%02d",
                year, month, day);
     }
     else {
@@ -1600,7 +1623,7 @@ amindexd_nicedate(
        minutes = (numtime / 100) % 100;
        seconds = numtime % 100;
 
-       snprintf(nice, SIZEOF(nice), "%4d-%02d-%02d-%02d-%02d-%02d",
+       g_snprintf(nice, SIZEOF(nice), "%4d-%02d-%02d-%02d-%02d-%02d",
                year, month, day, hours, minutes, seconds);
     }
 
@@ -1628,9 +1651,9 @@ clean_backslash(
            s++;
            s1 = s+1;
            s2 = s+2;
-           if (*s != '\0' && isdigit(*s) &&
-               *s1 != '\0' && isdigit(*s1) &&
-               *s2 != '\0' &&  isdigit(*s2)) {
+           if (*s != '\0' && isdigit((int)*s) &&
+               *s1 != '\0' && isdigit((int)*s1) &&
+               *s2 != '\0' &&  isdigit((int)*s2)) {
                /* this is \000, an octal value */
                i = ((*s)-'0')*64 + ((*s1)-'0')*8 + ((*s2)-'0');
                *p++ = i;