Imported Upstream version 3.3.1
[debian/amanda] / recover-src / set_commands.c
1 /*
2  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3  * Copyright (c) 1991-1998, 2000 University of Maryland at College Park
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of U.M. not be used in advertising or
11  * publicity pertaining to distribution of the software without specific,
12  * written prior permission.  U.M. makes no representations about the
13  * suitability of this software for any purpose.  It is provided "as is"
14  * without express or implied warranty.
15  *
16  * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Authors: the Amanda Development Team.  Its members are listed in a
24  * file named AUTHORS, in the root directory of this distribution.
25  */
26 /*
27  * $Id: set_commands.c,v 1.26 2006/07/05 13:14:58 martinea Exp $
28  *
29  * implements the "set" commands in amrecover
30  */
31
32 #include "amanda.h"
33 #include "match.h"
34 #include "util.h"
35 #include "amrecover.h"
36 #include "amxml.h"
37
38 extern unsigned short samba_extract_method;
39
40 /* sets a date, mapping given date into standard form if needed */
41 int
42 set_date(
43     char *      date)
44 {
45     char *cmd = NULL;
46     char *qdisk_path;
47
48     clear_dir_list();
49
50     cmd = stralloc2("DATE ", date);
51     if (converse(cmd) == -1)
52         exit(1);
53
54     /* if a host/disk/directory is set, then check if that directory
55        is still valid at the new date, and if not set directory to
56        mount_point */
57     if (disk_path != NULL) {
58         qdisk_path = quote_string(disk_path);
59         cmd = newstralloc2(cmd, "OISD ", qdisk_path);
60         amfree(qdisk_path);
61         if (exchange(cmd) == -1)
62             exit(1);
63         if (server_happy())
64         {
65             suck_dir_list_from_server();
66         }
67         else
68         {
69             g_printf(_("No index records for cwd on new date\n"));
70             g_printf(_("Setting cwd to mount point\n"));
71             disk_path = newstralloc(disk_path, "/");    /* fake it */
72             disk_tpath = newstralloc(disk_tpath, "/");  /* fake it */
73             clear_dir_list();
74         }
75     }
76     amfree(cmd);
77     return 0;
78 }
79
80
81 void
82 set_host(
83     const char *host)
84 {
85     char *cmd = NULL;
86     struct hostent *hp = NULL;
87     char **hostp;
88     int found_host = 0;
89     char *uqhost = unquote_string(host);
90
91     if (is_extract_list_nonempty())
92     {
93         g_printf(_("Must clear extract list before changing host\n"));
94         amfree(uqhost);
95         return;
96     }
97
98     /*
99      * The idea here is to try as many permutations of the hostname
100      * as we can imagine.  The server will reject anything it doesn't
101      * recognize.
102      */
103
104     cmd = stralloc2("HOST ", uqhost);
105     if (converse(cmd) == -1)
106         exit(1);
107     if (server_happy())
108         found_host = 1;
109
110     /*
111      * Try converting the given host to a fully qualified, canonical
112      * name.
113      */
114     if (!found_host) {
115         if ((hp = gethostbyname(uqhost)) != NULL) {
116             host = hp->h_name;
117             g_printf(_("Trying host %s ...\n"), host);
118             cmd = newstralloc2(cmd, "HOST ", host);
119             if (converse(cmd) == -1)
120                 exit(1);
121             if(server_happy())
122                 found_host = 1;
123         }
124     }
125
126     /*
127      * Since we have them, try any CNAMEs that were traversed from uqhost
128      * to the canonical name (this assumes gethostbyname was called above)
129      */
130     if (!found_host) {
131         if (hp) {
132             for (hostp = hp->h_aliases; (host = *hostp) != NULL; hostp++)
133             {
134                 g_printf(_("Trying host %s ...\n"), host);
135                 cmd = newstralloc2(cmd, "HOST ", host);
136                 if (converse(cmd) == -1)
137                     exit(1);
138                 if(server_happy())
139                 {
140                     found_host = 1;
141                     break;
142                 }
143             }
144         }
145     }
146
147     /* Try looking up the canonical name of the host */
148     if (!found_host) {
149         char *canonname;
150         int result;
151
152         result = resolve_hostname(uqhost, 0, NULL, &canonname);
153         if (result == 0 && canonname) {
154             host = canonname;
155             g_printf(_("Trying host %s ...\n"), host);
156             cmd = newstralloc2(cmd, "HOST ", host);
157             if (converse(cmd) == -1)
158                 exit(1);
159             if(server_happy())
160                 found_host = 1;
161         }
162     }
163
164     if(found_host) {
165         dump_hostname = newstralloc(dump_hostname, host);
166         amfree(disk_name);
167         amfree(mount_point);
168         amfree(disk_path);
169         amfree(disk_tpath);
170         clear_dir_list();
171     }
172     amfree(cmd);
173     amfree(uqhost);
174 }
175
176 void
177 list_host(void)
178 {
179     char *cmd = NULL;
180
181     cmd = stralloc("LISTHOST");
182     if (converse(cmd) == -1)
183         exit(1);
184     amfree(cmd);
185 }
186
187 void
188 set_disk(
189     char *      dsk,
190     char *      mtpt)
191 {
192     char *cmd = NULL;
193     char *qdsk;
194     char *uqdsk;
195     char *uqmtpt = NULL;
196
197     if (is_extract_list_nonempty())
198     {
199         g_printf(_("Must clear extract list before changing disk\n"));
200         return;
201     }
202
203     /* if mount point specified, check it is valid */
204     if (mtpt != NULL) {
205         uqmtpt = unquote_string(mtpt);
206         if (*mtpt != '/') {
207             g_printf(_("Mount point \"%s\" invalid - must start with /\n"), uqmtpt);
208             amfree(uqmtpt);
209             return;
210         }
211     }
212
213     clear_dir_list();
214     uqdsk = unquote_string(dsk);
215     qdsk = quote_string(uqdsk);
216     cmd = stralloc2("DISK ", qdsk);
217     amfree(qdsk);
218     if (converse(cmd) == -1)
219         exit(1);
220     amfree(cmd);
221
222     if (!server_happy()) {
223         amfree(uqmtpt);
224         amfree(uqdsk);
225         return;
226     }
227
228     disk_name = newstralloc(disk_name, uqdsk);
229     if (mtpt == NULL)
230     {
231         /* mount point not specified */
232         if (*uqdsk == '/')
233         {
234             /* disk specified by mount point, hence use it */
235             mount_point = newstralloc(mount_point, uqdsk);
236         }
237         else
238         {
239             /* device name given, use '/' because nothing better */
240             mount_point = newstralloc(mount_point, "/");
241         }
242     }
243     else
244     {
245         /* mount point specified */
246         mount_point = newstralloc(mount_point, uqmtpt);
247     }
248
249     /* set the working directory to the mount point */
250     /* there is the possibility that there are no index records for the
251        disk for the given date, hence setting the directory to the
252        mount point will fail. Preempt this by checking first so we can write
253        a more informative message. */
254     if (exchange("OISD /") == -1)
255         exit(1);
256     if (server_happy())
257     {
258         disk_path = newstralloc(disk_path, "/");
259         disk_tpath = newstralloc(disk_tpath, "/");
260         suck_dir_list_from_server();    /* get list of directory contents */
261     }
262     else
263     {
264         g_printf(_("No index records for disk for specified date\n"));
265         g_printf(_("If date correct, notify system administrator\n"));
266         disk_path = newstralloc(disk_path, "/");        /* fake it */
267         disk_tpath = newstralloc(disk_tpath, "/");      /* fake it */
268         clear_dir_list();
269     }
270     amfree(uqmtpt);
271     amfree(uqdsk);
272
273     if (am_has_feature(indexsrv_features, fe_amindexd_DLE)) {
274         char *dle_str;
275         char *errmsg = NULL;
276
277         cmd = stralloc("DLE");
278         if (exchange(cmd) == -1)
279             exit(1);
280         amfree(cmd);
281
282         if (!server_happy())
283             return;
284
285         dle_str = reply_line();
286         if (BSTRNCMP(dle_str+4, "NODLE") == 0) {
287             dump_dle = NULL;
288         } else {
289             dle_str = unquote_string(dle_str+4);
290             dump_dle = amxml_parse_node_CHAR(dle_str, &errmsg);
291             amfree(dle_str);
292         }
293     }
294 }
295
296 void
297 list_disk(
298     char *      amdevice)
299 {
300     char *cmd = NULL;
301     char *qamdevice, *uqamdevice;
302
303     if(amdevice) {
304         uqamdevice = unquote_string(amdevice);
305         qamdevice = quote_string(uqamdevice);
306         cmd = stralloc2("LISTDISK ", qamdevice);
307         amfree(uqamdevice);
308         amfree(qamdevice);
309         if (converse(cmd) == -1)
310             exit(1);
311         amfree(cmd);
312     }
313     else {
314         cmd = stralloc("LISTDISK");
315         if (converse(cmd) == -1)
316             exit(1);
317         amfree(cmd);
318     }
319 }
320
321 static GSList *prop_values = NULL;
322
323 void
324 set_property_name(
325     char *name,
326     int   append)
327 {
328     property_t *prop;
329     char       *property_name, *pn;
330
331     pn = unquote_string(name);
332     property_name = amandaify_property_name(pn);
333     amfree(pn);
334
335     if (!append) {
336         g_hash_table_remove(proplist, property_name);
337         prop = NULL;
338     } else {
339         prop = g_hash_table_lookup(proplist, property_name);
340     }
341     
342     if (!prop) {
343         prop = malloc(sizeof(property_t));
344         prop->append = 0;
345         prop->priority = 1;
346         prop->values = NULL;
347         g_hash_table_insert(proplist, stralloc(property_name), prop);
348     }
349
350     /* add prop_values to prop->values */
351     if (!prop->values) {
352         prop->values = prop_values;
353         prop_values = NULL;
354     } else {
355         GSList *pv;
356
357         for(pv = prop_values; pv != NULL; pv = pv->next) {
358             prop->values = g_slist_append(prop->values, pv->data);
359         }
360         g_slist_free(prop_values);
361         prop_values = NULL;
362     }
363     amfree(property_name);
364 }
365
366 void
367 add_property_value(
368     char *value)
369 {
370     if (value) {
371         prop_values = g_slist_prepend(prop_values, unquote_string(value));
372     }
373 }
374
375 /* A GHFunc (callback for g_hash_table_foreach) */
376 static void list_one_property(
377     gpointer key_p,
378     gpointer value_p,
379     gpointer user_data_p G_GNUC_UNUSED)
380 {
381     char       *property_s = key_p;
382     char       *qproperty;
383     property_t *property = value_p;
384     GSList     *value;
385     char       *qvalue;
386
387     qproperty = quote_string_always(property_s);
388     printf("property %s", qproperty);
389     amfree(qproperty);
390     for (value = property->values; value != NULL; value = value->next) {
391         qvalue = quote_string_always((char*)value->data);
392         printf(" %s", qvalue);
393         amfree(qvalue);
394     }
395     printf("\n");
396 }
397
398 void
399 list_property(void)
400 {
401     if (proplist) {
402         g_hash_table_foreach(proplist, list_one_property, NULL);
403     } else {
404         printf("No property set\n");
405     }
406 }
407
408 void
409 local_cd(
410     char *dir)
411 {
412     char *uqdir = unquote_string(dir);
413     if (chdir(uqdir) == -1) {
414         perror(uqdir);
415     }
416     amfree(uqdir);
417 }
418
419 int
420 cd_glob(
421     char *      glob,
422     int         verbose)
423 {
424     char *regex;
425     char *regex_path;
426     char *s;
427     char *uqglob;
428     int   result;
429
430     char *tpath_on_disk = NULL;
431
432     if (disk_name == NULL) {
433         g_printf(_("Must select disk before changing directory\n"));
434         return 0;
435     }
436
437     uqglob = unquote_string(glob);
438     regex = glob_to_regex(uqglob);
439     dbprintf(_("cd_glob (%s) -> %s\n"), uqglob, regex);
440     if ((s = validate_regexp(regex)) != NULL) {
441         g_printf(_("\"%s\" is not a valid shell wildcard pattern: "), glob);
442         puts(s);
443         amfree(regex);
444         amfree(uqglob);
445         return 0;
446     }
447     /*
448      * glob_to_regex() anchors the beginning of the pattern with ^,
449      * but we will be tacking it onto the end of the current directory
450      * in add_file, so strip that off.  Also, it anchors the end with
451      * $, but we need to match a trailing /, add it if it is not there
452      */
453     regex_path = stralloc(regex + 1);
454     amfree(regex);
455     if(regex_path[strlen(regex_path) - 2] != '/' ) {
456         regex_path[strlen(regex_path) - 1] = '\0';
457         strappend(regex_path, "/$");
458     }
459
460     /* convert path (assumed in cwd) to one on disk */
461     if (strcmp(disk_path, "/") == 0)
462         tpath_on_disk = stralloc2("/", regex_path);
463     else {
464         char *clean_disk_tpath = clean_regex(disk_tpath, 0);
465         tpath_on_disk = vstralloc(clean_disk_tpath, "/", regex_path, NULL);
466         amfree(clean_disk_tpath);
467     }
468
469     result = cd_dir(tpath_on_disk, uqglob, verbose);
470
471     amfree(regex_path);
472     amfree(tpath_on_disk);
473     amfree(uqglob);
474
475     return result;
476 }
477
478 int
479 cd_regex(
480     char *      regex,
481     int         verbose)
482 {
483     char *s;
484     char *uq_orig_regex;
485     char *uqregex;
486     int  len_uqregex;
487     int  result;
488
489     char *tpath_on_disk = NULL;
490
491     if (disk_name == NULL) {
492         g_printf(_("Must select disk before changing directory\n"));
493         return 0;
494     }
495
496     uq_orig_regex = unquote_string(regex);
497     uqregex = stralloc(uq_orig_regex);
498
499     /* Add a terminating '/' if it is not there, maybe before a '$' */
500     len_uqregex = strlen(uqregex);
501     if (uqregex[len_uqregex-1] == '$') {
502         if (uqregex[len_uqregex-2] != '/') {
503             uqregex[len_uqregex-1] = '\0';
504             strappend(uqregex, "/$");
505         }
506     } else if (uqregex[len_uqregex-1] != '/') {
507         //uqregex[len_uqregex-1] = '\0';
508         strappend(uqregex, "/");
509     }
510     if ((s = validate_regexp(uqregex)) != NULL) {
511         g_printf(_("\"%s\" is not a valid regular expression: "), uq_orig_regex);
512         amfree(uqregex);
513         amfree(uq_orig_regex);
514         puts(s);
515         return 0;
516     }
517
518     /* convert path (assumed in cwd) to one on disk */
519     if (strcmp(disk_path, "/") == 0)
520         tpath_on_disk = stralloc2("/", uqregex);
521     else {
522         char *clean_disk_tpath = clean_regex(disk_tpath, 0);
523         tpath_on_disk = vstralloc(clean_disk_tpath, "/", regex, NULL);
524         amfree(clean_disk_tpath);
525     }
526
527     result = cd_dir(tpath_on_disk, uq_orig_regex, verbose);
528
529     amfree(tpath_on_disk);
530     amfree(uqregex);
531     amfree(uq_orig_regex);
532
533     return result;
534 }
535
536 int
537 cd_dir(
538     char *tpath_on_disk,
539     char *default_dir,
540     int   verbose)
541 {
542     char *dir = NULL;
543     char *s;
544     int nb_found;
545     int result;
546     size_t i;
547
548     DIR_ITEM *ditem;
549
550     if ((s = validate_regexp(tpath_on_disk)) != NULL) {
551         result = set_directory(default_dir, verbose);
552         return result;
553     }
554
555     nb_found = 0;
556
557     for (ditem=get_dir_list(); ditem!=NULL && nb_found <= 1; 
558                                ditem=get_next_dir_item(ditem))
559     {
560         if (match(tpath_on_disk, ditem->tpath))
561         {
562             i = strlen(ditem->tpath);
563             if((i > 0 && ditem->tpath[i-1] == '/')
564                || (i > 1 && ditem->tpath[i-2] == '/' && ditem->tpath[i-1] == '.'))
565             {   /* It is a directory */
566                 char *dir1, *dir2;
567                 nb_found++;
568                 dir = newstralloc(dir,ditem->path);
569                 if(dir[strlen(dir)-1] == '/')
570                     dir[strlen(dir)-1] = '\0'; /* remove last / */
571                 /* remove everything before the last / */
572                 dir1 = strrchr(dir,'/');
573                 if (dir1) {
574                     dir1++;
575                     dir2 = stralloc(dir1);
576                     amfree(dir);
577                     dir = dir2;
578                 }
579             }
580         }
581     }
582
583     if(nb_found==0) {
584         result = set_directory(default_dir, verbose);
585     }
586     else if(nb_found==1) {
587         result = set_directory(dir, verbose);
588     }
589     else {
590         g_printf(_("Too many directories matching '%s'\n"), default_dir);
591         result = 0;
592     }
593     amfree(dir);
594     return result;
595 }
596
597 /* dir is relative to dir_path or absolute with mount_point */
598 int
599 set_directory(
600     char *      dir,
601     int         verbose)
602 {
603     char *cmd = NULL;
604     char *new_dir = NULL;
605     char *qnew_dir;
606     char *dp, *de;
607     char *ldir = NULL;
608     int   result;
609
610     /* do nothing if "." */
611     if(strcmp(dir,".")==0) {
612         show_directory();               /* say where we are */
613         return 1;
614         /*NOTREACHED*/
615     }
616
617     if (disk_name == NULL) {
618         g_printf(_("Must select disk before setting directory\n"));
619         return 0;
620         /*NOTREACHED*/
621     }
622
623     ldir = stralloc(dir);
624     clean_pathname(ldir);
625
626     /* convert directory into absolute path relative to disk mount point */
627     if (ldir[0] == '/')
628     {
629         /* absolute path specified, must start with mount point */
630         if (strcmp(mount_point, "/") == 0)
631         {
632             new_dir = stralloc(ldir);
633         }
634         else
635         {
636             if (strncmp(mount_point, ldir, strlen(mount_point)) != 0)
637             {
638                 g_printf(_("Invalid directory - Can't cd outside mount point \"%s\"\n"),
639                        mount_point);
640                 amfree(ldir);
641                 return 0;
642                 /*NOTREACHED*/
643             }
644             new_dir = stralloc(ldir+strlen(mount_point));
645             if (strlen(new_dir) == 0) {
646                 new_dir = newstralloc(new_dir, "/");
647                                         /* i.e. ldir == mount_point */
648             }
649         }
650     }
651     else
652     {
653         new_dir = stralloc(disk_path);
654         dp = ldir;
655         /* strip any leading ..s */
656         while (strncmp(dp, "../", 3) == 0)
657         {
658             de = strrchr(new_dir, '/'); /* always at least 1 */
659             if (de == new_dir)
660             {
661                 /* at top of disk */
662                 *(de + 1) = '\0';
663                 dp = dp + 3;
664             }
665             else
666             {
667                 *de = '\0';
668                 dp = dp + 3;
669             }
670         }
671         if (strcmp(dp, "..") == 0) {
672             if (strcmp(new_dir, "/") == 0) {
673                 /* at top of disk */
674                 g_printf(_("Invalid directory - Can't cd outside mount point \"%s\"\n"),
675                        mount_point);
676                 /*@ignore@*/
677                 amfree(new_dir);
678                 /*@end@*/
679                 amfree(ldir);
680                 return 0;
681                 /*NOTREACHED*/
682             }
683             de = strrchr(new_dir, '/'); /* always at least 1 */
684             if (de == new_dir)
685             {
686                 /* at top of disk */
687                 *(de+1) = '\0';
688             }
689             else
690             {
691                 *de = '\0';
692             }
693         } else {
694             /*@ignore@*/
695             if (strcmp(new_dir, "/") != 0) {
696                 strappend(new_dir, "/");
697             }
698             strappend(new_dir, ldir);
699             /*@end@*/
700         }
701     }
702
703     qnew_dir = quote_string(new_dir);
704     cmd = stralloc2("OISD ", qnew_dir);
705     amfree(qnew_dir);
706     if (exchange(cmd) == -1) {
707         exit(1);
708         /*NOTREACHED*/
709     }
710     amfree(cmd);
711
712     if (server_happy())
713     {
714         disk_path = newstralloc(disk_path, new_dir);
715         g_free(disk_tpath);
716         disk_tpath = translate_octal(g_strdup(disk_path));
717         suck_dir_list_from_server();    /* get list of directory contents */
718         if (verbose)
719             show_directory();           /* say where we moved to */
720         result = 1;
721     }
722     else
723     {
724         g_printf(_("Invalid directory - %s\n"), dir);
725         result = 0;
726     }
727
728     /*@ignore@*/
729     amfree(new_dir);
730     amfree(ldir);
731     /*@end@*/
732
733     return result;
734 }
735
736
737 /* prints the current working directory */
738 void
739 show_directory(void)
740 {
741     if (mount_point == NULL || disk_path == NULL)
742         g_printf(_("Must select disk first\n"));
743     else if (strcmp(mount_point, "/") == 0)
744         g_printf("%s\n", disk_tpath);
745     else if (strcmp(disk_path, "/") == 0)
746         g_printf("%s\n", mount_point);
747     else
748         g_printf("%s%s\n", mount_point, disk_tpath);
749 }
750
751
752 /* set the tape server and device (deprecated version) */
753 void
754 set_tape(
755     char *      tape)
756 {
757     char *uqtape = unquote_string(tape);
758     char *tapedev = strchr(uqtape, ':');
759     char *host = NULL;
760
761     g_printf(_("NOTE: 'settape' is deprecated; use setdevice instead.\n"));
762
763     if (tapedev)
764     {
765         /* This command is deprecated because this parsing is going to fall 
766          * behind the list of available device names at some point, or to shadow
767          * an interesting hostname (wouldn't 'tape' be a good name for a 
768          * tape server?) */
769         if (tapedev != uqtape) {
770             if((strchr(tapedev+1, ':') == NULL) &&
771                (strncmp_const(uqtape, "null:") == 0 ||
772                 strncmp_const(uqtape, "rait:") == 0 ||
773                 strncmp_const(uqtape, "file:") == 0 ||
774                 strncmp_const(uqtape, "s3:") == 0 ||
775                 strncmp_const(uqtape, "tape:") == 0)) {
776                 tapedev = uqtape;
777             }
778             else {
779                 *tapedev = '\0';
780                 host = stralloc(uqtape);
781                 ++tapedev;
782             }
783         } else {
784             ++tapedev;
785         }
786     } else
787         tapedev = uqtape;
788     
789     if (tapedev[0])
790     {
791         if (strcmp(tapedev, "default") == 0)
792             tapedev = NULL;
793     }
794
795     /* call out to the new version */
796     set_device(host, tapedev);
797
798     amfree(host);
799     amfree(uqtape);
800 }
801
802 /* set the tape server and device, for real */
803 void
804 set_device(
805     char *      host,
806     char *      device)
807 {
808     if (host)
809         tape_server_name = newstralloc(tape_server_name, host);
810     else
811         amfree(tape_server_name);
812
813     if (device)
814         tape_device_name = newstralloc(tape_device_name, device);
815     else
816         amfree(tape_device_name);
817
818     /* print the current status */
819     if (tape_device_name)
820         g_printf (_("Using tape \"%s\""), tape_device_name);
821     else
822         g_printf (_("Using default tape"));
823
824     if (tape_server_name)
825         g_printf (_(" from server %s.\n"), tape_server_name);
826     else
827         g_printf (_(".\nTape server unspecified, assumed to be %s.\n"),
828                 server_name);
829 }
830
831 void
832 set_translate(
833     char *translate)
834 {
835
836     if (translate == NULL) {
837         translate_mode = TRUE;
838     } else if (strcasecmp(translate, "yes") == 0 ||
839                strcasecmp(translate, "true") == 0 ||
840                strcasecmp(translate, "on") == 0) {
841         translate_mode = TRUE;
842     } else {
843         translate_mode = FALSE;
844     }
845     suck_dir_list_from_server();        /* get list of directory contents */
846 }
847
848 void
849 set_mode(
850     int         mode)
851 {
852   if (mode == SAMBA_SMBCLIENT) {
853     g_printf (_("SAMBA dumps will be extracted using smbclient\n"));
854     samba_extract_method = SAMBA_SMBCLIENT;
855   } else {
856     if (mode == SAMBA_TAR) {
857       g_printf (_("SAMBA dumps will be extracted as TAR dumps\n"));
858       samba_extract_method = SAMBA_TAR;
859     }
860   }
861 }
862
863 void
864 show_mode(void) 
865 {
866 #ifdef SAMBA_CLIENT
867   g_printf (_("SAMBA dumps are extracted "));
868
869   if (samba_extract_method == SAMBA_TAR) {
870     g_printf (_(" as TAR dumps\n"));
871   } else {
872     g_printf (_("using smbclient\n"));
873   }
874 #endif /* SAMBA_CLIENT */
875 }