Imported Upstream version 2.6.1p2
[debian/amanda] / server-src / amlabel.c
index 4e0ae46b26a6ab8a76c553ee8bf4c1e3dd771a1d..a170f7c552963282b2742559eaa0ec32865d4447 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amlabel.c,v 1.18.2.15.4.3.2.4 2003/01/01 23:28:53 martinea Exp $
+ * $Id: amlabel.c,v 1.53 2006/07/25 18:27:57 martinea Exp $
  *
  * write an Amanda label on a tape
  */
 #include "amanda.h"
 #include "conffile.h"
 #include "tapefile.h"
-#include "tapeio.h"
 #include "changer.h"
-
-#ifdef HAVE_LIBVTBLC
-#include <vtblc.h>
-#endif /* HAVE_LIBVTBLC */
+#include <device.h>
+#include <timestamp.h>
+#include <taperscan.h>
 
 /* local functions */
 
-void usage P((char *argv0));
+int main(int argc, char **argv);
 
-void usage(argv0)
-char *argv0;
-{
-    fprintf(stderr, "Usage: %s [-f] <conf> <label> [slot <slot-number>]\n",
-           argv0);
+static void usage(void) {
+    g_fprintf(stderr, _("Usage: %s [-f] <conf> <label> [slot <slot-number>] [-o configoption]*\n"),
+           get_pname());
     exit(1);
 }
 
-int main(argc, argv)
-    int argc;
-    char **argv;
+int
+main(
+    int                argc,
+    char **    argv)
 {
-    char *conffile;
     char *conf_tapelist;
     char *outslot = NULL;
-    char *errstr = NULL, *label, *oldlabel=NULL, *tapename = NULL;
+    char *label, *tapename = NULL;
     char *labelstr, *slotstr;
-    char *olddatestamp=NULL;
     char *conf_tapelist_old;
-    unsigned long malloc_hist_1, malloc_size_1;
-    unsigned long malloc_hist_2, malloc_size_2;
-    int fd;
     int have_changer;
     int force, tape_ok;
-    tape_t *tp;
     tapetype_t *tape;
-    long tt_blocksize_kb;
+    size_t tt_blocksize_kb;
     int slotcommand;
-    uid_t uid_me;
-    uid_t uid_dumpuser;
-    char *dumpuser;
-    struct passwd *pw;
-
-#ifdef HAVE_LIBVTBLC
-    int vtbl_no      = -1;
-    char *datestr    = NULL;
-    char *rawtapedev = NULL;
-    int first_seg, last_seg;
-#endif /* HAVE_LIBVTBLC */
-
-    for(fd = 3; fd < FD_SETSIZE; fd++) {
-       /*
-        * Make sure nobody spoofs us with a lot of extra open files
-        * that would cause an open we do to get a very high file
-        * descriptor, which in turn might be used as an index into
-        * an array (e.g. an fd_set).
-        */
-       close(fd);
-    }
-
+    Device * device;
+    DeviceStatusFlags device_status;
+    char *cfg_opt = NULL;
+    config_overwrites_t *cfg_ovr = NULL;
+
+    /*
+     * Configure program for internationalization:
+     *   1) Only set the message locale for now.
+     *   2) Set textdomain for all amanda related programs to "amanda"
+     *      We don't want to be forced to support dozens of message catalogs.
+     */  
+    setlocale(LC_MESSAGES, "C");
+    textdomain("amanda"); 
+
+    safe_fd(-1, 0);
     safe_cd();
 
     set_pname("amlabel");
-    dbopen();
 
-    malloc_size_1 = malloc_inuse(&malloc_hist_1);
+    dbopen(DBG_SUBDIR_SERVER);
+    device_api_init();
+
+    /* Don't die when child closes pipe */
+    signal(SIGPIPE, SIG_IGN);
 
     erroutput_type = ERR_INTERACTIVE;
 
+    cfg_ovr = extract_commandline_config_overwrites(&argc, &argv);
+
     if(argc > 1 && strcmp(argv[1],"-f") == 0)
         force=1;
     else force=0;
 
     if(argc != 3+force && argc != 5+force)
-       usage(argv[0]);
+       usage();
 
-    config_name = argv[1+force];
+    cfg_opt = argv[1+force];
     label = argv[2+force];
 
     if(argc == 5+force) {
        if(strcmp(argv[3+force], "slot"))
-           usage(argv[0]);
+           usage();
        slotstr = argv[4+force];
        slotcommand = 1;
     } else {
@@ -121,321 +110,187 @@ int main(argc, argv)
        slotcommand = 0;
     }
 
-    config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
-    conffile = stralloc2(config_dir, CONFFILE_NAME);
-    if (read_conffile(conffile)) {
-       error("errors processing config file \"%s\"", conffile);
-    }
-    conf_tapelist = getconf_str(CNF_TAPELIST);
-    if (*conf_tapelist == '/') {
-       conf_tapelist = stralloc(conf_tapelist);
-    } else {
-       conf_tapelist = stralloc2(config_dir, conf_tapelist);
-    }
-    if (read_tapelist(conf_tapelist)) {
-       error("could not load tapelist \"%s\"", conf_tapelist);
+    config_init(CONFIG_INIT_EXPLICIT_NAME, cfg_opt);
+    apply_config_overwrites(cfg_ovr);
+
+    if (config_errors(NULL) >= CFGERR_WARNINGS) {
+       config_print_errors();
+       if (config_errors(NULL) >= CFGERR_ERRORS) {
+           g_critical(_("errors processing config file"));
+       }
     }
 
-    uid_me = getuid();
-    uid_dumpuser = uid_me;
-    dumpuser = getconf_str(CNF_DUMPUSER);
+    check_running_as(RUNNING_AS_DUMPUSER);
 
-    if ((pw = getpwnam(dumpuser)) == NULL) {
-       error("cannot look up dump user \"%s\"", dumpuser);
-       /* NOTREACHED */
-    }
-    uid_dumpuser = pw->pw_uid;
-    if ((pw = getpwuid(uid_me)) == NULL) {
-       error("cannot look up my own uid %ld", (long)uid_me);
-       /* NOTREACHED */
-    }
-    if (uid_me != uid_dumpuser) {
-       error("running as user \"%s\" instead of \"%s\"",
-             pw->pw_name, dumpuser);
-       /* NOTREACHED */
+    dbrename(get_config_name(), DBG_SUBDIR_SERVER);
+
+    conf_tapelist = config_dir_relative(getconf_str(CNF_TAPELIST));
+    if (read_tapelist(conf_tapelist)) {
+       error(_("could not load tapelist \"%s\""), conf_tapelist);
+       /*NOTREACHED*/
     }
 
     labelstr = getconf_str(CNF_LABELSTR);
 
-    if(!match(labelstr, label))
-       error("label %s doesn't match labelstr \"%s\"", label, labelstr);
+    if(!match(labelstr, label)) {
+       error(_("label %s doesn't match labelstr \"%s\""), label, labelstr);
+       /*NOTREACHED*/
+    }
 
-    if((tp = lookup_tapelabel(label))!=NULL) {
-       if(!force)
-           error("label %s already on a tape\n",label);
+    if((lookup_tapelabel(label))!=NULL) {
+       if(!force) {
+           error(_("label %s already on a tape\n"),label);
+           /*NOTREACHED*/
+       }
     }
     tape = lookup_tapetype(getconf_str(CNF_TAPETYPE));
-    tt_blocksize_kb = tape->blocksize;
+    tt_blocksize_kb = (size_t)tapetype_get_blocksize(tape);
 
     if((have_changer = changer_init()) == 0) {
        if(slotcommand) {
-           fprintf(stderr,
-            "%s: no tpchanger specified in \"%s\", so slot command invalid\n",
-                   argv[0], conffile);
-           usage(argv[0]);
+           g_fprintf(stderr,
+            _("%s: no tpchanger specified in \"%s\", so slot command invalid\n"),
+                   argv[0], get_config_filename());
+           usage();
+       }
+       tapename = getconf_str(CNF_TAPEDEV);
+       if (tapename == NULL) {
+           error(_("No tapedev specified"));
        }
-       tapename = stralloc(getconf_str(CNF_TAPEDEV));
-#ifdef HAVE_LIBVTBLC
-       rawtapedev = stralloc(getconf_str(CNF_RAWTAPEDEV));
-#endif /* HAVE_LIBVTBLC */
     } else if(have_changer != 1) {
-       error("changer initialization failed: %s", strerror(errno));
+       error(_("changer initialization failed: %s"), strerror(errno));
+       /*NOTREACHED*/
     } else {
        if(changer_loadslot(slotstr, &outslot, &tapename)) {
-           error("could not load slot \"%s\": %s", slotstr, changer_resultstr);
+           error(_("could not load slot \"%s\": %s"), slotstr, changer_resultstr);
+           /*NOTREACHED*/
        }
 
-       printf("labeling tape in slot %s (%s):\n", outslot, tapename);
+       g_printf(_("labeling tape in slot %s (%s):\n"), outslot, tapename);
     }
 
-#ifdef HAVE_LINUX_ZFTAPE_H
-    if (is_zftape(tapename) == 1){
-       if((fd = tape_open(tapename, O_WRONLY)) == -1) {
-           errstr = newstralloc2(errstr, "amlabel: ",
-                                 (errno == EACCES) ? "tape is write-protected"
-                                 : strerror(errno));
-           error(errstr);
-       }
+    tape_ok=1;
+    g_printf("Reading label...\n");fflush(stdout);
+    device = device_open(tapename);
+    g_assert(device != NULL);
+    if (device->status != DEVICE_STATUS_SUCCESS) {
+        error("Could not open device %s: %s.\n", tapename,
+             device_error(device));
     }
-#endif /* HAVE_LINUX_ZFTAPE_H */
 
-    printf("rewinding"); fflush(stdout);
-
-#ifdef HAVE_LINUX_ZFTAPE_H
-    if (is_zftape(tapename) == 1){
-       if(tapefd_rewind(fd) == -1) {
-           putchar('\n');
-           error(strerror(errno));
-       }
-    }
-    else
-#endif /* HAVE_LINUX_ZFTAPE_H */
-    if((errstr = tape_rewind(tapename)) != NULL) {
-       putchar('\n');
-       error(errstr);
+    if (!device_configure(device, TRUE)) {
+        error("Could not configure device %s: %s.\n", tapename,
+             device_error(device));
     }
 
-    tape_ok=1;
-    printf(", reading label");fflush(stdout);
-    if((errstr = tape_rdlabel(tapename, &olddatestamp, &oldlabel)) != NULL) {
-       printf(", %s\n",errstr);
-       tape_ok=1;
-    }
-    else {
-       /* got an amanda tape */
-       printf(" %s",oldlabel);
-       if(strcmp(oldlabel, FAKE_LABEL) != 0
-          && match(labelstr, oldlabel) == 0) {
-           printf(", tape is in another amanda configuration");
+    device_status = device_read_label(device);
+
+    if (device_status & DEVICE_STATUS_VOLUME_UNLABELED) {
+       /* if there's no header, then the tape was truly empty; otherwise, there
+        * was *something* on the tape, so let's be careful and require a force */
+       if (!device->volume_header || device->volume_header->type == F_EMPTY) {
+           g_printf("Found an empty tape.\n");
+       } else {
+           g_printf("Found a non-Amanda tape.\n");
            if(!force)
                tape_ok=0;
        }
-       else {
-           if((tp = lookup_tapelabel(oldlabel)) != NULL) {
-               printf(", tape is active");
+    } else if (device_status != DEVICE_STATUS_SUCCESS) {
+        g_printf("Reading the tape label failed: %s.\n",
+                device_error_or_status(device));
+        tape_ok = 0;
+    } else {
+       /* got an amanda tape */
+       g_printf(_("Found Amanda tape %s"),device->volume_label);
+       if(match(labelstr, device->volume_label) == 0) {
+           g_printf(_(", but it is not from configuration %s."),
+                    get_config_name());
+           if(!force)
+               tape_ok=0;
+       } else {
+           if((lookup_tapelabel(device->volume_label)) != NULL) {
+               g_printf(_(", tape is active"));
                if(!force)
                    tape_ok=0;
            }
        }
-       printf("\n");
-    }
-    amfree(oldlabel);
-    amfree(olddatestamp);
-       
-    printf("rewinding"); fflush(stdout);
-
-#ifdef HAVE_LINUX_ZFTAPE_H
-    if (is_zftape(tapename) == 1){
-       if(tapefd_rewind(fd) == -1) {
-           putchar('\n');
-           error(strerror(errno));
-       }
-    }
-    else
-#endif /* HAVE_LINUX_ZFTAPE_H */
-    if((errstr = tape_rewind(tapename)) != NULL) {
-       putchar('\n');
-       error(errstr);
+       g_printf("\n");
     }
 
     if(tape_ok) {
-       printf(", writing label %s", label); fflush(stdout);
-
-#ifdef HAVE_LINUX_ZFTAPE_H
-       if (is_zftape(tapename) == 1){
-           errstr = tapefd_wrlabel(fd, "X", label, tt_blocksize_kb * 1024);
-           if(errstr != NULL) {
-               putchar('\n');
-               error(errstr);
-           }
-       }
-       else
-#endif /* HAVE_LINUX_ZFTAPE_H */
-       errstr = tape_wrlabel(tapename, "X", label, tt_blocksize_kb * 1024);
-       if(errstr != NULL) {
-           putchar('\n');
-           error(errstr);
+       char *timestamp = NULL;
+
+       g_printf(_("Writing label %s..\n"), label); fflush(stdout);
+        
+       timestamp = get_undef_timestamp();
+        if (!device_start(device, ACCESS_WRITE, label, timestamp)) {
+           error(_("Error writing label: %s.\n"),
+                 device_error(device));
+            g_assert_not_reached();
+       } else if (!device_finish(device)) {
+            error(_("Error closing device: %s.\n"),
+                 device_error(device));
+            g_assert_not_reached();
+        }
+       amfree(timestamp);
+
+        g_printf(_("Checking label...\n")); fflush(stdout);
+
+        device_status = device_read_label(device);
+        if (device_status != DEVICE_STATUS_SUCCESS) {
+           g_printf(_("Checking the tape label failed: %s.\n"),
+                    device_error_or_status(device));
+            exit(EXIT_FAILURE);
+        } else if (device->volume_label == NULL) {
+            error(_("no label found.\n"));
+            g_assert_not_reached();
+        } else if (strcmp(device->volume_label, label) != 0) {
+            error(_("Read back a different label: Got %s, but expected %s\n"),
+                  device->volume_label, label);
+            g_assert_not_reached();
+        } else if (get_timestamp_state(device->volume_time) !=
+                   TIME_STATE_UNDEF) {
+            error(_("Read the right label, but the wrong timestamp: "
+                    "Got %s, expected X.\n"), device->volume_time);
+            g_assert_not_reached();
+        }
+        
+        /* write tape list */
+        
+        /* make a copy */
+        conf_tapelist_old = stralloc2(conf_tapelist, ".amlabel");
+        if(write_tapelist(conf_tapelist_old)) {
+            error(_("couldn't write tapelist: %s"), strerror(errno));
+            /*NOTREACHED*/
+        }
+        amfree(conf_tapelist_old);
+        
+        /* XXX add cur_tape number to tape list structure */
+        remove_tapelabel(label);
+        add_tapelabel("0", label, NULL);
+        if(write_tapelist(conf_tapelist)) {
+            error(_("couldn't write tapelist: %s"), strerror(errno));
+            /*NOTREACHED*/
+        }
+
+        if (have_changer && changer_label(outslot, label) != 0) {
+           error(_("couldn't update barcode database for slot %s, label %s\n"), outslot, label);
+           /*NOTREACHED*/
        }
 
-#ifdef HAVE_LINUX_ZFTAPE_H
-       if (is_zftape(tapename) == 1){
-           tapefd_weof(fd, 1);
-       }
-#endif /* HAVE_LINUX_ZFTAPE_H */
-
-#ifdef HAVE_LINUX_ZFTAPE_H
-       if (is_zftape(tapename) == 1){
-           errstr = tapefd_wrendmark(fd, "X", tt_blocksize_kb * 1024);
-           if(errstr != NULL) {
-               putchar('\n');
-               error(errstr);
-           }
-       }
-       else
-#endif /* HAVE_LINUX_ZFTAPE_H */
-       errstr = tape_wrendmark(tapename, "X", tt_blocksize_kb * 1024);
-       if(errstr != NULL) {
-           putchar('\n');
-           error(errstr);
-       }
-
-#ifdef HAVE_LINUX_ZFTAPE_H
-       if (is_zftape(tapename) == 1){
-           tapefd_weof(fd, 1);
-
-           printf(",\nrewinding"); fflush(stdout); 
-     
-           if(tapefd_rewind(fd) == -1) { 
-               putchar('\n'); 
-               error(strerror(errno)); 
-           } 
-           close(fd);
-#ifdef HAVE_LIBVTBLC
-           /* update volume table */
-           printf(", updating volume table"); fflush(stdout);
-    
-           if ((fd = raw_tape_open(rawtapedev, O_RDWR)) == -1) {
-               if(errno == EACCES) {
-                   errstr = newstralloc(errstr,
-                                        "updating volume table: raw tape device is write protected");
-               } else {
-                   errstr = newstralloc2(errstr,
-                                         "updating volume table: ", strerror(errno));
-               }
-               putchar('\n');
-               error(errstr);
-           }
-           /* read volume table */
-           if ((num_volumes = read_vtbl(fd, volumes, vtbl_buffer,
-                                        &first_seg, &last_seg)) == -1 ) {
-               errstr = newstralloc2(errstr,
-                                     "reading volume table: ", strerror(errno));
-               putchar('\n');
-               error(errstr);
-           }
-           /* set date and volume label for first entry */
-           vtbl_no = 0;
-           datestr = NULL; 
-           if (set_date(datestr, volumes, num_volumes, vtbl_no)){
-               errstr = newstralloc2(errstr,
-                                     "setting date for entry 1: ", strerror(errno));
-               putchar('\n');
-               error(errstr);
-           }
-           if(set_label(label, volumes, num_volumes, vtbl_no)){
-               errstr = newstralloc2(errstr,
-                                     "setting label for entry 1: ", strerror(errno));
-               putchar('\n');
-               error(errstr);
-           }
-           /* set date and volume label for last entry */
-           vtbl_no = 1;
-           datestr = NULL; 
-           if (set_date(datestr, volumes, num_volumes, vtbl_no)){
-               errstr = newstralloc2(errstr,
-                                     "setting date for entry 2: ", strerror(errno));
-               putchar('\n');
-               error(errstr);
-           }
-           if(set_label("AMANDA Tape End", volumes, num_volumes, vtbl_no)){
-               errstr = newstralloc2(errstr,
-                                     "setting label for entry 2: ", strerror(errno));
-               putchar('\n');
-               error(errstr);
-           }
-           /* write volume table back */
-           if (write_vtbl(fd, volumes, vtbl_buffer, num_volumes, first_seg,
-                          op_mode == trunc)) {
-               errstr = newstralloc2(errstr,
-                                     "writing volume table: ", strerror(errno));
-               putchar('\n');
-               error(errstr);
-           }  
-           close(fd);
-#endif /* HAVE_LIBVTBLC */
-       }
-#endif /* HAVE_LINUX_ZFTAPE_H */
-
-       if (tape_ok) {
-           printf(", checking label"); fflush(stdout);
-
-           if((errstr = tape_rdlabel(tapename, &olddatestamp, &oldlabel)) != NULL) {
-               putchar('\n');
-               if (strcmp(errstr, "not an amanda tape") != 0)
-                   error(errstr);
-               error("no label found, are you sure %s is non-rewinding?",
-                     tapename);
-           }
-
-           if (strcmp("X", olddatestamp) != 0 ||
-               (strcmp(oldlabel, FAKE_LABEL) != 0
-                && strcmp(label, oldlabel) != 0)) {
-               putchar('\n');
-               error("read label %s back, timestamp %s (expected X), what now?",
-                     oldlabel, olddatestamp);
-           }
-           amfree(oldlabel);
-           amfree(olddatestamp);
-
-           /* write tape list */
-
-           /* make a copy */
-                   conf_tapelist_old = stralloc2(conf_tapelist, ".amlabel");
-           if(write_tapelist(conf_tapelist_old)) {
-               error("couldn't write tapelist: %s", strerror(errno));
-           }
-           amfree(conf_tapelist_old);
-
-           /* XXX add cur_tape number to tape list structure */
-           remove_tapelabel(label);
-           add_tapelabel(0, label);
-           if(write_tapelist(conf_tapelist)) {
-               error("couldn't write tapelist: %s", strerror(errno));
-           }
-       } /* write tape list */
-
-        if(have_changer) {
-           /* Now we try to inform the changer, about the new label */
-           changer_label(outslot,label); 
-       }
-       printf(", done.\n");
+        g_printf(_("Success!\n"));
     } else {
-       printf("\ntape not labeled\n");
+       g_printf(_("\ntape not labeled\n"));
+       exit(EXIT_FAILURE);
     }
+    
+    g_object_unref(device);
+    device = NULL;
 
+    clear_tapelist();
     amfree(outslot);
-    amfree(tapename);
-    amfree(conffile);
     amfree(conf_tapelist);
-    amfree(config_dir);
-    config_name=NULL;
-
-    malloc_size_2 = malloc_inuse(&malloc_hist_2);
-
-    if(malloc_size_1 != malloc_size_2) {
-       malloc_list(fileno(stderr), malloc_hist_1, malloc_hist_2);
-    }
-
     dbclose();
+
     return 0;
 }