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.43 2006/01/14 04:37:19 paddy_s Exp $
29 * write an Amanda label on a tape
39 #endif /* HAVE_LIBVTBLC */
43 int main P((int, char **));
44 void usage P((char *argv0));
49 fprintf(stderr, "Usage: %s [-f] <conf> <label> [slot <slot-number>]\n",
61 char *errstr = NULL, *label, *oldlabel=NULL, *tapename = NULL;
62 char *labelstr, *slotstr;
63 char *olddatestamp=NULL;
64 char *conf_tapelist_old;
65 unsigned long malloc_hist_1, malloc_size_1;
66 unsigned long malloc_hist_2, malloc_size_2;
67 #ifdef HAVE_LINUX_ZFTAPE_H
70 #endif /* HAVE_LINUX_ZFTAPE_H */
85 char *rawtapedev = NULL;
86 int first_seg, last_seg;
87 #endif /* HAVE_LIBVTBLC */
94 /* Don't die when child closes pipe */
95 signal(SIGPIPE, SIG_IGN);
97 malloc_size_1 = malloc_inuse(&malloc_hist_1);
99 erroutput_type = ERR_INTERACTIVE;
101 if(argc > 1 && strcmp(argv[1],"-f") == 0)
105 if(argc != 3+force && argc != 5+force)
108 config_name = argv[1+force];
109 label = argv[2+force];
111 if(argc == 5+force) {
112 if(strcmp(argv[3+force], "slot"))
114 slotstr = argv[4+force];
121 config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
122 conffile = stralloc2(config_dir, CONFFILE_NAME);
123 if (read_conffile(conffile)) {
124 error("errors processing config file \"%s\"", conffile);
127 conf_tapelist = getconf_str(CNF_TAPELIST);
128 if (*conf_tapelist == '/') {
129 conf_tapelist = stralloc(conf_tapelist);
131 conf_tapelist = stralloc2(config_dir, conf_tapelist);
133 if (read_tapelist(conf_tapelist)) {
134 error("could not load tapelist \"%s\"", conf_tapelist);
138 uid_dumpuser = uid_me;
139 dumpuser = getconf_str(CNF_DUMPUSER);
141 if ((pw = getpwnam(dumpuser)) == NULL) {
142 error("cannot look up dump user \"%s\"", dumpuser);
145 uid_dumpuser = pw->pw_uid;
146 if ((pw = getpwuid(uid_me)) == NULL) {
147 error("cannot look up my own uid %ld", (long)uid_me);
150 if (uid_me != uid_dumpuser) {
151 error("running as user \"%s\" instead of \"%s\"",
152 pw->pw_name, dumpuser);
156 labelstr = getconf_str(CNF_LABELSTR);
158 if(!match(labelstr, label))
159 error("label %s doesn't match labelstr \"%s\"", label, labelstr);
161 if((tp = lookup_tapelabel(label))!=NULL) {
163 error("label %s already on a tape\n",label);
165 tape = lookup_tapetype(getconf_str(CNF_TAPETYPE));
166 tt_blocksize_kb = tape->blocksize;
168 if((have_changer = changer_init()) == 0) {
171 "%s: no tpchanger specified in \"%s\", so slot command invalid\n",
175 tapename = stralloc(getconf_str(CNF_TAPEDEV));
177 rawtapedev = stralloc(getconf_str(CNF_RAWTAPEDEV));
178 #endif /* HAVE_LIBVTBLC */
179 } else if(have_changer != 1) {
180 error("changer initialization failed: %s", strerror(errno));
182 if(changer_loadslot(slotstr, &outslot, &tapename)) {
183 error("could not load slot \"%s\": %s", slotstr, changer_resultstr);
186 printf("labeling tape in slot %s (%s):\n", outslot, tapename);
189 #ifdef HAVE_LINUX_ZFTAPE_H
190 isa_zftape = is_zftape(tapename);
192 if((fd = tape_open(tapename, O_WRONLY)) == -1) {
193 errstr = newstralloc2(errstr, "amlabel: ",
194 (errno == EACCES) ? "tape is write-protected"
199 #endif /* HAVE_LINUX_ZFTAPE_H */
201 printf("rewinding"); fflush(stdout);
203 #ifdef HAVE_LINUX_ZFTAPE_H
205 if(tapefd_rewind(fd) == -1) {
207 error(strerror(errno));
211 #endif /* HAVE_LINUX_ZFTAPE_H */
212 if((errstr = tape_rewind(tapename)) != NULL) {
218 printf(", reading label");fflush(stdout);
219 if((errstr = tape_rdlabel(tapename, &olddatestamp, &oldlabel)) != NULL) {
220 printf(", %s\n",errstr);
224 /* got an amanda tape */
225 printf(" %s",oldlabel);
226 if(strcmp(oldlabel, FAKE_LABEL) != 0
227 && match(labelstr, oldlabel) == 0) {
228 printf(", tape is in another amanda configuration");
233 if((tp = lookup_tapelabel(oldlabel)) != NULL) {
234 printf(", tape is active");
242 amfree(olddatestamp);
244 printf("rewinding"); fflush(stdout);
246 #ifdef HAVE_LINUX_ZFTAPE_H
248 if(tapefd_rewind(fd) == -1) {
250 error(strerror(errno));
254 #endif /* HAVE_LINUX_ZFTAPE_H */
255 if((errstr = tape_rewind(tapename)) != NULL) {
261 printf(", writing label %s", label); fflush(stdout);
263 #ifdef HAVE_LINUX_ZFTAPE_H
265 errstr = tapefd_wrlabel(fd, "X", label, tt_blocksize_kb * 1024);
272 #endif /* HAVE_LINUX_ZFTAPE_H */
273 errstr = tape_wrlabel(tapename, "X", label, tt_blocksize_kb * 1024);
279 #ifdef HAVE_LINUX_ZFTAPE_H
283 #endif /* HAVE_LINUX_ZFTAPE_H */
285 #ifdef HAVE_LINUX_ZFTAPE_H
287 errstr = tapefd_wrendmark(fd, "X", tt_blocksize_kb * 1024);
294 #endif /* HAVE_LINUX_ZFTAPE_H */
295 errstr = tape_wrendmark(tapename, "X", tt_blocksize_kb * 1024);
301 #ifdef HAVE_LINUX_ZFTAPE_H
305 printf(",\nrewinding"); fflush(stdout);
307 if(tapefd_rewind(fd) == -1) {
309 error(strerror(errno));
313 /* update volume table */
314 printf(", updating volume table"); fflush(stdout);
316 if ((fd = raw_tape_open(rawtapedev, O_RDWR)) == -1) {
317 if(errno == EACCES) {
318 errstr = newstralloc(errstr,
319 "updating volume table: raw tape device is write protected");
321 errstr = newstralloc2(errstr,
322 "updating volume table: ", strerror(errno));
327 /* read volume table */
328 if ((num_volumes = read_vtbl(fd, volumes, vtbl_buffer,
329 &first_seg, &last_seg)) == -1 ) {
330 errstr = newstralloc2(errstr,
331 "reading volume table: ", strerror(errno));
335 /* set date and volume label for first entry */
338 if (set_date(datestr, volumes, num_volumes, vtbl_no)){
339 errstr = newstralloc2(errstr,
340 "setting date for entry 1: ", strerror(errno));
344 if(set_label(label, volumes, num_volumes, vtbl_no)){
345 errstr = newstralloc2(errstr,
346 "setting label for entry 1: ", strerror(errno));
350 /* set date and volume label for last entry */
353 if (set_date(datestr, volumes, num_volumes, vtbl_no)){
354 errstr = newstralloc2(errstr,
355 "setting date for entry 2: ", strerror(errno));
359 if(set_label("AMANDA Tape End", volumes, num_volumes, vtbl_no)){
360 errstr = newstralloc2(errstr,
361 "setting label for entry 2: ", strerror(errno));
365 /* write volume table back */
366 if (write_vtbl(fd, volumes, vtbl_buffer, num_volumes, first_seg,
368 errstr = newstralloc2(errstr,
369 "writing volume table: ", strerror(errno));
374 #endif /* HAVE_LIBVTBLC */
376 #endif /* HAVE_LINUX_ZFTAPE_H */
379 printf(", checking label"); fflush(stdout);
381 if((errstr = tape_rdlabel(tapename, &olddatestamp, &oldlabel)) != NULL) {
383 if (strcmp(errstr, "not an amanda tape") != 0)
385 error("no label found, are you sure %s is non-rewinding?",
389 if (strcmp("X", olddatestamp) != 0 ||
390 (strcmp(oldlabel, FAKE_LABEL) != 0
391 && strcmp(label, oldlabel) != 0)) {
393 error("read label %s back, timestamp %s (expected X), what now?",
394 oldlabel, olddatestamp);
397 amfree(olddatestamp);
399 /* write tape list */
402 conf_tapelist_old = stralloc2(conf_tapelist, ".amlabel");
403 if(write_tapelist(conf_tapelist_old)) {
404 error("couldn't write tapelist: %s", strerror(errno));
406 amfree(conf_tapelist_old);
408 /* XXX add cur_tape number to tape list structure */
409 remove_tapelabel(label);
410 add_tapelabel(0, label);
411 if(write_tapelist(conf_tapelist)) {
412 error("couldn't write tapelist: %s", strerror(errno));
414 } /* write tape list */
417 /* Now we try to inform the changer, about the new label */
418 /* changer_label(outslot,label); */
422 printf("\ntape not labeled\n");
428 amfree(conf_tapelist);
432 malloc_size_2 = malloc_inuse(&malloc_hist_2);
434 if(malloc_size_1 != malloc_size_2) {
435 malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);