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); } }
int volume_is_reusable( const char *label) { tape_t *tp = lookup_tapelabel(label); return reusable_tape(tp); }
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; }
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); }
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); } }
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; }
/* 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; }
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; }