2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-1998 University of Maryland at College Park
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of U.M. not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. U.M. makes no representations about the
13 * suitability of this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
16 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Authors: the Amanda Development Team. Its members are listed in a
24 * file named AUTHORS, in the root directory of this distribution.
27 * $Id: tapelist.c,v 1.8 2006/06/12 15:34:48 martinea Exp $
29 * Support code for amidxtaped and amindexd.
36 * Count the number of entries in this tapelist
40 tapelist_t * tapelist)
45 for(cur_tape = tapelist ; cur_tape ; cur_tape = cur_tape->next)
48 dbprintf("num_entries(tapelist=%p)=%d\n", tapelist, count);
60 dbprintf("dump_tapelist(%p):\n", tapelist);
61 for(cur_tape = tapelist ; cur_tape != NULL ; cur_tape = cur_tape->next) {
62 dbprintf(" %p->next = %p\n", cur_tape, cur_tape->next);
63 dbprintf(" %p->label = %s\n", cur_tape, cur_tape->label);
64 dbprintf(" %p->isafile = %d\n", cur_tape, cur_tape->isafile);
65 dbprintf(" %p->numfiles = %d\n", cur_tape, cur_tape->numfiles);
66 for (file=0; file < cur_tape->numfiles; file++) {
67 dbprintf(" %p->files[%d] = %lld, %p->partnum[%d] = %lld\n",
68 cur_tape, file, (long long)cur_tape->files[file],
69 cur_tape, file, (long long)cur_tape->partnum[file]);
73 dbprintf(" %p count = %d\n", tapelist, count);
77 * Add a tape entry with the given label to the given tapelist, creating a new
78 * tapelist if handed a NULL one. Squashes duplicates.
88 tapelist_t *new_tape, *cur_tape;
91 dbprintf("append_to_tapelist(tapelist=%p, label='%s', file=%lld, partnum=%d, isafile=%d)\n",
92 tapelist, label, (long long)file, partnum, isafile);
94 /* see if we have this tape already, and if so just add to its file list */
95 for(cur_tape = tapelist; cur_tape; cur_tape = cur_tape->next) {
96 if(strcmp(label, cur_tape->label) == 0) {
101 if(file >= (off_t)0) {
102 newfiles = alloc(SIZEOF(*newfiles) *
103 (cur_tape->numfiles + 1));
104 newpartnum = alloc(SIZEOF(*newpartnum) *
105 (cur_tape->numfiles + 1));
106 for(c = 0; c < cur_tape->numfiles ; c++) {
107 if(cur_tape->files[c] > file && c == d_idx) {
108 newfiles[d_idx] = file;
109 newpartnum[d_idx] = partnum;
112 newfiles[d_idx] = cur_tape->files[c];
113 newpartnum[d_idx] = cur_tape->partnum[c];
117 newfiles[d_idx] = file;
118 newpartnum[d_idx] = partnum;
120 cur_tape->numfiles++;
121 amfree(cur_tape->files);
122 amfree(cur_tape->partnum);
123 cur_tape->files = newfiles;
124 cur_tape->partnum = newpartnum;
130 new_tape = alloc(SIZEOF(tapelist_t));
131 memset(new_tape, 0, SIZEOF(tapelist_t));
132 new_tape->label = stralloc(label);
133 if(file >= (off_t)0){
134 new_tape->files = alloc(SIZEOF(*(new_tape->files)));
135 new_tape->files[0] = file;
136 new_tape->partnum = alloc(SIZEOF(*(new_tape->partnum)));
137 new_tape->partnum[0] = partnum;
138 new_tape->numfiles = 1;
139 new_tape->isafile = isafile;
142 /* first instance of anything, start our tapelist with it */
146 /* new tape, tack it onto the end of the list */
148 while (cur_tape->next != NULL)
149 cur_tape = cur_tape->next;
150 cur_tape->next = new_tape;
157 * Backslash-escape all of the commas (and backslashes) in a label string.
163 char *cooked_str, *temp_str;
164 int s_idx = 0, d_idx = 0;
166 if(!label) return(NULL);
168 temp_str = alloc(strlen(label) * 2);
171 if(label[s_idx] == ',' || label[s_idx] == '\\' ||
172 label[s_idx] == ';' || label[s_idx] == ':'){
173 temp_str[d_idx] = '\\';
176 temp_str[d_idx] = label[s_idx];
179 } while(label[s_idx] != '\0');
180 temp_str[d_idx] = '\0';
182 cooked_str = stralloc(temp_str);
189 * Strip out any escape characters (backslashes)
195 char *cooked_str, *temp_str;
196 int s_idx = 0, d_idx = 0, prev_esc = 0;
198 if(!label) return(NULL);
200 temp_str = alloc(strlen(label));
203 if(label[s_idx] == '\\' && !prev_esc){
209 temp_str[d_idx] = label[s_idx];
212 } while(label[s_idx] != '\0');
213 temp_str[d_idx] = '\0';
215 cooked_str = stralloc(temp_str);
222 * Convert a tapelist into a parseable string of tape labels and file numbers.
226 tapelist_t *tapelist,
229 tapelist_t *cur_tape;
232 for(cur_tape = tapelist; cur_tape; cur_tape = cur_tape->next){
234 char *files_str = NULL;
237 if(do_escape) esc_label = escape_label(cur_tape->label);
238 else esc_label = stralloc(cur_tape->label);
240 for(c = 0; c < cur_tape->numfiles ; c++){
241 char num_str[NUM_STR_SIZE];
242 g_snprintf(num_str, SIZEOF(num_str), "%lld",
243 (long long)cur_tape->files[c]);
245 files_str = stralloc(num_str);
247 vstrextend(&files_str, ",", num_str, NULL);
251 str = vstralloc(esc_label, ":", files_str, NULL);
253 vstrextend(&str, ";", esc_label, ":", files_str, NULL);
263 * Convert a previously str-ified and escaped list of tapes back into a
264 * tapelist structure.
267 unmarshal_tapelist_str(
270 char *temp_label, *temp_filenum;
273 tapelist_t *tapelist = NULL;
275 if(!tapelist_str) return(NULL);
277 input_length = strlen(tapelist_str);
279 temp_label = alloc(input_length+1);
280 temp_filenum = alloc(input_length+1);
283 /* first, read the label part */
284 memset(temp_label, '\0', input_length+1);
286 while(*tapelist_str != ':' && *tapelist_str != '\0'){
287 if(*tapelist_str == '\\')
288 tapelist_str++; /* skip escapes */
289 temp_label[l_idx] = *tapelist_str;
290 if(*tapelist_str == '\0')
291 break; /* bad format, should kvetch */
295 if(*tapelist_str != '\0')
297 tapelist = append_to_tapelist(tapelist, temp_label, (off_t)-1, -1, 0);
299 /* now read the list of file numbers */
300 while(*tapelist_str != ';' && *tapelist_str != '\0'){
303 memset(temp_filenum, '\0', input_length+1);
305 while(*tapelist_str != ';' && *tapelist_str != ',' &&
306 *tapelist_str != '\0'){
307 temp_filenum[n_idx] = *tapelist_str;
311 filenum = OFF_T_ATOI(temp_filenum);
313 tapelist = append_to_tapelist(tapelist, temp_label, filenum, -1, 0);
314 if(*tapelist_str != '\0' && *tapelist_str != ';')
317 if(*tapelist_str != '\0')
320 } while(*tapelist_str != '\0');
323 amfree(temp_filenum);
329 * Free up a list of tapes
333 tapelist_t * tapelist)
335 tapelist_t *cur_tape;
336 tapelist_t *prev = NULL;
338 for(cur_tape = tapelist ; cur_tape ; cur_tape = cur_tape->next){
339 amfree(cur_tape->label);
340 amfree(cur_tape->files);
341 amfree(cur_tape->partnum);