📄 tapeio.c
字号:
/* * 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 + -