2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-1998 University of Maryland at College Park
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.
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.
23 * Authors: the Amanda Development Team. Its members are listed in a
24 * file named AUTHORS, in the root directory of this distribution.
27 * $Id: amtape.c,v 1.47.2.2 2006/10/30 12:00:19 martinea Exp $
29 * tape changer interface program
34 #include "taperscan.h"
42 int main(int argc, char **argv);
43 void reset_changer(int argc, char **argv);
44 void eject_tape(int argc, char **argv);
45 void clean_tape(int argc, char **argv);
46 void load_slot(int argc, char **argv);
47 void load_label(int argc, char **argv);
48 void show_slots(int argc, char **argv);
49 void show_current(int argc, char **argv);
50 void update_labeldb (int argc, char **argv);
51 void amtape_taper_scan(int argc, char **argv);
52 void show_device(int argc, char **argv);
53 int update_one_slot (void *ud, int rc, char *slotstr, char *device);
54 int loadlabel_slot(void *ud, int rc, char *slotstr, char *device);
55 int show_init(void *ud, int rc, int ns, int bk, int s);
56 int show_init_all(void *ud, int rc, int ns, int bk, int s);
57 int show_init_current(void *ud, int rc, int ns, int bk, int s);
58 int show_slot(void *ud, int rc, char *slotstr, char *device);
62 void (*fn)(int, char **);
65 { "reset", reset_changer,
66 "reset Reset changer to known state" },
67 { "eject", eject_tape,
68 "eject Eject current tape from drive" },
69 { "clean", clean_tape,
70 "clean Clean the drive" },
72 "show Show contents of all slots" },
73 { "current", show_current,
74 "current Show contents of current slot" },
76 "slot <slot #> load tape from slot <slot #>" },
78 "slot current load tape from current slot" },
80 "slot prev load tape from previous slot" },
82 "slot next load tape from next slot" },
84 "slot advance advance to next slot but do not load" },
86 "slot first load tape from first slot" },
88 "slot last load tape from last slot" },
89 { "label", load_label,
90 "label <label> find and load labeled tape" },
91 { "taper", amtape_taper_scan,
92 "taper perform taper's scan alg." },
93 { "device", show_device,
94 "device show current tape device" },
95 { "update", update_labeldb,
96 "update update the label matchingdatabase"},
98 #define NCMDS (int)(sizeof(cmdtab) / sizeof(cmdtab[0]))
105 fprintf(stderr, "Usage: amtape%s <conf> <command> {<args>} [-o configoption]*\n", versionsuffix());
106 fprintf(stderr, "\tValid commands are:\n");
107 for (i = 0; i < NCMDS; i++)
108 fprintf(stderr, "\t\t%s\n", cmdtab[i].usage);
119 char *argv0 = argv[0];
120 unsigned long malloc_hist_1, malloc_size_1;
121 unsigned long malloc_hist_2, malloc_size_2;
136 /* Don't die when child closes pipe */
137 signal(SIGPIPE, SIG_IGN);
139 dbopen(DBG_SUBDIR_SERVER);
141 malloc_size_1 = malloc_inuse(&malloc_hist_1);
143 erroutput_type = ERR_INTERACTIVE;
145 parse_server_conf(argc, argv, &new_argc, &new_argv);
146 if(new_argc < 3) usage();
148 config_name = new_argv[1];
150 config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
151 conffile = stralloc2(config_dir, CONFFILE_NAME);
152 if (read_conffile(conffile)) {
153 error("errors processing config file \"%s\"", conffile);
157 dbrename(config_name, DBG_SUBDIR_SERVER);
159 conf_tapelist = getconf_str(CNF_TAPELIST);
160 if (*conf_tapelist == '/') {
161 conf_tapelist = stralloc(conf_tapelist);
163 conf_tapelist = stralloc2(config_dir, conf_tapelist);
165 if (read_tapelist(conf_tapelist)) {
166 error("could not load tapelist \"%s\"", conf_tapelist);
169 amfree(conf_tapelist);
172 uid_dumpuser = uid_me;
173 dumpuser = getconf_str(CNF_DUMPUSER);
175 if ((pw = getpwnam(dumpuser)) == NULL) {
176 error("cannot look up dump user \"%s\"", dumpuser);
179 uid_dumpuser = pw->pw_uid;
180 if ((pw = getpwuid(uid_me)) == NULL) {
181 error("cannot look up my own uid %ld", (long)uid_me);
184 if (uid_me != uid_dumpuser) {
185 error("running as user \"%s\" instead of \"%s\"",
186 pw->pw_name, dumpuser);
190 if((have_changer = changer_init()) == 0) {
191 error("no tpchanger specified in \"%s\"", conffile);
193 } else if (have_changer != 1) {
194 error("changer initialization failed: %s", strerror(errno));
198 /* switch on command name */
200 new_argc -= 2; new_argv += 2;
201 for (i = 0; i < NCMDS; i++)
202 if (strcmp(new_argv[0], cmdtab[i].name) == 0) {
203 (*cmdtab[i].fn)(new_argc, new_argv);
207 fprintf(stderr, "%s: unknown command \"%s\"\n", argv0, new_argv[0]);
211 amfree(changer_resultstr);
215 malloc_size_2 = malloc_inuse(&malloc_hist_2);
217 if(malloc_size_1 != malloc_size_2) {
218 malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
225 /* ---------------------------- */
232 char *slotstr = NULL;
234 (void)argc; /* Quiet unused parameter warning */
235 (void)argv; /* Quiet unused parameter warning */
237 switch(changer_reset(&slotstr)) {
239 fprintf(stderr, "%s: changer is reset, slot %s is loaded.\n",
240 get_pname(), slotstr);
243 fprintf(stderr, "%s: changer is reset, but slot %s not loaded: %s\n",
244 get_pname(), slotstr, changer_resultstr);
247 error("could not reset changer: %s", changer_resultstr);
254 /* ---------------------------- */
262 (void)argc; /* Quiet unused parameter warning */
263 (void)argv; /* Quiet unused parameter warning */
265 if(changer_clean(&devstr) == 0) {
266 fprintf(stderr, "%s: device %s is clean.\n", get_pname(), devstr);
268 fprintf(stderr, "%s: device %s not clean: %s\n",
269 get_pname(), devstr ? devstr : "??", changer_resultstr);
275 /* ---------------------------- */
281 char *slotstr = NULL;
283 (void)argc; /* Quiet unused parameter warning */
284 (void)argv; /* Quiet unused parameter warning */
286 if(changer_eject(&slotstr) == 0) {
287 fprintf(stderr, "%s: slot %s is ejected.\n", get_pname(), slotstr);
289 fprintf(stderr, "%s: slot %s not ejected: %s\n",
290 get_pname(), slotstr ? slotstr : "??", changer_resultstr);
296 /* ---------------------------- */
303 char *slotstr = NULL, *devicename = NULL;
310 is_advance = (strcmp(argv[1], "advance") == 0);
311 if(changer_loadslot(argv[1], &slotstr, &devicename)) {
312 error("could not load slot %s: %s", slotstr, changer_resultstr);
315 if(! is_advance && (errstr = tape_rewind(devicename)) != NULL) {
317 "%s: could not rewind %s: %s", get_pname(), devicename, errstr);
321 fprintf(stderr, "%s: changed to slot %s", get_pname(), slotstr);
323 fprintf(stderr, " on %s", devicename);
331 /* ---------------------------- */
333 int nslots, backwards, found, got_match, tapedays;
335 char *label = NULL, *first_match_label = NULL, *first_match = NULL;
336 char *searchlabel, *labelstr;
338 static int scan_init(void *ud, int rc, int ns, int bk, int s);
348 (void)ud; /* Quiet unused parameter warning */
349 (void)s; /* Quiet unused parameter warning */
352 error("could not get changer info: %s", changer_resultstr);
371 (void)ud; /* Quiet unused parameter warning */
374 error("could not load slot %s: %s", slotstr, changer_resultstr);
378 fprintf(stderr, "%s: slot %s: %s\n",
379 get_pname(), slotstr, changer_resultstr);
380 else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL)
381 fprintf(stderr, "%s: slot %s: %s\n", get_pname(), slotstr, errstr);
383 fprintf(stderr, "%s: slot %s: date %-8s label %s",
384 get_pname(), slotstr, datestamp, label);
385 if(strcmp(label, FAKE_LABEL) != 0
386 && strcmp(label, searchlabel) != 0)
387 fprintf(stderr, " (wrong tape)\n");
389 fprintf(stderr, " (exact label match)\n");
390 if((errstr = tape_rewind(device)) != NULL) {
392 "%s: could not rewind %s: %s",
393 get_pname(), device, errstr);
415 searchlabel = argv[1];
417 fprintf(stderr, "%s: scanning for tape with label %s\n",
418 get_pname(), searchlabel);
422 changer_find(NULL, scan_init, loadlabel_slot, searchlabel);
425 fprintf(stderr, "%s: label %s is now loaded.\n",
426 get_pname(), searchlabel);
428 fprintf(stderr, "%s: could not find label %s in tape rack.\n",
429 get_pname(), searchlabel);
433 /* ---------------------------- */
443 (void)ud; /* Quiet unused parameter warning */
444 (void)s; /* Quiet unused parameter warning */
447 error("could not get changer info: %s", changer_resultstr);
464 int ret = show_init(NULL, rc, ns, bk, s);
466 (void)ud; /* Quiet unused parameter warning */
468 fprintf(stderr, "%s: scanning all %d slots in tape-changer rack:\n",
469 get_pname(), nslots);
481 int ret = show_init(NULL, rc, ns, bk, s);
483 (void)ud; /* Quiet unused parameter warning */
485 fprintf(stderr, "%s: scanning current slot in tape-changer rack:\n",
499 (void)ud; /* Quiet unused parameter warning */
502 error("could not load slot %s: %s", slotstr, changer_resultstr);
506 fprintf(stderr, "slot %s: %s\n", slotstr, changer_resultstr);
508 else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL) {
509 fprintf(stderr, "slot %s: %s\n", slotstr, errstr);
512 fprintf(stderr, "slot %s: date %-8s label %s\n",
513 slotstr, datestamp, label);
525 (void)argv; /* Quiet unused parameter warning */
530 changer_current(NULL, show_init_current, show_slot);
538 (void)argv; /* Quiet unused parameter warning */
543 changer_find(NULL, show_init_all, show_slot, NULL);
547 /* ---------------------------- */
557 (void)argc; /* Quiet unused parameter warning */
558 (void)argv; /* Quiet unused parameter warning */
560 if((tp = lookup_last_reusable_tape(0)) == NULL)
563 searchlabel = stralloc(tp->label);
565 tapedays = getconf_int(CNF_TAPECYCLE);
566 labelstr = getconf_str(CNF_LABELSTR);
570 fprintf(stderr, "%s: scanning for ", get_pname());
571 if(searchlabel) fprintf(stderr, "tape label %s or ", searchlabel);
572 fprintf(stderr, "a new tape.\n");
574 taper_scan(searchlabel, &label, &datestamp,&device, FILE_taperscan_output_callback, stderr);
576 fprintf(stderr, "%s: label %s is now loaded.\n",
584 /* ---------------------------- */
591 char *slot = NULL, *device = NULL;
593 (void)argc; /* Quiet unused parameter warning */
594 (void)argv; /* Quiet unused parameter warning */
596 if(changer_loadslot("current", &slot, &device)) {
597 error("Could not load current slot.\n");
601 printf("%s\n", device);
606 /* ---------------------------- */
616 char *datestamp = NULL;
619 (void)ud; /* Quiet unused parameter warning */
622 error("could not load slot %s: %s", slotstr, changer_resultstr);
624 fprintf(stderr, "slot %s: %s\n", slotstr, changer_resultstr);
625 else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL)
626 fprintf(stderr, "slot %s: %s\n", slotstr, errstr);
628 fprintf(stderr, "slot %s: date %-8s label %s\n",
629 slotstr, datestamp, label);
630 changer_label(slotstr, label);
643 (void)argv; /* Quiet unused parameter warning */
648 changer_find(NULL, show_init_all, update_one_slot, NULL);