Imported Upstream version 3.3.1
[debian/amanda] / recover-src / amrecover.c
index 0f103dc87ca87cba193cc226ae2d62b22037b955..e0d7c18d722c27ab93322a420c10d0f47be0fe5e 100644 (file)
@@ -30,7 +30,6 @@
  */
 
 #include "amanda.h"
-#include "version.h"
 #include "stream.h"
 #include "amfeatures.h"
 #include "amrecover.h"
@@ -41,6 +40,8 @@
 #include "protocol.h"
 #include "event.h"
 #include "security.h"
+#include "conffile.h"
+#include "getopt.h"
 
 #define amrecover_debug(i, ...) do {   \
        if ((i) <= debug_amrecover) {   \
        }                               \
 } while (0)
 
+static struct option long_options[] = {
+    {"version"         , 0, NULL,  1},
+    {NULL, 0, NULL, 0}
+};
+
 extern int process_line(char *line);
 int get_line(void);
 int grab_reply(int show);
 void sigint_handler(int signum);
 int main(int argc, char **argv);
 
-#define USAGE _("Usage: amrecover [[-C] <config>] [-s <index-server>] [-t <tape-server>] [-d <tape-device>] [-o <clientconfigoption>]*\n")
+#define USAGE _("Usage: amrecover [--version] [[-C] <config>] [-s <index-server>] [-t <tape-server>] [-d <tape-device>] [-o <clientconfigoption>]*\n")
 
 char *server_name = NULL;
 int server_socket;
@@ -62,8 +68,10 @@ char *server_line = NULL;
 char *dump_datestamp = NULL;           /* date we are restoring */
 char *dump_hostname;                   /* which machine we are restoring */
 char *disk_name = NULL;                        /* disk we are restoring */
+dle_t *dump_dle = NULL;
 char *mount_point = NULL;              /* where disk was mounted */
 char *disk_path = NULL;                        /* path relative to mount point */
+char *disk_tpath = NULL;               /* translated path relative to mount point */
 char dump_date[STR_SIZE];              /* date on which we are restoring */
 int quit_prog;                         /* set when time to exit parser */
 char *tape_server_name = NULL;
@@ -73,6 +81,7 @@ am_feature_t *our_features = NULL;
 char *our_features_string = NULL;
 am_feature_t *indexsrv_features = NULL;
 am_feature_t *tapesrv_features = NULL;
+proplist_t proplist = NULL;
 static char *errstr = NULL;
 char *authopt;
 int amindexd_alive = 0;
@@ -88,7 +97,6 @@ static struct {
 
 static void amindexd_response(void *, pkt_t *, security_handle_t *);
 void stop_amindexd(void);
-char *amindexd_client_get_security_conf(char *, void *);
 
 static char* mesg_buffer = NULL;
 /* gets a "line" from server and put in server_line */
@@ -127,6 +135,7 @@ get_line(void)
        newbuf[strlen(mesg_buffer)+size] = '\0';
        amfree(mesg_buffer);
        mesg_buffer = newbuf;
+       amfree(buf);
     }
 
     s = strstr(mesg_buffer,"\r\n");
@@ -135,6 +144,8 @@ get_line(void)
     server_line = newstralloc(server_line, mesg_buffer);
     amfree(mesg_buffer);
     mesg_buffer = newbuf;
+    amrecover_debug(1, "server_line: %s\n", server_line);
+    amrecover_debug(1, "get: %s\n", mesg_buffer);
     return 0;
 }
 
@@ -144,6 +155,8 @@ get_line(void)
 /* return -1 if error */
 /* return code returned by server always occupies first 3 bytes of global
    variable server_line */
+/* show == 0: Print the reply if it is an error */
+/* show == 1: Always print the reply            */
 int
 grab_reply(
     int show)
@@ -152,7 +165,9 @@ grab_reply(
        if (get_line() == -1) {
            return -1;
        }
-       if(show) puts(server_line);
+       if (show || server_line[0] == '5') {
+           puts(server_line);
+       }
     } while (server_line[3] == '-');
     if(show) fflush(stdout);
 
@@ -207,6 +222,7 @@ send_command(
     buffer[strlen(cmd)+1] = '\n';
     buffer[strlen(cmd)+2] = '\0';
 
+    g_debug("sending: %s\n", buffer);
     if(security_stream_write(streams[MESGFD].fd, buffer, strlen(buffer)) < 0) {
        return -1;
     }
@@ -263,7 +279,7 @@ sigint_handler(
 }
 
 
-void
+char *
 clean_pathname(
     char *     s)
 {
@@ -281,6 +297,8 @@ clean_pathname(
     /* remove "/." at end of path */
     if(strcmp(&(s[length-2]),"/.")==0)
        s[length-2]='\0';
+
+    return s;
 }
 
 
@@ -292,8 +310,6 @@ quit(void)
     stop_amindexd();
 }
 
-char *localhost = NULL;
-
 #ifdef DEFAULT_TAPE_SERVER
 # define DEFAULT_TAPE_SERVER_FAILOVER (DEFAULT_TAPE_SERVER)
 #else
@@ -316,7 +332,8 @@ main(
     char *req = NULL;
     int response_error;
     struct tm *tm;
-    config_overwrites_t *cfg_ovr;
+    config_overrides_t *cfg_ovr;
+    char *starting_hostname = NULL;
 
     /*
      * Configure program for internationalization:
@@ -336,25 +353,15 @@ main(
 
     dbopen(DBG_SUBDIR_CLIENT);
 
-    localhost = alloc(MAX_HOSTNAME_LENGTH+1);
-    if (gethostname(localhost, MAX_HOSTNAME_LENGTH) != 0) {
-       error(_("cannot determine local host name\n"));
-       /*NOTREACHED*/
-    }
-    localhost[MAX_HOSTNAME_LENGTH] = '\0';
-
-    /* load the base client configuration */
-    config_init(CONFIG_INIT_CLIENT, NULL);
-
     /* treat amrecover-specific command line options as the equivalent
      * -o command-line options to set configuration values */
-    cfg_ovr = new_config_overwrites(argc/2);
+    cfg_ovr = new_config_overrides(argc/2);
 
     /* If the first argument is not an option flag, then we assume
      * it is a configuration name to match the syntax of the other
      * Amanda utilities. */
     if (argc > 1 && argv[1][0] != '-') {
-       add_config_overwrite(cfg_ovr, "conf", argv[1]);
+       add_config_override(cfg_ovr, "conf", argv[1]);
 
        /* remove that option from the command line */
        argv[1] = argv[0];
@@ -362,26 +369,34 @@ main(
     }
 
     /* now parse regular command-line '-' options */
-    while ((i = getopt(argc, argv, "o:C:s:t:d:U")) != EOF) {
+    while ((i = getopt_long(argc, argv, "o:C:s:t:d:Uh:", long_options, NULL)) != EOF) {
        switch (i) {
+           case 1:
+               printf("amrecover-%s\n", VERSION);
+               return(0);
+               break;
            case 'C':
-               add_config_overwrite(cfg_ovr, "conf", optarg);
+               add_config_override(cfg_ovr, "conf", optarg);
                break;
 
            case 's':
-               add_config_overwrite(cfg_ovr, "index_server", optarg);
+               add_config_override(cfg_ovr, "index_server", optarg);
                break;
 
            case 't':
-               add_config_overwrite(cfg_ovr, "tape_server", optarg);
+               add_config_override(cfg_ovr, "tape_server", optarg);
                break;
 
            case 'd':
-               add_config_overwrite(cfg_ovr, "tapedev", optarg);
+               add_config_override(cfg_ovr, "tapedev", optarg);
                break;
 
            case 'o':
-               add_config_overwrite_opt(cfg_ovr, optarg);
+               add_config_override_opt(cfg_ovr, optarg);
+               break;
+
+           case 'h':
+               starting_hostname = g_strdup(optarg);
                break;
 
            case 'U':
@@ -395,18 +410,37 @@ main(
        exit(1);
     }
 
+    /* load the base client configuration */
+    set_config_overrides(cfg_ovr);
+    config_init(CONFIG_INIT_CLIENT, NULL);
+
+    if (config_errors(NULL) >= CFGERR_WARNINGS) {
+       config_print_errors();
+       if (config_errors(NULL) >= CFGERR_ERRORS) {
+           g_critical(_("errors processing config file"));
+       }
+    }
+
     /* and now try to load the configuration named in that file */
-    apply_config_overwrites(cfg_ovr);
     config_init(CONFIG_INIT_CLIENT | CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_OVERLAY,
                getconf_str(CNF_CONF));
 
     check_running_as(RUNNING_AS_ROOT);
 
-    dbrename(config_name, DBG_SUBDIR_CLIENT);
+    dbrename(get_config_name(), DBG_SUBDIR_CLIENT);
 
     our_features = am_init_feature_set();
     our_features_string = am_feature_to_string(our_features);
 
+    if (!starting_hostname) {
+       starting_hostname = alloc(MAX_HOSTNAME_LENGTH+1);
+       if (gethostname(starting_hostname, MAX_HOSTNAME_LENGTH) != 0) {
+           error(_("cannot determine local host name\n"));
+           /*NOTREACHED*/
+       }
+       starting_hostname[MAX_HOSTNAME_LENGTH] = '\0';
+    }
+
     server_name = NULL;
     if (getconf_seen(CNF_INDEX_SERVER) == -2) { /* command line argument */
        server_name = getconf_str(CNF_INDEX_SERVER);
@@ -466,6 +500,7 @@ main(
     amfree(disk_name);
     amfree(mount_point);
     amfree(disk_path);
+    amfree(disk_tpath);
     dump_date[0] = '\0';
 
     /* Don't die when child closes pipe */
@@ -480,6 +515,8 @@ main(
        /*NOTREACHED*/
     }
 
+    proplist = g_hash_table_new_full(g_str_hash, g_str_equal, &g_free, &free_property_t);
+
     protocol_init();
 
     /* We assume that amindexd support fe_amindexd_options_features */
@@ -503,7 +540,7 @@ main(
     protocol_run();
 
     g_printf(_("AMRECOVER Version %s. Contacting server on %s ...\n"),
-          version(), server_name);
+          VERSION, server_name);
 
     if(response_error != 0) {
        g_fprintf(stderr,"%s\n",errstr);
@@ -525,14 +562,18 @@ main(
     {
        char *their_feature_string = NULL;
 
+       indexsrv_features = NULL;
+
        line = vstrallocf("FEATURES %s", our_features_string);
        if(exchange(line) == 0) {
            their_feature_string = stralloc(server_line+13);
            indexsrv_features = am_string_to_feature(their_feature_string);
+           if (!indexsrv_features)
+               g_printf(_("Bad feature string from server: %s"), their_feature_string);
        }
-       else {
+       if (!indexsrv_features)
            indexsrv_features = am_set_default_feature_set();
-        }
+
        amfree(their_feature_string);
        amfree(line);
     }
@@ -553,7 +594,7 @@ main(
     }
     amfree(line);
 
-    line = vstrallocf("SCNF %s", config_name);
+    line = vstrallocf("SCNF %s", get_config_name());
     if (converse(line) == -1) {
         aclose(server_socket);
        exit(1);
@@ -563,7 +604,7 @@ main(
     if (server_happy()) {
        /* set host we are restoring to this host by default */
        amfree(dump_hostname);
-       set_host(localhost);
+       set_host(starting_hostname);
        if (dump_hostname)
            g_printf(_("Use the setdisk command to choose dump disk to recover\n"));
        else
@@ -805,21 +846,39 @@ stop_amindexd(void)
     }
 }
 
+
 char *
-amindexd_client_get_security_conf(
-    char *     string,
-    void *     arg)
+translate_octal(
+    char *line)
 {
-    (void)arg; /* Quiet unused parameter warning */
+    char *s = line, *s1, *s2;
+    char *p = line;
+    int i;
 
-    if(!string || !*string)
-       return(NULL);
+    if (!translate_mode)
+       return strdup(line);
+
+    while(*s != '\0') {
+       if ((s == line || *(s-1) != '\\') && *s == '\\') {
+           s++;
+           s1 = s+1;
+           s2 = s+2;
+           if (g_ascii_isdigit(*s) && *s1 != '\0' &&
+               g_ascii_isdigit(*s1) &&
+               g_ascii_isdigit(*s2)) {
+               i = ((*s)-'0')*64 + ((*s1)-'0')*8 + ((*s2)-'0');
+               *p++ = i;
+               s += 3;
+           } else {
+               *p++ = *s++;
+           }
 
-    if(strcmp(string, "auth")==0) {
-       return(getconf_str(CNF_AUTH));
-    }
-    else if(strcmp(string, "ssh_keys")==0) {
-       return(getconf_str(CNF_SSH_KEYS));
+       } else {
+           *p++ = *s++;
+       }
     }
-    return(NULL);
+    *p = '\0';
+
+    return line;
 }
+