⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileheader.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-1999 University of Maryland at College Park * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of U.M. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission.  U.M. makes no representations about the * suitability of this software for any purpose.  It is provided "as is" * without express or implied warranty. * * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Authors: the Amanda Development Team.  Its members are listed in a * file named AUTHORS, in the root directory of this distribution. *//* * $Id: fileheader.c 6512 2007-05-24 17:00:24Z ian $ */#include "amanda.h"#include "fileheader.h"#include <glib.h>#include "util.h"static const char *	filetype2str(filetype_t);static filetype_t	str2filetype(const char *);static void		strange_header(dumpfile_t *, const char *,				size_t, const char *, const char *);static char *		strquotedstr(void);static ssize_t 		hexdump(const char *buffer, size_t len);voidfh_init(    dumpfile_t *file){    memset(file, '\0', SIZEOF(*file));    file->blocksize = DISK_BLOCK_BYTES;}static voidstrange_header(    dumpfile_t *file,    const char *buffer,    size_t	buflen,    const char *expected,    const char *actual){    if (actual == NULL)	actual = "<null>";    if (expected == NULL)	expected = "<null>";    g_fprintf(stderr, _("%s: strange amanda header: \"%.*s\"\n"), get_pname(),		(int)buflen, buffer);    g_fprintf(stderr, _("%s: Expected: \"%s\"  Actual: \"%s\"\n"), get_pname(),		expected, actual);    file->type = F_WEIRD;}voidparse_file_header(    const char *buffer,    dumpfile_t *file,    size_t	buflen){    char *buf, *line, *tok, *line1;    size_t lsize;    char *uqname;    int in_quotes;    /* put the buffer into a writable chunk of memory and nul-term it */    buf = alloc(buflen + 1);    memcpy(buf, buffer, buflen);    buf[buflen] = '\0';    fh_init(file);     in_quotes = 0;    for (line = buf, lsize = 0; lsize < buflen; line++) {	if ((*line == '\n') && !in_quotes)	    break;	if (*line == '"') {	    in_quotes = !in_quotes;	} else if ((*line == '\\') && (*(line + 1) == '"')) {	    line++;	    lsize++;	}	lsize++;    }    *line = '\0';    line1 = alloc(lsize + 1);    strncpy(line1, buf, lsize);    line1[lsize] = '\0';    *line = '\n';    tok = strtok(line1, " ");    if (tok == NULL) {        g_fprintf(stderr, _("%s: Empty amanda header: buflen=%zu lsize=%zu\n"), get_pname(),	    buflen, 	    lsize);	hexdump(buffer, lsize);	strange_header(file, buffer, buflen, _("<Non-empty line>"), tok);	goto out;    }    if (strcmp(tok, "NETDUMP:") != 0 && strcmp(tok, "AMANDA:") != 0) {	amfree(buf);	file->type = F_UNKNOWN;	amfree(line1);	return;    }    tok = strtok(NULL, " ");    if (tok == NULL) {	strange_header(file, buffer, buflen, _("<file type>"), tok);	goto out;    }    file->type = str2filetype(tok);        switch (file->type) {    case F_TAPESTART:	tok = strtok(NULL, " ");	if ((tok == NULL) || (strcmp(tok, "DATE") != 0)) {	    strange_header(file, buffer, buflen, "DATE", tok);	    goto out;	}	tok = strtok(NULL, " ");	if (tok == NULL) {	    strange_header(file, buffer, buflen, _("<date stamp>"), tok);	    goto out;	}	strncpy(file->datestamp, tok, SIZEOF(file->datestamp) - 1);	tok = strtok(NULL, " ");	if ((tok == NULL) || (strcmp(tok, "TAPE") != 0)) {	    strange_header(file, buffer, buflen, "TAPE", tok);	    goto out;	}	tok = strtok(NULL, " ");	if (tok == NULL) {	    strange_header(file, buffer, buflen, _("<file type>"), tok);	    goto out;	}	strncpy(file->name, tok, SIZEOF(file->name) - 1);	break;    case F_DUMPFILE:    case F_CONT_DUMPFILE:    case F_SPLIT_DUMPFILE:	tok = strtok(NULL, " ");	if (tok == NULL) {	    strange_header(file, buffer, buflen, _("<date stamp>"), tok);	    goto out;	}	strncpy(file->datestamp, tok, SIZEOF(file->datestamp) - 1);	tok = strtok(NULL, " ");	if (tok == NULL) {	    strange_header(file, buffer, buflen, _("<file name>"), tok);	    goto out;	}	strncpy(file->name, tok, SIZEOF(file->name) - 1);	tok = strquotedstr();	if (tok == NULL) {	    strange_header(file, buffer, buflen, _("<disk name>"), tok);	    goto out;	}	uqname = unquote_string(tok);	strncpy(file->disk, uqname, SIZEOF(file->disk) - 1); 	amfree(uqname);		if(file->type == F_SPLIT_DUMPFILE) {	    tok = strtok(NULL, " ");	    if (tok == NULL || strcmp(tok, "part") != 0) {		strange_header(file, buffer, buflen, "part", tok);		goto out;	    }	    tok = strtok(NULL, "/");	    if ((tok == NULL) || (sscanf(tok, "%d", &file->partnum) != 1)) {		strange_header(file, buffer, buflen, _("<part num param>"), tok);		goto out;	    }	    /* If totalparts == -1, then the original dump was done in  	       streaming mode (no holding disk), thus we don't know how                many parts there are. */	    tok = strtok(NULL, " ");            if((tok == NULL) || (sscanf(tok, "%d", &file->totalparts) != 1)) {		strange_header(file, buffer, buflen, _("<total parts param>"), tok);		goto out;	    }	}	tok = strtok(NULL, " ");	if ((tok == NULL) || (strcmp(tok, "lev") != 0)) {	    strange_header(file, buffer, buflen, "lev", tok);	    goto out;	}	tok = strtok(NULL, " ");	if ((tok == NULL) || (sscanf(tok, "%d", &file->dumplevel) != 1)) {	    strange_header(file, buffer, buflen, _("<dump level param>"), tok);	    goto out;	}	tok = strtok(NULL, " ");	if ((tok == NULL) || (strcmp(tok, "comp") != 0)) {	    strange_header(file, buffer, buflen, "comp", tok);	    goto out;	}	tok = strtok(NULL, " ");	if (tok == NULL) {	    strange_header(file, buffer, buflen, _("<comp param>"), tok);	    goto out;	}	strncpy(file->comp_suffix, tok, SIZEOF(file->comp_suffix) - 1);	file->compressed = strcmp(file->comp_suffix, "N");	/* compatibility with pre-2.2 amanda */	if (strcmp(file->comp_suffix, "C") == 0)	    strncpy(file->comp_suffix, ".Z", SIZEOF(file->comp_suffix) - 1);	       	tok = strtok(NULL, " ");        /* "program" is optional */        if (tok == NULL || strcmp(tok, "program") != 0) {	    amfree(buf);	    amfree(line1);            return;	}        tok = strtok(NULL, " ");        if (tok == NULL) {	    strange_header(file, buffer, buflen, _("<program name>"), tok);	    goto out;	}        strncpy(file->program, tok, SIZEOF(file->program) - 1);        if (file->program[0] == '\0')            strncpy(file->program, "RESTORE", SIZEOF(file->program) - 1);	if ((tok = strtok(NULL, " ")) == NULL)             break;          /* reached the end of the buffer */	/* "encryption" is optional */	if (BSTRNCMP(tok, "crypt") == 0) {	    tok = strtok(NULL, " ");	    if (tok == NULL) {		strange_header(file, buffer, buflen, _("<crypt param>"), tok);		goto out;	    }	    strncpy(file->encrypt_suffix, tok,		    SIZEOF(file->encrypt_suffix) - 1);	    file->encrypted = BSTRNCMP(file->encrypt_suffix, "N");	    if ((tok = strtok(NULL, " ")) == NULL)		break;	}	/* "srvcompprog" is optional */	if (BSTRNCMP(tok, "server_custom_compress") == 0) {	    tok = strtok(NULL, " ");	    if (tok == NULL) {		strange_header(file, buffer, buflen,				_("<server custom compress param>"), tok);		goto out;	    }	    strncpy(file->srvcompprog, tok, SIZEOF(file->srvcompprog) - 1);	    if ((tok = strtok(NULL, " ")) == NULL)		break;      	}	/* "clntcompprog" is optional */	if (BSTRNCMP(tok, "client_custom_compress") == 0) {	    tok = strtok(NULL, " ");	    if (tok == NULL) {		strange_header(file, buffer, buflen,				_("<client custom compress param>"), tok);		goto out;	    }	    strncpy(file->clntcompprog, tok, SIZEOF(file->clntcompprog) - 1);	    if ((tok = strtok(NULL, " ")) == NULL)		break;	}	/* "srv_encrypt" is optional */	if (BSTRNCMP(tok, "server_encrypt") == 0) {	    tok = strtok(NULL, " ");	    if (tok == NULL) {		strange_header(file, buffer, buflen,				_("<server encrypt param>"), tok);		goto out;	    }	    strncpy(file->srv_encrypt, tok, SIZEOF(file->srv_encrypt) - 1);	    if ((tok = strtok(NULL, " ")) == NULL) 		break;	}	/* "clnt_encrypt" is optional */	if (BSTRNCMP(tok, "client_encrypt") == 0) {	    tok = strtok(NULL, " ");	    if (tok == NULL) {		strange_header(file, buffer, buflen,				_("<client encrypt param>"), tok);		goto out;	    }	    strncpy(file->clnt_encrypt, tok, SIZEOF(file->clnt_encrypt) - 1);	    if ((tok = strtok(NULL, " ")) == NULL) 		break;	}	/* "srv_decrypt_opt" is optional */	if (BSTRNCMP(tok, "server_decrypt_option") == 0) {	    tok = strtok(NULL, " ");	    if (tok == NULL) {		strange_header(file, buffer, buflen,				_("<server decrypt param>"), tok);		goto out;	    }	    strncpy(file->srv_decrypt_opt, tok,		    SIZEOF(file->srv_decrypt_opt) - 1);	    if ((tok = strtok(NULL, " ")) == NULL) 		break;	}	/* "clnt_decrypt_opt" is optional */	if (BSTRNCMP(tok, "client_decrypt_option") == 0) {	    tok = strtok(NULL, " ");	    if (tok == NULL) {		strange_header(file, buffer, buflen,				_("<client decrypt param>"), tok);		goto out;	    }	    strncpy(file->clnt_decrypt_opt, tok,		    SIZEOF(file->clnt_decrypt_opt) - 1);	    if ((tok = strtok(NULL, " ")) == NULL) 		break;	}      break;          case F_TAPEEND:	tok = strtok(NULL, " ");	/* DATE is optional */	if (tok != NULL) {	    if (strcmp(tok, "DATE") == 0) {		tok = strtok(NULL, " ");		if(tok == NULL)		    file->datestamp[0] = '\0';		else		    strncpy(file->datestamp, tok, SIZEOF(file->datestamp) - 1);	    } else {		strange_header(file, buffer, buflen, _("<DATE>"), tok);	   }	} else {	    file->datestamp[0] = '\0';	}	break;    default:	strange_header(file, buffer, buflen,		_("TAPESTART|DUMPFILE|CONT_DUMPFILE|SPLIT_DUMPFILE|TAPEEND"), tok);	goto out;    }    (void)strtok(buf, "\n"); /* this is the first line */    /* iterate through the rest of the lines */    while ((line = strtok(NULL, "\n")) != NULL) {#define SC "CONT_FILENAME="	if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) {	    line += SIZEOF(SC) - 1;	    strncpy(file->cont_filename, line,		    SIZEOF(file->cont_filename) - 1);	    continue;	}#undef SC#define SC "PARTIAL="	if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) {	    line += SIZEOF(SC) - 1;	    file->is_partial = !strcasecmp(line, "yes");	    continue;	}#undef SC#define SC "DUMPER="	if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) {	    line += SIZEOF(SC) - 1;	    strncpy(file->dumper, line,		    SIZEOF(file->dumper) - 1);	    continue;	}#undef SC#define SC _("To restore, position tape at start of file and run:")	if (strncmp(line, SC, SIZEOF(SC) - 1) == 0)	    continue;#undef SC#define SC "\tdd if=<tape> bs="	if (strncmp(line, SC, SIZEOF(SC) - 1) == 0) {	    char *cmd1, *cmd2, *cmd3=NULL;	    /* skip over dd command */	    if ((cmd1 = strchr(line, '|')) == NULL) {	        strncpy(file->recover_cmd, "BUG",		        SIZEOF(file->recover_cmd) - 1);	        continue;	    }	    *cmd1++ = '\0';	    /* block out first pipeline command */	    if ((cmd2 = strchr(cmd1, '|')) != NULL) {	      *cmd2++ = '\0';	      if ((cmd3 = strchr(cmd2, '|')) != NULL)		*cmd3++ = '\0';	    }	   	    /* three cmds: decrypt    | uncompress | recover	     * two   cmds: uncompress | recover	     * XXX note that if there are two cmds, the first one 	     * XXX could be either uncompress or decrypt. Since no	     * XXX code actually call uncompress_cmd/decrypt_cmd, it's ok	     * XXX for header information.	     * one   cmds: recover	     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -