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: fileheader.c,v 1.11.4.1.4.1.2.6 2003/10/24 13:44:49 martinea Exp $
32 #include "fileheader.h"
38 memset(file,'\0',sizeof(*file));
39 file->blocksize = DISK_BLOCK_BYTES;
44 parse_file_header(buffer, file, buflen)
49 string_t line, save_line;
50 char *bp, *str, *ptr_buf, *start_buf;
57 /* isolate first line */
59 nchars = buflen<sizeof(line)? buflen : sizeof(line) - 1;
60 for(s=line, ptr_buf=buffer; ptr_buf < buffer+nchars; ptr_buf++, s++) {
68 line[sizeof(line)-1] = '\0';
69 strncpy(save_line, line, sizeof(save_line));
75 skip_whitespace(s, ch);
77 skip_non_whitespace(s, ch);
80 if(strcmp(str, "NETDUMP:") != 0 && strcmp(str,"AMANDA:") != 0) {
81 file->type = F_UNKNOWN;
85 skip_whitespace(s, ch);
90 skip_non_whitespace(s, ch);
93 if(strcmp(str, "TAPESTART") == 0) {
94 file->type = F_TAPESTART;
96 skip_whitespace(s, ch);
101 skip_non_whitespace(s, ch);
103 if(strcmp(verify, "DATE") != 0) {
107 skip_whitespace(s, ch);
111 copy_string(s, ch, file->datestamp, sizeof(file->datestamp), bp);
116 skip_whitespace(s, ch);
121 skip_non_whitespace(s, ch);
123 if(strcmp(verify, "TAPE") != 0) {
127 skip_whitespace(s, ch);
131 copy_string(s, ch, file->name, sizeof(file->name), bp);
135 } else if(strcmp(str, "FILE") == 0 ||
136 strcmp(str, "CONT_FILE") == 0) {
137 if(strcmp(str, "FILE") == 0)
138 file->type = F_DUMPFILE;
139 else if(strcmp(str, "CONT_FILE") == 0)
140 file->type = F_CONT_DUMPFILE;
142 skip_whitespace(s, ch);
146 copy_string(s, ch, file->datestamp, sizeof(file->datestamp), bp);
151 skip_whitespace(s, ch);
155 copy_string(s, ch, file->name, sizeof(file->name), bp);
160 skip_whitespace(s, ch);
164 copy_string(s, ch, file->disk, sizeof(file->disk), bp);
169 skip_whitespace(s, ch);
174 skip_non_whitespace(s, ch);
176 if(strcmp(verify, "lev") != 0) {
180 skip_whitespace(s, ch);
181 if(ch == '\0' || sscanf(s - 1, "%d", &file->dumplevel) != 1) {
186 skip_whitespace(s, ch);
191 skip_non_whitespace(s, ch);
193 if(strcmp(verify, "comp") != 0) {
197 skip_whitespace(s, ch);
201 copy_string(s, ch, file->comp_suffix, sizeof(file->comp_suffix), bp);
206 file->compressed = strcmp(file->comp_suffix, "N");
207 /* compatibility with pre-2.2 amanda */
208 if(strcmp(file->comp_suffix, "C") == 0) {
209 strncpy(file->comp_suffix, ".Z", sizeof(file->comp_suffix)-1);
210 file->comp_suffix[sizeof(file->comp_suffix)-1] = '\0';
213 skip_whitespace(s, ch);
215 return; /* "program" is optional */
218 skip_non_whitespace(s, ch);
220 if(strcmp(verify, "program") != 0) {
221 return; /* "program" is optional */
224 skip_whitespace(s, ch);
228 copy_string(s, ch, file->program, sizeof(file->program), bp);
233 if(file->program[0]=='\0') {
234 strncpy(file->program, "RESTORE", sizeof(file->program)-1);
235 file->program[sizeof(file->program)-1] = '\0';
238 } else if(strcmp(str, "TAPEEND") == 0) {
239 file->type = F_TAPEEND;
241 skip_whitespace(s, ch);
246 skip_non_whitespace(s, ch);
248 if(strcmp(verify, "DATE") != 0) {
249 return; /* "program" is optional */
252 skip_whitespace(s, ch);
256 copy_string(s, ch, file->datestamp, sizeof(file->datestamp), bp);
266 /* isolate the next line */
270 max_char = buflen - (ptr_buf - buffer);
271 nchars = max_char<sizeof(line)? max_char : sizeof(line) - 1;
272 for(s=line ; ptr_buf < start_buf+nchars; ptr_buf++, s++) {
278 else if(ch == '\0' || ch == '\014') {
284 if (done == 1) break;
285 if(ptr_buf >= start_buf+nchars) done = 1;
286 line[sizeof(line)-1] = '\0';
289 #define SC "CONT_FILENAME="
290 if(strncmp(line,SC,strlen(SC)) == 0) {
291 s = line + strlen(SC);
293 copy_string(s, ch, file->cont_filename,
294 sizeof(file->cont_filename), bp);
297 #define SC "PARTIAL="
298 else if(strncmp(line,SC,strlen(SC)) == 0) {
299 s = line + strlen(SC);
300 if(strncmp(s,"yes",3)==0 || strncmp(s,"YES",3)==0)
305 #define SC "To restore, position tape at start of file and run:"
306 else if(strncmp(line,SC,strlen(SC)) == 0) {
309 #define SC "\tdd if=<tape> bs="
310 else if(strncmp(line,SC,strlen(SC)) == 0) {
311 s = strtok(line, "|");
312 s1 = strtok(NULL, "|");
313 s2 = strtok(NULL, "|");
315 strncpy(file->recover_cmd,"BUG",sizeof(file->recover_cmd));
316 file->recover_cmd[sizeof(file->recover_cmd)-1] = '\0';
319 strncpy(file->recover_cmd,s1+1,sizeof(file->recover_cmd));
320 file->recover_cmd[sizeof(file->recover_cmd)-1] = '\0';
323 strncpy(file->uncompress_cmd,s1, sizeof(file->uncompress_cmd));
324 file->uncompress_cmd[sizeof(file->uncompress_cmd)-2] = '\0';
325 strcat(file->uncompress_cmd,"|");
326 strncpy(file->recover_cmd,s2+1,sizeof(file->recover_cmd));
327 file->recover_cmd[sizeof(file->recover_cmd)-1] = '\0';
331 else { /* ignore unknown line */
339 fprintf(stderr, "%s: strange amanda header: \"%s\"\n", get_pname(), save_line);
340 file->type = F_WEIRD;
346 build_header(buffer, file, buflen)
352 char number[NUM_STR_SIZE*2];
354 memset(buffer,'\0',buflen);
356 switch (file->type) {
357 case F_TAPESTART: ap_snprintf(buffer, buflen,
358 "AMANDA: TAPESTART DATE %s TAPE %s\n\014\n",
359 file->datestamp, file->name);
361 case F_CONT_DUMPFILE:
362 case F_DUMPFILE : if( file->type == F_DUMPFILE) {
363 ap_snprintf(buffer, buflen,
364 "AMANDA: FILE %s %s %s lev %d comp %s program %s\n",
365 file->datestamp, file->name, file->disk,
366 file->dumplevel, file->comp_suffix,
369 else if( file->type == F_CONT_DUMPFILE) {
370 ap_snprintf(buffer, buflen,
371 "AMANDA: CONT_FILE %s %s %s lev %d comp %s program %s\n",
372 file->datestamp, file->name, file->disk,
373 file->dumplevel, file->comp_suffix,
376 buffer[buflen-1] = '\0';
377 if(strlen(file->cont_filename) != 0) {
378 line = newvstralloc(line, "CONT_FILENAME=",
379 file->cont_filename, "\n", NULL);
380 strncat(buffer,line,buflen-strlen(buffer));
382 if(file->is_partial != 0) {
383 strncat(buffer,"PARTIAL=YES\n",buflen-strlen(buffer));
386 "To restore, position tape at start of file and run:\n",
387 buflen-strlen(buffer));
388 ap_snprintf(number, sizeof(number),
389 "%ld", file->blocksize / 1024);
390 line = newvstralloc(line, "\t",
395 " |", file->uncompress_cmd,
396 " ", file->recover_cmd,
400 strncat(buffer, line, buflen-strlen(buffer));
402 buffer[buflen-1] = '\0';
404 case F_TAPEEND : ap_snprintf(buffer, buflen,
405 "AMANDA: TAPEEND DATE %s\n\014\n",
408 case F_UNKNOWN : break;
409 case F_WEIRD : break;
414 void print_header(outf, file)
418 * Prints the contents of the file structure.
423 fprintf(outf, "UNKNOWN file\n");
426 fprintf(outf, "WEIRD file\n");
429 fprintf(outf, "start of tape: date %s label %s\n",
430 file->datestamp, file->name);
433 fprintf(outf, "dumpfile: date %s host %s disk %s lev %d comp %s",
434 file->datestamp, file->name, file->disk, file->dumplevel,
437 fprintf(outf, " program %s\n",file->program);
441 case F_CONT_DUMPFILE:
442 fprintf(outf, "cont dumpfile: date %s host %s disk %s lev %d comp %s",
443 file->datestamp, file->name, file->disk, file->dumplevel,
446 fprintf(outf, " program %s\n",file->program);
451 fprintf(outf, "end of tape: date %s\n", file->datestamp);
457 int known_compress_type(file)
460 if(strcmp(file->comp_suffix, ".Z") == 0)
463 if(strcmp(file->comp_suffix, ".gz") == 0)