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] = " OFF_T_FMT "\n",
68 cur_tape, file, (OFF_T_FMT_TYPE)cur_tape->files[file]));
72 dbprintf((" %p count = %d\n", tapelist, count));
76 * Add a tape entry with the given label to the given tapelist, creating a new
77 * tapelist if handed a NULL one. Squashes duplicates.
86 tapelist_t *new_tape, *cur_tape;
89 dbprintf(("append_to_tapelist(tapelist=%p, label='%s', , file="
90 OFF_T_FMT ", isafile=%d)\n",
91 tapelist, label, (OFF_T_FMT_TYPE)file, isafile));
93 /* see if we have this tape already, and if so just add to its file list */
94 for(cur_tape = tapelist; cur_tape; cur_tape = cur_tape->next) {
95 if(strcmp(label, cur_tape->label) == 0) {
99 if(file >= (off_t)0) {
100 newfiles = alloc(SIZEOF(*newfiles) *
101 (cur_tape->numfiles + 1));
102 for(c = 0; c < cur_tape->numfiles ; c++) {
103 if(cur_tape->files[c] > file && c == d_idx) {
104 newfiles[d_idx] = file;
107 newfiles[d_idx] = cur_tape->files[c];
111 newfiles[d_idx] = file;
112 cur_tape->numfiles++;
113 amfree(cur_tape->files);
114 cur_tape->files = newfiles;
116 dump_tapelist(tapelist);
121 new_tape = alloc(SIZEOF(tapelist_t));
122 memset(new_tape, 0, SIZEOF(tapelist_t));
123 new_tape->label = stralloc(label);
124 if(file >= (off_t)0){
125 new_tape->files = alloc(SIZEOF(*(new_tape->files)));
126 new_tape->files[0] = file;
127 new_tape->numfiles = 1;
128 new_tape->isafile = isafile;
131 /* first instance of anything, start our tapelist with it */
135 /* new tape, tack it onto the end of the list */
137 while (cur_tape->next != NULL)
138 cur_tape = cur_tape->next;
139 cur_tape->next = new_tape;
142 dump_tapelist(tapelist);
147 * Backslash-escape all of the commas (and backslashes) in a label string.
153 char *cooked_str, *temp_str;
154 int s_idx = 0, d_idx = 0;
156 if(!label) return(NULL);
158 temp_str = alloc(strlen(label) * 2);
161 if(label[s_idx] == ',' || label[s_idx] == '\\' ||
162 label[s_idx] == ';' || label[s_idx] == ':'){
163 temp_str[d_idx] = '\\';
166 temp_str[d_idx] = label[s_idx];
169 } while(label[s_idx] != '\0');
170 temp_str[d_idx] = '\0';
172 cooked_str = stralloc(temp_str);
179 * Strip out any escape characters (backslashes)
185 char *cooked_str, *temp_str;
186 int s_idx = 0, d_idx = 0, prev_esc = 0;
188 if(!label) return(NULL);
190 temp_str = alloc(strlen(label));
193 if(label[s_idx] == '\\' && !prev_esc){
199 temp_str[d_idx] = label[s_idx];
202 } while(label[s_idx] != '\0');
203 temp_str[d_idx] = '\0';
205 cooked_str = stralloc(temp_str);
212 * Convert a tapelist into a parseable string of tape labels and file numbers.
216 tapelist_t *tapelist,
219 tapelist_t *cur_tape;
222 for(cur_tape = tapelist; cur_tape; cur_tape = cur_tape->next){
224 char *files_str = NULL;
227 if(do_escape) esc_label = escape_label(cur_tape->label);
228 else esc_label = stralloc(cur_tape->label);
230 for(c = 0; c < cur_tape->numfiles ; c++){
231 char num_str[NUM_STR_SIZE];
232 snprintf(num_str, SIZEOF(num_str), OFF_T_FMT,
233 (OFF_T_FMT_TYPE)cur_tape->files[c]);
235 files_str = stralloc(num_str);
237 vstrextend(&files_str, ",", num_str, NULL);
241 str = vstralloc(esc_label, ":", files_str, NULL);
243 vstrextend(&str, ";", esc_label, ":", files_str, NULL);
253 * Convert a previously str-ified and escaped list of tapes back into a
254 * tapelist structure.
257 unmarshal_tapelist_str(
260 char *temp_label, *temp_filenum;
263 tapelist_t *tapelist = NULL;
265 if(!tapelist_str) return(NULL);
267 input_length = strlen(tapelist_str);
269 temp_label = alloc(input_length+1);
270 temp_filenum = alloc(input_length+1);
273 /* first, read the label part */
274 memset(temp_label, '\0', input_length+1);
276 while(*tapelist_str != ':' && *tapelist_str != '\0'){
277 if(*tapelist_str == '\\')
278 tapelist_str++; /* skip escapes */
279 temp_label[l_idx] = *tapelist_str;
280 if(*tapelist_str == '\0')
281 break; /* bad format, should kvetch */
285 if(*tapelist_str != '\0')
287 tapelist = append_to_tapelist(tapelist, temp_label, (off_t)-1, 0);
289 /* now read the list of file numbers */
290 while(*tapelist_str != ';' && *tapelist_str != '\0'){
293 memset(temp_filenum, '\0', input_length+1);
295 while(*tapelist_str != ';' && *tapelist_str != ',' &&
296 *tapelist_str != '\0'){
297 temp_filenum[n_idx] = *tapelist_str;
301 filenum = OFF_T_ATOI(temp_filenum);
303 tapelist = append_to_tapelist(tapelist, temp_label, filenum, 0);
304 if(*tapelist_str != '\0' && *tapelist_str != ';')
307 if(*tapelist_str != '\0')
310 } while(*tapelist_str != '\0');
313 amfree(temp_filenum);
319 * Free up a list of tapes
323 tapelist_t * tapelist)
325 tapelist_t *cur_tape;
326 tapelist_t *prev = NULL;
328 for(cur_tape = tapelist ; cur_tape ; cur_tape = cur_tape->next){
329 amfree(cur_tape->label);
330 amfree(cur_tape->files);