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.3 2006/01/15 21:00:59 martinea Exp $
29 * Support code for amidxtaped and amindexd.
36 * Count the number of entries in this tapelist
38 int num_entries (tapelist)
44 for(cur_tape = tapelist ; cur_tape ; cur_tape = cur_tape->next) count++;
50 * Add a tape entry with the given label to the given tapelist, creating a new
51 * tapelist if handed a NULL one. Squashes duplicates.
53 tapelist_t *append_to_tapelist (tapelist, label, file, isafile)
58 tapelist_t *new_tape, *cur_tape;
61 /* see if we have this tape already, and if so just add to its file list */
62 for(cur_tape = tapelist; cur_tape; cur_tape = cur_tape->next){
63 if(!strcmp(label, cur_tape->label)){
67 newfiles = alloc(sizeof(int) * (cur_tape->numfiles + 1));
68 for(c = 0; c < cur_tape->numfiles ; c++){
69 if(cur_tape->files[c] > file && c == d_idx){
70 newfiles[d_idx] = file;
73 newfiles[d_idx] = cur_tape->files[c];
76 if(c == d_idx) newfiles[d_idx] = file;
78 amfree(cur_tape->files);
79 cur_tape->files = newfiles;
85 new_tape = alloc(sizeof(tapelist_t));
86 memset(new_tape, 0, sizeof(tapelist_t));
87 new_tape->label = stralloc(label);
89 new_tape->files = alloc(sizeof(int));
90 new_tape->files[0] = file;
91 new_tape->numfiles = 1;
92 new_tape->isafile = isafile;
95 /* first instance of anything, start our tapelist with it */
101 /* new tape, tack it onto the end of the list */
102 for(cur_tape = tapelist; cur_tape->next; cur_tape = cur_tape->next);
103 cur_tape->next = new_tape;
109 * Backslash-escape all of the commas (and backslashes) in a label string.
111 char *escape_label (label)
114 char *cooked_str, *temp_str;
115 int s_idx = 0, d_idx = 0;
117 if(!label) return(NULL);
119 temp_str = alloc(strlen(label) * 2);
122 if(label[s_idx] == ',' || label[s_idx] == '\\' ||
123 label[s_idx] == ';' || label[s_idx] == ':'){
124 temp_str[d_idx] = '\\';
127 temp_str[d_idx] = label[s_idx];
130 } while(label[s_idx] != '\0');
131 temp_str[d_idx] = '\0';
133 cooked_str = stralloc(temp_str);
140 * Strip out any escape characters (backslashes)
142 char *unescape_label(label)
145 char *cooked_str, *temp_str;
146 int s_idx = 0, d_idx = 0, prev_esc = 0;
148 if(!label) return(NULL);
150 temp_str = alloc(strlen(label));
153 if(label[s_idx] == '\\' && !prev_esc){
159 temp_str[d_idx] = label[s_idx];
162 } while(label[s_idx] != '\0');
163 temp_str[d_idx] = '\0';
165 cooked_str = stralloc(temp_str);
172 * Convert a tapelist into a parseable string of tape labels and file numbers.
174 char *marshal_tapelist (tapelist, do_escape)
175 tapelist_t *tapelist;
178 tapelist_t *cur_tape;
181 for(cur_tape = tapelist; cur_tape; cur_tape = cur_tape->next){
183 char *files_str = NULL;
186 if(do_escape) esc_label = escape_label(cur_tape->label);
187 else esc_label = stralloc(cur_tape->label);
189 for(c = 0; c < cur_tape->numfiles ; c++){
190 char num_str[NUM_STR_SIZE];
191 snprintf(num_str, sizeof(num_str), "%d", cur_tape->files[c]);
192 if(!files_str) files_str = stralloc(num_str);
193 else files_str = vstralloc(files_str, ",", num_str, NULL);
196 if(!str) str = vstralloc(esc_label, ":", files_str, NULL);
197 else str = vstralloc(str, ";", esc_label, ":", files_str, NULL);
207 * Convert a previously str-ified and escaped list of tapes back into a
208 * tapelist structure.
210 tapelist_t *unmarshal_tapelist_str (tapelist_str)
213 char *temp_label, *temp_filenum;
214 int l_idx, n_idx, input_length;
215 tapelist_t *tapelist = NULL;
217 if(!tapelist_str) return(NULL);
219 input_length = strlen(tapelist_str);
221 temp_label = alloc(input_length+1);
222 temp_filenum = alloc(input_length+1);
225 /* first, read the label part */
226 memset(temp_label, '\0', input_length+1);
228 while(*tapelist_str != ':' && *tapelist_str != '\0'){
229 if(*tapelist_str == '\\') *tapelist_str++; /* skip escapes */
230 temp_label[l_idx] = *tapelist_str;
231 if(*tapelist_str == '\0') break; /* bad format, should kvetch */
235 if(*tapelist_str != '\0') *tapelist_str++;
236 tapelist = append_to_tapelist(tapelist, temp_label, -1, 0);
238 /* now read the list of file numbers */
239 while(*tapelist_str != ';' && *tapelist_str != '\0'){
241 memset(temp_filenum, '\0', input_length+1);
243 while(*tapelist_str != ';' && *tapelist_str != ',' &&
244 *tapelist_str != '\0'){
245 temp_filenum[n_idx] = *tapelist_str;
249 filenum = atoi(temp_filenum);
251 tapelist = append_to_tapelist(tapelist, temp_label, filenum, 0);
252 if(*tapelist_str != '\0' && *tapelist_str != ';') *tapelist_str++;
254 if(*tapelist_str != '\0') *tapelist_str++;
256 } while(*tapelist_str != '\0');
259 amfree(temp_filenum);
265 * Free up a list of tapes
267 void free_tapelist (tapelist)
268 tapelist_t *tapelist;
270 tapelist_t *cur_tape;
271 tapelist_t *prev = NULL;
273 for(cur_tape = tapelist ; cur_tape ; cur_tape = cur_tape->next){
274 if(cur_tape->label) amfree(cur_tape->label);
275 if(cur_tape->files) amfree(cur_tape->files);
276 if(prev) amfree(prev);
279 if(prev) amfree(prev);