Пример #1
0
void
remove_tapelabel(
    char *label)
{
    tape_t *tp, *prev, *next;

    tp = lookup_tapelabel(label);
    if(tp != NULL) {
	prev = tp->prev;
	next = tp->next;
	/*@ignore@*/
	if(prev != NULL)
	    prev->next = next;
	else /* begin of list */
	    tape_list = next;
	if(next != NULL)
	    next->prev = prev;
	/*@end@*/
	while (next != NULL) {
	    next->position--;
	    next = next->next;
	}
	amfree(tp->datestamp);
	amfree(tp->label);
	amfree(tp->meta);
	amfree(tp->comment);
	amfree(tp->barcode);
	amfree(tp);
    }
}
Пример #2
0
int
volume_is_reusable(
    const char *label)
{
    tape_t *tp = lookup_tapelabel(label);
    return reusable_tape(tp);
}
Пример #3
0
static gint
sort_needed_tapes_by_write_timestamp(
	gconstpointer a,
	gconstpointer b)
{
    needed_tape_t *a_nt = (needed_tape_t *)a;
    needed_tape_t *b_nt = (needed_tape_t *)b;
    tape_t *a_t = a_nt->isafile? NULL : lookup_tapelabel(a_nt->label);
    tape_t *b_t = b_nt->isafile? NULL : lookup_tapelabel(b_nt->label);
    char *a_ds = a_t? a_t->datestamp : "none";
    char *b_ds = b_t? b_t->datestamp : "none";

    /* if the tape timestamps match, sort them by usage_order, which is derived
     * from the order the tapes were written in a single run */
    int r = strcmp(a_ds, b_ds);
    if (r != 0)
	return r;
    return (a_nt->usage_order > b_nt->usage_order)? 1 : -1;
}
Пример #4
0
static void
update_tapelist(
    taper_state_t *state)
{
    char *tapelist_name = NULL;
    char *tapelist_name_old = NULL;
    tape_t *tp;
    char *comment = NULL;

    tapelist_name = config_dir_relative(getconf_str(CNF_TAPELIST));
    if (state->cur_tape == 0) {
	tapelist_name_old = stralloc2(tapelist_name, ".yesterday");
    } else {
	char cur_str[NUM_STR_SIZE];
	g_snprintf(cur_str, SIZEOF(cur_str), "%d", state->cur_tape - 1);
	tapelist_name_old = vstralloc(tapelist_name,
				      ".today.", cur_str, NULL);
    }

   if (read_tapelist(tapelist_name) != 0) {
        log_add(L_INFO, "pid-done %ld", (long)getpid());
        error("could not load tapelist \"%s\"", tapelist_name);
        /*NOTREACHED*/
    }

    /* make a copy of the tapelist file */
    if (write_tapelist(tapelist_name_old)) {
        log_add(L_INFO, "pid-done %ld", (long)getpid());
	error("could not write tapelist: %s", strerror(errno));
	/*NOTREACHED*/
    }
    amfree(tapelist_name_old);

    /* get a copy of the comment, before freeing the old record */
    tp = lookup_tapelabel(state->device->volume_label);
    if (tp && tp->comment)
	comment = stralloc(tp->comment);

    /* edit the tapelist and rewrite it */
    remove_tapelabel(state->device->volume_label);
    add_tapelabel(state->driver_start_time,
                  state->device->volume_label,
		  comment);
    if (write_tapelist(tapelist_name)) {
	error("could not write tapelist: %s", strerror(errno));
	/*NOTREACHED*/
    }
    amfree(tapelist_name);
    amfree(comment);
}
Пример #5
0
void
remove_tapelabel(
    const char *label)
{
    tape_t *tp, *prev, *next;

    tp = lookup_tapelabel(label);
    if (tp) {
	char *tape_key = tape_hash_key(tp->pool, tp->label);
	g_hash_table_remove(tape_table_storage_label, tape_key);
	g_hash_table_remove(tape_table_label, tp->label);
	g_free(tape_key);
	prev = tp->prev;
	next = tp->next;
	/*@ignore@*/
	if(prev != NULL)
	    prev->next = next;
	else /* begin of list */
	    tape_list = next;
	if(next != NULL)
	    next->prev = prev;
	else /* end of list */
	    tape_list_end = prev;
	/*@end@*/
	while (next != NULL) {
	    next->position--;
	    next = next->next;
	}
	amfree(tp->datestamp);
	amfree(tp->label);
	amfree(tp->meta);
	amfree(tp->comment);
	amfree(tp->pool);
	amfree(tp->storage);
	amfree(tp->config);
	amfree(tp->barcode);
	amfree(tp);
    }
}
Пример #6
0
static gboolean
volume_matches(
    const char *label1,
    const char *label2,
    const char *datestamp)
{
    tape_t *tp;

    if (!label2)
	return TRUE;

    if (label1)
	return (g_str_equal(label1, label2));

    /* check in tapelist */
    if (!(tp = lookup_tapelabel(label2)))
	return FALSE;

    if (!g_str_equal(tp->datestamp, datestamp))
	return FALSE;

    return TRUE;
}
Пример #7
0
/* This function checks the label of a single tape, which may or may not
 * have been loaded by the changer. With the addition of char *dev, and *slot,
 * it has the same interface as taper_scan. slot should be the slot where
 * this tape is found, or NULL if no changer is in use.
 * Return value is the same as taper_scan.
 */
int scan_read_label(
    char *dev,
    char *slot,
    char *desired_label,
    char** label,
    char** timestamp,
    char** error_message)
{
    Device * device;
    char *labelstr;
    DeviceStatusFlags device_status;
    char *new_label_errmsg;

    g_return_val_if_fail(dev != NULL, -1);

    if (*error_message == NULL)
        *error_message = stralloc("");

    *label = *timestamp = NULL;
    device = device_open(dev);
    g_assert(device != NULL);

    if (device->status != DEVICE_STATUS_SUCCESS ) {
        *error_message = newvstrallocf(*error_message,
                                       _("%sError opening device %s: %s.\n"),
                                       *error_message, dev,
                                       device_error_or_status(device));
        g_object_unref(device);
        amfree(*timestamp);
        amfree(*label);
        return -1;
    }

    if (!device_configure(device, TRUE)) {
        *error_message = newvstrallocf(*error_message,
                                       _("%sError configuring device %s: %s.\n"),
                                       *error_message, dev,
                                       device_error_or_status(device));
        g_object_unref(device);
        amfree(*timestamp);
        amfree(*label);
        return -1;
    }

    device_status = device_read_label(device);

    if (device_status == DEVICE_STATUS_SUCCESS && device->volume_label != NULL) {
        *label = g_strdup(device->volume_label);
        *timestamp = strdup(device->volume_time);
    } else if (device_status & DEVICE_STATUS_VOLUME_UNLABELED) {
        if (!getconf_seen(CNF_LABEL_NEW_TAPES)) {
            *error_message = newvstrallocf(*error_message,
                                           _("%sFound an empty or non-amanda tape.\n"),
                                           *error_message);
            g_object_unref(device);
            return -1;
        }

        /* If we got a header, but the Device doesn't think it's labeled, then this
         * tape probably has some data on it, so refuse to automatically label it */
        if (device->volume_header && device->volume_header->type != F_EMPTY) {
            *error_message = newvstrallocf(*error_message,
                                           _("%sFound a non-amanda tape; check and relabel it with 'amlabel -f'\n"),
                                           *error_message);
            g_object_unref(device);
            return -1;
        }
        g_object_unref(device);

        *label = find_brand_new_tape_label(&new_label_errmsg);
        if (*label != NULL) {
            *timestamp = stralloc("X");
            *error_message = newvstrallocf(*error_message,
                                           _("%sFound an empty tape, will label it `%s'.\n"),
                                           *error_message, *label);

            return 3;
        }
        *error_message = newvstrallocf(*error_message,
                                       _("%s%s.\n"),
                                       *error_message, new_label_errmsg);

        return -1;
    } else {
        char * label_errstr;
        label_errstr = g_strdup_printf(_("Error reading label: %s.\n"),
                                       device_error_or_status(device));
        *error_message = newvstralloc(*error_message, *error_message,
                                      label_errstr, NULL);
        g_free(label_errstr);
        return -1;
    }

    g_assert(*label != NULL && *timestamp != NULL);
    g_object_unref(device);

    *error_message = newvstrallocf(*error_message,
                                   _("%sread label `%s', date `%s'.\n"),
                                   *error_message, *label, *timestamp);

    /* Register this with the barcode database, even if its not ours. */
    if (slot != NULL) {
        changer_label(slot, *label);
    }

    if (desired_label != NULL && strcmp(*label, desired_label) == 0) {
        /* Got desired label. */
        return 1;
    }

    /* Is this actually an acceptable tape? */
    labelstr = getconf_str(CNF_LABELSTR);
    if(!match(labelstr, *label)) {
        *error_message = newvstrallocf(*error_message,
                                       _("%slabel \"%s\" doesn't match \"%s\".\n"),
                                       *error_message, *label, labelstr);

        return -1;
    } else {
        tape_t *tp;
        if (strcmp(*timestamp, "X") == 0) {
            /* new, labeled tape. */
            return 1;
        }

        tp = lookup_tapelabel(*label);

        if(tp == NULL) {
            *error_message =
                newvstrallocf(*error_message,
                              _("%slabel \"%s\" matches labelstr but it is"
                                " not listed in the tapelist file.\n"),
                              *error_message, *label);
            return -1;
        } else if(tp != NULL && !reusable_tape(tp)) {
            *error_message =
                newvstrallocf(*error_message,
                              _("%sTape with label %s is still active"
                                " and cannot be overwritten.\n"),
                              *error_message, *label);
            return -1;
        }
    }

    /* Yay! We got a good tape! */
    return 2;
}
Пример #8
0
char *
find_brand_new_tape_label(char **errmsg)
{
    char *format;
    char newlabel[AUTO_LABEL_MAX_LEN];
    char tmpnum[30]; /* 64-bit integers can be 21 digists... */
    char tmpfmt[16];
    char *auto_pos = NULL;
    int i;
    ssize_t label_len, auto_len;
    tape_t *tp;

    *errmsg = NULL;
    if (!getconf_seen(CNF_LABEL_NEW_TAPES)) {
        return NULL;
    }
    format = getconf_str(CNF_LABEL_NEW_TAPES);

    memset(newlabel, 0, AUTO_LABEL_MAX_LEN);
    label_len = 0;
    auto_len = -1; /* Only find the first '%' */
    while (*format != '\0') {
        if (label_len + 4 > AUTO_LABEL_MAX_LEN) {
            *errmsg = _("Auto label format is too long!");
            return NULL;
        }

        if (*format == '\\') {
            /* Copy the next character. */
            newlabel[label_len++] = format[1];
            format += 2;
        } else if (*format == '%' && auto_len == -1) {
            /* This is the format specifier. */
            auto_pos = newlabel + label_len;
            auto_len = 0;
            while (*format == '%' && label_len < AUTO_LABEL_MAX_LEN) {
                newlabel[label_len++] = '%';
                auto_len ++;
                format ++;
            }
        } else {
            /* Just copy a character. */
            newlabel[label_len++] = *(format++);
        }
    }

    /* Sometimes we copy the null, sometimes not. */
    if (newlabel[label_len] != '\0') {
        newlabel[label_len++] = '\0';
    }

    if (auto_pos == NULL) {
        *errmsg = _("Auto label template contains no '%%'!");
        return NULL;
    }

    g_snprintf(tmpfmt, SIZEOF(tmpfmt), "%%0%zdd",
               (size_t)auto_len);

    for (i = 1; i < INT_MAX; i ++) {
        g_snprintf(tmpnum, SIZEOF(tmpnum), tmpfmt, i);
        if (strlen(tmpnum) != (size_t)auto_len) {
            *errmsg = _("All possible auto-labels used.");
            return NULL;
        }

        strncpy(auto_pos, tmpnum, (size_t)auto_len);

        tp = lookup_tapelabel(newlabel);
        if (tp == NULL) {
            /* Got it. Double-check that this is a labelstr match. */
            if (!match(getconf_str(CNF_LABELSTR), newlabel)) {
                *errmsg = g_strdup_printf(_("New label %s does not match labelstr %s from amanda.conf"),
                                          newlabel, getconf_str(CNF_LABELSTR));
                return NULL;
            }
            return stralloc(newlabel);
        }
    }

    /* Should not get here unless you have over two billion tapes. */
    *errmsg = _("Taper internal error in find_brand_new_tape_label.");
    return 0;
}