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

📄 tapeio.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-1998 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. * * Author: James da Silva, Systems Design and Analysis Group *			   Computer Science Department *			   University of Maryland at College Park *//* * $Id: tapeio.c,v 1.57 2006/07/06 15:04:18 martinea Exp $ * * implements generic tape I/O functions */#include "amanda.h"#include "conffile.h"#include "tapeio.h"#include "fileheader.h"#ifndef R_OK#define R_OK 4#define W_OK 2#endif#include "output-tape.h"#include "output-null.h"#include "output-rait.h"#include "output-file.h"static struct virtualtape {    char *prefix;    int (*xxx_tape_access)(char *, int);    int (*xxx_tape_open)(char *, int, mode_t);    int (*xxx_tape_stat)(char *, struct stat *);    int (*xxx_tapefd_close)(int);    int (*xxx_tapefd_fsf)(int, off_t);    ssize_t (*xxx_tapefd_read)(int, void *, size_t);    int (*xxx_tapefd_rewind)(int);    void (*xxx_tapefd_resetofs)(int);    int (*xxx_tapefd_unload)(int);    int (*xxx_tapefd_status)(int, struct am_mt_status *);    int (*xxx_tapefd_weof)(int, off_t);    ssize_t (*xxx_tapefd_write)(int, const void *, size_t);    int (*xxx_tapefd_can_fork)(int);} vtable[] = {  /* note: "tape" has to be the first entry because it is the  **        default if no prefix match is found.  */  {"tape", tape_tape_access, tape_tape_open, tape_tape_stat,	tape_tapefd_close, tape_tapefd_fsf,	tape_tapefd_read, tape_tapefd_rewind, tape_tapefd_resetofs,	tape_tapefd_unload, tape_tapefd_status, tape_tapefd_weof,        tape_tapefd_write, tape_tapefd_can_fork },  {"null", null_tape_access, null_tape_open, null_tape_stat,	null_tapefd_close, null_tapefd_fsf,	null_tapefd_read, null_tapefd_rewind, null_tapefd_resetofs,	null_tapefd_unload, null_tapefd_status, null_tapefd_weof,        null_tapefd_write, null_tapefd_can_fork },  {"rait", rait_access, rait_tape_open, rait_stat,	rait_close, rait_tapefd_fsf,	rait_read, rait_tapefd_rewind, rait_tapefd_resetofs,	rait_tapefd_unload, rait_tapefd_status, rait_tapefd_weof,        rait_write, rait_tapefd_can_fork },  {"file", file_tape_access, file_tape_open, file_tape_stat,	file_tapefd_close, file_tapefd_fsf,	file_tapefd_read, file_tapefd_rewind, file_tapefd_resetofs,	file_tapefd_unload, file_tapefd_status, file_tapefd_weof,        file_tapefd_write, file_tapefd_can_fork },  {NULL, NULL, NULL, NULL,        NULL, NULL,	NULL, NULL, NULL,	NULL, NULL, NULL,	NULL, NULL}};static struct tape_info {    int vtape_index;    char *host;    char *disk;    int level;    char *datestamp;    off_t length;    char *tapetype;    int fake_label;    int ioctl_fork;    int master_fd;} *tape_info = NULL;static struct tape_info **tape_info_p = &tape_info;static size_t tape_info_count = 0;static char *errstr = NULL;static void tape_info_init(void *ptr);static int name2slot(char *name, char **ntrans);/* * Additional initialization function for tape_info table. */static voidtape_info_init(    void *ptr){    struct tape_info *t = ptr;    t->level = -1;    t->vtape_index = -1;    t->ioctl_fork = 1;    t->master_fd = -1;}/* * Convert the "name" part of a device to a vtape slot. */static intname2slot(    char *name,    char **ntrans){    char *pc;    size_t len;    int i;    if(0 != (pc = strchr(name, ':'))) {        len = (size_t)(pc - name);	for( i = 0 ; vtable[i].prefix && vtable[i].prefix[0]; i++ ) {	    if(0 == strncmp(vtable[i].prefix, name , len)		&& '\0' == vtable[i].prefix[len]) {		*ntrans = pc + 1;		return i;            }        }    }    *ntrans = name;    return 0;}/* * Routines for parsing a device name. *//* * Initialize parsing.  The text in the "dev" parameter will be altered, * so a copy should be passed to us. */inttapeio_init_devname(    char * dev,    char **dev_left,    char **dev_right,    char **dev_next){    int ch;    char *p;    int depth;    *dev_left = *dev_right = *dev_next = NULL;	/* defensive coding */    /*     * See if there is a '{' and find the matching '}'.     */    if((*dev_next = p = strchr(dev, '{')) != NULL) {	depth = 1;	p++;	while(depth > 0) {	    ch = *p++;	    while((ch != '\0') && (ch != '{') && (ch != '}'))	        ch = *p++;	    if(ch == '\0') {		/*		 * Did not find a matching '}'.		 */		amfree(dev);		errno = EINVAL;		return -1;	    } else if(ch == '{') {		depth++;	    } else if(ch == '}') {		depth--;	    }	}	if(strchr(p, '{') != NULL || strchr(p, '}') != NULL) {	    amfree(dev);	    errno = EINVAL;	    return -1;				/* only one list allowed */	}	*dev_left = dev;			/* text before the '{' */	**dev_next = '\0';			/* zap the '{' */	(*dev_next)++;				/* point to the first name */	p[-1] = '\0';				/* zap the '}' */	*dev_right = p;				/* text after the '}' */    } else {	/*	 * Arrange to return just one name.	 */	*dev_next = dev;	*dev_left = *dev_right = "";    }    return 0;}/* * Return the next device name.  A dynamic area is returned that the * caller is responsible for freeing. */char *tapeio_next_devname(    char * dev_left,    char * dev_right,    char **dev_next){    int ch;    char *next;    char *p;    int depth;    p = next = *dev_next;			/* remember the start point */    depth = 0;    do {	ch = *p++;	while((ch != '\0') && (ch != '{') && (ch != '}') && (ch != ','))	    ch = *p++;	if(ch == '\0') {	    /*	     * Found the end of a name.	     */	    assert(depth == 0);	    if(*next == '\0') {		return NULL;			/* end of the list */	    }	    p--;				/* point to the null byte */	    break;	} else if(ch == '{') {	    depth++;	} else if(ch == '}') {	    assert(depth > 0);	    depth--;	}    } while(depth != 0 || ch != ',');    if(ch == ',') {	p[-1] = '\0';				/* zap the ',' */    }    *dev_next = p;				/* set up for the next call */    return vstralloc(dev_left, next, dev_right, NULL);}/* * The following functions get/set fields in the tape_info structure. * To allow them to be called (e.g. set) from lower level open functions * started by tape_open, we check and allocate the tape_info structure * here as well as in tape_open. */char *tapefd_getinfo_host(    int fd){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    if(tape_info[fd].master_fd != -1)	return tapefd_getinfo_host(tape_info[fd].master_fd);    return tape_info[fd].host;}voidtapefd_setinfo_host(    int fd,    char *v){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    amfree(tape_info[fd].host);    if(v) {	tape_info[fd].host = stralloc(v);    }}char *tapefd_getinfo_disk(    int fd){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    if(tape_info[fd].master_fd != -1)	return tapefd_getinfo_disk(tape_info[fd].master_fd);    return tape_info[fd].disk;}voidtapefd_setinfo_disk(    int fd,    char *v){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    amfree(tape_info[fd].disk);    if(v) {	tape_info[fd].disk = stralloc(v);    }}inttapefd_getinfo_level(    int fd){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    if(tape_info[fd].master_fd != -1)	return tapefd_getinfo_level(tape_info[fd].master_fd);    return tape_info[fd].level;}voidtapefd_setinfo_level(    int fd,    int v){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    tape_info[fd].level = v;}char *tapefd_getinfo_datestamp(    int fd){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    return tape_info[fd].datestamp;}voidtapefd_setinfo_datestamp(    int fd,    char *v){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    tape_info[fd].datestamp = newstralloc(tape_info[fd].datestamp, v);}off_ttapefd_getinfo_length(    int fd){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    return tape_info[fd].length;}voidtapefd_setinfo_length(    int fd,    off_t v){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    tape_info[fd].length = v;}char *tapefd_getinfo_tapetype(    int fd){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    return tape_info[fd].tapetype;}voidtapefd_setinfo_tapetype(    int fd,    char *v){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    tape_info[fd].tapetype = newstralloc(tape_info[fd].tapetype, v);}inttapefd_getinfo_fake_label(    int fd){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    return tape_info[fd].fake_label;}voidtapefd_setinfo_fake_label(    int fd,    int v){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    tape_info[fd].fake_label = v;}inttapefd_getinfo_ioctl_fork(    int fd){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    return tape_info[fd].ioctl_fork;}voidtapefd_setinfo_ioctl_fork(    int fd,    int v){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    tape_info[fd].ioctl_fork = v;}voidtapefd_set_master_fd(    int fd,    int master_fd){    amtable_alloc((void **)tape_info_p,		  &tape_info_count,		  SIZEOF(*tape_info),		  (size_t)fd + 1,		  10,		  tape_info_init);    tape_info[fd].master_fd = master_fd;}/* * The normal tape operation functions. */inttape_access(    char *filename,    int mode){    char *tname;    int vslot;

⌨️ 快捷键说明

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