2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-1998, 2000 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: amlabel.c,v 1.18.2.15.4.3.2.4 2003/01/01 23:28:53 martinea Exp $
29 * write an Amanda label on a tape
39 #endif /* HAVE_LIBVTBLC */
43 void usage P((char *argv0));
48 fprintf(stderr, "Usage: %s [-f] <conf> <label> [slot <slot-number>]\n",
60 char *errstr = NULL, *label, *oldlabel=NULL, *tapename = NULL;
61 char *labelstr, *slotstr;
62 char *olddatestamp=NULL;
63 char *conf_tapelist_old;
64 unsigned long malloc_hist_1, malloc_size_1;
65 unsigned long malloc_hist_2, malloc_size_2;
81 char *rawtapedev = NULL;
82 int first_seg, last_seg;
83 #endif /* HAVE_LIBVTBLC */
85 for(fd = 3; fd < FD_SETSIZE; fd++) {
87 * Make sure nobody spoofs us with a lot of extra open files
88 * that would cause an open we do to get a very high file
89 * descriptor, which in turn might be used as an index into
90 * an array (e.g. an fd_set).
100 malloc_size_1 = malloc_inuse(&malloc_hist_1);
102 erroutput_type = ERR_INTERACTIVE;
104 if(argc > 1 && strcmp(argv[1],"-f") == 0)
108 if(argc != 3+force && argc != 5+force)
111 config_name = argv[1+force];
112 label = argv[2+force];
114 if(argc == 5+force) {
115 if(strcmp(argv[3+force], "slot"))
117 slotstr = argv[4+force];
124 config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
125 conffile = stralloc2(config_dir, CONFFILE_NAME);
126 if (read_conffile(conffile)) {
127 error("errors processing config file \"%s\"", conffile);
129 conf_tapelist = getconf_str(CNF_TAPELIST);
130 if (*conf_tapelist == '/') {
131 conf_tapelist = stralloc(conf_tapelist);
133 conf_tapelist = stralloc2(config_dir, conf_tapelist);
135 if (read_tapelist(conf_tapelist)) {
136 error("could not load tapelist \"%s\"", conf_tapelist);
140 uid_dumpuser = uid_me;
141 dumpuser = getconf_str(CNF_DUMPUSER);
143 if ((pw = getpwnam(dumpuser)) == NULL) {
144 error("cannot look up dump user \"%s\"", dumpuser);
147 uid_dumpuser = pw->pw_uid;
148 if ((pw = getpwuid(uid_me)) == NULL) {
149 error("cannot look up my own uid %ld", (long)uid_me);
152 if (uid_me != uid_dumpuser) {
153 error("running as user \"%s\" instead of \"%s\"",
154 pw->pw_name, dumpuser);
158 labelstr = getconf_str(CNF_LABELSTR);
160 if(!match(labelstr, label))
161 error("label %s doesn't match labelstr \"%s\"", label, labelstr);
163 if((tp = lookup_tapelabel(label))!=NULL) {
165 error("label %s already on a tape\n",label);
167 tape = lookup_tapetype(getconf_str(CNF_TAPETYPE));
168 tt_blocksize_kb = tape->blocksize;
170 if((have_changer = changer_init()) == 0) {
173 "%s: no tpchanger specified in \"%s\", so slot command invalid\n",
177 tapename = stralloc(getconf_str(CNF_TAPEDEV));
179 rawtapedev = stralloc(getconf_str(CNF_RAWTAPEDEV));
180 #endif /* HAVE_LIBVTBLC */
181 } else if(have_changer != 1) {
182 error("changer initialization failed: %s", strerror(errno));
184 if(changer_loadslot(slotstr, &outslot, &tapename)) {
185 error("could not load slot \"%s\": %s", slotstr, changer_resultstr);
188 printf("labeling tape in slot %s (%s):\n", outslot, tapename);
191 #ifdef HAVE_LINUX_ZFTAPE_H
192 if (is_zftape(tapename) == 1){
193 if((fd = tape_open(tapename, O_WRONLY)) == -1) {
194 errstr = newstralloc2(errstr, "amlabel: ",
195 (errno == EACCES) ? "tape is write-protected"
200 #endif /* HAVE_LINUX_ZFTAPE_H */
202 printf("rewinding"); fflush(stdout);
204 #ifdef HAVE_LINUX_ZFTAPE_H
205 if (is_zftape(tapename) == 1){
206 if(tapefd_rewind(fd) == -1) {
208 error(strerror(errno));
212 #endif /* HAVE_LINUX_ZFTAPE_H */
213 if((errstr = tape_rewind(tapename)) != NULL) {
219 printf(", reading label");fflush(stdout);
220 if((errstr = tape_rdlabel(tapename, &olddatestamp, &oldlabel)) != NULL) {
221 printf(", %s\n",errstr);
225 /* got an amanda tape */
226 printf(" %s",oldlabel);
227 if(strcmp(oldlabel, FAKE_LABEL) != 0
228 && match(labelstr, oldlabel) == 0) {
229 printf(", tape is in another amanda configuration");
234 if((tp = lookup_tapelabel(oldlabel)) != NULL) {
235 printf(", tape is active");
243 amfree(olddatestamp);
245 printf("rewinding"); fflush(stdout);
247 #ifdef HAVE_LINUX_ZFTAPE_H
248 if (is_zftape(tapename) == 1){
249 if(tapefd_rewind(fd) == -1) {
251 error(strerror(errno));
255 #endif /* HAVE_LINUX_ZFTAPE_H */
256 if((errstr = tape_rewind(tapename)) != NULL) {
262 printf(", writing label %s", label); fflush(stdout);
264 #ifdef HAVE_LINUX_ZFTAPE_H
265 if (is_zftape(tapename) == 1){
266 errstr = tapefd_wrlabel(fd, "X", label, tt_blocksize_kb * 1024);
273 #endif /* HAVE_LINUX_ZFTAPE_H */
274 errstr = tape_wrlabel(tapename, "X", label, tt_blocksize_kb * 1024);
280 #ifdef HAVE_LINUX_ZFTAPE_H
281 if (is_zftape(tapename) == 1){
284 #endif /* HAVE_LINUX_ZFTAPE_H */
286 #ifdef HAVE_LINUX_ZFTAPE_H
287 if (is_zftape(tapename) == 1){
288 errstr = tapefd_wrendmark(fd, "X", tt_blocksize_kb * 1024);
295 #endif /* HAVE_LINUX_ZFTAPE_H */
296 errstr = tape_wrendmark(tapename, "X", tt_blocksize_kb * 1024);
302 #ifdef HAVE_LINUX_ZFTAPE_H
303 if (is_zftape(tapename) == 1){
306 printf(",\nrewinding"); fflush(stdout);
308 if(tapefd_rewind(fd) == -1) {
310 error(strerror(errno));
314 /* update volume table */
315 printf(", updating volume table"); fflush(stdout);
317 if ((fd = raw_tape_open(rawtapedev, O_RDWR)) == -1) {
318 if(errno == EACCES) {
319 errstr = newstralloc(errstr,
320 "updating volume table: raw tape device is write protected");
322 errstr = newstralloc2(errstr,
323 "updating volume table: ", strerror(errno));
328 /* read volume table */
329 if ((num_volumes = read_vtbl(fd, volumes, vtbl_buffer,
330 &first_seg, &last_seg)) == -1 ) {
331 errstr = newstralloc2(errstr,
332 "reading volume table: ", strerror(errno));
336 /* set date and volume label for first entry */
339 if (set_date(datestr, volumes, num_volumes, vtbl_no)){
340 errstr = newstralloc2(errstr,
341 "setting date for entry 1: ", strerror(errno));
345 if(set_label(label, volumes, num_volumes, vtbl_no)){
346 errstr = newstralloc2(errstr,
347 "setting label for entry 1: ", strerror(errno));
351 /* set date and volume label for last entry */
354 if (set_date(datestr, volumes, num_volumes, vtbl_no)){
355 errstr = newstralloc2(errstr,
356 "setting date for entry 2: ", strerror(errno));
360 if(set_label("AMANDA Tape End", volumes, num_volumes, vtbl_no)){
361 errstr = newstralloc2(errstr,
362 "setting label for entry 2: ", strerror(errno));
366 /* write volume table back */
367 if (write_vtbl(fd, volumes, vtbl_buffer, num_volumes, first_seg,
369 errstr = newstralloc2(errstr,
370 "writing volume table: ", strerror(errno));
375 #endif /* HAVE_LIBVTBLC */
377 #endif /* HAVE_LINUX_ZFTAPE_H */
380 printf(", checking label"); fflush(stdout);
382 if((errstr = tape_rdlabel(tapename, &olddatestamp, &oldlabel)) != NULL) {
384 if (strcmp(errstr, "not an amanda tape") != 0)
386 error("no label found, are you sure %s is non-rewinding?",
390 if (strcmp("X", olddatestamp) != 0 ||
391 (strcmp(oldlabel, FAKE_LABEL) != 0
392 && strcmp(label, oldlabel) != 0)) {
394 error("read label %s back, timestamp %s (expected X), what now?",
395 oldlabel, olddatestamp);
398 amfree(olddatestamp);
400 /* write tape list */
403 conf_tapelist_old = stralloc2(conf_tapelist, ".amlabel");
404 if(write_tapelist(conf_tapelist_old)) {
405 error("couldn't write tapelist: %s", strerror(errno));
407 amfree(conf_tapelist_old);
409 /* XXX add cur_tape number to tape list structure */
410 remove_tapelabel(label);
411 add_tapelabel(0, label);
412 if(write_tapelist(conf_tapelist)) {
413 error("couldn't write tapelist: %s", strerror(errno));
415 } /* write tape list */
418 /* Now we try to inform the changer, about the new label */
419 changer_label(outslot,label);
423 printf("\ntape not labeled\n");
429 amfree(conf_tapelist);
433 malloc_size_2 = malloc_inuse(&malloc_hist_2);
435 if(malloc_size_1 != malloc_size_2) {
436 malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);