1 /*
2  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3  * Copyright (c) 1991-1998 University of Maryland at College Park
4  * Copyright (c) 2007-2013 Zmanda, Inc.  All Rights Reserved.
5  * All Rights Reserved.
6  *
7  * Permission to use, copy, modify, distribute, and sell this software and its
8  * documentation for any purpose is hereby granted without fee, provided that
9  * the above copyright notice appear in all copies and that both that
10  * copyright notice and this permission notice appear in supporting
11  * documentation, and that the name of U.M. not be used in advertising or
12  * publicity pertaining to distribution of the software without specific,
13  * written prior permission.  U.M. makes no representations about the
14  * suitability of this software for any purpose.  It is provided "as is"
15  * without express or implied warranty.
16  *
17  * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
19  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
21  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23  *
24  * Authors: the Amanda Development Team.  Its members are listed in a
25  * file named AUTHORS, in the root directory of this distribution.
26  */
27 /* $Id: disk_history.c,v 1.13 2006/05/25 01:47:19 johnfranks Exp $
28  *
29  * functions for obtaining backup history
30  */
31 
32 #include "amanda.h"
33 #include "disk_history.h"
34 
35 static DUMP_ITEM *disk_hist = NULL;
36 
37 void
clear_list(void)38 clear_list(void)
39 {
40     DUMP_ITEM *item, *this;
41 
42     item = disk_hist;
43     while (item != NULL)
44     {
45 	this = item;
46 	item = item->next;
47 	amfree(this->hostname);
48 	while(this->tapes != NULL) {
49 	    tapelist_t *tapes = this->tapes;
50 	    this->tapes = tapes->next;
51 	    amfree(tapes->label);
52 	    amfree(tapes->files);
53 	    amfree(tapes);
54 	}
55 	amfree(this);
56     }
57     disk_hist = NULL;
58 }
59 
60 /* add item, maintain list ordered by oldest date last */
61 
62 void
add_dump(char * hostname,char * date,int level,char * tape,off_t file,int partnum,int maxpart)63 add_dump(
64     char *      hostname,
65     char *	date,
66     int		level,
67     char *	tape,
68     off_t	file,
69     int		partnum,
70     int		maxpart)
71 {
72     DUMP_ITEM *new, *item, *before;
73     int isafile = 0;
74 
75     if(tape[0] == '/')
76 	isafile = 1; /* XXX kludgey, like this whole thing */
77 
78     /* See if we already have partnum=partnum-1 */
79     if (partnum > 1) {
80 	for(item = disk_hist, before = NULL; item;
81 	    before = item, item = item->next) {
82 	    if (!strcmp(item->date, date) &&
83 		    item->level == level && item->is_split) {
84 		item->tapes = append_to_tapelist(item->tapes, tape, file,
85 						 partnum, isafile);
86 		if (maxpart > item->maxpart)
87 		    item->maxpart = maxpart;
88 		return;
89 	    }
90 	}
91 	return;
92     }
93 
94     new = (DUMP_ITEM *)alloc(SIZEOF(DUMP_ITEM));
95     strncpy(new->date, date, SIZEOF(new->date)-1);
96     new->date[SIZEOF(new->date)-1] = '\0';
97     new->level = level;
98     strncpy(new->tape, tape, SIZEOF(new->tape)-1);
99     new->tape[SIZEOF(new->tape)-1] = '\0';
100     new->file = file;
101     new->maxpart = maxpart;
102     if(partnum == -1)
103         new->is_split = 0;
104     else
105         new->is_split = 1;
106     new->tapes = NULL;
107     new->hostname = stralloc(hostname);
108 
109     new->tapes = append_to_tapelist(new->tapes, tape, file, partnum, isafile);
110 
111     if (disk_hist == NULL)
112     {
113 	disk_hist = new;
114 	new->next = NULL;
115 	return;
116     }
117 
118     /* prepend this item to the history list, if it's newer */
119     /* XXX this should probably handle them being on the same date with
120        datestamp_uax or something */
121     if (strcmp(disk_hist->date, new->date) <= 0)
122     {
123 	new->next = disk_hist;
124 	disk_hist = new;
125 	return;
126     }
127 
128     /* append this item to the history list, if it's older */
129     before = disk_hist;
130     item = disk_hist->next;
131     while ((item != NULL) && (strcmp(item->date, new->date) > 0))
132     {
133 	before = item;
134 	item = item->next;
135     }
136     new->next = item;
137     before->next = new;
138 }
139 
140 void
clean_dump(void)141 clean_dump(void)
142 {
143     DUMP_ITEM *item, *before;
144 
145     /* check if the maxpart part is avaliable */
146     for(item = disk_hist, before = NULL; item;
147 					 before = item, item = item->next) {
148 	int found_maxpart = 0;
149 	tapelist_t *cur_tape;
150 
151 	if (item->maxpart > 1) {
152 	    for (cur_tape = item->tapes; cur_tape; cur_tape = cur_tape->next) {
153 		int files;
154 		for(files=0; files<cur_tape->numfiles; files++) {
155 		    if (cur_tape->partnum[files] == item->maxpart) {
156 			found_maxpart = 1;
157 		    }
158 		}
159 	    }
160 	    if (found_maxpart == 0) {
161 		DUMP_ITEM *myitem = item;
162 
163 		if (before)
164 		    before->next = item->next;
165 		else
166 		    disk_hist = item->next;
167 		item = item->next;
168 		/* free myitem */
169 		free_tapelist(myitem->tapes);
170 		amfree(myitem->hostname);
171 		amfree(myitem);
172 		if (item == NULL)
173 		    break;
174 	    }
175 	}
176     }
177 }
178 
179 DUMP_ITEM *
first_dump(void)180 first_dump(void)
181 {
182     return disk_hist;
183 }
184