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 2006/01/14 04:37:19 paddy_s 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 amtape_taper_scan P((int argc, char **argv));
51 void show_device P((int argc, char **argv));
52 int loadlabel_slot P((void *ud, int rc, char *slotstr, char *device));
53 int show_init P((void *ud, int rc, int ns, int bk, int s));
54 int show_init_all P((void *ud, int rc, int ns, int bk, int s));
55 int show_init_current P((void *ud, int rc, int ns, int bk, int s));
56 int show_slot P((void *ud, int rc, char *slotstr, char *device));
60 void (*fn) P((int, char **));
63 { "reset", reset_changer,
64 "reset Reset changer to known state" },
65 { "eject", eject_tape,
66 "eject Eject current tape from drive" },
67 { "clean", clean_tape,
68 "clean Clean the drive" },
70 "show Show contents of all slots" },
71 { "current", show_current,
72 "current Show contents of current slot" },
74 "slot <slot #> load tape from slot <slot #>" },
76 "slot current load tape from current slot" },
78 "slot prev load tape from previous slot" },
80 "slot next load tape from next slot" },
82 "slot advance advance to next slot but do not load" },
84 "slot first load tape from first slot" },
86 "slot last load tape from last slot" },
87 { "label", load_label,
88 "label <label> find and load labeled tape" },
89 { "taper", amtape_taper_scan,
90 "taper perform taper's scan alg." },
91 { "device", show_device,
92 "device show current tape device" },
94 #define NCMDS (sizeof(cmdtab) / sizeof(cmdtab[0]))
100 fprintf(stderr, "Usage: amtape%s <conf> <command>\n", versionsuffix());
101 fprintf(stderr, "\tValid commands are:\n");
102 for (i = 0; i < NCMDS; i++)
103 fprintf(stderr, "\t\t%s\n", cmdtab[i].usage);
113 char *argv0 = argv[0];
114 unsigned long malloc_hist_1, malloc_size_1;
115 unsigned long malloc_hist_2, malloc_size_2;
128 /* Don't die when child closes pipe */
129 signal(SIGPIPE, SIG_IGN);
131 malloc_size_1 = malloc_inuse(&malloc_hist_1);
133 erroutput_type = ERR_INTERACTIVE;
135 if(argc < 3) usage();
137 config_name = argv[1];
139 config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
140 conffile = stralloc2(config_dir, CONFFILE_NAME);
141 if (read_conffile(conffile)) {
142 error("errors processing config file \"%s\"", conffile);
145 conf_tapelist = getconf_str(CNF_TAPELIST);
146 if (*conf_tapelist == '/') {
147 conf_tapelist = stralloc(conf_tapelist);
149 conf_tapelist = stralloc2(config_dir, conf_tapelist);
151 if (read_tapelist(conf_tapelist)) {
152 error("could not load tapelist \"%s\"", conf_tapelist);
154 amfree(conf_tapelist);
157 uid_dumpuser = uid_me;
158 dumpuser = getconf_str(CNF_DUMPUSER);
160 if ((pw = getpwnam(dumpuser)) == NULL) {
161 error("cannot look up dump user \"%s\"", dumpuser);
164 uid_dumpuser = pw->pw_uid;
165 if ((pw = getpwuid(uid_me)) == NULL) {
166 error("cannot look up my own uid %ld", (long)uid_me);
169 if (uid_me != uid_dumpuser) {
170 error("running as user \"%s\" instead of \"%s\"",
171 pw->pw_name, dumpuser);
175 if((have_changer = changer_init()) == 0) {
176 error("no tpchanger specified in \"%s\"", conffile);
177 } else if (have_changer != 1) {
178 error("changer initialization failed: %s", strerror(errno));
181 /* switch on command name */
183 argc -= 2; argv += 2;
184 for (i = 0; i < NCMDS; i++)
185 if (strcmp(argv[0], cmdtab[i].name) == 0) {
186 (*cmdtab[i].fn)(argc, argv);
190 fprintf(stderr, "%s: unknown command \"%s\"\n", argv0, argv[0]);
194 amfree(changer_resultstr);
198 malloc_size_2 = malloc_inuse(&malloc_hist_2);
200 if(malloc_size_1 != malloc_size_2) {
201 malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
207 /* ---------------------------- */
209 void reset_changer(argc, argv)
213 char *slotstr = NULL;
215 switch(changer_reset(&slotstr)) {
217 fprintf(stderr, "%s: changer is reset, slot %s is loaded.\n",
218 get_pname(), slotstr);
221 fprintf(stderr, "%s: changer is reset, but slot %s not loaded: %s\n",
222 get_pname(), slotstr, changer_resultstr);
225 error("could not reset changer: %s", changer_resultstr);
231 /* ---------------------------- */
232 void clean_tape(argc, argv)
238 if(changer_clean(&devstr) == 0) {
239 fprintf(stderr, "%s: device %s is clean.\n", get_pname(), devstr);
241 fprintf(stderr, "%s: device %s not clean: %s\n",
242 get_pname(), devstr ? devstr : "??", changer_resultstr);
248 /* ---------------------------- */
249 void eject_tape(argc, argv)
253 char *slotstr = NULL;
255 if(changer_eject(&slotstr) == 0) {
256 fprintf(stderr, "%s: slot %s is ejected.\n", get_pname(), slotstr);
258 fprintf(stderr, "%s: slot %s not ejected: %s\n",
259 get_pname(), slotstr ? slotstr : "??", changer_resultstr);
265 /* ---------------------------- */
267 void load_slot(argc, argv)
271 char *slotstr = NULL, *devicename = NULL;
278 is_advance = (strcmp(argv[1], "advance") == 0);
279 if(changer_loadslot(argv[1], &slotstr, &devicename)) {
280 error("could not load slot %s: %s", slotstr, changer_resultstr);
282 if(! is_advance && (errstr = tape_rewind(devicename)) != NULL) {
284 "%s: could not rewind %s: %s", get_pname(), devicename, errstr);
288 fprintf(stderr, "%s: changed to slot %s", get_pname(), slotstr);
290 fprintf(stderr, " on %s", devicename);
298 /* ---------------------------- */
300 int nslots, backwards, found, got_match, tapedays;
302 char *label = NULL, *first_match_label = NULL, *first_match = NULL;
303 char *searchlabel, *labelstr;
307 scan_init(ud, rc, ns, bk, s)
312 error("could not get changer info: %s", changer_resultstr);
320 int loadlabel_slot(ud, rc, slotstr, device)
329 error("could not load slot %s: %s", slotstr, changer_resultstr);
331 fprintf(stderr, "%s: slot %s: %s\n",
332 get_pname(), slotstr, changer_resultstr);
333 else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL)
334 fprintf(stderr, "%s: slot %s: %s\n", get_pname(), slotstr, errstr);
336 fprintf(stderr, "%s: slot %s: date %-8s label %s",
337 get_pname(), slotstr, datestamp, label);
338 if(strcmp(label, FAKE_LABEL) != 0
339 && strcmp(label, searchlabel) != 0)
340 fprintf(stderr, " (wrong tape)\n");
342 fprintf(stderr, " (exact label match)\n");
343 if((errstr = tape_rewind(device)) != NULL) {
345 "%s: could not rewind %s: %s",
346 get_pname(), device, errstr);
360 void load_label(argc, argv)
367 searchlabel = argv[1];
369 fprintf(stderr, "%s: scanning for tape with label %s\n",
370 get_pname(), searchlabel);
374 changer_find(NULL, scan_init, loadlabel_slot, searchlabel);
377 fprintf(stderr, "%s: label %s is now loaded.\n",
378 get_pname(), searchlabel);
380 fprintf(stderr, "%s: could not find label %s in tape rack.\n",
381 get_pname(), searchlabel);
385 /* ---------------------------- */
387 int show_init(ud, rc, ns, bk, s)
392 error("could not get changer info: %s", changer_resultstr);
399 int show_init_all(ud, rc, ns, bk, s)
403 int ret = show_init(NULL, rc, ns, bk, s);
404 fprintf(stderr, "%s: scanning all %d slots in tape-changer rack:\n",
405 get_pname(), nslots);
409 int show_init_current(ud, rc, ns, bk, s)
413 int ret = show_init(NULL, rc, ns, bk, s);
414 fprintf(stderr, "%s: scanning current slot in tape-changer rack:\n",
419 int show_slot(ud, rc, slotstr, device)
422 char *slotstr, *device;
427 error("could not load slot %s: %s", slotstr, changer_resultstr);
429 fprintf(stderr, "slot %s: %s\n", slotstr, changer_resultstr);
430 else if((errstr = tape_rdlabel(device, &datestamp, &label)) != NULL)
431 fprintf(stderr, "slot %s: %s\n", slotstr, errstr);
433 fprintf(stderr, "slot %s: date %-8s label %s\n",
434 slotstr, datestamp, label);
441 void show_current(argc, argv)
448 changer_current(NULL, show_init_current, show_slot);
451 void show_slots(argc, argv)
458 changer_find(NULL, show_init_all, show_slot, NULL);
462 /* ---------------------------- */
463 void amtape_taper_scan(argc, argv)
468 char *label = NULL, *errmsg = NULL;
470 if((tp = lookup_last_reusable_tape(0)) == NULL)
473 searchlabel = stralloc(tp->label);
475 tapedays = getconf_int(CNF_TAPECYCLE);
476 labelstr = getconf_str(CNF_LABELSTR);
480 fprintf(stderr, "%s: scanning for ", get_pname());
481 if(searchlabel) fprintf(stderr, "tape label %s or ", searchlabel);
482 fprintf(stderr, "a new tape.\n");
484 if (taper_scan(searchlabel, &label, &datestamp, &errmsg, &device) <= 0) {
485 fprintf(stderr, "%s\n", errmsg);
488 fprintf(stderr, "%s: label %s is now loaded.\n",
497 /* ---------------------------- */
499 void show_device(argc, argv)
503 char *slot = NULL, *device = NULL;
505 if(changer_loadslot("current", &slot, &device))
506 error("Could not load current slot.\n");
508 printf("%s\n", device);