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;
120 new_tape = alloc(SIZEOF(tapelist_t));
121 memset(new_tape, 0, SIZEOF(tapelist_t));
122 new_tape->label = stralloc(label);
123 if(file >= (off_t)0){
124 new_tape->files = alloc(SIZEOF(*(new_tape->files)));
125 new_tape->files[0] = file;
126 new_tape->numfiles = 1;
127 new_tape->isafile = isafile;
130 /* first instance of anything, start our tapelist with it */
134 /* new tape, tack it onto the end of the list */
136 while (cur_tape->next != NULL)
137 cur_tape = cur_tape->next;
138 cur_tape->next = new_tape;
145 * Backslash-escape all of the commas (and backslashes) in a label string.
151 char *cooked_str, *temp_str;
152 int s_idx = 0, d_idx = 0;
154 if(!label) return(NULL);
156 temp_str = alloc(strlen(label) * 2);
159 if(label[s_idx] == ',' || label[s_idx] == '\\' ||
160 label[s_idx] == ';' || label[s_idx] == ':'){
161 temp_str[d_idx] = '\\';
164 temp_str[d_idx] = label[s_idx];
167 } while(label[s_idx] != '\0');
168 temp_str[d_idx] = '\0';
170 cooked_str = stralloc(temp_str);
177 * Strip out any escape characters (backslashes)
183 char *cooked_str, *temp_str;
184 int s_idx = 0, d_idx = 0, prev_esc = 0;
186 if(!label) return(NULL);
188 temp_str = alloc(strlen(label));
191 if(label[s_idx] == '\\' && !prev_esc){
197 temp_str[d_idx] = label[s_idx];
200 } while(label[s_idx] != '\0');
201 temp_str[d_idx] = '\0';
203 cooked_str = stralloc(temp_str);
210 * Convert a tapelist into a parseable string of tape labels and file numbers.
214 tapelist_t *tapelist,
217 tapelist_t *cur_tape;
220 for(cur_tape = tapelist; cur_tape; cur_tape = cur_tape->next){
222 char *files_str = NULL;
225 if(do_escape) esc_label = escape_label(cur_tape->label);
226 else esc_label = stralloc(cur_tape->label);
228 for(c = 0; c < cur_tape->numfiles ; c++){
229 char num_str[NUM_STR_SIZE];
230 snprintf(num_str, SIZEOF(num_str), OFF_T_FMT,
231 (OFF_T_FMT_TYPE)cur_tape->files[c]);
233 files_str = stralloc(num_str);
235 vstrextend(&files_str, ",", num_str, NULL);
239 str = vstralloc(esc_label, ":", files_str, NULL);
241 vstrextend(&str, ";", esc_label, ":", files_str, NULL);
251 * Convert a previously str-ified and escaped list of tapes back into a
252 * tapelist structure.
255 unmarshal_tapelist_str(
258 char *temp_label, *temp_filenum;
261 tapelist_t *tapelist = NULL;
263 if(!tapelist_str) return(NULL);
265 input_length = strlen(tapelist_str);
267 temp_label = alloc(input_length+1);
268 temp_filenum = alloc(input_length+1);
271 /* first, read the label part */
272 memset(temp_label, '\0', input_length+1);
274 while(*tapelist_str != ':' && *tapelist_str != '\0'){
275 if(*tapelist_str == '\\')
276 tapelist_str++; /* skip escapes */
277 temp_label[l_idx] = *tapelist_str;
278 if(*tapelist_str == '\0')
279 break; /* bad format, should kvetch */
283 if(*tapelist_str != '\0')
285 tapelist = append_to_tapelist(tapelist, temp_label, (off_t)-1, 0);
287 /* now read the list of file numbers */
288 while(*tapelist_str != ';' && *tapelist_str != '\0'){
291 memset(temp_filenum, '\0', input_length+1);
293 while(*tapelist_str != ';' && *tapelist_str != ',' &&
294 *tapelist_str != '\0'){
295 temp_filenum[n_idx] = *tapelist_str;
299 filenum = OFF_T_ATOI(temp_filenum);
301 tapelist = append_to_tapelist(tapelist, temp_label, filenum, 0);
302 if(*tapelist_str != '\0' && *tapelist_str != ';')
305 if(*tapelist_str != '\0')
308 } while(*tapelist_str != '\0');
311 amfree(temp_filenum);
317 * Free up a list of tapes
321 tapelist_t * tapelist)
323 tapelist_t *cur_tape;
324 tapelist_t *prev = NULL;
326 for(cur_tape = tapelist ; cur_tape ; cur_tape = cur_tape->next){
327 amfree(cur_tape->label);
328 amfree(cur_tape->files);