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 " -o D-agent-fd=<fd> -- file descriptor to read the -D agent.",
121 "CONTROL of ROBOT agent parameters",
122 " -R AGENT -- robot agent if different than -T (see AGENT below)",
123 " -m MEDIA -- add entry to media table (see below)",
124 " -o tape-addr=ELEMADDR",
125 " -- robot element address of drive (default first)",
126 " -o tape-scsi=SCSI",
127 " -- tape drive SCSI target (see below)",
128 " -o robot-timeout=SECONDS",
129 " -- how long to retry moving tapes (await robot)",
130 " -r SCSI -- tape robot target (see below)",
133 " AGENT HOST[:PORT][/FLAGS][,USERNAME,PASSWORD]",
134 " FLAGS [234][ntm] 2->v2 3->v3 4->v4 n->AUTH_NONE t->TEXT m->MD5",
135 " AGENT . (resident)",
136 " SCSI DEVICE[,[CNUM,]SID[,LUN]]",
137 " MEDIA [TAPE-LABEL][+SKIP-FILEMARKS][@ELEMADDR][/WINDOW-SIZE]",
140 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
146 process_args (int argc, char *argv[])
158 if (argc == 2 && strcmp (argv[1], "-help") == 0) {
163 if (argc == 2 && strcmp (argv[1], "-v") == 0) {
164 ndmjob_version_info ();
171 o_config_file = g_strdup_printf("%s/ndmjob.conf", amdatadir);
172 if ((p = getenv ("NDMJOB_CONF")) != 0) {
177 for (pp = help_text; *pp; pp++) {
180 if (strncmp (p, " -", 3) != 0)
183 continue; /* don't include o: repeatedly */
188 *op++ = 'o'; /* include o: once */
192 ac = copy_args_expanding_macros (argc, argv,
193 av, sizeof(av)/sizeof(av[0]));
195 while ((c = getopt (ac, av, options)) != EOF) {
198 handle_long_option (optarg);
201 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
202 case 'c': /* -c -- create a backup */
203 set_job_mode (NDM_JOB_OP_BACKUP);
206 case 't': /* -t -- list contents on a backup */
207 set_job_mode (NDM_JOB_OP_TOC);
210 case 'x': /* -x -- extract from a backup */
211 set_job_mode (NDM_JOB_OP_EXTRACT);
214 case 'l': /* -l -- list media labels */
215 set_job_mode (NDM_JOB_OP_LIST_LABELS);
218 case 'q': /* -q -- query agent(s) */
219 set_job_mode (NDM_JOB_OP_QUERY_AGENTS);
222 case 'Z': /* -Z -- clean up zee mess */
223 set_job_mode (NDM_JOB_OP_REMEDY_ROBOT);
226 case 'B': /* -B TYPE -- set backup format (default tar) */
228 error_byebye ("more than one of -B");
233 case 'b': /* -b N -- block size in 512-byte records (20) */
235 long b = strtol(optarg, NULL, 10);
236 if (b < 1 || b > 200 || (!b && EINVAL == errno)) {
237 error_byebye ("bad -b option");
243 case 'p': /* -p N -- port number for daemon mode (10000) */
245 long p = strtol(optarg, NULL, 10);
246 if (p < 1 || p > 65535 || (!p && EINVAL == errno)) {
247 error_byebye ("bad -p option");
249 p_ndmp_port = (int) p;
253 case 'C': /* -C DIR -- change directory on data agent */
255 /* allow second to override first. make recover easier */
257 error_byebye ("more than one of -C");
263 case 'D': /* -D AGENT -- data agent (see below) */
264 if (AGENT_GIVEN(D_data_agent)) {
265 error_byebye ("more than one of -D");
267 if (ndmagent_from_str (&D_data_agent, optarg)) {
268 error_byebye ("bad -D argument");
271 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
273 case 'd': /* -d N -- set debug level to N */
274 d_debug = atoi(optarg);
277 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
278 case 'E': /* -E NAME=VAL -- add to data agent environment */
279 if (n_E_environment >= NDM_MAX_ENV) {
280 error_byebye ("too many of -E");
286 E_environment[n_E_environment].name = p;
287 while (*p && *p != '=') p++;
289 error_byebye ("missing value in -E");
292 E_environment[n_E_environment].value = p;
297 case 'e': /* -e PATN -- exclude files matching pattern */
298 if (n_e_exclude_pattern >= MAX_EXCLUDE_PATTERN) {
299 error_byebye ("too many of -e");
301 e_exclude_pattern[n_e_exclude_pattern++] = optarg;
304 case 'F': /* -F FILE -- add to list of files */
305 if (n_file_arg >= MAX_FILE_ARG) {
306 error_byebye ("too many FILE args");
308 if (strchr(optarg, '=')) {
309 char *p = strchr(optarg, '=');
311 file_arg[n_file_arg] = p;
312 file_arg_new[n_file_arg] = optarg;
315 file_arg[n_file_arg] = optarg;
316 file_arg_new[n_file_arg] = 0;
322 case 'f': /* -f TAPE -- tape drive device name */
324 error_byebye ("more than one of -f");
326 f_tape_device = optarg;
329 case 'I': /* -I FILE -- output index, enab FILEHIST */
331 error_byebye ("more than one of -I");
333 I_index_file = optarg;
336 case 'J': /* -J FILE -- input index */
338 error_byebye ("more than one of -J");
340 J_index_file = optarg;
343 case 'L': /* -L FILE -- set log file (def stderr, incl. dbg) */
345 error_byebye ("more than one of -L");
348 if (d_debug < 2) d_debug = 2;
351 case 'm': /* -m MEDIA -- add entry to media table (see below) */
352 if (n_m_media >= NDM_MAX_MEDIA) {
353 error_byebye ("too many of -m");
355 if (ndmmedia_from_str (&m_media[n_m_media], optarg)) {
356 error_byebye ("bad -m argument: %s", optarg);
360 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
362 case 'n': /* -n -- no-op, show how args were handled */
366 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
367 case 'R': /* -R AGENT -- robot agent if different than -T */
368 if (AGENT_GIVEN(R_robot_agent)) {
369 error_byebye ("more than one of -R");
371 if (ndmagent_from_str (&R_robot_agent, optarg)) {
372 error_byebye ("bad -R argument");
376 case 'r': /* -r SCSI -- tape robot target (see below) */
378 error_byebye ("more than one of -r");
380 if (ndmscsi_target_from_str (&r_robot_target, optarg)) {
381 error_byebye ("bad -r argument");
385 case 'T': /* -T AGENT -- tape agent if different than -D */
386 if (AGENT_GIVEN(T_tape_agent)) {
387 error_byebye ("more than one of -T");
389 if (ndmagent_from_str (&T_tape_agent, optarg)) {
390 error_byebye ("bad -T argument");
394 case 'U': /* -U USER -- user rights to use on data agent */
396 error_byebye ("more than one of -U");
400 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
402 case 'v': /* -v -- verbose */
412 if (n_noop && d_debug > 1) {
415 for (i = 0; i < ac; i++) {
416 printf (" av[%d] = '%s'\n", i, av[i]);
421 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
422 printf ("must specify one of -[ctxlqZ] or other mode\n");
423 #else /* !NDMOS_OPTION_NO_CONTROL_AGENT */
424 printf ("must specify -o daemon\n");
425 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
429 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
430 for (c = optind; c < ac; c++) {
431 if (n_file_arg >= MAX_FILE_ARG) {
432 error_byebye ("too many file args");
434 if (strchr(av[c], '=')) {
435 char *p = strchr(av[c], '=');
437 file_arg[n_file_arg] = p;
438 file_arg_new[n_file_arg] = av[c];
440 file_arg[n_file_arg] = av[c];
441 file_arg_new[n_file_arg] = 0;
446 if (o_load_files_file) {
449 static struct load_file_entry {
450 struct load_file_entry *next;
452 } *load_files_list = 0;
454 /* clean up old load_files_list */
455 while (load_files_list) {
456 struct load_file_entry *p;
458 load_files_list = p->next;
463 fp = fopen(o_load_files_file, "r");
465 perror (o_load_files_file);
466 error_byebye ("can't open load_files file %s",
470 while (fgets (buf, sizeof buf, fp) != NULL) {
471 char *bp = buf, *p, *ep;
473 struct load_file_entry *lfe;
476 while (*bp && isspace(*bp))
479 while (*ep && (*ep != '\n') && (*ep != '\r'))
485 if (n_file_arg >= MAX_FILE_ARG) {
486 error_byebye ("too many FILE args");
489 /* allocate memory */
491 len = sizeof(struct load_file_entry)+(ep-bp)+1;
494 error_byebye ("can't allocate entry for load_files file line %s",
500 /* see if we have destination */
501 if ((p = strchr(bp, '=')) != 0) {
506 /* double conversion -- assume the strings shrink */
508 ndmcstr_to_str(p, &lfe->name[plen+2], slen-plen-2);
509 ndmcstr_to_str(bp, lfe->name, plen+1);
510 file_arg[n_file_arg] = &lfe->name[plen+2];
511 file_arg_new[n_file_arg] = lfe->name;
514 /* simple conversion copy */
515 ndmcstr_to_str(bp, lfe->name, slen-1);
516 file_arg[n_file_arg] = lfe->name;
517 file_arg_new[n_file_arg] = 0;
522 lfe->next = load_files_list;
523 load_files_list = lfe;
527 } /* end of load_files option */
533 * A quirk of the NDMP protocol is that the robot
534 * should be accessed over a different connection
535 * than the TAPE agent. (See the Workflow document).
538 if (!AGENT_GIVEN(R_robot_agent)) {
539 if (AGENT_GIVEN(T_tape_agent))
540 R_robot_agent = T_tape_agent;
542 R_robot_agent = D_data_agent;
544 if (!AGENT_GIVEN(R_robot_agent)) {
545 error_byebye ("-r given, can't determine -R");
548 } else if (AGENT_GIVEN(R_robot_agent)) {
549 if (the_mode != NDM_JOB_OP_QUERY_AGENTS) {
550 error_byebye ("-R but no -r");
553 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
558 struct ndmp_enum_str_table mode_long_name_table[] = {
559 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
560 { "init-labels", NDM_JOB_OP_INIT_LABELS },
561 { "test-tape", NDM_JOB_OP_TEST_TAPE },
562 { "test-mover", NDM_JOB_OP_TEST_MOVER },
563 { "test-data", NDM_JOB_OP_TEST_DATA },
564 { "eject", NDM_JOB_OP_EJECT_TAPE },
565 { "rewind", NDM_JOB_OP_REWIND_TAPE },
566 { "move", NDM_JOB_OP_MOVE_TAPE },
567 { "import", NDM_JOB_OP_IMPORT_TAPE },
568 { "export", NDM_JOB_OP_EXPORT_TAPE },
569 { "load", NDM_JOB_OP_LOAD_TAPE },
570 { "unload", NDM_JOB_OP_UNLOAD_TAPE },
571 { "init-elem-status", NDM_JOB_OP_INIT_ELEM_STATUS },
572 { "-c", NDM_JOB_OP_BACKUP },
573 { "-t", NDM_JOB_OP_TOC },
574 { "-x", NDM_JOB_OP_EXTRACT },
575 { "-l", NDM_JOB_OP_LIST_LABELS },
576 { "-q", NDM_JOB_OP_QUERY_AGENTS },
577 { "-Z", NDM_JOB_OP_REMEDY_ROBOT },
578 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
579 #ifndef NDMOS_EFFECT_NO_SERVER_AGENTS
580 { "daemon", NDM_JOB_OP_DAEMON },
581 { "test-daemon", NDM_JOB_OP_TEST_DAEMON },
582 #endif /* !NDMOS_EFFECT_NO_SERVER_AGENTS */
588 handle_long_option (char *str)
595 for (value = str; *value; value++)
603 if (ndmp_enum_from_str (&mode, name, mode_long_name_table)) {
605 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
608 default: /* value part ignored */
611 case NDM_JOB_OP_LOAD_TAPE:
612 case NDM_JOB_OP_EXPORT_TAPE:
613 o_from_addr = atoi(value);
615 case NDM_JOB_OP_UNLOAD_TAPE:
616 case NDM_JOB_OP_IMPORT_TAPE:
617 o_to_addr = atoi(value);
621 } else if (strcmp (name, "swap-connect") == 0) {
622 /* value part ignored */
624 } else if (strcmp (name, "time-limit") == 0) {
628 o_time_limit = atoi(value);
630 } else if (strcmp (name, "use-eject") == 0) {
634 o_use_eject = atoi(value);
636 } else if (strcmp (name, "tape-addr") == 0 && value) {
637 o_tape_addr = atoi(value);
638 } else if (strcmp (name, "from-addr") == 0 && value) {
639 o_from_addr = atoi(value);
640 } else if (strcmp (name, "to-addr") == 0 && value) {
641 o_to_addr = atoi(value);
642 } else if (strcmp (name, "tape-timeout") == 0 && value) {
643 o_tape_timeout = atoi(value);
644 } else if (strcmp (name, "robot-timeout") == 0 && value) {
645 o_robot_timeout = atoi(value);
646 } else if (strcmp (name, "tape-scsi") == 0 && value) {
647 if (ndmscsi_target_from_str (&o_tape_scsi, value)) {
648 error_byebye ("bad -otape-scsi argument");
650 } else if (strcmp (name, "rules") == 0 && value) {
652 error_byebye ("missing RULES in -o rules");
654 } else if (strcmp (name, "load-files") == 0 && value) {
655 o_load_files_file = value;
656 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
657 } else if (strcmp (name, "no-time-stamps") == 0) {
658 /* value part ignored */
660 } else if (strcmp (name, "config-file") == 0 && value) {
661 o_config_file = value;
662 } else if (strcmp (name, "tape-tcp") == 0 && value) {
664 } else if (strcmp (name, "D-agent-fd") == 0 && value) {
666 int fd = atoi(value);
669 if (AGENT_GIVEN(D_data_agent)) {
670 error_byebye ("more than one of -D or -D-agent-fd");
673 size = full_read(fd, d_agent, 1024);
674 d_agent[size] = '\0';
675 if (size > 0 && d_agent[size-1] == '\n')
676 d_agent[size-1] = '\0';
677 if (ndmagent_from_str (&D_data_agent, d_agent)) {
678 error_byebye ("bad -D-agent-fd argument");
680 } else if (strcmp (name, "tape-limit") == 0) {
682 error_byebye ("tape-limit argument is required");
684 o_tape_limit = atoi(value);
687 if (value) value[-1] = '=';
688 error_byebye ("unknown/bad long option -o%s", str);
691 if (value) value[-1] = '=';
696 set_job_mode (int mode)
699 printf ("more than one -[ctxlqZ] or other mode");
708 error_byebye ("bad usage, use -help");
717 for (pp = help_text; *pp; pp++) {
721 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
723 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
727 ndmjob_version_info (void)
734 #ifndef NDMOS_OPTION_NO_NDMP2
735 strcat (vbuf, " NDMPv2");
736 #endif /* !NDMOS_OPTION_NO_NDMP2 */
737 #ifndef NDMOS_OPTION_NO_NDMP3
738 strcat (vbuf, " NDMPv3");
739 #endif /* !NDMOS_OPTION_NO_NDMP3 */
740 #ifndef NDMOS_OPTION_NO_NDMP4
741 strcat (vbuf, " NDMPv4");
742 #endif /* !NDMOS_OPTION_NO_NDMP4 */
745 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
746 strcat (abuf, " CONTROL");
747 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
748 #ifndef NDMOS_OPTION_NO_DATA_AGENT
749 strcat (abuf, " DATA");
750 #endif /* !NDMOS_OPTION_NO_DATA_AGENT */
751 #ifndef NDMOS_OPTION_NO_TAPE_AGENT
752 strcat (abuf, " TAPE");
753 #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
754 #ifndef NDMOS_OPTION_NO_ROBOT_AGENT
755 strcat (abuf, " ROBOT");
756 #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */
758 obuf[0] = (char)(NDMOS_ID >> 24);
759 obuf[1] = (char)(NDMOS_ID >> 16);
760 obuf[2] = (char)(NDMOS_ID >> 8);
761 obuf[3] = (char)(NDMOS_ID >> 0);
765 NDMOS_CONST_PRODUCT_NAME,
766 NDMOS_CONST_VENDOR_NAME);
768 printf (" Rev %s LIB:%d.%d/%s OS:%s (%s)\n",
769 NDMOS_CONST_PRODUCT_REVISION,
770 NDMJOBLIB_VERSION, NDMJOBLIB_RELEASE,
771 NDMOS_CONST_NDMJOBLIB_REVISION,
772 NDMOS_CONST_NDMOS_REVISION,
775 printf (" Agents: %s\n", abuf);
776 printf (" Protocols:%s\n", vbuf);
786 *buf = 0; /* shuts up -Wall */
787 i = 0; /* shuts up -Wall */
788 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
791 printf ("mode = x (extract)\n");
795 printf ("mode = c (create)\n");
799 printf ("mode = t (table-of-contents)\n");
803 printf ("mode = q (query-agents)\n");
807 printf ("mode = %c (unknown)\n", the_mode);
810 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
813 printf ("verbose %d\n", v_verbose);
815 printf ("not verbose\n");
817 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
818 printf ("blocksize = %d (%dkb, %db)\n",
819 b_bsize, b_bsize/2, b_bsize*512);
820 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
823 printf ("debug %d\n", d_debug);
825 printf ("no debug\n");
827 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
828 printf ("Data agent %s\n", D_data_agent.host);
829 if (AGENT_GIVEN(T_tape_agent))
830 printf ("Tape agent %s\n", T_tape_agent.host);
832 printf ("Tape agent same as data agent\n");
834 printf ("tape device %s\n", f_tape_device);
836 printf ("tape format %s\n", B_bu_type);
839 printf ("Chdir %s\n", C_chdir);
841 printf ("Chdir / (default)\n");
842 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
845 printf ("Log to file %s\n", L_log_file);
847 printf ("Log to stderr (default)\n");
849 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
851 if (strcmp (I_index_file, "-") == 0) {
852 printf ("Index to log, enable FILEHIST\n");
854 printf ("Index to file %s, enable FILEHIST\n",
858 printf ("Index off (default), no FILEHIST\n");
861 printf ("%d media entries\n", n_m_media);
862 for (i = 0; i < n_m_media; i++) {
863 ndmmedia_to_str (&m_media[i], buf);
864 printf (" %2d: %s\n", i, buf);
867 printf ("%d excludes\n", n_e_exclude_pattern);
868 for (i = 0; i < n_e_exclude_pattern; i++) {
869 printf (" %2d: %s\n", i, e_exclude_pattern[i]);
872 printf ("%d environment values\n", n_E_environment);
873 for (i = 0; i < n_E_environment; i++) {
874 printf (" %2d: %s=%s\n", i,
875 E_environment[i].name, E_environment[i].value);
878 printf ("%d files\n", n_file_arg);
879 for (i = 0; i < n_file_arg; i++) {
880 printf (" %2d: @%-8lld %s\n", i,
881 nlist[i].fh_info.valid ? nlist[i].fh_info.value : NDMP9_INVALID_U_QUAD,
884 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
890 copy_args_expanding_macros (int argc, char *argv[], char *av[], int max_ac)
898 for (i = 0; i < argc; i++) {
901 if (strncmp (arg, "--", 2) != 0 || arg[2] == 0) {
906 sprintf (env_name, "NDMJOB_%s", arg+2);
907 if ((p = getenv (env_name)) != 0) {
908 ac += snarf_macro (&av[ac], p);
912 rc = lookup_and_snarf (&av[ac], arg+2);
914 error_byebye ("bad arg macro --%s", arg+2);
925 lookup_and_snarf (char *av[], char *name)
933 argfile = o_config_file;
936 fp = fopen (argfile, "r");
939 error_byebye ("can't open config file %s", argfile);
942 while (ndmstz_getstanza (fp, buf, sizeof buf) >= 0) {
943 if (buf[0] == '-' && buf[1] == '-'
944 && strcmp (buf+2, name) == 0) {
951 while (ndmstz_getline (fp, buf, sizeof buf) >= 0) {
954 ac += snarf_macro (&av[ac], buf);
967 snarf_macro (char *av[], char *val)
974 p = NDMOS_API_STRDUP (val);
976 error_byebye ("bad strdup macro");
979 while (isspace((int)*p)) p++;
981 tmp_av[tmp_ac++] = p;
982 while (*p && !isspace((int)*p)) p++;
986 ac = copy_args_expanding_macros (tmp_ac, tmp_av, av, 100);