/*
* Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 2006 Zmanda Inc.
+ * Copyright (c) 2005-2008 Zmanda Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
NULL
};
- type = g_type_register_static (TAPER_TYPE_SOURCE, "TaperFileSource",
+ type = g_type_register_static (TAPER_SOURCE_TYPE, "TaperFileSource",
&info, (GTypeFlags)0);
}
if(self->_priv->current_chunk_fd >= 0) {
close (self->_priv->current_chunk_fd);
}
+ dumpfile_free_data(&(self->_priv->part_start_chunk_header));
+ dumpfile_free_data(&(self->_priv->current_chunk_header));
+ amfree(self->_priv);
}
static void
o->_priv->part_start_chunk_fd = -1;
o->_priv->current_chunk_fd = -1;
o->_priv->predicted_splits = -1;
+ fh_init(&o->_priv->part_start_chunk_header);
+ fh_init(&o->_priv->current_chunk_header);
o->holding_disk_file = NULL;
}
GObjectClass *g_object_class = (GObjectClass*) c;
TaperSourceClass *taper_source_class = (TaperSourceClass *)c;
- parent_class = g_type_class_ref (TAPER_TYPE_SOURCE);
+ parent_class = g_type_class_ref (TAPER_SOURCE_TYPE);
taper_source_class->read = taper_file_source_read;
taper_source_class->seek_to_part_start =
everything went OK. Writes the fd into fd_pointer and the header
into header_pointer. Both must be non-NULL. */
static gboolean open_holding_file(char * filename, int * fd_pointer,
- dumpfile_t * header_pointer) {
+ dumpfile_t * header_pointer, char **errmsg) {
int fd;
- int read_result;
+ size_t read_result;
char * header_buffer;
g_return_val_if_fail(filename != NULL, FALSE);
fd = robust_open(filename, O_NOCTTY | O_RDONLY, 0);
if (fd < 0) {
- g_fprintf(stderr, "Could not open holding disk file %s: %s\n",
+ *errmsg = newvstrallocf(*errmsg,
+ "Could not open holding disk file \"%s\": %s",
filename, strerror(errno));
return FALSE;
}
header_buffer = malloc(DISK_BLOCK_BYTES);
- read_result = fullread(fd, header_buffer, DISK_BLOCK_BYTES);
+ read_result = full_read(fd, header_buffer, DISK_BLOCK_BYTES);
if (read_result < DISK_BLOCK_BYTES) {
- g_fprintf(stderr,
- "Could not read header from holding disk file %s: %s\n",
- filename, strerror(errno));
+ if (errno != 0) {
+ *errmsg = newvstrallocf(*errmsg,
+ "Could not read header from holding disk file %s: %s",
+ filename, strerror(errno));
+ } else {
+ *errmsg = newvstrallocf(*errmsg,
+ "Could not read header from holding disk file %s: got EOF",
+ filename);
+ }
aclose(fd);
+ amfree(header_buffer);
return FALSE;
}
-
+
+ dumpfile_free_data(header_pointer);
parse_file_header(header_buffer, header_pointer, DISK_BLOCK_BYTES);
amfree(header_buffer);
if (!(header_pointer->type == F_DUMPFILE ||
header_pointer->type == F_CONT_DUMPFILE)) {
- g_fprintf(stderr, "Got strange header from file %s.\n",
+ *errmsg = newvstrallocf(*errmsg,
+ "Got strange header from file %s",
filename);
aclose(fd);
return FALSE;
chunk. Returns FALSE if an error occurs (unlikely). */
static gboolean copy_chunk_data(int * from_fd, int* to_fd,
dumpfile_t * from_header,
- dumpfile_t * to_header) {
+ dumpfile_t * to_header,
+ char **errmsg) {
g_return_val_if_fail(from_fd != NULL, FALSE);
g_return_val_if_fail(to_fd != NULL, FALSE);
g_return_val_if_fail(from_header != NULL, FALSE);
*to_fd = dup(*from_fd);
if (*to_fd < 0) {
- g_fprintf(stderr, "dup(%d) failed!\n", *from_fd);
+ *errmsg = newvstrallocf(*errmsg, "dup(%d) failed!", *from_fd);
return FALSE;
}
- memcpy(to_header, from_header, sizeof(*to_header));
+ dumpfile_free_data(to_header);
+ dumpfile_copy_in_place(to_header, from_header);
return TRUE;
}
if (!open_holding_file(self->holding_disk_file,
&(selfp->part_start_chunk_fd),
- &(selfp->part_start_chunk_header))) {
+ &(selfp->part_start_chunk_header),
+ &(pself->errmsg))) {
return FALSE;
}
if (!copy_chunk_data(&(selfp->part_start_chunk_fd),
&(selfp->current_chunk_fd),
&(selfp->part_start_chunk_header),
- &(selfp->current_chunk_header))) {
+ &(selfp->current_chunk_header),
+ &(pself->errmsg))) {
aclose(selfp->part_start_chunk_fd);
return FALSE;
}
- pself->first_header = g_memdup(&(selfp->part_start_chunk_header),
- sizeof(dumpfile_t));
+ dumpfile_free(pself->first_header);
+ pself->first_header = dumpfile_copy(&(selfp->part_start_chunk_header));
/* Should not be necessary. You never know! */
selfp->current_part_pos = selfp->part_start_chunk_offset =
occurs. */
static gboolean get_next_chunk(TaperFileSource * self) {
char * cont_filename = NULL;
+ TaperSource * pself = (TaperSource*)self;
if (selfp->current_chunk_header.cont_filename[0] != '\0') {
cont_filename =
} else {
/* No more data. */
aclose(selfp->current_chunk_fd);
+ dumpfile_free_data(&(selfp->current_chunk_header));
bzero(&(selfp->current_chunk_header),
sizeof(selfp->current_chunk_header));
return TRUE;
if (!open_holding_file(cont_filename,
&(selfp->current_chunk_fd),
- &(selfp->current_chunk_header))) {
+ &(selfp->current_chunk_header),
+ &(pself->errmsg))) {
amfree(cont_filename);
+ dumpfile_free_data(&(selfp->current_chunk_header));
bzero(&(selfp->current_chunk_header),
sizeof(selfp->current_chunk_header));
aclose(selfp->current_chunk_fd);
return 0;
}
- /* We don't use fullread, because we would rather return a partial
+ /* We don't use full_read, because we would rather return a partial
* read ASAP. */
read_result = retry_read(selfp->current_chunk_fd, buf, count);
if (read_result < 0) {
/* Nothing we can do. */
+ pself->errmsg = newvstrallocf(pself->errmsg,
+ "Error reading holding disk '%s': %s'",
+ self->holding_disk_file, strerror(errno));
return read_result;
} else if (read_result == 0) {
if (!get_next_chunk(self)) {
if (!copy_chunk_data(&(selfp->part_start_chunk_fd),
&(selfp->current_chunk_fd),
&(selfp->part_start_chunk_header),
- &(selfp->current_chunk_header))) {
+ &(selfp->current_chunk_header),
+ &(pself->errmsg))) {
return FALSE;
}
DISK_BLOCK_BYTES + selfp->current_chunk_position,
SEEK_SET);
if (lseek_result < 0) {
- g_fprintf(stderr, "Could not seek holding disk file: %s\n",
+ pself->errmsg = newvstrallocf(pself->errmsg,
+ "Could not seek holding disk file: %s\n",
strerror(errno));
return FALSE;
}
if (!copy_chunk_data(&(selfp->current_chunk_fd),
&(selfp->part_start_chunk_fd),
&(selfp->current_chunk_header),
- &(selfp->part_start_chunk_header))) {
+ &(selfp->part_start_chunk_header),
+ &(pself->errmsg))) {
/* We can't return FALSE. :-( Instead, we set things up so
they will fail on the next read(). */
aclose(selfp->current_chunk_fd);