/*
* Amanda, The Advanced Maryland Automatic Network Disk Archiver
* Copyright (c) 1991-1998 University of Maryland at College Park
* Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved.
* Copyright (c) 2013-2016 Carbonite, Inc. All Rights Reserved.
* All Rights Reserved.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of U.M. not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. U.M. makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Authors: the Amanda Development Team. Its members are listed in a
* file named AUTHORS, in the root directory of this distribution.
*/
/* $Id: disk_history.c,v 1.13 2006/05/25 01:47:19 johnfranks Exp $
*
* functions for obtaining backup history
*/
#include "amanda.h"
#include "disk_history.h"
static DUMP_ITEM *disk_hist = NULL;
void
clear_list(void)
{
DUMP_ITEM *item, *this;
item = disk_hist;
while (item != NULL)
{
this = item;
item = item->next;
amfree(this->hostname);
while(this->tapes != NULL) {
tapelist_t *tapes = this->tapes;
this->tapes = tapes->next;
amfree(tapes->label);
amfree(tapes->files);
amfree(tapes);
}
amfree(this);
}
disk_hist = NULL;
}
/* add item, maintain list ordered by oldest date last */
void
add_dump(
char * hostname,
char * date,
int level,
char * storage,
char * tape,
off_t file,
int partnum,
int maxpart)
{
DUMP_ITEM *new, *item, *before;
int isafile = 0;
if(tape[0] == '/')
isafile = 1; /* XXX kludgey, like this whole thing */
/* See if we already have partnum=partnum-1 */
if (partnum > 1) {
for(item = disk_hist, before = NULL; item;
before = item, item = item->next) {
if (g_str_equal(item->date, date) &&
item->level == level && item->is_split &&
g_str_equal(item->storage, storage)) {
item->tapes = append_to_tapelist(item->tapes, storage, tape, file,
partnum, isafile);
if (maxpart > item->maxpart)
item->maxpart = maxpart;
return;
}
}
return;
}
new = (DUMP_ITEM *)g_malloc(sizeof(DUMP_ITEM));
strncpy(new->date, date, sizeof(new->date)-1);
new->date[sizeof(new->date)-1] = '\0';
new->level = level;
strncpy(new->storage, storage, sizeof(new->storage)-1);
new->storage[sizeof(new->storage)-1] = '\0';
strncpy(new->tape, tape, sizeof(new->tape)-1);
new->tape[sizeof(new->tape)-1] = '\0';
new->file = file;
new->maxpart = maxpart;
if(partnum == -1)
new->is_split = 0;
else
new->is_split = 1;
new->tapes = NULL;
new->hostname = g_strdup(hostname);
new->tapes = append_to_tapelist(new->tapes, storage, tape, file, partnum, isafile);
if (disk_hist == NULL)
{
disk_hist = new;
new->next = NULL;
return;
}
/* prepend this item to the history list, if it's newer */
/* XXX this should probably handle them being on the same date with
datestamp_uax or something */
if (strcmp(disk_hist->date, new->date) < 0)
{
new->next = disk_hist;
disk_hist = new;
return;
}
/* append this item to the history list, if it's older */
before = disk_hist;
item = disk_hist->next;
while ((item != NULL) && (strcmp(item->date, new->date) >= 0))
{
before = item;
item = item->next;
}
new->next = item;
before->next = new;
}
void
clean_dump(void)
{
DUMP_ITEM *item, *before;
/* check if the maxpart part is avaliable */
for(item = disk_hist, before = NULL; item;
before = item, item = item->next) {
int found_maxpart = 0;
tapelist_t *cur_tape;
if (item->maxpart > 1) {
for (cur_tape = item->tapes; cur_tape; cur_tape = cur_tape->next) {
int files;
for(files=0; files<cur_tape->numfiles; files++) {
if (cur_tape->partnum[files] == item->maxpart) {
found_maxpart = 1;
}
}
}
if (found_maxpart == 0) {
DUMP_ITEM *myitem = item;
if (before)
before->next = item->next;
else
disk_hist = item->next;
item = item->next;
/* free myitem */
free_tapelist(myitem->tapes);
amfree(myitem->hostname);
amfree(myitem);
if (item == NULL)
break;
}
}
}
}
DUMP_ITEM *
first_dump(void)
{
return disk_hist;
}