2 * Copyright (c) 1998,1999,2000
3 * Traakan, Inc., Los Altos, CA
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 "ndmjob -v -- print version and configuration info",
43 "ndmjob OPTIONS ... FILES ...",
44 " FILES can be FILEPATH or NEWFILEPATH=OLDFILEPATH with",
45 " '=' quoted by backslash.",
46 "Modes (exactly one required)",
47 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
48 " -c -- create a backup",
49 " -t -- list contents on a backup",
50 " -x -- extract from a backup",
51 " -l -- list media labels",
52 " -q -- query agent(s)",
53 " -Z -- clean up zee mess (put robot right)",
54 " -o init-labels -- init media labels",
55 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
56 #ifndef NDMOS_EFFECT_NO_SERVER_AGENTS
57 " -o daemon -- launch session for incomming connections",
58 " -o test-daemon -- launch session for incomming connections, exit when stdin is closed",
59 " -o tape-size=SIZE -- specify the length, in bytes of the simulated tape",
60 #endif /* !NDMOS_EFFECT_NO_SERVER_AGENTS */
61 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
62 " -o rewind -- rewind tape in drive, need -T and -f",
63 " -o eject -- eject tape in drive, need -T and -f",
64 " -o move -- cmd ROBOT to move tape, need -o from/to-addr",
65 " -o import=ELEMADDR -- cmd ROBOT to import tape from door to slot",
66 " -o export=ELEMADDR -- cmd ROBOT to export tape from slot to door",
67 " -o load=ELEMADDR -- cmd ROBOT to load tape from slot to drive",
68 " -o unload[=ELEMADDR]-- cmd ROBOT to unload tape, sometimes auto",
69 " -o init-elem-status -- cmd ROBOT to rescan tape slots",
70 " -o test-tape -- test TAPE agent NDMP_TAPE functions",
71 " -o test-mover -- test TAPE agent NDMP_MOVER functions",
72 " -o test-data -- test DATA agent NDMP_DATA functions",
74 " -- check for reply within specified seconds (default 360)",
75 " -o swap-connect -- perform DATA LISTEN & MOVER CONNECT",
77 " -p -- pass DATA->DATA (ndmpcopy)",
78 " -P -- pass TAPE->TAPE",
79 " -o c-partial -- partial backup",
80 " -o c-full -- full backup",
81 " -o x-restore -- extract restoring",
83 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
84 "General and Logging parameters",
85 " --MACRO -- expand MACRO from ndmjob-args file",
86 " -d N -- set debug level to N (default 0, max 9)",
87 " -L FILE -- set log file (default stderr, includes debug)",
88 " -n -- no-op, just show how args were handled",
89 " -v -- verbose, same messages as -d1 to standard out",
90 " -S -- Perform DATA listen and MOVER CONNECT",
91 " -p PORT -- NDMP port to listen on (for -o daemon)",
92 " -o no-time-stamps -- log w/o time stamps, makes diff(1)s easier",
93 " -o config-file=PATH",
94 " -- set config file ($NDMJOB_CONFIG, /usr/local/etc/ndmjob.conf)",
95 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
96 "CONTROL of DATA agent parameters",
97 " -D AGENT -- data agent (see AGENT below)",
98 " -B TYPE -- set backup format (default tar)",
99 " -C DIR -- change directory on data agent before operation",
100 " -e PATN -- exclude files matching pattern",
101 " -E NAME=VAL -- add to data agent environment",
102 " -F FILE -- add FILE arg (used to not confuse arg processing)",
103 " -o load-files=PATHNAME",
104 " -- load FILES from the specified PATHANME",
105 " -o import=ELEMADDR -- cmd ROBOT to import tape from door to slot",
107 " -I FILE -- set output index file, enable FILEHIST (default to log)",
108 " -J FILE -- set input index file (default none)",
109 " -U USER -- user rights to use on data agent",
110 " -o rules=RULES -- apply RULES to job (see RULES below)",
111 "CONTROL of TAPE agent parameters",
112 " -T AGENT -- tape agent if different than -D (see AGENT below)",
113 " -b N -- block size in 512-byte records (default 20)",
114 " -f TAPE -- tape drive device name",
115 " -o tape-timeout=SECONDS",
116 " -- how long to retry opening drive (await tape)",
118 " -- use eject when unloading tapes (default 0)",
119 " -o tape-tcp=hostname:port -- send the data directly to that tcp port.",
120 "CONTROL of ROBOT agent parameters",
121 " -R AGENT -- robot agent if different than -T (see AGENT below)",
122 " -m MEDIA -- add entry to media table (see below)",
123 " -o tape-addr=ELEMADDR",
124 " -- robot element address of drive (default first)",
125 " -o tape-scsi=SCSI",
126 " -- tape drive SCSI target (see below)",
127 " -o robot-timeout=SECONDS",
128 " -- how long to retry moving tapes (await robot)",
129 " -r SCSI -- tape robot target (see below)",
132 " AGENT HOST[:PORT][/FLAGS][,USERNAME,PASSWORD]",
133 " FLAGS [234][ntm] 2->v2 3->v3 4->v4 n->AUTH_NONE t->TEXT m->MD5",
134 " AGENT . (resident)",
135 " SCSI DEVICE[,[CNUM,]SID[,LUN]]",
136 " MEDIA [TAPE-LABEL][+SKIP-FILEMARKS][@ELEMADDR][/WINDOW-SIZE]",
139 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
145 process_args (int argc, char *argv[])
157 if (argc == 2 && strcmp (argv[1], "-help") == 0) {
162 if (argc == 2 && strcmp (argv[1], "-v") == 0) {
163 ndmjob_version_info ();
170 o_config_file = g_strdup_printf("%s/ndmjob.conf", amdatadir);
171 if ((p = getenv ("NDMJOB_CONF")) != 0) {
176 for (pp = help_text; *pp; pp++) {
179 if (strncmp (p, " -", 3) != 0)
182 continue; /* don't include o: repeatedly */
187 *op++ = 'o'; /* include o: once */
191 ac = copy_args_expanding_macros (argc, argv,
192 av, sizeof(av)/sizeof(av[0]));
194 while ((c = getopt (ac, av, options)) != EOF) {
197 handle_long_option (optarg);
200 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
201 case 'c': /* -c -- create a backup */
202 set_job_mode (NDM_JOB_OP_BACKUP);
205 case 't': /* -t -- list contents on a backup */
206 set_job_mode (NDM_JOB_OP_TOC);
209 case 'x': /* -x -- extract from a backup */
210 set_job_mode (NDM_JOB_OP_EXTRACT);
213 case 'l': /* -l -- list media labels */
214 set_job_mode (NDM_JOB_OP_LIST_LABELS);
217 case 'q': /* -q -- query agent(s) */
218 set_job_mode (NDM_JOB_OP_QUERY_AGENTS);
221 case 'Z': /* -Z -- clean up zee mess */
222 set_job_mode (NDM_JOB_OP_REMEDY_ROBOT);
225 case 'B': /* -B TYPE -- set backup format (default tar) */
227 error_byebye ("more than one of -B");
232 case 'b': /* -b N -- block size in 512-byte records (20) */
234 long b = strtol(optarg, NULL, 10);
235 if (b < 1 || b > 200 || (!b && EINVAL == errno)) {
236 error_byebye ("bad -b option");
242 case 'p': /* -p N -- port number for daemon mode (10000) */
244 long p = strtol(optarg, NULL, 10);
245 if (p < 1 || p > 65535 || (!p && EINVAL == errno)) {
246 error_byebye ("bad -p option");
248 p_ndmp_port = (int) p;
252 case 'C': /* -C DIR -- change directory on data agent */
254 /* allow second to override first. make recover easier */
256 error_byebye ("more than one of -C");
262 case 'D': /* -D AGENT -- data agent (see below) */
263 if (AGENT_GIVEN(D_data_agent)) {
264 error_byebye ("more than one of -D");
266 if (ndmagent_from_str (&D_data_agent, optarg)) {
267 error_byebye ("bad -D argument");
270 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
272 case 'd': /* -d N -- set debug level to N */
273 d_debug = atoi(optarg);
276 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
277 case 'E': /* -E NAME=VAL -- add to data agent environment */
278 if (n_E_environment >= NDM_MAX_ENV) {
279 error_byebye ("too many of -E");
285 E_environment[n_E_environment].name = p;
286 while (*p && *p != '=') p++;
288 error_byebye ("missing value in -E");
291 E_environment[n_E_environment].value = p;
296 case 'e': /* -e PATN -- exclude files matching pattern */
297 if (n_e_exclude_pattern >= MAX_EXCLUDE_PATTERN) {
298 error_byebye ("too many of -e");
300 e_exclude_pattern[n_e_exclude_pattern++] = optarg;
303 case 'F': /* -F FILE -- add to list of files */
304 if (n_file_arg >= MAX_FILE_ARG) {
305 error_byebye ("too many FILE args");
307 if (strchr(optarg, '=')) {
308 char *p = strchr(optarg, '=');
310 file_arg[n_file_arg] = p;
311 file_arg_new[n_file_arg] = optarg;
314 file_arg[n_file_arg] = optarg;
315 file_arg_new[n_file_arg] = 0;
321 case 'f': /* -f TAPE -- tape drive device name */
323 error_byebye ("more than one of -f");
325 f_tape_device = optarg;
328 case 'I': /* -I FILE -- output index, enab FILEHIST */
330 error_byebye ("more than one of -I");
332 I_index_file = optarg;
335 case 'J': /* -J FILE -- input index */
337 error_byebye ("more than one of -J");
339 J_index_file = optarg;
342 case 'L': /* -L FILE -- set log file (def stderr, incl. dbg) */
344 error_byebye ("more than one of -L");
347 if (d_debug < 2) d_debug = 2;
350 case 'm': /* -m MEDIA -- add entry to media table (see below) */
351 if (n_m_media >= NDM_MAX_MEDIA) {
352 error_byebye ("too many of -m");
354 if (ndmmedia_from_str (&m_media[n_m_media], optarg)) {
355 error_byebye ("bad -m argument: %s", optarg);
359 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
361 case 'n': /* -n -- no-op, show how args were handled */
365 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
366 case 'R': /* -R AGENT -- robot agent if different than -T */
367 if (AGENT_GIVEN(R_robot_agent)) {
368 error_byebye ("more than one of -R");
370 if (ndmagent_from_str (&R_robot_agent, optarg)) {
371 error_byebye ("bad -R argument");
375 case 'r': /* -r SCSI -- tape robot target (see below) */
377 error_byebye ("more than one of -r");
379 if (ndmscsi_target_from_str (&r_robot_target, optarg)) {
380 error_byebye ("bad -r argument");
384 case 'T': /* -T AGENT -- tape agent if different than -D */
385 if (AGENT_GIVEN(T_tape_agent)) {
386 error_byebye ("more than one of -T");
388 if (ndmagent_from_str (&T_tape_agent, optarg)) {
389 error_byebye ("bad -T argument");
393 case 'U': /* -U USER -- user rights to use on data agent */
395 error_byebye ("more than one of -U");
399 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
401 case 'v': /* -v -- verbose */
411 if (n_noop && d_debug > 1) {
414 for (i = 0; i < ac; i++) {
415 printf (" av[%d] = '%s'\n", i, av[i]);
420 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
421 printf ("must specify one of -[ctxlqZ] or other mode\n");
422 #else /* !NDMOS_OPTION_NO_CONTROL_AGENT */
423 printf ("must specify -o daemon\n");
424 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
428 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
429 for (c = optind; c < ac; c++) {
430 if (n_file_arg >= MAX_FILE_ARG) {
431 error_byebye ("too many file args");
433 if (strchr(av[c], '=')) {
434 char *p = strchr(av[c], '=');
436 file_arg[n_file_arg] = p;
437 file_arg_new[n_file_arg] = av[c];
439 file_arg[n_file_arg] = av[c];
440 file_arg_new[n_file_arg] = 0;
445 if (o_load_files_file) {
448 static struct load_file_entry {
449 struct load_file_entry *next;
451 } *load_files_list = 0;
453 /* clean up old load_files_list */
454 while (load_files_list) {
455 struct load_file_entry *p;
457 load_files_list = p->next;
462 fp = fopen(o_load_files_file, "r");
464 perror (o_load_files_file);
465 error_byebye ("can't open load_files file %s",
469 while (fgets (buf, sizeof buf, fp) != NULL) {
470 char *bp = buf, *p, *ep;
472 struct load_file_entry *lfe;
475 while (*bp && isspace(*bp))
478 while (*ep && (*ep != '\n') && (*ep != '\r'))
484 if (n_file_arg >= MAX_FILE_ARG) {
485 error_byebye ("too many FILE args");
488 /* allocate memory */
490 len = sizeof(struct load_file_entry)+(ep-bp)+1;
493 error_byebye ("can't allocate entry for load_files file line %s",
499 /* see if we have destination */
500 if ((p = strchr(bp, '=')) != 0) {
505 /* double conversion -- assume the strings shrink */
507 ndmcstr_to_str(p, &lfe->name[plen+2], slen-plen-2);
508 ndmcstr_to_str(bp, lfe->name, plen+1);
509 file_arg[n_file_arg] = &lfe->name[plen+2];
510 file_arg_new[n_file_arg] = lfe->name;
513 /* simple conversion copy */
514 ndmcstr_to_str(bp, lfe->name, slen-1);
515 file_arg[n_file_arg] = lfe->name;
516 file_arg_new[n_file_arg] = 0;
521 lfe->next = load_files_list;
522 load_files_list = lfe;
526 } /* end of load_files option */
532 * A quirk of the NDMP protocol is that the robot
533 * should be accessed over a different connection
534 * than the TAPE agent. (See the Workflow document).
537 if (!AGENT_GIVEN(R_robot_agent)) {
538 if (AGENT_GIVEN(T_tape_agent))
539 R_robot_agent = T_tape_agent;
541 R_robot_agent = D_data_agent;
543 if (!AGENT_GIVEN(R_robot_agent)) {
544 error_byebye ("-r given, can't determine -R");
547 } else if (AGENT_GIVEN(R_robot_agent)) {
548 if (the_mode != NDM_JOB_OP_QUERY_AGENTS) {
549 error_byebye ("-R but no -r");
552 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
557 struct ndmp_enum_str_table mode_long_name_table[] = {
558 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
559 { "init-labels", NDM_JOB_OP_INIT_LABELS },
560 { "test-tape", NDM_JOB_OP_TEST_TAPE },
561 { "test-mover", NDM_JOB_OP_TEST_MOVER },
562 { "test-data", NDM_JOB_OP_TEST_DATA },
563 { "eject", NDM_JOB_OP_EJECT_TAPE },
564 { "rewind", NDM_JOB_OP_REWIND_TAPE },
565 { "move", NDM_JOB_OP_MOVE_TAPE },
566 { "import", NDM_JOB_OP_IMPORT_TAPE },
567 { "export", NDM_JOB_OP_EXPORT_TAPE },
568 { "load", NDM_JOB_OP_LOAD_TAPE },
569 { "unload", NDM_JOB_OP_UNLOAD_TAPE },
570 { "init-elem-status", NDM_JOB_OP_INIT_ELEM_STATUS },
571 { "-c", NDM_JOB_OP_BACKUP },
572 { "-t", NDM_JOB_OP_TOC },
573 { "-x", NDM_JOB_OP_EXTRACT },
574 { "-l", NDM_JOB_OP_LIST_LABELS },
575 { "-q", NDM_JOB_OP_QUERY_AGENTS },
576 { "-Z", NDM_JOB_OP_REMEDY_ROBOT },
577 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
578 #ifndef NDMOS_EFFECT_NO_SERVER_AGENTS
579 { "daemon", NDM_JOB_OP_DAEMON },
580 { "test-daemon", NDM_JOB_OP_TEST_DAEMON },
581 #endif /* !NDMOS_EFFECT_NO_SERVER_AGENTS */
587 handle_long_option (char *str)
594 for (value = str; *value; value++)
602 if (ndmp_enum_from_str (&mode, name, mode_long_name_table)) {
604 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
607 default: /* value part ignored */
610 case NDM_JOB_OP_LOAD_TAPE:
611 case NDM_JOB_OP_EXPORT_TAPE:
612 o_from_addr = atoi(value);
614 case NDM_JOB_OP_UNLOAD_TAPE:
615 case NDM_JOB_OP_IMPORT_TAPE:
616 o_to_addr = atoi(value);
620 } else if (strcmp (name, "swap-connect") == 0) {
621 /* value part ignored */
623 } else if (strcmp (name, "time-limit") == 0) {
627 o_time_limit = atoi(value);
629 } else if (strcmp (name, "use-eject") == 0) {
633 o_use_eject = atoi(value);
635 } else if (strcmp (name, "tape-addr") == 0 && value) {
636 o_tape_addr = atoi(value);
637 } else if (strcmp (name, "from-addr") == 0 && value) {
638 o_from_addr = atoi(value);
639 } else if (strcmp (name, "to-addr") == 0 && value) {
640 o_to_addr = atoi(value);
641 } else if (strcmp (name, "tape-timeout") == 0 && value) {
642 o_tape_timeout = atoi(value);
643 } else if (strcmp (name, "robot-timeout") == 0 && value) {
644 o_robot_timeout = atoi(value);
645 } else if (strcmp (name, "tape-scsi") == 0 && value) {
646 if (ndmscsi_target_from_str (&o_tape_scsi, value)) {
647 error_byebye ("bad -otape-scsi argument");
649 } else if (strcmp (name, "rules") == 0 && value) {
651 error_byebye ("missing RULES in -o rules");
653 } else if (strcmp (name, "load-files") == 0 && value) {
654 o_load_files_file = value;
655 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
656 } else if (strcmp (name, "no-time-stamps") == 0) {
657 /* value part ignored */
659 } else if (strcmp (name, "config-file") == 0 && value) {
660 o_config_file = value;
661 } else if (strcmp (name, "tape-tcp") == 0 && value) {
663 } else if (strcmp (name, "tape-limit") == 0) {
665 error_byebye ("tape-limit argument is required");
667 o_tape_limit = atoi(value);
670 if (value) value[-1] = '=';
671 error_byebye ("unknown/bad long option -o%s", str);
674 if (value) value[-1] = '=';
679 set_job_mode (int mode)
682 printf ("more than one -[ctxlqZ] or other mode");
691 error_byebye ("bad usage, use -help");
700 for (pp = help_text; *pp; pp++) {
704 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
706 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
710 ndmjob_version_info (void)
717 #ifndef NDMOS_OPTION_NO_NDMP2
718 strcat (vbuf, " NDMPv2");
719 #endif /* !NDMOS_OPTION_NO_NDMP2 */
720 #ifndef NDMOS_OPTION_NO_NDMP3
721 strcat (vbuf, " NDMPv3");
722 #endif /* !NDMOS_OPTION_NO_NDMP3 */
723 #ifndef NDMOS_OPTION_NO_NDMP4
724 strcat (vbuf, " NDMPv4");
725 #endif /* !NDMOS_OPTION_NO_NDMP4 */
728 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
729 strcat (abuf, " CONTROL");
730 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
731 #ifndef NDMOS_OPTION_NO_DATA_AGENT
732 strcat (abuf, " DATA");
733 #endif /* !NDMOS_OPTION_NO_DATA_AGENT */
734 #ifndef NDMOS_OPTION_NO_TAPE_AGENT
735 strcat (abuf, " TAPE");
736 #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
737 #ifndef NDMOS_OPTION_NO_ROBOT_AGENT
738 strcat (abuf, " ROBOT");
739 #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */
741 obuf[0] = (char)(NDMOS_ID >> 24);
742 obuf[1] = (char)(NDMOS_ID >> 16);
743 obuf[2] = (char)(NDMOS_ID >> 8);
744 obuf[3] = (char)(NDMOS_ID >> 0);
748 NDMOS_CONST_PRODUCT_NAME,
749 NDMOS_CONST_VENDOR_NAME);
751 printf (" Rev %s LIB:%d.%d/%s OS:%s (%s)\n",
752 NDMOS_CONST_PRODUCT_REVISION,
753 NDMJOBLIB_VERSION, NDMJOBLIB_RELEASE,
754 NDMOS_CONST_NDMJOBLIB_REVISION,
755 NDMOS_CONST_NDMOS_REVISION,
758 printf (" Agents: %s\n", abuf);
759 printf (" Protocols:%s\n", vbuf);
769 *buf = 0; /* shuts up -Wall */
770 i = 0; /* shuts up -Wall */
771 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
774 printf ("mode = x (extract)\n");
778 printf ("mode = c (create)\n");
782 printf ("mode = t (table-of-contents)\n");
786 printf ("mode = q (query-agents)\n");
790 printf ("mode = %c (unknown)\n", the_mode);
793 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
796 printf ("verbose %d\n", v_verbose);
798 printf ("not verbose\n");
800 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
801 printf ("blocksize = %d (%dkb, %db)\n",
802 b_bsize, b_bsize/2, b_bsize*512);
803 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
806 printf ("debug %d\n", d_debug);
808 printf ("no debug\n");
810 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
811 printf ("Data agent %s\n", D_data_agent.host);
812 if (AGENT_GIVEN(T_tape_agent))
813 printf ("Tape agent %s\n", T_tape_agent.host);
815 printf ("Tape agent same as data agent\n");
817 printf ("tape device %s\n", f_tape_device);
819 printf ("tape format %s\n", B_bu_type);
822 printf ("Chdir %s\n", C_chdir);
824 printf ("Chdir / (default)\n");
825 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
828 printf ("Log to file %s\n", L_log_file);
830 printf ("Log to stderr (default)\n");
832 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
834 if (strcmp (I_index_file, "-") == 0) {
835 printf ("Index to log, enable FILEHIST\n");
837 printf ("Index to file %s, enable FILEHIST\n",
841 printf ("Index off (default), no FILEHIST\n");
844 printf ("%d media entries\n", n_m_media);
845 for (i = 0; i < n_m_media; i++) {
846 ndmmedia_to_str (&m_media[i], buf);
847 printf (" %2d: %s\n", i, buf);
850 printf ("%d excludes\n", n_e_exclude_pattern);
851 for (i = 0; i < n_e_exclude_pattern; i++) {
852 printf (" %2d: %s\n", i, e_exclude_pattern[i]);
855 printf ("%d environment values\n", n_E_environment);
856 for (i = 0; i < n_E_environment; i++) {
857 printf (" %2d: %s=%s\n", i,
858 E_environment[i].name, E_environment[i].value);
861 printf ("%d files\n", n_file_arg);
862 for (i = 0; i < n_file_arg; i++) {
863 printf (" %2d: @%-8lld %s\n", i,
864 nlist[i].fh_info.valid ? nlist[i].fh_info.value : NDMP9_INVALID_U_QUAD,
867 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
873 copy_args_expanding_macros (int argc, char *argv[], char *av[], int max_ac)
881 for (i = 0; i < argc; i++) {
884 if (strncmp (arg, "--", 2) != 0 || arg[2] == 0) {
889 sprintf (env_name, "NDMJOB_%s", arg+2);
890 if ((p = getenv (env_name)) != 0) {
891 ac += snarf_macro (&av[ac], p);
895 rc = lookup_and_snarf (&av[ac], arg+2);
897 error_byebye ("bad arg macro --%s", arg+2);
908 lookup_and_snarf (char *av[], char *name)
916 argfile = o_config_file;
919 fp = fopen (argfile, "r");
922 error_byebye ("can't open config file %s", argfile);
925 while (ndmstz_getstanza (fp, buf, sizeof buf) >= 0) {
926 if (buf[0] == '-' && buf[1] == '-'
927 && strcmp (buf+2, name) == 0) {
934 while (ndmstz_getline (fp, buf, sizeof buf) >= 0) {
937 ac += snarf_macro (&av[ac], buf);
950 snarf_macro (char *av[], char *val)
957 p = NDMOS_API_STRDUP (val);
959 error_byebye ("bad strdup macro");
962 while (isspace((int)*p)) p++;
964 tmp_av[tmp_ac++] = p;
965 while (*p && !isspace((int)*p)) p++;
969 ac = copy_args_expanding_macros (tmp_ac, tmp_av, av, 100);