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

📄 output-rait.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* write the chunks in the main buffer */    for( i = 0; i < data_fds; i++ ) {	res = tapefd_write(pr->fds[i], buf + len*i , len);	rait_debug(stderr, _("rait_write: write(%d,%lx,%d) returns %d%s%s\n"),		        pr->fds[i],			(unsigned long)(buf + len*i),			len,			res,			(res < 0) ? ": " : "",			(res < 0) ? strerror(errno) : "");	if (res < 0) {	    total = res;	    break;	}	total += res;    }    if (total >= 0 && pr->nfds > 1) {        /* write the sum, don't include it in the total bytes written */	res = tapefd_write(pr->fds[i], pr->xorbuf, len);	rait_debug(stderr, _("rait_write: write(%d,%lx,%d) returns %d%s%s\n"),		    pr->fds[i],		    (unsigned long)pr->xorbuf,		    len,		    res,		    (res < 0) ? ": " : "",		    (res < 0) ? strerror(errno) : "");	if (res < 0) {	    total = res;	}    }    rait_debug(stderr, _("rait_write:returning %d%s%s\n"),			total,			(total < 0) ? ": " : "",			(total < 0) ? strerror(errno) : "");    return total;}/**//*** once again, if there is one data stream do a read, otherwise** do all n reads, and if any of the first n - 1 fail, compute** the missing block from the other three, then return the data.** there's some silliness here for reading tape with bigger buffers** than we wrote with, (thus the extra bcopys down below).  On disk if** you read with a bigger buffer size than you wrote with, you just** garble the data...*/ssize_trait_read(    int		fd,    void *	bufptr,    size_t	len){    char *buf = bufptr;    int nerrors, neofs, errorblock;    ssize_t    total;    int i;    size_t j;    RAIT *pr;    int data_fds;    int save_errno = errno;    ssize_t maxreadres = 0;    int sum_mismatch = 0;    rait_debug(stderr, _("rait_read(%d,%lx,%d)\n"),fd,(unsigned long)buf,len);    if ((fd < 0) || ((size_t)fd >= rait_table_count)) {	errno = EBADF;	rait_debug(stderr, _("rait_read:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    pr = &rait_table[fd];    if (0 == pr->nopen) {	errno = EBADF;	rait_debug(stderr, _("rait_read:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    nerrors = 0;    neofs = 0;    errorblock = -1;    /* once again , we slice it evenly... */    if (pr->nfds > 1) {	data_fds = pr->nfds - 1;	if (0 != len % data_fds) {	    errno = EDOM;	    rait_debug(stderr, _("rait_read:returning %d: %s\n"),			        -1,			        strerror(errno));	    return -1;	}	len = len / data_fds;    } else {	data_fds = 1;    }    /* try all the reads, save the result codes */    /* count the eof/errors */    for( i = 0; i < data_fds; i++ ) {	pr->readres[i] = tapefd_read(pr->fds[i], buf + len*i , len);	rait_debug(stderr, _("rait_read: read on fd %d returns %d%s%s\n"),		    pr->fds[i],		    pr->readres[i],		    (pr->readres[i] < 0) ? ": " : "",		    (pr->readres[i] < 0) ? strerror(errno) : "");	if ( pr->readres[i] <= 0 ) {	    if ( pr->readres[i] == 0 ) {		neofs++;	    } else {	        if (0 == nerrors) {		    save_errno = errno;	        }	        nerrors++;	    }	    errorblock = i;	} else if (pr->readres[i] > maxreadres) {	    maxreadres = pr->readres[i];	}    }    if (pr->nfds > 1) {	/* make sure we have enough buffer space */	if (len > (size_t)pr->xorbuflen) {	    if (0 != pr->xorbuf) {		amfree(pr->xorbuf);	    }	    pr->xorbuf = alloc(len);	    pr->xorbuflen = len;	}	pr->readres[i] = tapefd_read(pr->fds[i], pr->xorbuf , len);	rait_debug(stderr, _("rait_read: read on fd %d returns %d%s%s\n"),		    pr->fds[i],		    pr->readres[i],		    (pr->readres[i] < 0) ? ": " : "",		    (pr->readres[i] < 0) ? strerror(errno) : "");    }    /*     * Make sure all the reads were the same length     */    for (j = 0; j < (size_t)pr->nfds; j++) {	if (pr->readres[j] != maxreadres) {	    nerrors++;	    errorblock = (int)j;	}    }    /*     * If no errors, check that the xor sum matches     */    if ( nerrors == 0 && pr->nfds > 1  ) {       for(i = 0; i < (int)maxreadres; i++ ) {	   int sum = 0;	   for(j = 0; (j + 1) < (size_t)pr->nfds; j++) {	       sum ^= (buf + len * j)[i];           }	   if (sum != pr->xorbuf[i]) {	      sum_mismatch = 1;	   }       }    }    /*    ** now decide what "really" happened --    ** all n getting eof is a "real" eof    ** just one getting an error/eof is recoverable if we are doing RAIT    ** anything else fails    */    if (neofs == pr->nfds) {	rait_debug(stderr, _("rait_read:returning 0\n"));	return 0;    }    if (sum_mismatch) {	errno = EDOM;	rait_debug(stderr, _("rait_read:returning %d: %s\n"),			    -1,			    _("XOR block mismatch"));	return -1;    }    if (nerrors > 1 || (pr->nfds <= 1 && nerrors > 0)) {	errno = save_errno;	rait_debug(stderr, _("rait_read:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    /*    ** so now if we failed on a data block, we need to do a recovery    ** if we failed on the xor block -- who cares?    */    if (nerrors == 1 && pr->nfds > 1 && errorblock != pr->nfds-1) {	rait_debug(stderr, _("rait_read: fixing data from fd %d\n"),			    pr->fds[errorblock]);	/* the reads were all *supposed* to be the same size, so... */	pr->readres[errorblock] = maxreadres;	/* fill it in first with the xor sum */	memcpy(buf + len * errorblock, pr->xorbuf, len);	/* xor back out the other blocks */	for( i = 0; i < data_fds; i++ ) {	    if( i != errorblock ) {		for( j = 0; j < len ; j++ ) {		    buf[j + len * errorblock] ^= buf[j + len * i];		}	    }	}	/* there, now the block is back as if it never failed... */    }    /* pack together partial reads... */    total = pr->readres[0];    for( i = 1; i < data_fds; i++ ) {	if (total != (ssize_t)(len * i)) {	    memmove(buf + total, buf + len*i, (size_t)pr->readres[i]);        }	total += pr->readres[i];    }    rait_debug(stderr, _("rait_read:returning %d%s%s\n"),			total,			(total < 0) ? ": " : "",			(total < 0) ? strerror(errno) : "");    return total;}/**/intrait_ioctl(    int		fd,    int		op,    void *	p){    int i, res = 0;    RAIT *pr;    int errors = 0;    rait_debug(stderr, _("rait_ioctl(%d,%d)\n"),fd,op);    if ((fd < 0) || ((size_t)fd >= rait_table_count)) {	errno = EBADF;	rait_debug(stderr, _("rait_ioctl:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    pr = &rait_table[fd];    if (0 == pr->nopen) {	errno = EBADF;	rait_debug(stderr, _("rait_ioctl:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    for( i = 0; i < pr->nfds ; i++ ) {	/*@ignore@*/	res = ioctl(pr->fds[i], op, p);	/*@end@*/	if ( res != 0 ) {	    errors++;	    if (errors > 1) {		break;	    }	    res = 0;	}    }    rait_debug(stderr, _("rait_ioctl: returning %d%s%s\n"),			res,			(res < 0) ? ": " : "",			(res < 0) ? strerror(errno) : "");    return res;}/*** access() all the devices, returning if any fail*/intrait_access(    char *	devname,    int		flags){    int res = 0;    char *dev_left;		/* string before { */    char *dev_right;		/* string after } */    char *dev_next;		/* string inside {} */    char *dev_real;		/* parsed device name */    /* copy and parse the dev string so we can scribble on it */    devname = stralloc(devname);    if (0 == devname) {	rait_debug(stderr, _("rait_access:returning %d: %s\n"),			    -1,			    _("out of stralloc memory"));	return -1;    }    if ( 0 != tapeio_init_devname(devname, &dev_left, &dev_right, &dev_next)) {	rait_debug(stderr, _("rait_access:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    while( 0 != (dev_real = tapeio_next_devname(dev_left, dev_right, &dev_next))) {	res = tape_access(dev_real, flags);	rait_debug(stderr,_("rait_access:access( %s, %d ) yields %d\n"),		dev_real, flags, res );	amfree(dev_real);	if (res < 0) {	    break;        }    }    amfree(devname);    rait_debug(stderr, _("rait_access: returning %d%s%s\n"),			res,			(res < 0) ? ": " : "",			(res < 0) ? strerror(errno) : "");    return res;}/*** stat all the devices, returning the last one unless one fails*/intrait_stat(    char *	 devname,    struct stat *buf){    int res = 0;    char *dev_left;		/* string before { */    char *dev_right;		/* string after } */    char *dev_next;		/* string inside {} */    char *dev_real;		/* parsed device name */    /* copy and parse the dev string so we can scribble on it */    devname = stralloc(devname);    if (0 == devname) {	rait_debug(stderr, _("rait_access:returning %d: %s\n"),			    -1,			    _("out of stralloc memory"));	return -1;    }    if ( 0 != tapeio_init_devname(devname, &dev_left, &dev_right, &dev_next)) {	rait_debug(stderr, _("rait_access:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    while( 0 != (dev_real = tapeio_next_devname(dev_left, dev_right, &dev_next))) {	res = tape_stat(dev_real, buf);	rait_debug(stderr,_("rait_stat:stat( %s ) yields %d (%s)\n"),		dev_real, res, (res != 0) ? strerror(errno) : _("no error") );	amfree(dev_real);	if (res != 0) {	    break;        }    }    amfree(devname);    rait_debug(stderr, _("rait_access: returning %d%s%s\n"),			res,			(res < 0) ? ": " : "",			(res < 0) ? strerror(errno) : "");    return res;}/**/intrait_copy(    char *	f1,    char *	f2,    size_t	buflen){    int t1, t2;    ssize_t len;    ssize_t wres;    char *buf;    int save_errno;    t1 = rait_open(f1,O_RDONLY,0644);    if (t1 < 0) {	return t1;    }    t2 = rait_open(f2,O_CREAT|O_RDWR,0644);    if (t2 < 0) {	save_errno = errno;	(void)rait_close(t1);	errno = save_errno;	return -1;    }    buf = alloc(buflen);    do {	len = rait_read(t1,buf,buflen);	if (len > 0 ) {	    wres = rait_write(t2, buf, (size_t)len);	    if (wres < 0) {		len = -1;		break;	    }	}    } while( len > 0 );    save_errno = errno;    amfree(buf);    (void)rait_close(t1);    (void)rait_close(t2);    errno = save_errno;    return (len < 0) ? -1 : 0;}/**//*** Amanda Tape API routines:*/static intrait_tapefd_ioctl(    int		(*func0)(int),    int		(*func1)(int, off_t),    int		fd,    off_t	count){    int i, j, res = 0;    RAIT *pr;    int errors = 0;    pid_t kid;    int status = 0;    rait_debug(stderr, _("rait_tapefd_ioctl(%d,%d)\n"),fd,count);    if ((fd < 0) || ((size_t)fd >= rait_table_count)) {	errno = EBADF;	rait_debug(stderr, _("rait_tapefd_ioctl:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    pr = &rait_table[fd];    if (0 == pr->nopen) {	errno = EBADF;	rait_debug(stderr, _("rait_tapefd_ioctl:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    if (0 == pr->readres && 0 < pr->nfds) {	pr->readres = alloc(pr->nfds * SIZEOF(*pr->readres));	memset(pr->readres, 0, pr->nfds * SIZEOF(*pr->readres));    }    for( i = 0; i < pr->nfds ; i++ ) {	if(tapefd_can_fork(pr->fds[i])) {            if ((kid = fork()) < 1) {		rait_debug(stderr, _("in kid, fork returned %d\n"), kid);		/* if we are the kid, or fork failed do the action */		if (func0 != NULL) {		    res = (*func0)(pr->fds[i]);		} else {		    res = (*func1)(pr->fds[i], count);		}		rait_debug(stderr, _("in kid, func (%d) returned %d errno %s\n"),				pr->fds[i], res, strerror(errno));		if (kid == 0)		    exit(res);            } else {		rait_debug(stderr, _("in parent, fork returned %d\n"), kid);		pr->readres[i] = (ssize_t)kid;            }	}	else {	    if(func0 != NULL) {		j = (*func0)(pr->fds[i]);	    } else {		j = (*func1)(pr->fds[i], count);	    }	    if( j != 0) {		errors++;	    }	    pr->readres[i] = -1;	}    }    for( i = 0; i < pr->nfds ; i++ ) {	if(tapefd_can_fork(pr->fds[i])) {            rait_debug(stderr, _("in parent, waiting for %d\n"), pr->readres[i]);	    waitpid((pid_t)pr->readres[i], &status, 0);	    if( WEXITSTATUS(status) != 0 ) {		res = WEXITSTATUS(status);		if( res == 255 )		    res = -1;            }            rait_debug(stderr, _("in parent, return code was %d\n"), res);	    if ( res != 0 ) {		errors++;		res = 0;	    }	}    }    if (errors > 0) {	res = -1;    }    rait_debug(stderr, _("rait_tapefd_ioctl: returning %d%s%s\n"),			res,			(res < 0) ? ": " : "",			(res < 0) ? strerror(errno) : "");    return res;}intrait_tapefd_fsf(    int		fd,    off_t	count){    return rait_tapefd_ioctl(NULL, tapefd_fsf, fd, count);}intrait_tapefd_rewind(    int		fd){    return rait_tapefd_ioctl(tapefd_rewind, NULL, fd, (off_t)-1);}intrait_tapefd_unload(    int		fd){    return rait_tapefd_ioctl(tapefd_unload, NULL, fd, (off_t)-1);}intrait_tapefd_weof(    int		fd,    off_t	count){    return rait_tapefd_ioctl(NULL, tapefd_weof, fd, count);}intrait_tape_open(    char *	name,    int		flags,    mode_t	mask){    return rait_open(name, flags, mask);}intrait_tapefd_status(    int			 fd,    struct am_mt_status *stat){    int i;    RAIT *pr;    int res = 0;    int errors = 0;    rait_debug(stderr, _("rait_tapefd_status(%d)\n"),fd);    if ((fd < 0) || ((size_t)fd >= rait_table_count)) {	errno = EBADF;	rait_debug(stderr, _("rait_tapefd_status:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    pr = &rait_table[fd];    if (0 == pr->nopen) {	errno = EBADF;	rait_debug(stderr, _("rait_tapefd_status:returning %d: %s\n"),			    -1,			    strerror(errno));	return -1;    }    for( i = 0; i < pr->nfds ; i++ ) {	res = tapefd_status(pr->fds[i], stat);	if(res != 0) {	    errors++;	}    }    if (errors > 0) {	res = -1;    }    return res;}voidrait_tapefd_resetofs(    int		fd){    (void)rait_lseek(fd, (off_t)0, SEEK_SET);}intrait_tapefd_can_fork(    int		fd){    (void)fd;	/* Quiet unused parameter warning */    return 0;}

⌨️ 快捷键说明

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