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.40.2.1 2006/04/14 11:32:07 martinea Exp $
29 * tape changer interface program
34 #include "taperscan.h"
42 int main P((int argc, char **argv));
43 void reset_changer P((int argc, char **argv));
44 void eject_tape P((int argc, char **argv));
45 void clean_tape P((int argc, char **argv));
46 void load_slot P((int argc, char **argv));
47 void load_label P((int argc, char **argv));
48 void show_slots P((int argc, char **argv));
49 void show_current P((int argc, char **argv));
50 void update_labeldb P((int argc, char **argv));
51 void amtape_taper_scan P((int argc, char **argv));
52 void show_device P((int argc, char **argv));
53 int update_one_slot P((void *ud, int rc, char *slotstr, char *device));
54 int loadlabel_slot P((void *ud, int rc, char *slotstr, char *device));
55 int show_init P((void *ud, int rc, int ns, int bk, int s));
56 int show_init_all P((void *ud, int rc, int ns, int bk, int s));
57 int show_init_current P((void *ud, int rc, int ns, int bk, int s));
58 int show_slot P((void *ud, int rc, char *slotstr, char *device));
62 void (*fn) P((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 (sizeof(cmdtab) / sizeof(cmdtab[0]))
104 fprintf(stderr, "Usage: amtape%s <conf> <command>\n", versionsuffix());
105 fprintf(stderr, "\tValid commands are:\n");
106 for (i = 0; i < NCMDS; i++)
107 fprintf(stderr, "\t\t%s\n", cmdtab[i].usage);
117 char *argv0 = argv[0];
118 unsigned long malloc_hist_1, malloc_size_1;
119 unsigned long malloc_hist_2, malloc_size_2;
132 /* Don't die when child closes pipe */
133 signal(SIGPIPE, SIG_IGN);
135 malloc_size_1 = malloc_inuse(&malloc_hist_1);
137 erroutput_type = ERR_INTERACTIVE;
139 if(argc < 3) usage();
141 config_name = argv[1];
143 config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
144 conffile = stralloc2(config_dir, CONFFILE_NAME);
145 if (read_conffile(conffile)) {
146 error("errors processing config file \"%s\"", conffile);
149 conf_tapelist = getconf_str(CNF_TAPELIST);
150 if (*conf_tapelist == '/') {
151 conf_tapelist = stralloc(conf_tapelist);
153 conf_tapelist = stralloc2(config_dir, conf_tapelist);
155 if (read_tapelist(conf_tapelist)) {
156 error("could not load tapelist \"%s\"", conf_tapelist);
158 amfree(conf_tapelist);
161 uid_dumpuser = uid_me;
162 dumpuser = getconf_str(CNF_DUMPUSER);
164 if ((pw = getpwnam(dumpuser)) == NULL) {
165 error("cannot look up dump user \"%s\"", dumpuser);
168 uid_dumpuser = pw->pw_uid;
169 if ((pw = getpwuid(uid_me)) == NULL) {
170 error("cannot look up my own uid %ld", (long)uid_me);
173 if (uid_me != uid_dumpuser) {
174 error("running as user \"%s\" instead of \"%s\"",
175 pw->pw_name, dumpuser);
179 if((have_changer = changer_init()) == 0) {
180 error("no tpchanger specified in \"%s\"", conffile);
181 } else if (have_changer != 1) {
182 error("changer initialization failed: %s", strerror(errno));
185 /* switch on command name */
187 argc -= 2; argv += 2;
188 for (i = 0; i < NCMDS; i++)
189 if (strcmp(argv[0], cmdtab[i].name) == 0) {
190 (*cmdtab[i].fn)(argc, argv);
194 fprintf(stderr, "%s: unknown command \"%s\"\n", argv0, argv[0]);
198 amfree(changer_resultstr);
202 malloc_size_2 = malloc_inuse(&malloc_hist_2);
204 if(malloc_size_1 != malloc_size_2) {
205 malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
211 /* ---------------------------- */
213 void reset_changer(argc, argv)
217 char *slotstr = NULL;
219 switch(changer_reset(&slotstr)) {
221 fprintf(stderr, "%s: changer is reset, slot %s is loaded.\n",
222 get_pname(), slotstr);
225 fprintf(stderr, "%s: changer is reset, but slot %s not loaded: %s\n",
226 get_pname(), slotstr, changer_resultstr);
229 error("could not reset changer: %s", changer_resultstr);
235 /* ---------------------------- */
236 void clean_tape(argc, argv)
242 if(changer_clean(&devstr) == 0) {
243 fprintf(stderr, "%s: device %s is clean.\n", get_pname(), devstr);
245 fprintf(stderr, "%s: device %s not clean: %s\n",
246 get_pname(), devstr ? devstr : "??", changer_resultstr);
252 /* ---------------------------- */
253 void eject_tape(argc, argv)
257 char *slotstr = NULL;
259 if(changer_eject(&slotstr) == 0) {
260 fprintf(stderr, "%s: slot %s is ejected.\n", get_pname(), slotstr);
262 fprintf(stderr, "%s: slot %s not ejected: %s\n",
263 get_pname(), slotstr ? slotstr : "??", changer_resultstr);
269 /* ---------------------------- */
271 void load_slot(argc, argv)
275 char *slotstr = NULL, *devicename = NULL;
282 is_advance = (strcmp(argv[1], "advance") == 0);
283 if(changer_loadslot(argv[1], &slotstr, &devicename)) {
284 error("could not load slot %s: %s", slotstr, changer_resultstr);
286 if(! is_advance && (errstr = tape_rewind(devicename)) != NULL) {
288 "%s: could not rewind %s: %s", get_pname(), devicename, errstr);
292 fprintf(stderr, "%s: changed to slot %s", get_pname(), slotstr);
294 fprintf(stderr, " on %s", devicename);
302 /* ---------------------------- */
304 int nslots, backwards, found, got_match, tapedays;
306 char *label = NULL, *first_match_label = NULL, *first_match = NULL;
307 char *searchlabel, *labelstr;
311 scan_init(ud, rc, ns, bk, s)
316 error("could not get changer info: %s", changer_resultstr);
324 int loadlabel_slot(ud, rc, slotstr, device)
333 error("could not load slot %s: %s", slotstr, changer_resultstr);
335 fprintf(stderr, "%s: slot %s: %s\n",
336 get_pname(), slotstr, changer_resultstr);
337 else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL)
338 fprintf(stderr, "%s: slot %s: %s\n", get_pname(), slotstr, errstr);
340 fprintf(stderr, "%s: slot %s: date %-8s label %s",
341 get_pname(), slotstr, datestamp, label);
342 if(strcmp(label, FAKE_LABEL) != 0
343 && strcmp(label, searchlabel) != 0)
344 fprintf(stderr, " (wrong tape)\n");
346 fprintf(stderr, " (exact label match)\n");
347 if((errstr = tape_rewind(device)) != NULL) {
349 "%s: could not rewind %s: %s",
350 get_pname(), device, errstr);
364 void load_label(argc, argv)
371 searchlabel = argv[1];
373 fprintf(stderr, "%s: scanning for tape with label %s\n",
374 get_pname(), searchlabel);
378 changer_find(NULL, scan_init, loadlabel_slot, searchlabel);
381 fprintf(stderr, "%s: label %s is now loaded.\n",
382 get_pname(), searchlabel);
384 fprintf(stderr, "%s: could not find label %s in tape rack.\n",
385 get_pname(), searchlabel);
389 /* ---------------------------- */
391 int show_init(ud, rc, ns, bk, s)
396 error("could not get changer info: %s", changer_resultstr);
403 int show_init_all(ud, rc, ns, bk, s)
407 int ret = show_init(NULL, rc, ns, bk, s);
408 fprintf(stderr, "%s: scanning all %d slots in tape-changer rack:\n",
409 get_pname(), nslots);
413 int show_init_current(ud, rc, ns, bk, s)
417 int ret = show_init(NULL, rc, ns, bk, s);
418 fprintf(stderr, "%s: scanning current slot in tape-changer rack:\n",
423 int show_slot(ud, rc, slotstr, device)
426 char *slotstr, *device;
431 error("could not load slot %s: %s", slotstr, changer_resultstr);
433 fprintf(stderr, "slot %s: %s\n", slotstr, changer_resultstr);
434 else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL)
435 fprintf(stderr, "slot %s: %s\n", slotstr, errstr);
437 fprintf(stderr, "slot %s: date %-8s label %s\n",
438 slotstr, datestamp, label);
445 void show_current(argc, argv)
452 changer_current(NULL, show_init_current, show_slot);
455 void show_slots(argc, argv)
462 changer_find(NULL, show_init_all, show_slot, NULL);
466 /* ---------------------------- */
467 void amtape_taper_scan(argc, argv)
472 char *label = NULL, *errmsg = NULL;
474 if((tp = lookup_last_reusable_tape(0)) == NULL)
477 searchlabel = stralloc(tp->label);
479 tapedays = getconf_int(CNF_TAPECYCLE);
480 labelstr = getconf_str(CNF_LABELSTR);
484 fprintf(stderr, "%s: scanning for ", get_pname());
485 if(searchlabel) fprintf(stderr, "tape label %s or ", searchlabel);
486 fprintf(stderr, "a new tape.\n");
488 if (taper_scan(searchlabel, &label, &datestamp, &errmsg, &device) <= 0) {
489 fprintf(stderr, "%s\n", errmsg);
492 fprintf(stderr, "%s: label %s is now loaded.\n",
501 /* ---------------------------- */
503 void show_device(argc, argv)
507 char *slot = NULL, *device = NULL;
509 if(changer_loadslot("current", &slot, &device))
510 error("Could not load current slot.\n");
512 printf("%s\n", device);
517 /* ---------------------------- */
519 int update_one_slot(ud, rc, slotstr, device)
526 char *datestamp = NULL;
530 error("could not load slot %s: %s", slotstr, changer_resultstr);
532 fprintf(stderr, "slot %s: %s\n", slotstr, changer_resultstr);
533 else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL)
534 fprintf(stderr, "slot %s: %s\n", slotstr, errstr);
536 fprintf(stderr, "slot %s: date %-8s label %s\n",
537 slotstr, datestamp, label);
538 changer_label(slotstr, label);
546 void update_labeldb(argc, argv)
553 changer_find(NULL, show_init_all, update_one_slot, NULL);