X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=recover-src%2Famrecover.c;h=b44724d12a4c42ee76f8faa8b54debaf76f442ab;hb=HEAD;hp=f3630b2abc17fd1c2301b0925d257dea70bd0d51;hpb=310f09c0f55a2fb6f3f3746d6ded20099792b773;p=debian%2Famanda diff --git a/recover-src/amrecover.c b/recover-src/amrecover.c index f3630b2..b44724d 100644 --- a/recover-src/amrecover.c +++ b/recover-src/amrecover.c @@ -1,6 +1,7 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-1998, 2000 University of Maryland at College Park + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its @@ -24,23 +25,35 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: amrecover.c,v 1.73.2.2 2007/01/24 18:33:30 martinea Exp $ + * $Id: amrecover.c,v 1.73 2006/07/25 18:27:57 martinea Exp $ * * an interactive program for recovering backed-up files */ #include "amanda.h" -#include "version.h" #include "stream.h" #include "amfeatures.h" #include "amrecover.h" #include "getfsent.h" #include "dgram.h" #include "util.h" -#include "clientconf.h" +#include "conffile.h" #include "protocol.h" #include "event.h" #include "security.h" +#include "conffile.h" +#include "getopt.h" + +#define amrecover_debug(i, ...) do { \ + if ((i) <= debug_amrecover) { \ + dbprintf(__VA_ARGS__); \ + } \ +} 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); @@ -48,17 +61,18 @@ int grab_reply(int show); void sigint_handler(int signum); int main(int argc, char **argv); -#define USAGE "Usage: amrecover [[-C] ] [-s ] [-t ] [-d ] [-o ]*\n" +#define USAGE _("Usage: amrecover [--version] [[-C] ] [-s ] [-t ] [-d ] [-o ]*\n") -char *config = NULL; char *server_name = NULL; int server_socket; 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; @@ -68,6 +82,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; @@ -83,7 +98,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 */ @@ -101,19 +115,28 @@ get_line(void) mesg_buffer = stralloc(""); while (!strstr(mesg_buffer,"\r\n")) { + buf = NULL; size = security_stream_read_sync(streams[MESGFD].fd, &buf); if(size < 0) { + amrecover_debug(1, "amrecover: get_line size < 0 (%zd)\n", size); return -1; } else if(size == 0) { + amrecover_debug(1, "amrecover: get_line size == 0 (%zd)\n", size); + return -1; + } + else if (buf == NULL) { + amrecover_debug(1, "amrecover: get_line buf == NULL\n"); return -1; } + amrecover_debug(1, "amrecover: get_line size = %zd\n", size); newbuf = alloc(strlen(mesg_buffer)+size+1); strncpy(newbuf, mesg_buffer, (size_t)(strlen(mesg_buffer) + size)); memcpy(newbuf+strlen(mesg_buffer), buf, (size_t)size); newbuf[strlen(mesg_buffer)+size] = '\0'; amfree(mesg_buffer); mesg_buffer = newbuf; + amfree(buf); } s = strstr(mesg_buffer,"\r\n"); @@ -122,6 +145,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; } @@ -131,6 +156,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) @@ -139,7 +166,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); @@ -194,6 +223,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; } @@ -250,7 +280,7 @@ sigint_handler( } -void +char * clean_pathname( char * s) { @@ -268,6 +298,8 @@ clean_pathname( /* remove "/." at end of path */ if(strcmp(&(s[length-2]),"/.")==0) s[length-2]='\0'; + + return s; } @@ -279,8 +311,6 @@ quit(void) stop_amindexd(); } -char *localhost = NULL; - #ifdef DEFAULT_TAPE_SERVER # define DEFAULT_TAPE_SERVER_FAILOVER (DEFAULT_TAPE_SERVER) #else @@ -299,13 +329,21 @@ main( extern char *optarg; extern int optind; char *line = NULL; - char *conffile; const security_driver_t *secdrv; char *req = NULL; int response_error; - int new_argc; - char **new_argv; struct tm *tm; + config_overrides_t *cfg_ovr; + char *starting_hostname = 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(-1, 0); @@ -316,149 +354,154 @@ main( dbopen(DBG_SUBDIR_CLIENT); -#ifndef IGNORE_UID_CHECK - if (geteuid() != 0) { - erroutput_type |= ERR_SYSLOG; - error("amrecover must be run by root"); - /*NOTREACHED*/ - } -#endif - - 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'; - - parse_client_conf(argc, argv, &new_argc, &new_argv); + /* treat amrecover-specific command line options as the equivalent + * -o command-line options to set configuration values */ + cfg_ovr = new_config_overrides(argc/2); - if (new_argc > 1 && new_argv[1][0] != '-') { - /* - * 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. - */ - char **new_argv1; + /* 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_override(cfg_ovr, "conf", argv[1]); - new_argv1 = (char **) alloc((size_t)((new_argc + 1 + 1) * sizeof(*new_argv1))); - new_argv1[0] = new_argv[0]; - new_argv1[1] = "-C"; - for (i = 1; i < new_argc; i++) { - new_argv1[i + 1] = new_argv[i]; - } - new_argv1[i + 1] = NULL; - new_argc++; - amfree(new_argv); - new_argv = new_argv1; + /* remove that option from the command line */ + argv[1] = argv[0]; + argv++; argc--; } - while ((i = getopt(new_argc, new_argv, "C:s:t:d:U")) != EOF) { + + /* now parse regular command-line '-' options */ + 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_client_conf(CLN_CONF, optarg); + add_config_override(cfg_ovr, "conf", optarg); break; case 's': - add_client_conf(CLN_INDEX_SERVER, optarg); + add_config_override(cfg_ovr, "index_server", optarg); break; case 't': - add_client_conf(CLN_TAPE_SERVER, optarg); + add_config_override(cfg_ovr, "tape_server", optarg); break; case 'd': - add_client_conf(CLN_TAPEDEV, optarg); + add_config_override(cfg_ovr, "tapedev", optarg); + break; + + case 'o': + add_config_override_opt(cfg_ovr, optarg); + break; + + case 'h': + starting_hostname = g_strdup(optarg); break; case 'U': case '?': - (void)printf(USAGE); + (void)g_printf(USAGE); return 0; } } - if (optind != new_argc) { - (void)fprintf(stderr, USAGE); + if (optind != argc) { + (void)g_fprintf(stderr, USAGE); exit(1); } - our_features = am_init_feature_set(); - our_features_string = am_feature_to_string(our_features); + /* load the base client configuration */ + set_config_overrides(cfg_ovr); + config_init(CONFIG_INIT_CLIENT, NULL); - conffile = vstralloc(CONFIG_DIR, "/", "amanda-client.conf", NULL); - if (read_clientconf(conffile) > 0) { - error("error reading conffile: %s", conffile); - /*NOTREACHED*/ + if (config_errors(NULL) >= CFGERR_WARNINGS) { + config_print_errors(); + if (config_errors(NULL) >= CFGERR_ERRORS) { + g_critical(_("errors processing config file")); + } } - amfree(conffile); - config = stralloc(client_getconf_str(CLN_CONF)); + /* and now try to load the configuration named in that file */ + config_init(CONFIG_INIT_CLIENT | CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_OVERLAY, + getconf_str(CNF_CONF)); - conffile = vstralloc(CONFIG_DIR, "/", config, "/", "amanda-client.conf", - NULL); - if (read_clientconf(conffile) > 0) { - error("error reading conffile: %s", conffile); - /*NOTREACHED*/ - } - amfree(conffile); + check_running_as(RUNNING_AS_ROOT); - dbrename(config, DBG_SUBDIR_CLIENT); + dbrename(get_config_name(), DBG_SUBDIR_CLIENT); - report_bad_client_arg(); + 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 (client_getconf_seen(CLN_INDEX_SERVER) == -2) { /* command line argument */ - server_name = client_getconf_str(CLN_INDEX_SERVER); + if (getconf_seen(CNF_INDEX_SERVER) == -2) { /* command line argument */ + server_name = getconf_str(CNF_INDEX_SERVER); } if (!server_name) { server_name = getenv("AMANDA_SERVER"); if (server_name) { - printf("Using index server from environment AMANDA_SERVER (%s)\n", server_name); + g_printf(_("Using index server from environment AMANDA_SERVER (%s)\n"), server_name); } } if (!server_name) { - server_name = client_getconf_str(CLN_INDEX_SERVER); + server_name = getconf_str(CNF_INDEX_SERVER); } if (!server_name) { - error("No index server set"); + error(_("No index server set")); /*NOTREACHED*/ } server_name = stralloc(server_name); tape_server_name = NULL; - if (client_getconf_seen(CLN_TAPE_SERVER) == -2) { /* command line argument */ - tape_server_name = client_getconf_str(CLN_TAPE_SERVER); + if (getconf_seen(CNF_TAPE_SERVER) == -2) { /* command line argument */ + tape_server_name = getconf_str(CNF_TAPE_SERVER); } if (!tape_server_name) { tape_server_name = getenv("AMANDA_TAPE_SERVER"); if (!tape_server_name) { tape_server_name = getenv("AMANDA_TAPESERVER"); if (tape_server_name) { - printf("Using tape server from environment AMANDA_TAPESERVER (%s)\n", tape_server_name); + g_printf(_("Using tape server from environment AMANDA_TAPESERVER (%s)\n"), tape_server_name); } } else { - printf("Using tape server from environment AMANDA_TAPE_SERVER (%s)\n", tape_server_name); + g_printf(_("Using tape server from environment AMANDA_TAPE_SERVER (%s)\n"), tape_server_name); } } if (!tape_server_name) { - tape_server_name = client_getconf_str(CLN_TAPE_SERVER); + tape_server_name = getconf_str(CNF_TAPE_SERVER); } if (!tape_server_name) { - error("No tape server set"); + error(_("No tape server set")); /*NOTREACHED*/ } tape_server_name = stralloc(tape_server_name); amfree(tape_device_name); - tape_device_name = client_getconf_str(CLN_TAPEDEV); - if (tape_device_name) + tape_device_name = getconf_str(CNF_TAPEDEV); + if (!tape_device_name || + strlen(tape_device_name) == 0 || + !getconf_seen(CNF_TAPEDEV)) { + tape_device_name = NULL; + } else { tape_device_name = stralloc(tape_device_name); + } - authopt = stralloc(client_getconf_str(CLN_AUTH)); + authopt = stralloc(getconf_str(CNF_AUTH)); amfree(disk_name); amfree(mount_point); amfree(disk_path); + amfree(disk_tpath); dump_date[0] = '\0'; /* Don't die when child closes pipe */ @@ -469,51 +512,42 @@ main( sigemptyset(&act.sa_mask); act.sa_flags = 0; if (sigaction(SIGINT, &act, &oact) != 0) { - error("error setting signal handler: %s", strerror(errno)); + error(_("error setting signal handler: %s"), strerror(errno)); /*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 */ /* and fe_amindexd_options_auth */ /* We should send a noop to really know */ - req = vstralloc("SERVICE amindexd\n", - "OPTIONS ", "features=", our_features_string, ";", - "auth=", authopt, ";", - "\n", NULL); + req = vstrallocf("SERVICE amindexd\n" + "OPTIONS features=%s;auth=%s;\n", + our_features_string, authopt); secdrv = security_getdriver(authopt); if (secdrv == NULL) { - error("no '%s' security driver available for host '%s'", + error(_("no '%s' security driver available for host '%s'"), authopt, server_name); /*NOTREACHED*/ } - protocol_sendreq(server_name, secdrv, amindexd_client_get_security_conf, + protocol_sendreq(server_name, secdrv, generic_client_get_security_conf, req, STARTUP_TIMEOUT, amindexd_response, &response_error); amfree(req); protocol_run(); - printf("AMRECOVER Version %s. Contacting server on %s ...\n", - version(), server_name); + g_printf(_("AMRECOVER Version %s. Contacting server on %s ...\n"), + VERSION, server_name); if(response_error != 0) { - fprintf(stderr,"%s\n",errstr); + g_fprintf(stderr,"%s\n",errstr); exit(1); } -#if 0 - /* - * We may need root privilege again later for a reserved port to - * the tape server, so we will drop down now but might have to - * come back later. - */ - setegid(getgid()); - seteuid(getuid()); -#endif - /* get server's banner */ if (grab_reply(1) == -1) { aclose(server_socket); @@ -529,14 +563,18 @@ main( { char *their_feature_string = NULL; - line = stralloc2("FEATURES ", our_features_string); + 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); } @@ -547,17 +585,17 @@ main( if (tm) strftime(dump_date, sizeof(dump_date), "%Y-%m-%d", tm); else - error("BAD DATE"); + error(_("BAD DATE")); - printf("Setting restore date to today (%s)\n", dump_date); - line = stralloc2("DATE ", dump_date); + g_printf(_("Setting restore date to today (%s)\n"), dump_date); + line = vstrallocf("DATE %s", dump_date); if (converse(line) == -1) { aclose(server_socket); exit(1); } amfree(line); - line = stralloc2("SCNF ", config); + line = vstrallocf("SCNF %s", get_config_name()); if (converse(line) == -1) { aclose(server_socket); exit(1); @@ -567,11 +605,11 @@ 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) - printf("Use the setdisk command to choose dump disk to recover\n"); + g_printf(_("Use the setdisk command to choose dump disk to recover\n")); else - printf("Use the sethost command to choose a host to recover\n"); + g_printf(_("Use the sethost command to choose a host to recover\n")); } @@ -585,6 +623,7 @@ main( if (lineread[0] != '\0') { add_history(lineread); + dbprintf(_("user command: '%s'\n"), lineread); process_line(lineread); /* act on line's content */ } amfree(lineread); @@ -611,15 +650,15 @@ amindexd_response( assert(sech != NULL); if (pkt == NULL) { - errstr = newvstralloc(errstr, "[request failed: ", - security_geterror(sech), "]", NULL); + errstr = newvstrallocf(errstr, _("[request failed: %s]"), + security_geterror(sech)); *response_error = 1; return; } if (pkt->type == P_NAK) { #if defined(PACKET_DEBUG) - fprintf(stderr, "got nak response:\n----\n%s\n----\n\n", pkt->body); + dbprintf(_("got nak response:\n----\n%s\n----\n\n"), pkt->body); #endif tok = strtok(pkt->body, " "); @@ -628,25 +667,25 @@ amindexd_response( tok = strtok(NULL, "\n"); if (tok != NULL) { - errstr = newvstralloc(errstr, "NAK: ", tok, NULL); + errstr = newvstrallocf(errstr, "NAK: %s", tok); *response_error = 1; } else { bad_nak: - errstr = newstralloc(errstr, "request NAK"); + errstr = newvstrallocf(errstr, _("request NAK")); *response_error = 2; } return; } if (pkt->type != P_REP) { - errstr = newvstralloc(errstr, "received strange packet type ", - pkt_type2str(pkt->type), ": ", pkt->body, NULL); + errstr = newvstrallocf(errstr, _("received strange packet type %s: %s"), + pkt_type2str(pkt->type), pkt->body); *response_error = 1; return; } #if defined(PACKET_DEBUG) - fprintf(stderr, "got response:\n----\n%s\n----\n\n", pkt->body); + g_fprintf(stderr, _("got response:\n----\n%s\n----\n\n"), pkt->body); #endif for(i = 0; i < NSTREAMS; i++) { @@ -664,9 +703,11 @@ bad_nak: */ if (strcmp(tok, "ERROR") == 0) { tok = strtok(NULL, "\n"); - if (tok == NULL) - tok = "[bogus error packet]"; - errstr = newstralloc(errstr, tok); + if (tok == NULL) { + errstr = newvstrallocf(errstr, _("[bogus error packet]")); + } else { + errstr = newvstrallocf(errstr, "%s", tok); + } *response_error = 2; return; } @@ -683,22 +724,16 @@ bad_nak: for (i = 0; i < NSTREAMS; i++) { tok = strtok(NULL, " "); if (tok == NULL || strcmp(tok, streams[i].name) != 0) { - extra = vstralloc("CONNECT token is \"", - tok ? tok : "(null)", - "\": expected \"", - streams[i].name, - "\"", - NULL); + extra = vstrallocf( + _("CONNECT token is \"%s\": expected \"%s\""), + tok ? tok : _("(null)"), streams[i].name); goto parse_error; } tok = strtok(NULL, " \n"); if (tok == NULL || sscanf(tok, "%d", &ports[i]) != 1) { - extra = vstralloc("CONNECT ", - streams[i].name, - " token is \"", - tok ? tok : "(null)", - "\": expected a port number", - NULL); + extra = vstrallocf( + _("CONNECT %s token is \"%s\" expected a port number"), + streams[i].name, tok ? tok : _("(null)")); goto parse_error; } } @@ -711,38 +746,32 @@ bad_nak: if (strcmp(tok, "OPTIONS") == 0) { tok = strtok(NULL, "\n"); if (tok == NULL) { - extra = stralloc("OPTIONS token is missing"); + extra = vstrallocf(_("OPTIONS token is missing")); goto parse_error; } -/* +#if 0 tok_end = tok + strlen(tok); while((p = strchr(tok, ';')) != NULL) { *p++ = '\0'; -#define sc "features=" - if(strncmp(tok, sc, sizeof(sc)-1) == 0) { - tok += sizeof(sc) - 1; -#undef sc + if(strncmp_const(tok, "features=") == 0) { + tok += SIZEOF("features=") - 1; am_release_feature_set(their_features); if((their_features = am_string_to_feature(tok)) == NULL) { - errstr = newvstralloc(errstr, - "OPTIONS: bad features value: ", - tok, - NULL); + errstr = newvstrallocf(errstr, + _("OPTIONS: bad features value: %s"), + tok); goto parse_error; } } tok = p; } -*/ +#endif continue; } -/* - extra = vstralloc("next token is \"", - tok ? tok : "(null)", - "\": expected \"CONNECT\", \"ERROR\" or \"OPTIONS\"", - NULL); +#if 0 + extra = vstrallocf(_("next token is \"%s\": expected \"CONNECT\", \"ERROR\" or \"OPTIONS\""), tok ? tok : _("(null)")); goto parse_error; -*/ +#endif } /* @@ -753,9 +782,9 @@ bad_nak: continue; streams[i].fd = security_stream_client(sech, ports[i]); if (streams[i].fd == NULL) { - errstr = newvstralloc(errstr, - "[could not connect ", streams[i].name, " stream: ", - security_geterror(sech), "]", NULL); + errstr = newvstrallocf(errstr, + _("[could not connect %s stream: %s]"), + streams[i].name, security_geterror(sech)); goto connect_error; } } @@ -766,9 +795,9 @@ bad_nak: if (streams[i].fd == NULL) continue; if (security_stream_auth(streams[i].fd) < 0) { - errstr = newvstralloc(errstr, - "[could not authenticate ", streams[i].name, " stream: ", - security_stream_geterror(streams[i].fd), "]", NULL); + errstr = newvstrallocf(errstr, + _("[could not authenticate %s stream: %s]"), + streams[i].name, security_stream_geterror(streams[i].fd)); goto connect_error; } } @@ -778,7 +807,7 @@ bad_nak: * them, complain. */ if (streams[MESGFD].fd == NULL) { - errstr = newstralloc(errstr, "[couldn't open MESG streams]"); + errstr = newvstrallocf(errstr, _("[couldn't open MESG streams]")); goto connect_error; } @@ -788,11 +817,9 @@ bad_nak: return; parse_error: - errstr = newvstralloc(errstr, - "[parse of reply message failed: ", - extra ? extra : "(no additional information)", - "]", - NULL); + errstr = newvstrallocf(errstr, + _("[parse of reply message failed: %s]"), + extra ? extra : _("(no additional information)")); amfree(extra); *response_error = 2; return; @@ -820,21 +847,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(client_getconf_str(CLN_AUTH)); - } - else if(strcmp(string, "ssh_keys")==0) { - return(client_getconf_str(CLN_SSH_KEYS)); + } else { + *p++ = *s++; + } } - return(NULL); + *p = '\0'; + + return line; } +