1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate /* 31*7c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 32*7c478bd9Sstevel@tonic-gate * The Regents of the University of California 33*7c478bd9Sstevel@tonic-gate * All Rights Reserved 34*7c478bd9Sstevel@tonic-gate * 35*7c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 36*7c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 37*7c478bd9Sstevel@tonic-gate * contributors. 38*7c478bd9Sstevel@tonic-gate */ 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 43*7c478bd9Sstevel@tonic-gate #include <signal.h> 44*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 46*7c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 47*7c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_fsdir.h> 48*7c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_inode.h> 49*7c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_fs.h> 50*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 51*7c478bd9Sstevel@tonic-gate #include <sys/statvfs.h> 52*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 53*7c478bd9Sstevel@tonic-gate #include <stdio.h> 54*7c478bd9Sstevel@tonic-gate #include <unistd.h> 55*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 56*7c478bd9Sstevel@tonic-gate #include <errno.h> 57*7c478bd9Sstevel@tonic-gate #include <signal.h> 58*7c478bd9Sstevel@tonic-gate #include <stdarg.h> 59*7c478bd9Sstevel@tonic-gate #include <sys/errno.h> 60*7c478bd9Sstevel@tonic-gate #include <sys/utsname.h> 61*7c478bd9Sstevel@tonic-gate #include <sys/ipc.h> 62*7c478bd9Sstevel@tonic-gate #include <sys/sem.h> 63*7c478bd9Sstevel@tonic-gate #include <sys/shm.h> 64*7c478bd9Sstevel@tonic-gate #include <archives.h> 65*7c478bd9Sstevel@tonic-gate #include "volcopy.h" 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate #include <locale.h> 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate /* 70*7c478bd9Sstevel@tonic-gate * main I/O information structure, contains information for the 71*7c478bd9Sstevel@tonic-gate * source and destination files. 72*7c478bd9Sstevel@tonic-gate */ 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate struct file_info { 75*7c478bd9Sstevel@tonic-gate char *f_dev_p, /* name of device */ 76*7c478bd9Sstevel@tonic-gate *f_vol_p; /* volume name */ 77*7c478bd9Sstevel@tonic-gate int f_bsize, /* size to buffer I/O to */ 78*7c478bd9Sstevel@tonic-gate f_des, /* file descriptor */ 79*7c478bd9Sstevel@tonic-gate f_dev; /* device type (generic I/O library) */ 80*7c478bd9Sstevel@tonic-gate } In, Out; 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate int Sem_id[BUFCNT], /* semaphore ids for controlling shared memory */ 84*7c478bd9Sstevel@tonic-gate Shm_id[BUFCNT], /* shared memory identifier */ 85*7c478bd9Sstevel@tonic-gate *Cnts[BUFCNT]; /* an array of byte counts for shared memory */ 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate char Empty[BLKSIZ], /* empty memory used to clear sections of memory */ 88*7c478bd9Sstevel@tonic-gate *Buf[BUFCNT]; /* buffer pointers (possibly to shared memory) */ 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate struct sembuf Sem_buf, /* semaphore operation buffer */ 91*7c478bd9Sstevel@tonic-gate Rstsem_buf; /* semaphore reset operation buffer */ 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate typedef union { 94*7c478bd9Sstevel@tonic-gate char dummy[SBSIZE]; 95*7c478bd9Sstevel@tonic-gate struct fs sblk; 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate } sb_un; 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate sb_un isup, osup, tsup; 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate #define Isup isup.sblk 102*7c478bd9Sstevel@tonic-gate #define Osup osup.sblk 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate struct fs *Sptr = (struct fs *)&tsup.sblk; /* super-block pointer */ 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate char *Ifname, *Ifpack, *Ofname, *Ofpack; 107*7c478bd9Sstevel@tonic-gate struct volcopy_label V_labl; 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate char From_vol[VVOLLEN + 1], 110*7c478bd9Sstevel@tonic-gate To_vol[VVOLLEN + 1], 111*7c478bd9Sstevel@tonic-gate *Fsys_p; 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate static char *nolabel = ""; /* used when there is no room for label */ 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate int Blk_cnt = 1, /* Do I/O in (Blk_cnt * BLKSIZ) byte blocks */ 116*7c478bd9Sstevel@tonic-gate Blocks = 0, /* Number of blocks transferred */ 117*7c478bd9Sstevel@tonic-gate Bpi = 0, 118*7c478bd9Sstevel@tonic-gate Bufcnt, 119*7c478bd9Sstevel@tonic-gate Bufflg = 0, 120*7c478bd9Sstevel@tonic-gate Bufsz = BLKSIZ, 121*7c478bd9Sstevel@tonic-gate Disk_cnt = 1, /* Disk I/O (Disk_cnt * Blk_cnt * BLKSIZ) byte blocks */ 122*7c478bd9Sstevel@tonic-gate Drive_typ = 0, /* Flag for special tape drive types */ 123*7c478bd9Sstevel@tonic-gate Eomflg = 0, 124*7c478bd9Sstevel@tonic-gate Ipc = 0, 125*7c478bd9Sstevel@tonic-gate Itape, 126*7c478bd9Sstevel@tonic-gate M3b15 = 0, /* Machine types, set to 1 for the machine */ 127*7c478bd9Sstevel@tonic-gate M3b2 = 0, /* the command is executing on */ 128*7c478bd9Sstevel@tonic-gate Otape, 129*7c478bd9Sstevel@tonic-gate Pid = -1, 130*7c478bd9Sstevel@tonic-gate R_blks = 0, /* Number of blocks per tape reel */ 131*7c478bd9Sstevel@tonic-gate R_cur = 1, /* Current tape reel being processed */ 132*7c478bd9Sstevel@tonic-gate R_len = 0, /* Length in feet of tape reels */ 133*7c478bd9Sstevel@tonic-gate R_num = 0, /* Number of tape reels to be processed */ 134*7c478bd9Sstevel@tonic-gate Shell_esc = 1, /* Allow shell after delete -nosh (3b15) can disable */ 135*7c478bd9Sstevel@tonic-gate Yesflg = 0; 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate void (*singal())(); 138*7c478bd9Sstevel@tonic-gate long Fs, 139*7c478bd9Sstevel@tonic-gate Fstype; 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate time_t Tvec; 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate FILE *Devtty; 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate static void getinfs(), 146*7c478bd9Sstevel@tonic-gate getoutfs(); 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate static char *getfslabel(); 149*7c478bd9Sstevel@tonic-gate static char *getvolabel(); 150*7c478bd9Sstevel@tonic-gate static void prompt(int verify, const char *fmt, ...); 151*7c478bd9Sstevel@tonic-gate static void perr(int severity, const char *fmt, ...); 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate /* 154*7c478bd9Sstevel@tonic-gate * g_init(), g_read(), g_write() originally came from libgenIO, 155*7c478bd9Sstevel@tonic-gate * a totally obsolete device interface library, now deleted. 156*7c478bd9Sstevel@tonic-gate * volcopy should be deleted too, since it doesn't work. 157*7c478bd9Sstevel@tonic-gate */ 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate #define G_TM_TAPE 1 /* Tapemaster controller */ 160*7c478bd9Sstevel@tonic-gate #define G_XY_DISK 3 /* xy disks */ 161*7c478bd9Sstevel@tonic-gate #define G_SD_DISK 7 /* scsi sd disk */ 162*7c478bd9Sstevel@tonic-gate #define G_XT_TAPE 8 /* xt tapes */ 163*7c478bd9Sstevel@tonic-gate #define G_SF_FLOPPY 9 /* sf floppy */ 164*7c478bd9Sstevel@tonic-gate #define G_XD_DISK 10 /* xd disks */ 165*7c478bd9Sstevel@tonic-gate #define G_ST_TAPE 11 /* scsi tape */ 166*7c478bd9Sstevel@tonic-gate #define G_NS 12 /* noswap pseudo-dev */ 167*7c478bd9Sstevel@tonic-gate #define G_RAM 13 /* ram pseudo-dev */ 168*7c478bd9Sstevel@tonic-gate #define G_FT 14 /* tftp */ 169*7c478bd9Sstevel@tonic-gate #define G_HD 15 /* 386 network disk */ 170*7c478bd9Sstevel@tonic-gate #define G_FD 16 /* 386 AT disk */ 171*7c478bd9Sstevel@tonic-gate #define G_FILE 28 /* file, not a device */ 172*7c478bd9Sstevel@tonic-gate #define G_NO_DEV 29 /* device does not require special treatment */ 173*7c478bd9Sstevel@tonic-gate #define G_DEV_MAX 30 /* last valid device type */ 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate /* 176*7c478bd9Sstevel@tonic-gate * g_init: Determine the device being accessed, set the buffer size, 177*7c478bd9Sstevel@tonic-gate * and perform any device specific initialization. Since at this point 178*7c478bd9Sstevel@tonic-gate * Sun has no system call to read the configuration, the major numbers 179*7c478bd9Sstevel@tonic-gate * are assumed to be static and types are figured out as such. However, 180*7c478bd9Sstevel@tonic-gate * as a rough estimate, the buffer size for all types is set to 512 181*7c478bd9Sstevel@tonic-gate * as a default. 182*7c478bd9Sstevel@tonic-gate */ 183*7c478bd9Sstevel@tonic-gate static int 184*7c478bd9Sstevel@tonic-gate g_init(int *devtype, int *fdes) 185*7c478bd9Sstevel@tonic-gate { 186*7c478bd9Sstevel@tonic-gate major_t maj; 187*7c478bd9Sstevel@tonic-gate int bufsize; 188*7c478bd9Sstevel@tonic-gate struct stat64 st_buf; 189*7c478bd9Sstevel@tonic-gate struct statvfs64 stfs_buf; 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate *devtype = G_NO_DEV; 192*7c478bd9Sstevel@tonic-gate if (fstat64(*fdes, &st_buf) == -1) 193*7c478bd9Sstevel@tonic-gate return (-1); 194*7c478bd9Sstevel@tonic-gate if (!(st_buf.st_mode & S_IFCHR) && !(st_buf.st_mode & S_IFBLK)) { 195*7c478bd9Sstevel@tonic-gate if (st_buf.st_mode & S_IFIFO) 196*7c478bd9Sstevel@tonic-gate bufsize = 512; 197*7c478bd9Sstevel@tonic-gate else { 198*7c478bd9Sstevel@tonic-gate /* find block size for this file system */ 199*7c478bd9Sstevel@tonic-gate *devtype = G_FILE; 200*7c478bd9Sstevel@tonic-gate if (fstatvfs64(*fdes, &stfs_buf) < 0) { 201*7c478bd9Sstevel@tonic-gate bufsize = -1; 202*7c478bd9Sstevel@tonic-gate errno = ENODEV; 203*7c478bd9Sstevel@tonic-gate } else { 204*7c478bd9Sstevel@tonic-gate bufsize = stfs_buf.f_bsize; 205*7c478bd9Sstevel@tonic-gate } 206*7c478bd9Sstevel@tonic-gate } 207*7c478bd9Sstevel@tonic-gate return (bufsize); 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate return (512); 211*7c478bd9Sstevel@tonic-gate } 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate /* 214*7c478bd9Sstevel@tonic-gate * g_read: Read nbytes of data from fdes (of type devtype) and place 215*7c478bd9Sstevel@tonic-gate * data in location pointed to by buf. In case of end of medium, 216*7c478bd9Sstevel@tonic-gate * translate (where necessary) device specific EOM indications into 217*7c478bd9Sstevel@tonic-gate * the generic EOM indication of rv = -1, errno = ENOSPC. 218*7c478bd9Sstevel@tonic-gate */ 219*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 220*7c478bd9Sstevel@tonic-gate static ssize_t 221*7c478bd9Sstevel@tonic-gate g_read(int devtype, int fdes, void *buf, size_t nbytes) 222*7c478bd9Sstevel@tonic-gate { 223*7c478bd9Sstevel@tonic-gate ssize_t rv; 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate rv = read(fdes, buf, nbytes); 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate /* st devices return 0 when no space left */ 228*7c478bd9Sstevel@tonic-gate if ((rv == 0 && errno == 0) || (rv == -1 && errno == EIO)) { 229*7c478bd9Sstevel@tonic-gate errno = ENOSPC; 230*7c478bd9Sstevel@tonic-gate rv = -1; 231*7c478bd9Sstevel@tonic-gate } 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate return (rv); 234*7c478bd9Sstevel@tonic-gate } 235*7c478bd9Sstevel@tonic-gate 236*7c478bd9Sstevel@tonic-gate /* 237*7c478bd9Sstevel@tonic-gate * g_write: Write nbytes of data to fdes (of type devtype) from 238*7c478bd9Sstevel@tonic-gate * the location pointed to by buf. In case of end of medium, 239*7c478bd9Sstevel@tonic-gate * translate (where necessary) device specific EOM indications into 240*7c478bd9Sstevel@tonic-gate * the generic EOM indication of rv = -1, errno = ENOSPC. 241*7c478bd9Sstevel@tonic-gate */ 242*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 243*7c478bd9Sstevel@tonic-gate static ssize_t 244*7c478bd9Sstevel@tonic-gate g_write(int devtype, int fdes, void *buf, size_t nbytes) 245*7c478bd9Sstevel@tonic-gate { 246*7c478bd9Sstevel@tonic-gate ssize_t rv; 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate rv = write(fdes, buf, nbytes); 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate /* st devices return 0 when no more space left */ 251*7c478bd9Sstevel@tonic-gate if ((rv == 0 && errno == 0) || (rv == -1 && errno == EIO)) { 252*7c478bd9Sstevel@tonic-gate errno = ENOSPC; 253*7c478bd9Sstevel@tonic-gate rv = -1; 254*7c478bd9Sstevel@tonic-gate } 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate return (rv); 257*7c478bd9Sstevel@tonic-gate } 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate /* 260*7c478bd9Sstevel@tonic-gate * filesystem copy with propagation of volume ID and filesystem name: 261*7c478bd9Sstevel@tonic-gate * 262*7c478bd9Sstevel@tonic-gate * volcopy [-options] filesystem /dev/from From_vol /dev/to To_vol 263*7c478bd9Sstevel@tonic-gate * 264*7c478bd9Sstevel@tonic-gate * options are: 265*7c478bd9Sstevel@tonic-gate * -feet - length of tape 266*7c478bd9Sstevel@tonic-gate * -bpi - recording density 267*7c478bd9Sstevel@tonic-gate * -reel - reel number (if not starting from beginning) 268*7c478bd9Sstevel@tonic-gate * -buf - use double buffered i/o (if dens >= 1600 bpi) 269*7c478bd9Sstevel@tonic-gate * -block - Set the transfer block size to NUM physical blocks (512 270*7c478bd9Sstevel@tonic-gate * bytes on 3B2 and 3B15). Note that an arbitrary block size might 271*7c478bd9Sstevel@tonic-gate * or might not work on a given system. Also, the block size 272*7c478bd9Sstevel@tonic-gate * read from the header of an input tape silently overrides this. 273*7c478bd9Sstevel@tonic-gate * -nosh - Don't offer the user a shell after hitting break or delete. 274*7c478bd9Sstevel@tonic-gate * -r - Read NUM transfer blocks from the disk at once and write it 275*7c478bd9Sstevel@tonic-gate * to the output device one block at a time. Intended only to 276*7c478bd9Sstevel@tonic-gate * boost the 3B15 EDFC disk to tape performance. Disabled on 3B2. 277*7c478bd9Sstevel@tonic-gate * -a - ask "y or n" instead of "DEL if wrong" 278*7c478bd9Sstevel@tonic-gate * -s - inverse of -a, from/to devices are printed followed by `?'. 279*7c478bd9Sstevel@tonic-gate * User has 10 seconds to DEL if mistaken! 280*7c478bd9Sstevel@tonic-gate * -y - assume "yes" response to all questions 281*7c478bd9Sstevel@tonic-gate * 282*7c478bd9Sstevel@tonic-gate * Examples: 283*7c478bd9Sstevel@tonic-gate * 284*7c478bd9Sstevel@tonic-gate * volcopy root /dev/rdsk/0s2 pk5 /dev/rdsk/1s2 pk12 285*7c478bd9Sstevel@tonic-gate * 286*7c478bd9Sstevel@tonic-gate * volcopy u3 /dev/rdsk/1s5 pk1 /dev/rmt/0m tp123 287*7c478bd9Sstevel@tonic-gate * 288*7c478bd9Sstevel@tonic-gate * volcopy u5 /dev/rmt/0m - /dev/rdsk/1s5 - 289*7c478bd9Sstevel@tonic-gate */ 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate main(argc, argv) 292*7c478bd9Sstevel@tonic-gate int argc; 293*7c478bd9Sstevel@tonic-gate char **argv; 294*7c478bd9Sstevel@tonic-gate { 295*7c478bd9Sstevel@tonic-gate register char c; 296*7c478bd9Sstevel@tonic-gate register int lfdes, altflg = 0, result, verify; 297*7c478bd9Sstevel@tonic-gate register long dist; 298*7c478bd9Sstevel@tonic-gate char *align(); 299*7c478bd9Sstevel@tonic-gate void sigalrm(), sigint(); 300*7c478bd9Sstevel@tonic-gate struct stat stbuf; 301*7c478bd9Sstevel@tonic-gate int cnt; 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 304*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 305*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 306*7c478bd9Sstevel@tonic-gate #endif 307*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate (void) get_mach_type(); 310*7c478bd9Sstevel@tonic-gate (void) signal(SIGINT, sigint); 311*7c478bd9Sstevel@tonic-gate (void) signal(SIGALRM, sigalrm); 312*7c478bd9Sstevel@tonic-gate In.f_bsize = Out.f_bsize = BLKSIZ; 313*7c478bd9Sstevel@tonic-gate while (argc > 1 && argv[1][0] == '-') { 314*7c478bd9Sstevel@tonic-gate if (EQ(argv[1], "-a", 2)) { 315*7c478bd9Sstevel@tonic-gate altflg |= MINUSA; 316*7c478bd9Sstevel@tonic-gate } else if (EQ(argv[1], "-e", 2)) { 317*7c478bd9Sstevel@tonic-gate Eomflg = 1; 318*7c478bd9Sstevel@tonic-gate } else if (EQ(argv[1], "-s", 2)) { 319*7c478bd9Sstevel@tonic-gate altflg |= MINUSS; 320*7c478bd9Sstevel@tonic-gate } else if (EQ(argv[1], "-y", 2)) { 321*7c478bd9Sstevel@tonic-gate Yesflg++; 322*7c478bd9Sstevel@tonic-gate } else if (EQ(argv[1], "-buf", 4)) { 323*7c478bd9Sstevel@tonic-gate Bufflg++; 324*7c478bd9Sstevel@tonic-gate } else if (EQ(argv[1], "-bpi", 4)) { 325*7c478bd9Sstevel@tonic-gate if ((c = argv[1][4]) >= '0' && c <= '9') 326*7c478bd9Sstevel@tonic-gate Bpi = getbpi(&argv[1][4]); 327*7c478bd9Sstevel@tonic-gate else { 328*7c478bd9Sstevel@tonic-gate ++argv; 329*7c478bd9Sstevel@tonic-gate --argc; 330*7c478bd9Sstevel@tonic-gate Bpi = getbpi(&argv[1][0]); 331*7c478bd9Sstevel@tonic-gate } 332*7c478bd9Sstevel@tonic-gate } else if (EQ(argv[1], "-feet", 5)) { 333*7c478bd9Sstevel@tonic-gate if ((c = argv[1][5]) >= '0' && c <= '9') 334*7c478bd9Sstevel@tonic-gate R_len = atoi(&argv[1][5]); 335*7c478bd9Sstevel@tonic-gate else { 336*7c478bd9Sstevel@tonic-gate ++argv; 337*7c478bd9Sstevel@tonic-gate --argc; 338*7c478bd9Sstevel@tonic-gate R_len = atoi(&argv[1][0]); 339*7c478bd9Sstevel@tonic-gate } 340*7c478bd9Sstevel@tonic-gate } else if (EQ(argv[1], "-reel", 5)) { 341*7c478bd9Sstevel@tonic-gate if ((c = argv[1][5]) >= '0' && c <= '9') 342*7c478bd9Sstevel@tonic-gate R_cur = atoi(&argv[1][5]); 343*7c478bd9Sstevel@tonic-gate else { 344*7c478bd9Sstevel@tonic-gate ++argv; 345*7c478bd9Sstevel@tonic-gate --argc; 346*7c478bd9Sstevel@tonic-gate R_cur = atoi(&argv[1][0]); 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate } else if (EQ(argv[1], "-r", 2)) { /* 3b15 only */ 349*7c478bd9Sstevel@tonic-gate if ((c = argv[1][2]) >= '0' && c <= '9') 350*7c478bd9Sstevel@tonic-gate Disk_cnt = atoi(&argv[1][2]); 351*7c478bd9Sstevel@tonic-gate else { 352*7c478bd9Sstevel@tonic-gate ++argv; 353*7c478bd9Sstevel@tonic-gate --argc; 354*7c478bd9Sstevel@tonic-gate Disk_cnt = atoi(&argv[1][0]); 355*7c478bd9Sstevel@tonic-gate } 356*7c478bd9Sstevel@tonic-gate if (Disk_cnt == 0) 357*7c478bd9Sstevel@tonic-gate perr(1, "volcopy: Need a non-zero value for the -r option\n"); 358*7c478bd9Sstevel@tonic-gate } else if (EQ(argv[1], "-block", 6)) { /* 3b15 only */ 359*7c478bd9Sstevel@tonic-gate if ((c = argv[1][6]) >= '0' && c <= '9') 360*7c478bd9Sstevel@tonic-gate Blk_cnt = atoi(&argv[1][6]); 361*7c478bd9Sstevel@tonic-gate else { 362*7c478bd9Sstevel@tonic-gate ++argv; 363*7c478bd9Sstevel@tonic-gate --argc; 364*7c478bd9Sstevel@tonic-gate Blk_cnt = atoi(&argv[1][0]); 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate if (Blk_cnt == 0) 367*7c478bd9Sstevel@tonic-gate perr(1, "volcopy: Need a non-zero value for the -block option\n"); 368*7c478bd9Sstevel@tonic-gate } else if (EQ(argv[1], "-nosh", 5)) { /* 3b15 only */ 369*7c478bd9Sstevel@tonic-gate Shell_esc = 0; 370*7c478bd9Sstevel@tonic-gate } else 371*7c478bd9Sstevel@tonic-gate perr(1, "<%s> invalid option\n", argv[1]); 372*7c478bd9Sstevel@tonic-gate ++argv; 373*7c478bd9Sstevel@tonic-gate --argc; 374*7c478bd9Sstevel@tonic-gate } /* argv[1][0] == '-' */ 375*7c478bd9Sstevel@tonic-gate 376*7c478bd9Sstevel@tonic-gate Devtty = fopen("/dev/tty", "r"); 377*7c478bd9Sstevel@tonic-gate if ((Devtty == NULL) && !isatty(0)) 378*7c478bd9Sstevel@tonic-gate Devtty = stdin; 379*7c478bd9Sstevel@tonic-gate time(&Tvec); 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate if (Eomflg && R_len) 382*7c478bd9Sstevel@tonic-gate perr(9, "volcopy: -e and -feet are mutually exclusive\n"); 383*7c478bd9Sstevel@tonic-gate if ((altflg & MINUSA) && (altflg & MINUSS)) 384*7c478bd9Sstevel@tonic-gate perr(9, "volcopy: -a and -s are mutually exclusive\n"); 385*7c478bd9Sstevel@tonic-gate if (argc != 6) /* if mandatory fields not present */ 386*7c478bd9Sstevel@tonic-gate perr(9, "ufs usage: volcopy [-F ufs] [generic options] \ 387*7c478bd9Sstevel@tonic-gate fsname /devfrom volfrom /devto volto\n"); 388*7c478bd9Sstevel@tonic-gate if (!(altflg & MINUSA)) /* -a was not specified, use default (-s) */ 389*7c478bd9Sstevel@tonic-gate altflg |= MINUSS; 390*7c478bd9Sstevel@tonic-gate 391*7c478bd9Sstevel@tonic-gate In.f_dev_p = argv[DEV_IN]; 392*7c478bd9Sstevel@tonic-gate Out.f_dev_p = argv[DEV_OUT]; 393*7c478bd9Sstevel@tonic-gate strncpy(To_vol, argv[VOL_OUT], VVOLLEN); 394*7c478bd9Sstevel@tonic-gate To_vol[VVOLLEN] = '\0'; 395*7c478bd9Sstevel@tonic-gate Out.f_vol_p = &To_vol[0]; 396*7c478bd9Sstevel@tonic-gate strncpy(From_vol, argv[VOL_IN], VVOLLEN); 397*7c478bd9Sstevel@tonic-gate From_vol[VVOLLEN] = '\0'; 398*7c478bd9Sstevel@tonic-gate In.f_vol_p = &From_vol[0]; 399*7c478bd9Sstevel@tonic-gate Fsys_p = argv[FIL_SYS]; 400*7c478bd9Sstevel@tonic-gate 401*7c478bd9Sstevel@tonic-gate if ((In.f_des = open(In.f_dev_p, O_RDONLY)) < 1) 402*7c478bd9Sstevel@tonic-gate perr(10, "%s: cannot open\n", In.f_dev_p); 403*7c478bd9Sstevel@tonic-gate if ((Out.f_des = open(Out.f_dev_p, O_RDONLY)) < 1) 404*7c478bd9Sstevel@tonic-gate perr(10, "%s: cannot open\n", Out.f_dev_p); 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate if (fstat(In.f_des, &stbuf) < 0 || (stbuf.st_mode & S_IFMT) != S_IFCHR) 407*7c478bd9Sstevel@tonic-gate perr(10, "From device not character-special\n"); 408*7c478bd9Sstevel@tonic-gate if (fstat(Out.f_des, &stbuf) < 0 || (stbuf.st_mode & S_IFMT) != S_IFCHR) 409*7c478bd9Sstevel@tonic-gate perr(10, "To device not character-special\n"); 410*7c478bd9Sstevel@tonic-gate 411*7c478bd9Sstevel@tonic-gate if ((Itape = tapeck(&In, INPUT)) == 1) 412*7c478bd9Sstevel@tonic-gate R_blks = V_labl.v_reelblks; 413*7c478bd9Sstevel@tonic-gate Otape = tapeck(&Out, OUTPUT); 414*7c478bd9Sstevel@tonic-gate if (Otape && Itape) 415*7c478bd9Sstevel@tonic-gate perr(10, "Use dd(1) command to copy tapes\n"); 416*7c478bd9Sstevel@tonic-gate (void) mem_setup(); 417*7c478bd9Sstevel@tonic-gate if (Bufflg && !Ipc) 418*7c478bd9Sstevel@tonic-gate perr(1, "The -buf option requires ipc\n"); 419*7c478bd9Sstevel@tonic-gate if (!Itape && !Otape) 420*7c478bd9Sstevel@tonic-gate R_cur = 1; 421*7c478bd9Sstevel@tonic-gate if (R_cur == 1 || !Itape) { 422*7c478bd9Sstevel@tonic-gate /* read in superblock */ 423*7c478bd9Sstevel@tonic-gate verify = 0; 424*7c478bd9Sstevel@tonic-gate (void) getinfs(In.f_dev, In.f_des, Sptr); 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate if ((Sptr->fs_magic != FS_MAGIC) && 427*7c478bd9Sstevel@tonic-gate (Sptr->fs_magic != MTB_UFS_MAGIC)) 428*7c478bd9Sstevel@tonic-gate perr(10, "File System type unknown--get help\n"); 429*7c478bd9Sstevel@tonic-gate 430*7c478bd9Sstevel@tonic-gate if (Sptr->fs_magic == MTB_UFS_MAGIC && 431*7c478bd9Sstevel@tonic-gate (Sptr->fs_version > MTB_UFS_VERSION_1 || 432*7c478bd9Sstevel@tonic-gate Sptr->fs_version < MTB_UFS_VERSION_MIN)) 433*7c478bd9Sstevel@tonic-gate perr(10, "Unrecognized version of UFS--get help\n"); 434*7c478bd9Sstevel@tonic-gate 435*7c478bd9Sstevel@tonic-gate (void) memcpy(&Isup, Sptr, Sptr->fs_sbsize); 436*7c478bd9Sstevel@tonic-gate Ifname = getfslabel(&Isup); 437*7c478bd9Sstevel@tonic-gate Ifpack = getvolabel(&Isup); 438*7c478bd9Sstevel@tonic-gate Fs = Sptr->fs_size * Sptr->fs_nspf; 439*7c478bd9Sstevel@tonic-gate } /* R_cur == 1 || !Itape */ 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate /* read in superblock */ 442*7c478bd9Sstevel@tonic-gate verify = !Otape || (altflg & MINUSS); 443*7c478bd9Sstevel@tonic-gate (void) getoutfs(Out.f_dev, Out.f_des, Sptr, verify); 444*7c478bd9Sstevel@tonic-gate 445*7c478bd9Sstevel@tonic-gate if ((Sptr->fs_magic == FS_MAGIC) || (Sptr->fs_magic == MTB_UFS_MAGIC)) { 446*7c478bd9Sstevel@tonic-gate (void) memcpy(&Osup, Sptr, Sptr->fs_sbsize); 447*7c478bd9Sstevel@tonic-gate Ofname = getfslabel(&Osup); 448*7c478bd9Sstevel@tonic-gate Ofpack = getvolabel(&Osup); 449*7c478bd9Sstevel@tonic-gate } else { 450*7c478bd9Sstevel@tonic-gate int i; 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate /* out vol does not contain a ufs file system */ 453*7c478bd9Sstevel@tonic-gate /* stuff let over from Isup */ 454*7c478bd9Sstevel@tonic-gate (void) memcpy(&Osup, &Isup, Isup.fs_sbsize); 455*7c478bd9Sstevel@tonic-gate Ofname = getfslabel(&Osup); 456*7c478bd9Sstevel@tonic-gate Ofpack = getvolabel(&Osup); 457*7c478bd9Sstevel@tonic-gate /* wipe out the fs name and pack name for warning purposes */ 458*7c478bd9Sstevel@tonic-gate for (i = 0; i < 6; i++) Ofname[i] = ' '; 459*7c478bd9Sstevel@tonic-gate for (i = 0; i < 6; i++) Ofpack[i] = ' '; 460*7c478bd9Sstevel@tonic-gate } 461*7c478bd9Sstevel@tonic-gate 462*7c478bd9Sstevel@tonic-gate if (Itape) { 463*7c478bd9Sstevel@tonic-gate if (R_cur != 1) { 464*7c478bd9Sstevel@tonic-gate (void) printf(gettext( 465*7c478bd9Sstevel@tonic-gate "\nvolcopy: IF REEL 1 HAS NOT BEEN RESTORED,")); 466*7c478bd9Sstevel@tonic-gate (void) printf(gettext( 467*7c478bd9Sstevel@tonic-gate " STOP NOW AND START OVER ***\07\n")); 468*7c478bd9Sstevel@tonic-gate if (!ask(" Continue? ")) { 469*7c478bd9Sstevel@tonic-gate cleanup(); 470*7c478bd9Sstevel@tonic-gate exit(31+9); 471*7c478bd9Sstevel@tonic-gate } 472*7c478bd9Sstevel@tonic-gate strncpy(Ifname, Fsys_p, 6); 473*7c478bd9Sstevel@tonic-gate strncpy(Ifpack, In.f_vol_p, 6); 474*7c478bd9Sstevel@tonic-gate } 475*7c478bd9Sstevel@tonic-gate if (V_labl.v_reel != R_cur || V_labl.v_reels != R_num) 476*7c478bd9Sstevel@tonic-gate prompt(1, "Tape disagrees: Reel %d of %d : looking for %d of %d\n", 477*7c478bd9Sstevel@tonic-gate V_labl.v_reel, V_labl.v_reels, R_cur, R_num); 478*7c478bd9Sstevel@tonic-gate } else if (Otape) { 479*7c478bd9Sstevel@tonic-gate strncpy(V_labl.v_volume, Out.f_vol_p, 6); 480*7c478bd9Sstevel@tonic-gate strncpy(Ofpack, Out.f_vol_p, 6); 481*7c478bd9Sstevel@tonic-gate strncpy(Ofname, Fsys_p, 6); 482*7c478bd9Sstevel@tonic-gate if (!Eomflg) { 483*7c478bd9Sstevel@tonic-gate R_num = Fs / R_blks + ((Fs % R_blks) ? 1 : 0); 484*7c478bd9Sstevel@tonic-gate (void) printf(gettext( 485*7c478bd9Sstevel@tonic-gate "You will need %d reels.\n"), R_num); 486*7c478bd9Sstevel@tonic-gate (void) printf(gettext( 487*7c478bd9Sstevel@tonic-gate "(\tThe same size and density is expected for all reels)\n")); 488*7c478bd9Sstevel@tonic-gate } 489*7c478bd9Sstevel@tonic-gate } 490*7c478bd9Sstevel@tonic-gate if (NOT_EQ(Fsys_p, Ifname, 6)) { 491*7c478bd9Sstevel@tonic-gate verify = !Otape || (altflg & MINUSS); 492*7c478bd9Sstevel@tonic-gate prompt(verify, 493*7c478bd9Sstevel@tonic-gate "arg. (%.6s) doesn't agree with from fs. (%.6s)\n", 494*7c478bd9Sstevel@tonic-gate Fsys_p, Ifname); 495*7c478bd9Sstevel@tonic-gate } 496*7c478bd9Sstevel@tonic-gate if (NOT_EQ(In.f_vol_p, "-", 6) && NOT_EQ(In.f_vol_p, Ifpack, 6)) { 497*7c478bd9Sstevel@tonic-gate verify = !Otape || (altflg & MINUSS); 498*7c478bd9Sstevel@tonic-gate prompt(verify, "arg. (%.6s) doesn't agree with from vol.(%.6s)\n", 499*7c478bd9Sstevel@tonic-gate In.f_vol_p, Ifpack); 500*7c478bd9Sstevel@tonic-gate } 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate if (*In.f_vol_p == '-') 503*7c478bd9Sstevel@tonic-gate In.f_vol_p = Ifpack; 504*7c478bd9Sstevel@tonic-gate if (*Out.f_vol_p == '-') 505*7c478bd9Sstevel@tonic-gate Out.f_vol_p = Ofpack; 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate if (R_cur == 1 && (Osup.fs_time + _2_DAYS) > Isup.fs_time) { 508*7c478bd9Sstevel@tonic-gate time_t t; 509*7c478bd9Sstevel@tonic-gate 510*7c478bd9Sstevel@tonic-gate verify = altflg & MINUSS; 511*7c478bd9Sstevel@tonic-gate t = (time_t)Osup.fs_time; 512*7c478bd9Sstevel@tonic-gate prompt(verify, "%s less than 48 hours older than %s\n" 513*7c478bd9Sstevel@tonic-gate "To filesystem dated: %s", 514*7c478bd9Sstevel@tonic-gate Out.f_dev_p, In.f_dev_p, ctime(&t)); 515*7c478bd9Sstevel@tonic-gate } 516*7c478bd9Sstevel@tonic-gate if (NOT_EQ(Out.f_vol_p, Ofpack, 6)) { 517*7c478bd9Sstevel@tonic-gate prompt(1, "arg.(%.6s) doesn't agree with to vol.(%.6s)\n", 518*7c478bd9Sstevel@tonic-gate Out.f_vol_p, Ofpack); 519*7c478bd9Sstevel@tonic-gate strncpy(Ofpack, Out.f_vol_p, 6); 520*7c478bd9Sstevel@tonic-gate } 521*7c478bd9Sstevel@tonic-gate if (Isup.fs_size > Osup.fs_size && !Otape) 522*7c478bd9Sstevel@tonic-gate prompt(1, "from fs larger than to fs\n"); 523*7c478bd9Sstevel@tonic-gate if (!Otape && NOT_EQ(Ifname, Ofname, 6)) { 524*7c478bd9Sstevel@tonic-gate verify = altflg & MINUSS; 525*7c478bd9Sstevel@tonic-gate prompt(verify, "warning! from fs(%.6s) differs from to fs(%.6s)\n", 526*7c478bd9Sstevel@tonic-gate Ifname, Ofname); 527*7c478bd9Sstevel@tonic-gate } 528*7c478bd9Sstevel@tonic-gate 529*7c478bd9Sstevel@tonic-gate (void) printf(gettext("From: %s, to: %s? "), In.f_dev_p, Out.f_dev_p); 530*7c478bd9Sstevel@tonic-gate if (!(altflg & MINUSA)) { 531*7c478bd9Sstevel@tonic-gate (void) printf(gettext("(DEL if wrong)\n")); 532*7c478bd9Sstevel@tonic-gate sleep(10); 533*7c478bd9Sstevel@tonic-gate } else if (!ask("(y or n) ")) 534*7c478bd9Sstevel@tonic-gate perr(10, "\nvolcopy: STOP\n"); 535*7c478bd9Sstevel@tonic-gate close(In.f_des); 536*7c478bd9Sstevel@tonic-gate close(Out.f_des); 537*7c478bd9Sstevel@tonic-gate sync(); 538*7c478bd9Sstevel@tonic-gate In.f_des = open(In.f_dev_p, O_RDONLY); 539*7c478bd9Sstevel@tonic-gate Out.f_des = open(Out.f_dev_p, O_WRONLY); 540*7c478bd9Sstevel@tonic-gate errno = 0; 541*7c478bd9Sstevel@tonic-gate if (g_init(&In.f_dev, &In.f_des) < 0 || 542*7c478bd9Sstevel@tonic-gate g_init(&Out.f_dev, &Out.f_des) < 0) 543*7c478bd9Sstevel@tonic-gate perr(1, "volcopy: Error %d during initialization\n", errno); 544*7c478bd9Sstevel@tonic-gate if (Itape) { 545*7c478bd9Sstevel@tonic-gate errno = 0; 546*7c478bd9Sstevel@tonic-gate if (g_read(In.f_dev, In.f_des, &V_labl, sizeof (V_labl)) < 547*7c478bd9Sstevel@tonic-gate sizeof (V_labl)) 548*7c478bd9Sstevel@tonic-gate perr(10, "Error while reading label\n"); 549*7c478bd9Sstevel@tonic-gate } else if (Otape) { 550*7c478bd9Sstevel@tonic-gate V_labl.v_reels = R_num; 551*7c478bd9Sstevel@tonic-gate V_labl.v_reel = R_cur; 552*7c478bd9Sstevel@tonic-gate V_labl.v_time = Tvec; 553*7c478bd9Sstevel@tonic-gate V_labl.v_reelblks = R_blks; 554*7c478bd9Sstevel@tonic-gate V_labl.v_blksize = BLKSIZ * Blk_cnt; 555*7c478bd9Sstevel@tonic-gate V_labl.v_nblocks = Blk_cnt; 556*7c478bd9Sstevel@tonic-gate V_labl.v_offset = 0L; 557*7c478bd9Sstevel@tonic-gate V_labl.v_type = T_TYPE; 558*7c478bd9Sstevel@tonic-gate errno = 0; 559*7c478bd9Sstevel@tonic-gate if (g_write(Out.f_dev, Out.f_des, &V_labl, sizeof (V_labl)) < 560*7c478bd9Sstevel@tonic-gate sizeof (V_labl)) 561*7c478bd9Sstevel@tonic-gate perr(10, "Error while writing label\n"); 562*7c478bd9Sstevel@tonic-gate } 563*7c478bd9Sstevel@tonic-gate if (R_cur > 1) { 564*7c478bd9Sstevel@tonic-gate if (!Eomflg) { 565*7c478bd9Sstevel@tonic-gate Fs = (R_cur - 1) * actual_blocks(); 566*7c478bd9Sstevel@tonic-gate lfdes = Otape ? In.f_des : Out.f_des; 567*7c478bd9Sstevel@tonic-gate dist = (long)(Fs * BLKSIZ); 568*7c478bd9Sstevel@tonic-gate } else { /* Eomflg */ 569*7c478bd9Sstevel@tonic-gate if (Otape) 570*7c478bd9Sstevel@tonic-gate perr(1, "Cannot use -reel with -e when copying to tape\n"); 571*7c478bd9Sstevel@tonic-gate lfdes = Out.f_des; 572*7c478bd9Sstevel@tonic-gate dist = (long)(V_labl.v_offset * BLKSIZ); 573*7c478bd9Sstevel@tonic-gate Fs = V_labl.v_offset; 574*7c478bd9Sstevel@tonic-gate } 575*7c478bd9Sstevel@tonic-gate if (lseek(lfdes, dist, 0) < 0) 576*7c478bd9Sstevel@tonic-gate perr(1, "Cannot lseek()\n"); 577*7c478bd9Sstevel@tonic-gate Sptr = Otape ? &Isup : &Osup; 578*7c478bd9Sstevel@tonic-gate if ((Sptr -> fs_magic != FS_MAGIC) && 579*7c478bd9Sstevel@tonic-gate (Sptr -> fs_magic != MTB_UFS_MAGIC)) 580*7c478bd9Sstevel@tonic-gate perr(10, "File System type unknown--get help!\n"); 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate if (Sptr->fs_magic == MTB_UFS_MAGIC && 583*7c478bd9Sstevel@tonic-gate (Sptr->fs_version > MTB_UFS_VERSION_1 || 584*7c478bd9Sstevel@tonic-gate Sptr->fs_version < MTB_UFS_VERSION_MIN)) 585*7c478bd9Sstevel@tonic-gate perr(10, "Unrecognized version of UFS--get help\n"); 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate Fs = (Sptr->fs_size * Sptr->fs_nspf) - Fs; 588*7c478bd9Sstevel@tonic-gate } 589*7c478bd9Sstevel@tonic-gate if (Itape || Otape) 590*7c478bd9Sstevel@tonic-gate rprt(); 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate if (Ipc) { 593*7c478bd9Sstevel@tonic-gate parent_copy(); 594*7c478bd9Sstevel@tonic-gate (void) cleanup(); 595*7c478bd9Sstevel@tonic-gate } else 596*7c478bd9Sstevel@tonic-gate copy(); 597*7c478bd9Sstevel@tonic-gate (void) printf(gettext(" END: %ld blocks.\n"), Blocks); 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate #ifdef LOG 600*7c478bd9Sstevel@tonic-gate fslog(); 601*7c478bd9Sstevel@tonic-gate #endif 602*7c478bd9Sstevel@tonic-gate if (Blocks) 603*7c478bd9Sstevel@tonic-gate exit(0); 604*7c478bd9Sstevel@tonic-gate exit(31+1); /* failed.. 0 blocks */ 605*7c478bd9Sstevel@tonic-gate } 606*7c478bd9Sstevel@tonic-gate 607*7c478bd9Sstevel@tonic-gate /* 608*7c478bd9Sstevel@tonic-gate * sigalrm: catch alarm signals. 609*7c478bd9Sstevel@tonic-gate */ 610*7c478bd9Sstevel@tonic-gate 611*7c478bd9Sstevel@tonic-gate void 612*7c478bd9Sstevel@tonic-gate sigalrm() 613*7c478bd9Sstevel@tonic-gate { 614*7c478bd9Sstevel@tonic-gate void (*signal())(); 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate (void) signal(SIGALRM, sigalrm); 617*7c478bd9Sstevel@tonic-gate } 618*7c478bd9Sstevel@tonic-gate 619*7c478bd9Sstevel@tonic-gate /* 620*7c478bd9Sstevel@tonic-gate * sigsys: catch illegal system calls to determine if IPC is available. 621*7c478bd9Sstevel@tonic-gate */ 622*7c478bd9Sstevel@tonic-gate 623*7c478bd9Sstevel@tonic-gate void 624*7c478bd9Sstevel@tonic-gate sigsys() 625*7c478bd9Sstevel@tonic-gate { 626*7c478bd9Sstevel@tonic-gate 627*7c478bd9Sstevel@tonic-gate Ipc = 0; 628*7c478bd9Sstevel@tonic-gate } 629*7c478bd9Sstevel@tonic-gate 630*7c478bd9Sstevel@tonic-gate /* 631*7c478bd9Sstevel@tonic-gate * sigint: catch interrupts and prompt user for shell or to quit. 632*7c478bd9Sstevel@tonic-gate */ 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate void 635*7c478bd9Sstevel@tonic-gate sigint() 636*7c478bd9Sstevel@tonic-gate { 637*7c478bd9Sstevel@tonic-gate void (*signal())(); 638*7c478bd9Sstevel@tonic-gate extern char **environ; 639*7c478bd9Sstevel@tonic-gate register int tmpflg, i = 0, ps1 = -1, ps2 = -1; 640*7c478bd9Sstevel@tonic-gate 641*7c478bd9Sstevel@tonic-gate tmpflg = Yesflg; /* override yesflag for duration of interrupt */ 642*7c478bd9Sstevel@tonic-gate Yesflg = 0; 643*7c478bd9Sstevel@tonic-gate if (Shell_esc && ask("Want Shell? ")) { 644*7c478bd9Sstevel@tonic-gate if (!fork()) { 645*7c478bd9Sstevel@tonic-gate /* both PS1 and PS2 must be exported */ 646*7c478bd9Sstevel@tonic-gate while (environ[i]) { 647*7c478bd9Sstevel@tonic-gate if (EQ(environ[i], "PS1", 3)) 648*7c478bd9Sstevel@tonic-gate ps1 = i; 649*7c478bd9Sstevel@tonic-gate if (EQ(environ[i], "PS2", 3)) 650*7c478bd9Sstevel@tonic-gate ps2 = i; 651*7c478bd9Sstevel@tonic-gate i++; 652*7c478bd9Sstevel@tonic-gate } 653*7c478bd9Sstevel@tonic-gate if (ps1 >= 0 && ps2 >= 0) 654*7c478bd9Sstevel@tonic-gate environ[ps1] = environ[ps2]; 655*7c478bd9Sstevel@tonic-gate (void) signal(SIGINT, SIG_DFL); 656*7c478bd9Sstevel@tonic-gate execl("/usr/bin/sh", "/usr/bin/sh", 0); 657*7c478bd9Sstevel@tonic-gate } else { /* parent */ 658*7c478bd9Sstevel@tonic-gate (void) signal(SIGINT, SIG_IGN); 659*7c478bd9Sstevel@tonic-gate wait((int *)0); 660*7c478bd9Sstevel@tonic-gate } 661*7c478bd9Sstevel@tonic-gate } else if (ask("Want to quit? ")) { 662*7c478bd9Sstevel@tonic-gate if (Pid > 0) 663*7c478bd9Sstevel@tonic-gate kill(Pid, 9); 664*7c478bd9Sstevel@tonic-gate (void) cleanup(); /* ipc */ 665*7c478bd9Sstevel@tonic-gate exit(31+2); 666*7c478bd9Sstevel@tonic-gate } 667*7c478bd9Sstevel@tonic-gate (void) signal(SIGINT, sigint); 668*7c478bd9Sstevel@tonic-gate Yesflg = tmpflg; /* reset Yesflg */ 669*7c478bd9Sstevel@tonic-gate } 670*7c478bd9Sstevel@tonic-gate 671*7c478bd9Sstevel@tonic-gate /* 672*7c478bd9Sstevel@tonic-gate * actual_blocks: Calculate the actual number of blocks written to 673*7c478bd9Sstevel@tonic-gate * the tape (will differ from V_labl.v_reelblks if v_reelblks is not 674*7c478bd9Sstevel@tonic-gate * an even multiple of the blocking factor Blk_cnt). 675*7c478bd9Sstevel@tonic-gate */ 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate int 678*7c478bd9Sstevel@tonic-gate actual_blocks() 679*7c478bd9Sstevel@tonic-gate { 680*7c478bd9Sstevel@tonic-gate 681*7c478bd9Sstevel@tonic-gate if (R_blks % Blk_cnt) 682*7c478bd9Sstevel@tonic-gate return (((R_blks / Blk_cnt) + 1) * Blk_cnt); 683*7c478bd9Sstevel@tonic-gate else 684*7c478bd9Sstevel@tonic-gate return (R_blks); 685*7c478bd9Sstevel@tonic-gate } 686*7c478bd9Sstevel@tonic-gate 687*7c478bd9Sstevel@tonic-gate /* 688*7c478bd9Sstevel@tonic-gate * get_mach_type: Determine what machine this is executing on. 689*7c478bd9Sstevel@tonic-gate */ 690*7c478bd9Sstevel@tonic-gate 691*7c478bd9Sstevel@tonic-gate int 692*7c478bd9Sstevel@tonic-gate get_mach_type() 693*7c478bd9Sstevel@tonic-gate { 694*7c478bd9Sstevel@tonic-gate struct utsname utsinfo; 695*7c478bd9Sstevel@tonic-gate 696*7c478bd9Sstevel@tonic-gate errno = 0; 697*7c478bd9Sstevel@tonic-gate if (uname(&utsinfo) < 0) 698*7c478bd9Sstevel@tonic-gate perr(1, "Unable to determine machine type\n"); 699*7c478bd9Sstevel@tonic-gate if (strcmp(utsinfo.machine, "3B2") == 0) 700*7c478bd9Sstevel@tonic-gate M3b2 = 1; 701*7c478bd9Sstevel@tonic-gate else if (strcmp(utsinfo.machine, "3B15") == 0) 702*7c478bd9Sstevel@tonic-gate M3b15 = 1; 703*7c478bd9Sstevel@tonic-gate } 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate /* 706*7c478bd9Sstevel@tonic-gate * mem_setup: Determine memory needs and check for IPC. If IPC is available, 707*7c478bd9Sstevel@tonic-gate * used shared memory and semaphores to increase performance. If no IPC, 708*7c478bd9Sstevel@tonic-gate * get normal memory and only use one process. 709*7c478bd9Sstevel@tonic-gate */ 710*7c478bd9Sstevel@tonic-gate 711*7c478bd9Sstevel@tonic-gate int 712*7c478bd9Sstevel@tonic-gate mem_setup() 713*7c478bd9Sstevel@tonic-gate { 714*7c478bd9Sstevel@tonic-gate void (*signal())(); 715*7c478bd9Sstevel@tonic-gate register int cnt, num, size; 716*7c478bd9Sstevel@tonic-gate char *align(); 717*7c478bd9Sstevel@tonic-gate 718*7c478bd9Sstevel@tonic-gate union semun { 719*7c478bd9Sstevel@tonic-gate int val; 720*7c478bd9Sstevel@tonic-gate struct semid_ds *buf; 721*7c478bd9Sstevel@tonic-gate ushort_t *array; 722*7c478bd9Sstevel@tonic-gate } sem_arg; 723*7c478bd9Sstevel@tonic-gate 724*7c478bd9Sstevel@tonic-gate if (Blk_cnt == 1) { 725*7c478bd9Sstevel@tonic-gate switch (Drive_typ) { 726*7c478bd9Sstevel@tonic-gate case A_DRIVE: 727*7c478bd9Sstevel@tonic-gate Blk_cnt = 32; 728*7c478bd9Sstevel@tonic-gate break; 729*7c478bd9Sstevel@tonic-gate case C_DRIVE: 730*7c478bd9Sstevel@tonic-gate Blk_cnt = 10; 731*7c478bd9Sstevel@tonic-gate break; 732*7c478bd9Sstevel@tonic-gate case K_DRIVE: 733*7c478bd9Sstevel@tonic-gate Blk_cnt = 4; 734*7c478bd9Sstevel@tonic-gate break; 735*7c478bd9Sstevel@tonic-gate case T_DRIVE: 736*7c478bd9Sstevel@tonic-gate if (Bpi == 6250) 737*7c478bd9Sstevel@tonic-gate Blk_cnt = 50; 738*7c478bd9Sstevel@tonic-gate else 739*7c478bd9Sstevel@tonic-gate Blk_cnt = 10; 740*7c478bd9Sstevel@tonic-gate break; 741*7c478bd9Sstevel@tonic-gate default: 742*7c478bd9Sstevel@tonic-gate if (M3b15) { 743*7c478bd9Sstevel@tonic-gate if (Itape || Otape) 744*7c478bd9Sstevel@tonic-gate Blk_cnt = 16; 745*7c478bd9Sstevel@tonic-gate } else { 746*7c478bd9Sstevel@tonic-gate if (Otape || Itape) { 747*7c478bd9Sstevel@tonic-gate if (Bpi == 6250) 748*7c478bd9Sstevel@tonic-gate Blk_cnt = 50; 749*7c478bd9Sstevel@tonic-gate else 750*7c478bd9Sstevel@tonic-gate Blk_cnt = 10; 751*7c478bd9Sstevel@tonic-gate } 752*7c478bd9Sstevel@tonic-gate } 753*7c478bd9Sstevel@tonic-gate break; 754*7c478bd9Sstevel@tonic-gate } /* Drive_typ */ 755*7c478bd9Sstevel@tonic-gate } /* Blk_cnt == 1 */ 756*7c478bd9Sstevel@tonic-gate if (Blk_cnt > 1) /* user overrode g_init */ 757*7c478bd9Sstevel@tonic-gate In.f_bsize = Out.f_bsize = Blk_cnt * BLKSIZ; 758*7c478bd9Sstevel@tonic-gate In.f_bsize = (!Itape) ? Disk_cnt * In.f_bsize : In.f_bsize; 759*7c478bd9Sstevel@tonic-gate Out.f_bsize = (!Otape) ? Disk_cnt * Out.f_bsize : Out.f_bsize; 760*7c478bd9Sstevel@tonic-gate Bufsz = find_lcm(In.f_bsize, Out.f_bsize); 761*7c478bd9Sstevel@tonic-gate num = _128K / (Bufsz + sizeof (int)); 762*7c478bd9Sstevel@tonic-gate Bufsz *= num; 763*7c478bd9Sstevel@tonic-gate size = Bufsz + sizeof (int); 764*7c478bd9Sstevel@tonic-gate /* test to see if ipc is available, the shmat should fail with EINVAL */ 765*7c478bd9Sstevel@tonic-gate (void) signal(SIGSYS, sigsys); 766*7c478bd9Sstevel@tonic-gate errno = 0; 767*7c478bd9Sstevel@tonic-gate if (Ipc) { 768*7c478bd9Sstevel@tonic-gate if ((int)shmat(0, (char *)NULL, 0) < 0 && errno != EINVAL) 769*7c478bd9Sstevel@tonic-gate Ipc = 0; /* something went wrong */ 770*7c478bd9Sstevel@tonic-gate } 771*7c478bd9Sstevel@tonic-gate if (Ipc) { /* ipc is available */ 772*7c478bd9Sstevel@tonic-gate Bufcnt = 2; 773*7c478bd9Sstevel@tonic-gate sem_arg.val = 0; 774*7c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < BUFCNT; cnt++) { 775*7c478bd9Sstevel@tonic-gate errno = 0; 776*7c478bd9Sstevel@tonic-gate if ((Sem_id[cnt] = semget(IPC_PRIVATE, 1, 0)) < 0) 777*7c478bd9Sstevel@tonic-gate perr(1, "Error allocating semaphores: %d", 778*7c478bd9Sstevel@tonic-gate errno); 779*7c478bd9Sstevel@tonic-gate if (semctl(Sem_id[cnt], 0, SETVAL, sem_arg) < 0) 780*7c478bd9Sstevel@tonic-gate perr(1, "Error setting semaphores: %d", errno); 781*7c478bd9Sstevel@tonic-gate if ((Shm_id[cnt] = shmget(IPC_PRIVATE, size, 0)) < 0) 782*7c478bd9Sstevel@tonic-gate perr(1, "Error allocating shared memory: %d", 783*7c478bd9Sstevel@tonic-gate errno); 784*7c478bd9Sstevel@tonic-gate if ((Buf[cnt] = shmat(Shm_id[cnt], 0, 0)) == (void *)-1) 785*7c478bd9Sstevel@tonic-gate perr(1, "Error attaching shared memory: %d", 786*7c478bd9Sstevel@tonic-gate errno); 787*7c478bd9Sstevel@tonic-gate if (shmctl(Shm_id[cnt], SHM_LOCK, 0) < 0) 788*7c478bd9Sstevel@tonic-gate perr(0, "Error locking in shared memory: %d", 789*7c478bd9Sstevel@tonic-gate errno); 790*7c478bd9Sstevel@tonic-gate Cnts[cnt] = (int *)(Buf[cnt] + Bufsz); 791*7c478bd9Sstevel@tonic-gate } 792*7c478bd9Sstevel@tonic-gate } else { /* ipc is not available */ 793*7c478bd9Sstevel@tonic-gate Bufcnt = 1; 794*7c478bd9Sstevel@tonic-gate if ((Buf[0] = align(size)) == (char *)NULL) 795*7c478bd9Sstevel@tonic-gate perr(1, "Out of memory\n"); 796*7c478bd9Sstevel@tonic-gate Cnts[0] = (int *)(Buf[0] + Bufsz); 797*7c478bd9Sstevel@tonic-gate *Cnts[0] = 0; 798*7c478bd9Sstevel@tonic-gate } 799*7c478bd9Sstevel@tonic-gate } 800*7c478bd9Sstevel@tonic-gate 801*7c478bd9Sstevel@tonic-gate /* 802*7c478bd9Sstevel@tonic-gate * prompt: Prompt the user for verification. 803*7c478bd9Sstevel@tonic-gate */ 804*7c478bd9Sstevel@tonic-gate 805*7c478bd9Sstevel@tonic-gate static void 806*7c478bd9Sstevel@tonic-gate prompt(int verify, const char *fmt, ...) 807*7c478bd9Sstevel@tonic-gate { 808*7c478bd9Sstevel@tonic-gate va_list ap; 809*7c478bd9Sstevel@tonic-gate 810*7c478bd9Sstevel@tonic-gate va_start(ap, fmt); 811*7c478bd9Sstevel@tonic-gate if (fmt != NULL) 812*7c478bd9Sstevel@tonic-gate (void) vfprintf(stdout, gettext(fmt), ap); 813*7c478bd9Sstevel@tonic-gate va_end(ap); 814*7c478bd9Sstevel@tonic-gate if (verify) { 815*7c478bd9Sstevel@tonic-gate (void) fprintf(stdout, gettext("Type 'y' to override: ")); 816*7c478bd9Sstevel@tonic-gate if (!ask("")) { 817*7c478bd9Sstevel@tonic-gate cleanup(); 818*7c478bd9Sstevel@tonic-gate exit(31+9); 819*7c478bd9Sstevel@tonic-gate } 820*7c478bd9Sstevel@tonic-gate } 821*7c478bd9Sstevel@tonic-gate } 822*7c478bd9Sstevel@tonic-gate 823*7c478bd9Sstevel@tonic-gate /* 824*7c478bd9Sstevel@tonic-gate * ask: Ask the user a question and get the answer. 825*7c478bd9Sstevel@tonic-gate */ 826*7c478bd9Sstevel@tonic-gate 827*7c478bd9Sstevel@tonic-gate ask(s) 828*7c478bd9Sstevel@tonic-gate char *s; 829*7c478bd9Sstevel@tonic-gate { 830*7c478bd9Sstevel@tonic-gate char ans[12]; 831*7c478bd9Sstevel@tonic-gate 832*7c478bd9Sstevel@tonic-gate (void) printf(gettext(s)); 833*7c478bd9Sstevel@tonic-gate if (Yesflg) { 834*7c478bd9Sstevel@tonic-gate (void) printf(gettext("YES\n")); 835*7c478bd9Sstevel@tonic-gate return (1); 836*7c478bd9Sstevel@tonic-gate } 837*7c478bd9Sstevel@tonic-gate ans[0] = '\0'; 838*7c478bd9Sstevel@tonic-gate fgets(ans, 10, Devtty); 839*7c478bd9Sstevel@tonic-gate for (;;) { 840*7c478bd9Sstevel@tonic-gate switch (ans[0]) { 841*7c478bd9Sstevel@tonic-gate case 'a': 842*7c478bd9Sstevel@tonic-gate case 'A': 843*7c478bd9Sstevel@tonic-gate if (Pid > 0) /* parent with a child */ 844*7c478bd9Sstevel@tonic-gate kill(Pid, 9); 845*7c478bd9Sstevel@tonic-gate cleanup(); 846*7c478bd9Sstevel@tonic-gate exit(31+1); 847*7c478bd9Sstevel@tonic-gate case 'y': 848*7c478bd9Sstevel@tonic-gate case 'Y': 849*7c478bd9Sstevel@tonic-gate return (1); 850*7c478bd9Sstevel@tonic-gate case 'n': 851*7c478bd9Sstevel@tonic-gate case 'N': 852*7c478bd9Sstevel@tonic-gate return (0); 853*7c478bd9Sstevel@tonic-gate default: 854*7c478bd9Sstevel@tonic-gate (void) printf(gettext("\n(y or n)?")); 855*7c478bd9Sstevel@tonic-gate fgets(ans, 10, Devtty); 856*7c478bd9Sstevel@tonic-gate } 857*7c478bd9Sstevel@tonic-gate } 858*7c478bd9Sstevel@tonic-gate } 859*7c478bd9Sstevel@tonic-gate 860*7c478bd9Sstevel@tonic-gate /* 861*7c478bd9Sstevel@tonic-gate * align: Align a malloc'd memory section on a page boundry. 862*7c478bd9Sstevel@tonic-gate */ 863*7c478bd9Sstevel@tonic-gate 864*7c478bd9Sstevel@tonic-gate char * 865*7c478bd9Sstevel@tonic-gate align(size) 866*7c478bd9Sstevel@tonic-gate register int size; 867*7c478bd9Sstevel@tonic-gate { 868*7c478bd9Sstevel@tonic-gate register int pad; 869*7c478bd9Sstevel@tonic-gate 870*7c478bd9Sstevel@tonic-gate if ((pad = ((int)malloc(0) & (PAGESIZE-1))) > 0) { 871*7c478bd9Sstevel@tonic-gate pad = PAGESIZE - pad; 872*7c478bd9Sstevel@tonic-gate if (malloc(pad) == (char *)NULL) 873*7c478bd9Sstevel@tonic-gate return ((char *)NULL); 874*7c478bd9Sstevel@tonic-gate } 875*7c478bd9Sstevel@tonic-gate return (malloc((unsigned)size)); 876*7c478bd9Sstevel@tonic-gate } 877*7c478bd9Sstevel@tonic-gate 878*7c478bd9Sstevel@tonic-gate /* 879*7c478bd9Sstevel@tonic-gate * child_copy: Using IPC, this child process reads from shared memory 880*7c478bd9Sstevel@tonic-gate * and writes to the destination file system. 881*7c478bd9Sstevel@tonic-gate */ 882*7c478bd9Sstevel@tonic-gate 883*7c478bd9Sstevel@tonic-gate int 884*7c478bd9Sstevel@tonic-gate child_copy() 885*7c478bd9Sstevel@tonic-gate { 886*7c478bd9Sstevel@tonic-gate register int rv, cur_buf, left, have, tpcnt; 887*7c478bd9Sstevel@tonic-gate register char *c_p; 888*7c478bd9Sstevel@tonic-gate 889*7c478bd9Sstevel@tonic-gate (void) signal(SIGINT, SIG_IGN); 890*7c478bd9Sstevel@tonic-gate Sem_buf.sem_op = -1; 891*7c478bd9Sstevel@tonic-gate (void) close(In.f_des); 892*7c478bd9Sstevel@tonic-gate if (Otape && !Eomflg) 893*7c478bd9Sstevel@tonic-gate tpcnt = actual_blocks() * BLKSIZ; 894*7c478bd9Sstevel@tonic-gate cur_buf = 0; 895*7c478bd9Sstevel@tonic-gate for (;;) { 896*7c478bd9Sstevel@tonic-gate if (semop(Sem_id[cur_buf], &Sem_buf, 1) < 0) 897*7c478bd9Sstevel@tonic-gate perr(1, "semaphore operation error %d\n", errno); 898*7c478bd9Sstevel@tonic-gate left = *Cnts[cur_buf]; 899*7c478bd9Sstevel@tonic-gate if (!left) 900*7c478bd9Sstevel@tonic-gate break; 901*7c478bd9Sstevel@tonic-gate c_p = Buf[cur_buf]; 902*7c478bd9Sstevel@tonic-gate rv = 0; 903*7c478bd9Sstevel@tonic-gate while (left) { 904*7c478bd9Sstevel@tonic-gate have = (left < Out.f_bsize) ? left : Out.f_bsize; 905*7c478bd9Sstevel@tonic-gate if (!Eomflg && Otape) { 906*7c478bd9Sstevel@tonic-gate if (!tpcnt) { 907*7c478bd9Sstevel@tonic-gate (void) chgreel(&Out, OUTPUT); 908*7c478bd9Sstevel@tonic-gate tpcnt = actual_blocks() * BLKSIZ; 909*7c478bd9Sstevel@tonic-gate } 910*7c478bd9Sstevel@tonic-gate have = (tpcnt < have) ? tpcnt : have; 911*7c478bd9Sstevel@tonic-gate } 912*7c478bd9Sstevel@tonic-gate errno = 0; 913*7c478bd9Sstevel@tonic-gate if ((rv = g_write(Out.f_dev, Out.f_des, c_p, have)) < 914*7c478bd9Sstevel@tonic-gate 0) { 915*7c478bd9Sstevel@tonic-gate if (Eomflg && errno == ENOSPC) { 916*7c478bd9Sstevel@tonic-gate (void) chgreel(&Out, OUTPUT); 917*7c478bd9Sstevel@tonic-gate continue; 918*7c478bd9Sstevel@tonic-gate } else 919*7c478bd9Sstevel@tonic-gate perr(1, "I/O error %d on write\n", 920*7c478bd9Sstevel@tonic-gate errno); 921*7c478bd9Sstevel@tonic-gate } 922*7c478bd9Sstevel@tonic-gate left -= rv; 923*7c478bd9Sstevel@tonic-gate c_p += rv; 924*7c478bd9Sstevel@tonic-gate V_labl.v_offset += rv; 925*7c478bd9Sstevel@tonic-gate if (!Eomflg && Otape) 926*7c478bd9Sstevel@tonic-gate tpcnt -= rv; 927*7c478bd9Sstevel@tonic-gate } 928*7c478bd9Sstevel@tonic-gate if (semop(Sem_id[cur_buf], &Sem_buf, 1) < 0) 929*7c478bd9Sstevel@tonic-gate perr(2, "semaphore operation error %d\n", errno); 930*7c478bd9Sstevel@tonic-gate cur_buf = (cur_buf + 1) % BUFCNT; 931*7c478bd9Sstevel@tonic-gate } 932*7c478bd9Sstevel@tonic-gate exit(0); 933*7c478bd9Sstevel@tonic-gate } 934*7c478bd9Sstevel@tonic-gate 935*7c478bd9Sstevel@tonic-gate /* 936*7c478bd9Sstevel@tonic-gate * parent_copy: Using shared memory, the parent process reads fromt the 937*7c478bd9Sstevel@tonic-gate * source file system and writes to shared memory. 938*7c478bd9Sstevel@tonic-gate */ 939*7c478bd9Sstevel@tonic-gate 940*7c478bd9Sstevel@tonic-gate int 941*7c478bd9Sstevel@tonic-gate parent_copy() 942*7c478bd9Sstevel@tonic-gate { 943*7c478bd9Sstevel@tonic-gate register int rv, left, have, tpcnt, cur_buf; 944*7c478bd9Sstevel@tonic-gate register char *c_p; 945*7c478bd9Sstevel@tonic-gate int eom = 0, xfer_cnt = Fs * BLKSIZ; 946*7c478bd9Sstevel@tonic-gate 947*7c478bd9Sstevel@tonic-gate Sem_buf.sem_num = 0; 948*7c478bd9Sstevel@tonic-gate Sem_buf.sem_flg = 0; 949*7c478bd9Sstevel@tonic-gate if ((Pid = fork()) == 0) 950*7c478bd9Sstevel@tonic-gate child_copy(); /* child does not return */ 951*7c478bd9Sstevel@tonic-gate (void) close(Out.f_des); 952*7c478bd9Sstevel@tonic-gate Rstsem_buf.sem_num = 0; 953*7c478bd9Sstevel@tonic-gate Rstsem_buf.sem_flg = 0; 954*7c478bd9Sstevel@tonic-gate Rstsem_buf.sem_op = 2; 955*7c478bd9Sstevel@tonic-gate Sem_buf.sem_op = 0; 956*7c478bd9Sstevel@tonic-gate cur_buf = 0; 957*7c478bd9Sstevel@tonic-gate if (Itape && !Eomflg) 958*7c478bd9Sstevel@tonic-gate tpcnt = actual_blocks() * BLKSIZ; 959*7c478bd9Sstevel@tonic-gate while (xfer_cnt) { 960*7c478bd9Sstevel@tonic-gate if (semop(Sem_id[cur_buf], &Sem_buf, 1) < 0) 961*7c478bd9Sstevel@tonic-gate perr(1, "Semaphore operation error %d\n", errno); 962*7c478bd9Sstevel@tonic-gate c_p = Buf[cur_buf]; 963*7c478bd9Sstevel@tonic-gate left = Bufsz; 964*7c478bd9Sstevel@tonic-gate rv = 0; 965*7c478bd9Sstevel@tonic-gate while (left >= In.f_bsize && xfer_cnt) { 966*7c478bd9Sstevel@tonic-gate have = (xfer_cnt < In.f_bsize) ? xfer_cnt : In.f_bsize; 967*7c478bd9Sstevel@tonic-gate if (!Eomflg && Itape) { 968*7c478bd9Sstevel@tonic-gate if (!tpcnt) { 969*7c478bd9Sstevel@tonic-gate *Cnts[cur_buf] = Bufsz - left; 970*7c478bd9Sstevel@tonic-gate (void) flush_bufs(cur_buf); 971*7c478bd9Sstevel@tonic-gate (void) chgreel(&In, INPUT); 972*7c478bd9Sstevel@tonic-gate tpcnt = actual_blocks() * BLKSIZ; 973*7c478bd9Sstevel@tonic-gate cur_buf = (cur_buf == 0) ? 1 : 0; 974*7c478bd9Sstevel@tonic-gate eom = 1; 975*7c478bd9Sstevel@tonic-gate break; 976*7c478bd9Sstevel@tonic-gate } 977*7c478bd9Sstevel@tonic-gate have = (tpcnt < have) ? tpcnt : have; 978*7c478bd9Sstevel@tonic-gate } 979*7c478bd9Sstevel@tonic-gate errno = 0; 980*7c478bd9Sstevel@tonic-gate if ((rv = g_read(In.f_dev, In.f_des, c_p, have)) < 0) { 981*7c478bd9Sstevel@tonic-gate if (Eomflg && errno == ENOSPC) { 982*7c478bd9Sstevel@tonic-gate *Cnts[cur_buf] = Bufsz - left; 983*7c478bd9Sstevel@tonic-gate (void) flush_bufs(cur_buf); 984*7c478bd9Sstevel@tonic-gate (void) chgreel(&In, INPUT); 985*7c478bd9Sstevel@tonic-gate cur_buf = (cur_buf == 0) ? 1 : 0; 986*7c478bd9Sstevel@tonic-gate eom = 1; 987*7c478bd9Sstevel@tonic-gate break; 988*7c478bd9Sstevel@tonic-gate } else 989*7c478bd9Sstevel@tonic-gate perr(1, "I/O error %d on read\n", 990*7c478bd9Sstevel@tonic-gate errno); 991*7c478bd9Sstevel@tonic-gate } 992*7c478bd9Sstevel@tonic-gate left -= rv; 993*7c478bd9Sstevel@tonic-gate c_p += rv; 994*7c478bd9Sstevel@tonic-gate xfer_cnt -= rv; 995*7c478bd9Sstevel@tonic-gate if (!Eomflg && Itape) 996*7c478bd9Sstevel@tonic-gate tpcnt -= rv; 997*7c478bd9Sstevel@tonic-gate } 998*7c478bd9Sstevel@tonic-gate if (eom > 0) { 999*7c478bd9Sstevel@tonic-gate eom = 0; 1000*7c478bd9Sstevel@tonic-gate if (Eomflg) 1001*7c478bd9Sstevel@tonic-gate xfer_cnt -= rv; 1002*7c478bd9Sstevel@tonic-gate else if (Itape) 1003*7c478bd9Sstevel@tonic-gate tpcnt -= rv; 1004*7c478bd9Sstevel@tonic-gate continue; 1005*7c478bd9Sstevel@tonic-gate } 1006*7c478bd9Sstevel@tonic-gate *Cnts[cur_buf] = Bufsz - left; 1007*7c478bd9Sstevel@tonic-gate Blocks += *Cnts[cur_buf]; 1008*7c478bd9Sstevel@tonic-gate if (semop(Sem_id[cur_buf], &Rstsem_buf, 1) < 0) 1009*7c478bd9Sstevel@tonic-gate perr(2, "Semaphore operation error %d\n", errno); 1010*7c478bd9Sstevel@tonic-gate cur_buf = (cur_buf == 0) ? 1 : 0; 1011*7c478bd9Sstevel@tonic-gate } 1012*7c478bd9Sstevel@tonic-gate if (semop(Sem_id[cur_buf], &Sem_buf, 1) < 0) 1013*7c478bd9Sstevel@tonic-gate perr(3, "Semaphore operation error %d\n", errno); 1014*7c478bd9Sstevel@tonic-gate *Cnts[cur_buf] = 0; 1015*7c478bd9Sstevel@tonic-gate if (semop(Sem_id[cur_buf], &Rstsem_buf, 1) < 0) 1016*7c478bd9Sstevel@tonic-gate perr(4, "Semaphore operation error %d\n", errno); 1017*7c478bd9Sstevel@tonic-gate wait((int *)NULL); 1018*7c478bd9Sstevel@tonic-gate Blocks /= BLKSIZ; 1019*7c478bd9Sstevel@tonic-gate } 1020*7c478bd9Sstevel@tonic-gate 1021*7c478bd9Sstevel@tonic-gate /* 1022*7c478bd9Sstevel@tonic-gate * copy: Copy without shared memory. The process reads from the source 1023*7c478bd9Sstevel@tonic-gate * filesystem and writes to the destination filesystem. 1024*7c478bd9Sstevel@tonic-gate */ 1025*7c478bd9Sstevel@tonic-gate 1026*7c478bd9Sstevel@tonic-gate int 1027*7c478bd9Sstevel@tonic-gate copy() 1028*7c478bd9Sstevel@tonic-gate { 1029*7c478bd9Sstevel@tonic-gate register int rv, left, have, tpcnt = 1, xfer_cnt = Fs * BLKSIZ; 1030*7c478bd9Sstevel@tonic-gate register char *c_p; 1031*7c478bd9Sstevel@tonic-gate 1032*7c478bd9Sstevel@tonic-gate if ((Itape || Otape) && !Eomflg) 1033*7c478bd9Sstevel@tonic-gate tpcnt = actual_blocks() * BLKSIZ; 1034*7c478bd9Sstevel@tonic-gate while (xfer_cnt) { 1035*7c478bd9Sstevel@tonic-gate c_p = (char *)(Buf[0] + *Cnts[0]); 1036*7c478bd9Sstevel@tonic-gate left = Bufsz - *Cnts[0]; 1037*7c478bd9Sstevel@tonic-gate rv = 0; 1038*7c478bd9Sstevel@tonic-gate while (left >= In.f_bsize && xfer_cnt) { 1039*7c478bd9Sstevel@tonic-gate have = (xfer_cnt < In.f_bsize) ? xfer_cnt : In.f_bsize; 1040*7c478bd9Sstevel@tonic-gate if (!Eomflg && Itape) { 1041*7c478bd9Sstevel@tonic-gate if (!tpcnt) { 1042*7c478bd9Sstevel@tonic-gate *Cnts[0] = Bufsz - left; 1043*7c478bd9Sstevel@tonic-gate (void) chgreel(&In, INPUT); 1044*7c478bd9Sstevel@tonic-gate tpcnt = actual_blocks() * BLKSIZ; 1045*7c478bd9Sstevel@tonic-gate break; 1046*7c478bd9Sstevel@tonic-gate } 1047*7c478bd9Sstevel@tonic-gate have = (tpcnt < have) ? tpcnt : have; 1048*7c478bd9Sstevel@tonic-gate } 1049*7c478bd9Sstevel@tonic-gate errno = 0; 1050*7c478bd9Sstevel@tonic-gate if ((rv = g_read(In.f_dev, In.f_des, c_p, have)) < 0) { 1051*7c478bd9Sstevel@tonic-gate if (Eomflg && errno == ENOSPC) { 1052*7c478bd9Sstevel@tonic-gate (void) chgreel(&In, INPUT); 1053*7c478bd9Sstevel@tonic-gate break; 1054*7c478bd9Sstevel@tonic-gate } else 1055*7c478bd9Sstevel@tonic-gate perr(1, "I/O error %d on read\n", 1056*7c478bd9Sstevel@tonic-gate errno); 1057*7c478bd9Sstevel@tonic-gate } 1058*7c478bd9Sstevel@tonic-gate left -= rv; 1059*7c478bd9Sstevel@tonic-gate c_p += rv; 1060*7c478bd9Sstevel@tonic-gate xfer_cnt -= rv; 1061*7c478bd9Sstevel@tonic-gate if (!Eomflg && Itape) 1062*7c478bd9Sstevel@tonic-gate tpcnt -= rv; 1063*7c478bd9Sstevel@tonic-gate } /* left >= In.f_bsize && xfer_cnt */ 1064*7c478bd9Sstevel@tonic-gate *Cnts[0] = Bufsz - left; 1065*7c478bd9Sstevel@tonic-gate Blocks += *Cnts[0]; 1066*7c478bd9Sstevel@tonic-gate c_p = Buf[0]; 1067*7c478bd9Sstevel@tonic-gate left = *Cnts[0]; 1068*7c478bd9Sstevel@tonic-gate rv = 0; 1069*7c478bd9Sstevel@tonic-gate while (left >= Out.f_bsize || (left > 0 && !xfer_cnt)) { 1070*7c478bd9Sstevel@tonic-gate have = (left < Out.f_bsize) ? left : Out.f_bsize; 1071*7c478bd9Sstevel@tonic-gate if (!Eomflg && Otape) { 1072*7c478bd9Sstevel@tonic-gate if (!tpcnt) { 1073*7c478bd9Sstevel@tonic-gate (void) chgreel(&Out, OUTPUT); 1074*7c478bd9Sstevel@tonic-gate tpcnt = actual_blocks() * BLKSIZ; 1075*7c478bd9Sstevel@tonic-gate } 1076*7c478bd9Sstevel@tonic-gate have = (tpcnt < have) ? tpcnt : have; 1077*7c478bd9Sstevel@tonic-gate } 1078*7c478bd9Sstevel@tonic-gate errno = 0; 1079*7c478bd9Sstevel@tonic-gate if ((rv = g_write(Out.f_dev, Out.f_des, c_p, have)) < 1080*7c478bd9Sstevel@tonic-gate 0) { 1081*7c478bd9Sstevel@tonic-gate if (Eomflg && errno == ENOSPC) { 1082*7c478bd9Sstevel@tonic-gate (void) chgreel(&Out, OUTPUT); 1083*7c478bd9Sstevel@tonic-gate continue; 1084*7c478bd9Sstevel@tonic-gate } else 1085*7c478bd9Sstevel@tonic-gate perr(1, "I/O error %d on write\n", 1086*7c478bd9Sstevel@tonic-gate errno); 1087*7c478bd9Sstevel@tonic-gate } 1088*7c478bd9Sstevel@tonic-gate left -= rv; 1089*7c478bd9Sstevel@tonic-gate c_p += rv; 1090*7c478bd9Sstevel@tonic-gate V_labl.v_offset += rv; 1091*7c478bd9Sstevel@tonic-gate if (!Eomflg && Otape) 1092*7c478bd9Sstevel@tonic-gate tpcnt -= rv; 1093*7c478bd9Sstevel@tonic-gate } /* left >= Out.f_bsize */ 1094*7c478bd9Sstevel@tonic-gate if (left) { 1095*7c478bd9Sstevel@tonic-gate (void) memcpy(Buf[0], c_p, left); 1096*7c478bd9Sstevel@tonic-gate Blocks -= left; 1097*7c478bd9Sstevel@tonic-gate } 1098*7c478bd9Sstevel@tonic-gate *Cnts[0] = left; 1099*7c478bd9Sstevel@tonic-gate } /* xfer_cnt */ 1100*7c478bd9Sstevel@tonic-gate Blocks /= BLKSIZ; 1101*7c478bd9Sstevel@tonic-gate } 1102*7c478bd9Sstevel@tonic-gate 1103*7c478bd9Sstevel@tonic-gate /* 1104*7c478bd9Sstevel@tonic-gate * flush_bufs: Permit child to read the remaining data from the 1105*7c478bd9Sstevel@tonic-gate * buffer before prompting user for end-of-media. 1106*7c478bd9Sstevel@tonic-gate */ 1107*7c478bd9Sstevel@tonic-gate 1108*7c478bd9Sstevel@tonic-gate int 1109*7c478bd9Sstevel@tonic-gate flush_bufs(buffer) 1110*7c478bd9Sstevel@tonic-gate register int buffer; 1111*7c478bd9Sstevel@tonic-gate { 1112*7c478bd9Sstevel@tonic-gate 1113*7c478bd9Sstevel@tonic-gate Blocks += *Cnts[buffer]; 1114*7c478bd9Sstevel@tonic-gate if (semop(Sem_id[buffer], &Rstsem_buf, 1) < 0) 1115*7c478bd9Sstevel@tonic-gate perr(5, "Semaphore operation error %d\n", errno); 1116*7c478bd9Sstevel@tonic-gate if (semop(Sem_id[buffer], &Sem_buf, 1) < 0) 1117*7c478bd9Sstevel@tonic-gate perr(6, "Semaphore operation error %d\n", errno); 1118*7c478bd9Sstevel@tonic-gate } 1119*7c478bd9Sstevel@tonic-gate 1120*7c478bd9Sstevel@tonic-gate /* 1121*7c478bd9Sstevel@tonic-gate * cleanup: Clean up shared memory and semaphore resources. 1122*7c478bd9Sstevel@tonic-gate */ 1123*7c478bd9Sstevel@tonic-gate 1124*7c478bd9Sstevel@tonic-gate int 1125*7c478bd9Sstevel@tonic-gate cleanup() 1126*7c478bd9Sstevel@tonic-gate { 1127*7c478bd9Sstevel@tonic-gate register int cnt; 1128*7c478bd9Sstevel@tonic-gate 1129*7c478bd9Sstevel@tonic-gate if (Ipc) { 1130*7c478bd9Sstevel@tonic-gate for (cnt = 0; cnt < BUFCNT; cnt++) { 1131*7c478bd9Sstevel@tonic-gate (void) semctl(Sem_id[cnt], IPC_RMID, 0); 1132*7c478bd9Sstevel@tonic-gate (void) shmctl(Shm_id[cnt], IPC_RMID, 0); 1133*7c478bd9Sstevel@tonic-gate } 1134*7c478bd9Sstevel@tonic-gate } 1135*7c478bd9Sstevel@tonic-gate } 1136*7c478bd9Sstevel@tonic-gate 1137*7c478bd9Sstevel@tonic-gate /* 1138*7c478bd9Sstevel@tonic-gate * find_lcm: Find the lowest common multiple of two numbers. This is used 1139*7c478bd9Sstevel@tonic-gate * to determine the buffer size that should be malloc(3)'d such that the 1140*7c478bd9Sstevel@tonic-gate * input and output data blocks can both fit evenly into the buffer. 1141*7c478bd9Sstevel@tonic-gate */ 1142*7c478bd9Sstevel@tonic-gate 1143*7c478bd9Sstevel@tonic-gate int 1144*7c478bd9Sstevel@tonic-gate find_lcm(sz1, sz2) 1145*7c478bd9Sstevel@tonic-gate register int sz1, sz2; 1146*7c478bd9Sstevel@tonic-gate { 1147*7c478bd9Sstevel@tonic-gate register int inc, lcm, small; 1148*7c478bd9Sstevel@tonic-gate 1149*7c478bd9Sstevel@tonic-gate if (sz1 < sz2) { 1150*7c478bd9Sstevel@tonic-gate lcm = inc = sz2; 1151*7c478bd9Sstevel@tonic-gate small = sz1; 1152*7c478bd9Sstevel@tonic-gate } else { /* sz1 >= sz2 */ 1153*7c478bd9Sstevel@tonic-gate lcm = inc = sz1; 1154*7c478bd9Sstevel@tonic-gate small = sz2; 1155*7c478bd9Sstevel@tonic-gate } 1156*7c478bd9Sstevel@tonic-gate while (lcm % small != 0) 1157*7c478bd9Sstevel@tonic-gate lcm += inc; 1158*7c478bd9Sstevel@tonic-gate return (lcm); 1159*7c478bd9Sstevel@tonic-gate } 1160*7c478bd9Sstevel@tonic-gate 1161*7c478bd9Sstevel@tonic-gate /* 1162*7c478bd9Sstevel@tonic-gate * Determine bpi information from drive names. 1163*7c478bd9Sstevel@tonic-gate */ 1164*7c478bd9Sstevel@tonic-gate 1165*7c478bd9Sstevel@tonic-gate getbpi(inp) 1166*7c478bd9Sstevel@tonic-gate register char *inp; 1167*7c478bd9Sstevel@tonic-gate { 1168*7c478bd9Sstevel@tonic-gate 1169*7c478bd9Sstevel@tonic-gate /* 1170*7c478bd9Sstevel@tonic-gate * Kludge to recognize Accellerated Tape Controller usage from 1171*7c478bd9Sstevel@tonic-gate * letter 'a' or 'A' following density given by user. 1172*7c478bd9Sstevel@tonic-gate * 1173*7c478bd9Sstevel@tonic-gate * Kludge to recognize 3B15 Compatibility Mode from 1174*7c478bd9Sstevel@tonic-gate * letter 'c' or 'C' following density given by user. 1175*7c478bd9Sstevel@tonic-gate */ 1176*7c478bd9Sstevel@tonic-gate if (M3b15) { 1177*7c478bd9Sstevel@tonic-gate if (inp[4] == 'a' || inp[4] == 'A') { 1178*7c478bd9Sstevel@tonic-gate Drive_typ = A_DRIVE; 1179*7c478bd9Sstevel@tonic-gate inp[4] = '\0'; 1180*7c478bd9Sstevel@tonic-gate } 1181*7c478bd9Sstevel@tonic-gate if (inp[4] == 'c' || inp[4] == 'C') { 1182*7c478bd9Sstevel@tonic-gate Drive_typ = C_DRIVE; 1183*7c478bd9Sstevel@tonic-gate inp[4] = '\0'; 1184*7c478bd9Sstevel@tonic-gate } 1185*7c478bd9Sstevel@tonic-gate } 1186*7c478bd9Sstevel@tonic-gate return (atoi(inp)); 1187*7c478bd9Sstevel@tonic-gate } 1188*7c478bd9Sstevel@tonic-gate 1189*7c478bd9Sstevel@tonic-gate /* 1190*7c478bd9Sstevel@tonic-gate * blks_per_ft: Determine the number of blocks per foot of tape. 1191*7c478bd9Sstevel@tonic-gate * Inter-block gap (dgap) is 0.3 in. 1192*7c478bd9Sstevel@tonic-gate */ 1193*7c478bd9Sstevel@tonic-gate 1194*7c478bd9Sstevel@tonic-gate int 1195*7c478bd9Sstevel@tonic-gate blks_per_ft(disc) 1196*7c478bd9Sstevel@tonic-gate register double disc; 1197*7c478bd9Sstevel@tonic-gate { 1198*7c478bd9Sstevel@tonic-gate register double dcnt = Blk_cnt, dBpi = Bpi, dsiz = BLKSIZ, dgap = 0.3; 1199*7c478bd9Sstevel@tonic-gate 1200*7c478bd9Sstevel@tonic-gate return ((int)(dcnt / (((dcnt * dsiz / dBpi) + dgap) / 12.0) * disc)); 1201*7c478bd9Sstevel@tonic-gate } 1202*7c478bd9Sstevel@tonic-gate 1203*7c478bd9Sstevel@tonic-gate /* 1204*7c478bd9Sstevel@tonic-gate * tapeck: Arbitrary block size. Determine the number of physical blocks per 1205*7c478bd9Sstevel@tonic-gate * foot of tape, including the inter-block gap, and the possibility of a short 1206*7c478bd9Sstevel@tonic-gate * tape. Assume the usable portion of a tape is 85% of its length for small 1207*7c478bd9Sstevel@tonic-gate * block sizes and 88% for large block sizes. 1208*7c478bd9Sstevel@tonic-gate */ 1209*7c478bd9Sstevel@tonic-gate 1210*7c478bd9Sstevel@tonic-gate tapeck(f_p, dir) 1211*7c478bd9Sstevel@tonic-gate register struct file_info *f_p; 1212*7c478bd9Sstevel@tonic-gate register int dir; 1213*7c478bd9Sstevel@tonic-gate { 1214*7c478bd9Sstevel@tonic-gate register int again = 1, verify, old_style, new_style; 1215*7c478bd9Sstevel@tonic-gate char resp[16]; 1216*7c478bd9Sstevel@tonic-gate 1217*7c478bd9Sstevel@tonic-gate errno = 0; 1218*7c478bd9Sstevel@tonic-gate if ((f_p->f_bsize = g_init(&f_p->f_dev, &f_p->f_des)) < 0) 1219*7c478bd9Sstevel@tonic-gate perr(1, "volcopy: Error %d during initialization\n", errno); 1220*7c478bd9Sstevel@tonic-gate if ((f_p->f_dev != G_TM_TAPE) && (f_p->f_dev != G_XT_TAPE) && 1221*7c478bd9Sstevel@tonic-gate (f_p->f_dev != G_ST_TAPE)) 1222*7c478bd9Sstevel@tonic-gate return (0); 1223*7c478bd9Sstevel@tonic-gate V_labl.v_magic[0] = '\0'; /* scribble on old data */ 1224*7c478bd9Sstevel@tonic-gate alarm(5); 1225*7c478bd9Sstevel@tonic-gate if (g_read(f_p->f_dev, f_p->f_des, &V_labl, sizeof (V_labl)) <= 0) { 1226*7c478bd9Sstevel@tonic-gate if (dir == INPUT) 1227*7c478bd9Sstevel@tonic-gate perror("input tape"); 1228*7c478bd9Sstevel@tonic-gate else 1229*7c478bd9Sstevel@tonic-gate perror("output tape"); 1230*7c478bd9Sstevel@tonic-gate } 1231*7c478bd9Sstevel@tonic-gate alarm(0); 1232*7c478bd9Sstevel@tonic-gate if (V_labl.v_reel == (char)NULL && dir == INPUT) 1233*7c478bd9Sstevel@tonic-gate perr(9, "Input tape is empty\n"); 1234*7c478bd9Sstevel@tonic-gate else { 1235*7c478bd9Sstevel@tonic-gate old_style = strncmp(V_labl.v_magic, "Volcopy", 7) == 0; 1236*7c478bd9Sstevel@tonic-gate new_style = strncmp(V_labl.v_magic, "VOLCOPY", 7) == 0; 1237*7c478bd9Sstevel@tonic-gate if (!old_style && !new_style) { 1238*7c478bd9Sstevel@tonic-gate verify = (dir == INPUT) ? 0 : 1; 1239*7c478bd9Sstevel@tonic-gate prompt(verify, "Not a labeled tape\n"); 1240*7c478bd9Sstevel@tonic-gate if (dir == INPUT) 1241*7c478bd9Sstevel@tonic-gate perr(10, "Input tape not made by volcopy\n"); 1242*7c478bd9Sstevel@tonic-gate mklabel(); 1243*7c478bd9Sstevel@tonic-gate strncpy(V_labl.v_volume, f_p->f_vol_p, 6); 1244*7c478bd9Sstevel@tonic-gate Osup.fs_time = 0; 1245*7c478bd9Sstevel@tonic-gate } else if (new_style) { 1246*7c478bd9Sstevel@tonic-gate Eomflg = (dir == INPUT) ? 1 : Eomflg; 1247*7c478bd9Sstevel@tonic-gate if (!Eomflg) 1248*7c478bd9Sstevel@tonic-gate strncpy(V_labl.v_magic, "Volcopy", 7); 1249*7c478bd9Sstevel@tonic-gate } 1250*7c478bd9Sstevel@tonic-gate } 1251*7c478bd9Sstevel@tonic-gate if (*f_p->f_vol_p == '-') 1252*7c478bd9Sstevel@tonic-gate strncpy(f_p->f_vol_p, V_labl.v_volume, 6); 1253*7c478bd9Sstevel@tonic-gate else if (NOT_EQ(V_labl.v_volume, f_p->f_vol_p, 6)) { 1254*7c478bd9Sstevel@tonic-gate prompt(1, "Header volume(%.6s) does not match (%s)\n", 1255*7c478bd9Sstevel@tonic-gate V_labl.v_volume, f_p->f_vol_p); 1256*7c478bd9Sstevel@tonic-gate strncpy(V_labl.v_volume, f_p->f_vol_p, 6); 1257*7c478bd9Sstevel@tonic-gate } 1258*7c478bd9Sstevel@tonic-gate if (dir == INPUT) { 1259*7c478bd9Sstevel@tonic-gate Bpi = V_labl.v_dens; 1260*7c478bd9Sstevel@tonic-gate if (!Eomflg) { 1261*7c478bd9Sstevel@tonic-gate R_len = V_labl.v_length; 1262*7c478bd9Sstevel@tonic-gate R_num = V_labl.v_reels; 1263*7c478bd9Sstevel@tonic-gate } 1264*7c478bd9Sstevel@tonic-gate if (M3b15) { 1265*7c478bd9Sstevel@tonic-gate if (V_labl.v_type == T_TYPE) { 1266*7c478bd9Sstevel@tonic-gate if (V_labl.v_nblocks == 0) { 1267*7c478bd9Sstevel@tonic-gate Blk_cnt = 10; 1268*7c478bd9Sstevel@tonic-gate Drive_typ = C_DRIVE; 1269*7c478bd9Sstevel@tonic-gate } else 1270*7c478bd9Sstevel@tonic-gate Blk_cnt = V_labl.v_nblocks; 1271*7c478bd9Sstevel@tonic-gate if (V_labl.v_nblocks == 32) 1272*7c478bd9Sstevel@tonic-gate Drive_typ = A_DRIVE; 1273*7c478bd9Sstevel@tonic-gate else 1274*7c478bd9Sstevel@tonic-gate Drive_typ = 0; 1275*7c478bd9Sstevel@tonic-gate } else { 1276*7c478bd9Sstevel@tonic-gate Drive_typ = 0; 1277*7c478bd9Sstevel@tonic-gate Blk_cnt = 10; 1278*7c478bd9Sstevel@tonic-gate Drive_typ = C_DRIVE; 1279*7c478bd9Sstevel@tonic-gate } 1280*7c478bd9Sstevel@tonic-gate } 1281*7c478bd9Sstevel@tonic-gate } 1282*7c478bd9Sstevel@tonic-gate while (!Eomflg && (R_len <= 0 || R_len > 3600)) { 1283*7c478bd9Sstevel@tonic-gate (void) printf(gettext( 1284*7c478bd9Sstevel@tonic-gate "Enter size of reel in feet for <%s>: "), 1285*7c478bd9Sstevel@tonic-gate f_p->f_vol_p); 1286*7c478bd9Sstevel@tonic-gate fgets(resp, 10, Devtty); 1287*7c478bd9Sstevel@tonic-gate R_len = atoi(resp); 1288*7c478bd9Sstevel@tonic-gate if (R_len > 0 && R_len <= 3600) 1289*7c478bd9Sstevel@tonic-gate break; 1290*7c478bd9Sstevel@tonic-gate perr(0, "Size of reel must be > 0, <= 3600\n"); 1291*7c478bd9Sstevel@tonic-gate } 1292*7c478bd9Sstevel@tonic-gate while (!Eomflg && again) { 1293*7c478bd9Sstevel@tonic-gate again = 0; 1294*7c478bd9Sstevel@tonic-gate if (!Bpi) { 1295*7c478bd9Sstevel@tonic-gate (void) printf(gettext( 1296*7c478bd9Sstevel@tonic-gate "Tape density? (i.e., 800 | 1600 | 6250)? ")); 1297*7c478bd9Sstevel@tonic-gate fgets(resp, 10, Devtty); 1298*7c478bd9Sstevel@tonic-gate Bpi = getbpi(resp); 1299*7c478bd9Sstevel@tonic-gate } 1300*7c478bd9Sstevel@tonic-gate switch (Bpi) { 1301*7c478bd9Sstevel@tonic-gate case 800: 1302*7c478bd9Sstevel@tonic-gate R_blks = Ft800x10 * R_len; 1303*7c478bd9Sstevel@tonic-gate break; 1304*7c478bd9Sstevel@tonic-gate case 1600: 1305*7c478bd9Sstevel@tonic-gate if (M3b15) { 1306*7c478bd9Sstevel@tonic-gate switch (Blk_cnt) { 1307*7c478bd9Sstevel@tonic-gate case 1: /* Writing a new tape */ 1308*7c478bd9Sstevel@tonic-gate if (Drive_typ == A_DRIVE) 1309*7c478bd9Sstevel@tonic-gate R_blks = Ft1600x32 * R_len; 1310*7c478bd9Sstevel@tonic-gate else if (Drive_typ == C_DRIVE) 1311*7c478bd9Sstevel@tonic-gate R_blks = Ft1600x10 * R_len; 1312*7c478bd9Sstevel@tonic-gate else 1313*7c478bd9Sstevel@tonic-gate R_blks = Ft1600x16 * R_len; 1314*7c478bd9Sstevel@tonic-gate break; 1315*7c478bd9Sstevel@tonic-gate case 10: 1316*7c478bd9Sstevel@tonic-gate R_blks = Ft1600x10 * R_len; 1317*7c478bd9Sstevel@tonic-gate break; 1318*7c478bd9Sstevel@tonic-gate case 16: 1319*7c478bd9Sstevel@tonic-gate R_blks = Ft1600x16 * R_len; 1320*7c478bd9Sstevel@tonic-gate break; 1321*7c478bd9Sstevel@tonic-gate case 32: 1322*7c478bd9Sstevel@tonic-gate R_blks = Ft1600x32 * R_len; 1323*7c478bd9Sstevel@tonic-gate break; 1324*7c478bd9Sstevel@tonic-gate default: 1325*7c478bd9Sstevel@tonic-gate if (Blk_cnt < 32) 1326*7c478bd9Sstevel@tonic-gate R_blks = blks_per_ft(0.85); 1327*7c478bd9Sstevel@tonic-gate else 1328*7c478bd9Sstevel@tonic-gate R_blks = blks_per_ft(0.88); 1329*7c478bd9Sstevel@tonic-gate R_blks *= R_len; 1330*7c478bd9Sstevel@tonic-gate } /* Blk_cnt */ 1331*7c478bd9Sstevel@tonic-gate } else 1332*7c478bd9Sstevel@tonic-gate R_blks = Ft1600x10 * R_len; 1333*7c478bd9Sstevel@tonic-gate break; 1334*7c478bd9Sstevel@tonic-gate case 6250: 1335*7c478bd9Sstevel@tonic-gate if (M3b15) { 1336*7c478bd9Sstevel@tonic-gate switch (Blk_cnt) { 1337*7c478bd9Sstevel@tonic-gate case 1: /* Writing a new tape */ 1338*7c478bd9Sstevel@tonic-gate if (Drive_typ == A_DRIVE) 1339*7c478bd9Sstevel@tonic-gate R_blks = Ft6250x32 * R_len; 1340*7c478bd9Sstevel@tonic-gate else if (Drive_typ == C_DRIVE) 1341*7c478bd9Sstevel@tonic-gate R_blks = Ft6250x10 * R_len; 1342*7c478bd9Sstevel@tonic-gate else 1343*7c478bd9Sstevel@tonic-gate R_blks = Ft6250x16 * R_len; 1344*7c478bd9Sstevel@tonic-gate break; 1345*7c478bd9Sstevel@tonic-gate case 10: 1346*7c478bd9Sstevel@tonic-gate R_blks = Ft6250x10 * R_len; 1347*7c478bd9Sstevel@tonic-gate break; 1348*7c478bd9Sstevel@tonic-gate case 16: 1349*7c478bd9Sstevel@tonic-gate R_blks = Ft6250x16 * R_len; 1350*7c478bd9Sstevel@tonic-gate break; 1351*7c478bd9Sstevel@tonic-gate case 32: 1352*7c478bd9Sstevel@tonic-gate R_blks = Ft6250x32 * R_len; 1353*7c478bd9Sstevel@tonic-gate break; 1354*7c478bd9Sstevel@tonic-gate default: 1355*7c478bd9Sstevel@tonic-gate if (Blk_cnt < 32) 1356*7c478bd9Sstevel@tonic-gate R_blks = blks_per_ft(0.85); 1357*7c478bd9Sstevel@tonic-gate else 1358*7c478bd9Sstevel@tonic-gate R_blks = blks_per_ft(0.88); 1359*7c478bd9Sstevel@tonic-gate R_blks *= R_len; 1360*7c478bd9Sstevel@tonic-gate } 1361*7c478bd9Sstevel@tonic-gate } else 1362*7c478bd9Sstevel@tonic-gate R_blks = Ft6250x50 * R_len; 1363*7c478bd9Sstevel@tonic-gate break; 1364*7c478bd9Sstevel@tonic-gate default: 1365*7c478bd9Sstevel@tonic-gate perr(0, "Bpi must be 800, 1600, or 6250\n"); 1366*7c478bd9Sstevel@tonic-gate Bpi = 0; 1367*7c478bd9Sstevel@tonic-gate again = 1; 1368*7c478bd9Sstevel@tonic-gate } /* Bpi */ 1369*7c478bd9Sstevel@tonic-gate } /* again */ 1370*7c478bd9Sstevel@tonic-gate (void) printf(gettext("\nReel %.6s"), V_labl.v_volume); 1371*7c478bd9Sstevel@tonic-gate if (!Eomflg) { 1372*7c478bd9Sstevel@tonic-gate V_labl.v_length = R_len; 1373*7c478bd9Sstevel@tonic-gate V_labl.v_dens = Bpi; 1374*7c478bd9Sstevel@tonic-gate (void) printf(gettext(", %d feet, %d BPI\n"), R_len, Bpi); 1375*7c478bd9Sstevel@tonic-gate } else 1376*7c478bd9Sstevel@tonic-gate (void) printf(gettext(", ? feet\n")); 1377*7c478bd9Sstevel@tonic-gate return (1); 1378*7c478bd9Sstevel@tonic-gate } 1379*7c478bd9Sstevel@tonic-gate 1380*7c478bd9Sstevel@tonic-gate /* 1381*7c478bd9Sstevel@tonic-gate * hdrck: Look for and validate a volcopy style tape label. 1382*7c478bd9Sstevel@tonic-gate */ 1383*7c478bd9Sstevel@tonic-gate 1384*7c478bd9Sstevel@tonic-gate hdrck(dev, fd, tvol) 1385*7c478bd9Sstevel@tonic-gate register int dev, fd; 1386*7c478bd9Sstevel@tonic-gate register char *tvol; 1387*7c478bd9Sstevel@tonic-gate { 1388*7c478bd9Sstevel@tonic-gate register int verify; 1389*7c478bd9Sstevel@tonic-gate struct volcopy_label tlabl; 1390*7c478bd9Sstevel@tonic-gate 1391*7c478bd9Sstevel@tonic-gate alarm(15); /* don't scan whole tape for label */ 1392*7c478bd9Sstevel@tonic-gate errno = 0; 1393*7c478bd9Sstevel@tonic-gate if (g_read(dev, fd, &tlabl, sizeof (tlabl)) != sizeof (tlabl)) { 1394*7c478bd9Sstevel@tonic-gate alarm(0); 1395*7c478bd9Sstevel@tonic-gate verify = Otape; 1396*7c478bd9Sstevel@tonic-gate prompt(verify, "Cannot read header\n"); 1397*7c478bd9Sstevel@tonic-gate if (Itape) 1398*7c478bd9Sstevel@tonic-gate close(fd); 1399*7c478bd9Sstevel@tonic-gate else 1400*7c478bd9Sstevel@tonic-gate strncpy(V_labl.v_volume, tvol, 6); 1401*7c478bd9Sstevel@tonic-gate return (verify); 1402*7c478bd9Sstevel@tonic-gate } 1403*7c478bd9Sstevel@tonic-gate alarm(0); 1404*7c478bd9Sstevel@tonic-gate V_labl.v_reel = tlabl.v_reel; 1405*7c478bd9Sstevel@tonic-gate if (NOT_EQ(tlabl.v_volume, tvol, 6)) { 1406*7c478bd9Sstevel@tonic-gate perr(0, "Volume is <%.6s>, not <%s>.\n", tlabl.v_volume, tvol); 1407*7c478bd9Sstevel@tonic-gate if (ask("Want to override? ")) { 1408*7c478bd9Sstevel@tonic-gate if (Otape) 1409*7c478bd9Sstevel@tonic-gate strncpy(V_labl.v_volume, tvol, 6); 1410*7c478bd9Sstevel@tonic-gate else 1411*7c478bd9Sstevel@tonic-gate strncpy(tvol, tlabl.v_volume, 6); 1412*7c478bd9Sstevel@tonic-gate return (1); 1413*7c478bd9Sstevel@tonic-gate } 1414*7c478bd9Sstevel@tonic-gate return (0); 1415*7c478bd9Sstevel@tonic-gate } 1416*7c478bd9Sstevel@tonic-gate return (1); 1417*7c478bd9Sstevel@tonic-gate } 1418*7c478bd9Sstevel@tonic-gate 1419*7c478bd9Sstevel@tonic-gate /* 1420*7c478bd9Sstevel@tonic-gate * mklabel: Zero out and initialize a volcopy label. 1421*7c478bd9Sstevel@tonic-gate */ 1422*7c478bd9Sstevel@tonic-gate 1423*7c478bd9Sstevel@tonic-gate mklabel() 1424*7c478bd9Sstevel@tonic-gate { 1425*7c478bd9Sstevel@tonic-gate 1426*7c478bd9Sstevel@tonic-gate (void) memcpy(&V_labl, Empty, sizeof (V_labl)); 1427*7c478bd9Sstevel@tonic-gate if (!Eomflg) 1428*7c478bd9Sstevel@tonic-gate (void) strcpy(V_labl.v_magic, "Volcopy"); 1429*7c478bd9Sstevel@tonic-gate else 1430*7c478bd9Sstevel@tonic-gate (void) strcpy(V_labl.v_magic, "VOLCOPY"); 1431*7c478bd9Sstevel@tonic-gate } 1432*7c478bd9Sstevel@tonic-gate 1433*7c478bd9Sstevel@tonic-gate /* 1434*7c478bd9Sstevel@tonic-gate * rprt: Report activity to user. 1435*7c478bd9Sstevel@tonic-gate */ 1436*7c478bd9Sstevel@tonic-gate 1437*7c478bd9Sstevel@tonic-gate rprt() 1438*7c478bd9Sstevel@tonic-gate { 1439*7c478bd9Sstevel@tonic-gate 1440*7c478bd9Sstevel@tonic-gate if (Itape) 1441*7c478bd9Sstevel@tonic-gate (void) printf(gettext("\nReading ")); 1442*7c478bd9Sstevel@tonic-gate else /* Otape */ 1443*7c478bd9Sstevel@tonic-gate (void) printf(gettext("\nWriting ")); 1444*7c478bd9Sstevel@tonic-gate if (!Eomflg) 1445*7c478bd9Sstevel@tonic-gate (void) printf(gettext( 1446*7c478bd9Sstevel@tonic-gate "REEL %d of %d VOL = %.6s\n"), 1447*7c478bd9Sstevel@tonic-gate R_cur, R_num, In.f_vol_p); 1448*7c478bd9Sstevel@tonic-gate else 1449*7c478bd9Sstevel@tonic-gate (void) printf(gettext( 1450*7c478bd9Sstevel@tonic-gate "REEL %d of ? VOL = %.6s\n"), R_cur, In.f_vol_p); 1451*7c478bd9Sstevel@tonic-gate } 1452*7c478bd9Sstevel@tonic-gate 1453*7c478bd9Sstevel@tonic-gate #ifdef LOG 1454*7c478bd9Sstevel@tonic-gate /* 1455*7c478bd9Sstevel@tonic-gate * fslog: Log current activity. 1456*7c478bd9Sstevel@tonic-gate */ 1457*7c478bd9Sstevel@tonic-gate 1458*7c478bd9Sstevel@tonic-gate fslog() 1459*7c478bd9Sstevel@tonic-gate { 1460*7c478bd9Sstevel@tonic-gate FILE *fp = NULL; 1461*7c478bd9Sstevel@tonic-gate 1462*7c478bd9Sstevel@tonic-gate fp = fopen("/var/adm/filesave.log", "a"); 1463*7c478bd9Sstevel@tonic-gate if (fp == NULL) { 1464*7c478bd9Sstevel@tonic-gate perr(1, "volcopy: cannot open /var/adm/filesave.log\n"); 1465*7c478bd9Sstevel@tonic-gate } 1466*7c478bd9Sstevel@tonic-gate 1467*7c478bd9Sstevel@tonic-gate fprintf(fp, "%s%c%.6s%c%.6s -> %s%c%.6s%c%.6s on %.24s\n", 1468*7c478bd9Sstevel@tonic-gate In.f_dev_p, ';', Ifname, ';', Ifpack, Out.f_dev_p, 1469*7c478bd9Sstevel@tonic-gate ';', Ofname, ';', Ofpack, ctime(&Tvec)); 1470*7c478bd9Sstevel@tonic-gate fclose(fp); 1471*7c478bd9Sstevel@tonic-gate exit(0); 1472*7c478bd9Sstevel@tonic-gate } 1473*7c478bd9Sstevel@tonic-gate #endif /* LOG */ 1474*7c478bd9Sstevel@tonic-gate 1475*7c478bd9Sstevel@tonic-gate /* 1476*7c478bd9Sstevel@tonic-gate * getname: Get device name. 1477*7c478bd9Sstevel@tonic-gate */ 1478*7c478bd9Sstevel@tonic-gate 1479*7c478bd9Sstevel@tonic-gate getname(nam_p) 1480*7c478bd9Sstevel@tonic-gate register char *nam_p; 1481*7c478bd9Sstevel@tonic-gate { 1482*7c478bd9Sstevel@tonic-gate register int lastchar; 1483*7c478bd9Sstevel@tonic-gate char nam_buf[21]; 1484*7c478bd9Sstevel@tonic-gate 1485*7c478bd9Sstevel@tonic-gate nam_buf[0] = '\0'; 1486*7c478bd9Sstevel@tonic-gate (void) printf(gettext("Changing drives? (type RETURN for no,\n")); 1487*7c478bd9Sstevel@tonic-gate (void) printf(gettext("\t`/dev/rmt/??\' or `/dev/rtp/??\' for yes: ")); 1488*7c478bd9Sstevel@tonic-gate fgets(nam_buf, 20, Devtty); 1489*7c478bd9Sstevel@tonic-gate nam_buf[20] = '\0'; 1490*7c478bd9Sstevel@tonic-gate lastchar = strlen(nam_buf) - 1; 1491*7c478bd9Sstevel@tonic-gate if (nam_buf[lastchar] == '\n') 1492*7c478bd9Sstevel@tonic-gate nam_buf[lastchar] = '\0'; /* remove it */ 1493*7c478bd9Sstevel@tonic-gate if (nam_buf[0] != '\0') 1494*7c478bd9Sstevel@tonic-gate (void) strcpy(nam_p, nam_buf); 1495*7c478bd9Sstevel@tonic-gate } 1496*7c478bd9Sstevel@tonic-gate 1497*7c478bd9Sstevel@tonic-gate /* 1498*7c478bd9Sstevel@tonic-gate * chgreel: Change reel on end-of-media. 1499*7c478bd9Sstevel@tonic-gate */ 1500*7c478bd9Sstevel@tonic-gate 1501*7c478bd9Sstevel@tonic-gate chgreel(f_p, dir) 1502*7c478bd9Sstevel@tonic-gate register struct file_info *f_p; 1503*7c478bd9Sstevel@tonic-gate register int dir; 1504*7c478bd9Sstevel@tonic-gate { 1505*7c478bd9Sstevel@tonic-gate register int again = 1, lastchar, temp; 1506*7c478bd9Sstevel@tonic-gate char vol_tmp[11]; 1507*7c478bd9Sstevel@tonic-gate 1508*7c478bd9Sstevel@tonic-gate R_cur++; 1509*7c478bd9Sstevel@tonic-gate while (again) { 1510*7c478bd9Sstevel@tonic-gate again = 0; 1511*7c478bd9Sstevel@tonic-gate errno = 0; 1512*7c478bd9Sstevel@tonic-gate (void) close(f_p->f_des); 1513*7c478bd9Sstevel@tonic-gate (void) getname(f_p->f_dev_p); 1514*7c478bd9Sstevel@tonic-gate (void) printf(gettext( 1515*7c478bd9Sstevel@tonic-gate "Mount tape %d\nType volume-ID when ready: "), R_cur); 1516*7c478bd9Sstevel@tonic-gate vol_tmp[0] = '\0'; 1517*7c478bd9Sstevel@tonic-gate fgets(vol_tmp, 10, Devtty); 1518*7c478bd9Sstevel@tonic-gate vol_tmp[10] = '\0'; 1519*7c478bd9Sstevel@tonic-gate lastchar = strlen(vol_tmp) - 1; 1520*7c478bd9Sstevel@tonic-gate if (vol_tmp[lastchar] == '\n') 1521*7c478bd9Sstevel@tonic-gate vol_tmp[lastchar] = '\0'; /* remove it */ 1522*7c478bd9Sstevel@tonic-gate if (vol_tmp[0] != '\0') { /* if null string, use old vol-id */ 1523*7c478bd9Sstevel@tonic-gate strncpy(f_p->f_vol_p, vol_tmp, 6); 1524*7c478bd9Sstevel@tonic-gate strncpy(V_labl.v_volume, vol_tmp, 6); 1525*7c478bd9Sstevel@tonic-gate } 1526*7c478bd9Sstevel@tonic-gate errno = 0; 1527*7c478bd9Sstevel@tonic-gate f_p->f_des = open(f_p->f_dev_p, 0); 1528*7c478bd9Sstevel@tonic-gate if (f_p->f_des <= 0 || f_p->f_des > 10) { 1529*7c478bd9Sstevel@tonic-gate if (dir == INPUT) 1530*7c478bd9Sstevel@tonic-gate perror("input ERR"); 1531*7c478bd9Sstevel@tonic-gate else 1532*7c478bd9Sstevel@tonic-gate perror("output ERR"); 1533*7c478bd9Sstevel@tonic-gate } 1534*7c478bd9Sstevel@tonic-gate errno = 0; 1535*7c478bd9Sstevel@tonic-gate if (g_init(&(f_p->f_dev), &(f_p->f_des)) < 0) 1536*7c478bd9Sstevel@tonic-gate perr(0, "Initialization error %d\n", errno); 1537*7c478bd9Sstevel@tonic-gate if ((f_p->f_dev != G_TM_TAPE) && (f_p->f_dev != G_XT_TAPE) && 1538*7c478bd9Sstevel@tonic-gate (f_p->f_dev != G_ST_TAPE)) { 1539*7c478bd9Sstevel@tonic-gate (void) printf(gettext( 1540*7c478bd9Sstevel@tonic-gate "\n'%s' is not a valid device"), f_p->f_dev_p); 1541*7c478bd9Sstevel@tonic-gate (void) printf(gettext( 1542*7c478bd9Sstevel@tonic-gate "\n\tenter device name `/dev/rmt/??\' or `/dev/rtp/??\' :")); 1543*7c478bd9Sstevel@tonic-gate again = 1; 1544*7c478bd9Sstevel@tonic-gate continue; 1545*7c478bd9Sstevel@tonic-gate } 1546*7c478bd9Sstevel@tonic-gate if (!hdrck(f_p->f_dev, f_p->f_des, f_p->f_vol_p)) { 1547*7c478bd9Sstevel@tonic-gate again = 1; 1548*7c478bd9Sstevel@tonic-gate continue; 1549*7c478bd9Sstevel@tonic-gate } 1550*7c478bd9Sstevel@tonic-gate switch (dir) { 1551*7c478bd9Sstevel@tonic-gate case INPUT: 1552*7c478bd9Sstevel@tonic-gate if (V_labl.v_reel != R_cur) { 1553*7c478bd9Sstevel@tonic-gate perr(0, "Need reel %d, label says reel %d\n", 1554*7c478bd9Sstevel@tonic-gate R_cur, V_labl.v_reel); 1555*7c478bd9Sstevel@tonic-gate again = 1; 1556*7c478bd9Sstevel@tonic-gate continue; 1557*7c478bd9Sstevel@tonic-gate } 1558*7c478bd9Sstevel@tonic-gate break; 1559*7c478bd9Sstevel@tonic-gate case OUTPUT: 1560*7c478bd9Sstevel@tonic-gate V_labl.v_reel = R_cur; 1561*7c478bd9Sstevel@tonic-gate temp = V_labl.v_offset; 1562*7c478bd9Sstevel@tonic-gate V_labl.v_offset /= BUFSIZ; 1563*7c478bd9Sstevel@tonic-gate close(f_p->f_des); 1564*7c478bd9Sstevel@tonic-gate sleep(2); 1565*7c478bd9Sstevel@tonic-gate errno = 0; 1566*7c478bd9Sstevel@tonic-gate f_p->f_des = open(f_p->f_dev_p, 1); 1567*7c478bd9Sstevel@tonic-gate if (f_p->f_des <= 0 || f_p->f_des > 10) 1568*7c478bd9Sstevel@tonic-gate perror("output ERR"); 1569*7c478bd9Sstevel@tonic-gate errno = 0; 1570*7c478bd9Sstevel@tonic-gate if (g_init(&(f_p->f_dev), &(f_p->f_des)) < 0) 1571*7c478bd9Sstevel@tonic-gate perr(1, "Initialization error %d\n", errno); 1572*7c478bd9Sstevel@tonic-gate errno = 0; 1573*7c478bd9Sstevel@tonic-gate if (g_write(f_p->f_dev, f_p->f_des, &V_labl, 1574*7c478bd9Sstevel@tonic-gate sizeof (V_labl)) < 0) { 1575*7c478bd9Sstevel@tonic-gate perr(0, "Cannot re-write header -Try again!\n"); 1576*7c478bd9Sstevel@tonic-gate again = 1; 1577*7c478bd9Sstevel@tonic-gate V_labl.v_offset = temp; 1578*7c478bd9Sstevel@tonic-gate continue; 1579*7c478bd9Sstevel@tonic-gate } 1580*7c478bd9Sstevel@tonic-gate V_labl.v_offset = temp; 1581*7c478bd9Sstevel@tonic-gate break; 1582*7c478bd9Sstevel@tonic-gate default: 1583*7c478bd9Sstevel@tonic-gate perr(1, "Impossible case\n"); 1584*7c478bd9Sstevel@tonic-gate } /* dir */ 1585*7c478bd9Sstevel@tonic-gate } /* again */ 1586*7c478bd9Sstevel@tonic-gate rprt(); 1587*7c478bd9Sstevel@tonic-gate } 1588*7c478bd9Sstevel@tonic-gate 1589*7c478bd9Sstevel@tonic-gate /* 1590*7c478bd9Sstevel@tonic-gate * perr: Print error messages. 1591*7c478bd9Sstevel@tonic-gate */ 1592*7c478bd9Sstevel@tonic-gate 1593*7c478bd9Sstevel@tonic-gate static void 1594*7c478bd9Sstevel@tonic-gate perr(int severity, const char *fmt, ...) 1595*7c478bd9Sstevel@tonic-gate { 1596*7c478bd9Sstevel@tonic-gate va_list ap; 1597*7c478bd9Sstevel@tonic-gate 1598*7c478bd9Sstevel@tonic-gate va_start(ap, fmt); 1599*7c478bd9Sstevel@tonic-gate (void) fflush(stdout); 1600*7c478bd9Sstevel@tonic-gate (void) fflush(stderr); 1601*7c478bd9Sstevel@tonic-gate if (severity == 10) { 1602*7c478bd9Sstevel@tonic-gate (void) vfprintf(stdout, gettext(fmt), ap); 1603*7c478bd9Sstevel@tonic-gate (void) fprintf(stdout, gettext( 1604*7c478bd9Sstevel@tonic-gate "\t%d reel(s) completed\n"), --R_cur); 1605*7c478bd9Sstevel@tonic-gate (void) fflush(stdout); 1606*7c478bd9Sstevel@tonic-gate (void) fflush(stderr); 1607*7c478bd9Sstevel@tonic-gate cleanup(); 1608*7c478bd9Sstevel@tonic-gate exit(31+9); 1609*7c478bd9Sstevel@tonic-gate } 1610*7c478bd9Sstevel@tonic-gate (void) vfprintf(stderr, gettext(fmt), ap); 1611*7c478bd9Sstevel@tonic-gate (void) fflush(stderr); 1612*7c478bd9Sstevel@tonic-gate va_end(ap); 1613*7c478bd9Sstevel@tonic-gate if (severity > 0) { 1614*7c478bd9Sstevel@tonic-gate (void) cleanup(); 1615*7c478bd9Sstevel@tonic-gate exit(31+severity); 1616*7c478bd9Sstevel@tonic-gate } 1617*7c478bd9Sstevel@tonic-gate } 1618*7c478bd9Sstevel@tonic-gate 1619*7c478bd9Sstevel@tonic-gate 1620*7c478bd9Sstevel@tonic-gate static void 1621*7c478bd9Sstevel@tonic-gate getinfs(dev, fd, buf) 1622*7c478bd9Sstevel@tonic-gate int dev; 1623*7c478bd9Sstevel@tonic-gate int fd; 1624*7c478bd9Sstevel@tonic-gate char *buf; 1625*7c478bd9Sstevel@tonic-gate { 1626*7c478bd9Sstevel@tonic-gate int cnt; 1627*7c478bd9Sstevel@tonic-gate int i; 1628*7c478bd9Sstevel@tonic-gate 1629*7c478bd9Sstevel@tonic-gate if (lseek(fd, SBLOCK * DEV_BSIZE, 0) != SBLOCK * DEV_BSIZE) { 1630*7c478bd9Sstevel@tonic-gate perr(10, "Unable to lseek on input\n"); 1631*7c478bd9Sstevel@tonic-gate } 1632*7c478bd9Sstevel@tonic-gate cnt = SBSIZE/DEV_BSIZE; 1633*7c478bd9Sstevel@tonic-gate for (i = 0; i < cnt; i++) { 1634*7c478bd9Sstevel@tonic-gate if (g_read(dev, fd, (char *)buf + i*DEV_BSIZE, DEV_BSIZE) 1635*7c478bd9Sstevel@tonic-gate != DEV_BSIZE) { 1636*7c478bd9Sstevel@tonic-gate perr(10, "Unable to read on input\n"); 1637*7c478bd9Sstevel@tonic-gate } 1638*7c478bd9Sstevel@tonic-gate } 1639*7c478bd9Sstevel@tonic-gate } 1640*7c478bd9Sstevel@tonic-gate 1641*7c478bd9Sstevel@tonic-gate static void 1642*7c478bd9Sstevel@tonic-gate getoutfs(dev, fd, buf, verify) 1643*7c478bd9Sstevel@tonic-gate int dev; 1644*7c478bd9Sstevel@tonic-gate int fd; 1645*7c478bd9Sstevel@tonic-gate char *buf; 1646*7c478bd9Sstevel@tonic-gate int verify; 1647*7c478bd9Sstevel@tonic-gate { 1648*7c478bd9Sstevel@tonic-gate int cnt; 1649*7c478bd9Sstevel@tonic-gate int i; 1650*7c478bd9Sstevel@tonic-gate 1651*7c478bd9Sstevel@tonic-gate errno = 0; 1652*7c478bd9Sstevel@tonic-gate if (lseek(fd, SBLOCK * DEV_BSIZE, 0) != SBLOCK * DEV_BSIZE) { 1653*7c478bd9Sstevel@tonic-gate prompt(verify, "Unable to lseek on output\n", errno); 1654*7c478bd9Sstevel@tonic-gate } 1655*7c478bd9Sstevel@tonic-gate cnt = SBSIZE/DEV_BSIZE; 1656*7c478bd9Sstevel@tonic-gate for (i = 0; i < cnt; i++) { 1657*7c478bd9Sstevel@tonic-gate if (g_read(dev, fd, (char *)buf + i*DEV_BSIZE, DEV_BSIZE) 1658*7c478bd9Sstevel@tonic-gate != DEV_BSIZE) { 1659*7c478bd9Sstevel@tonic-gate prompt(verify, "Unable to read on output\n", errno); 1660*7c478bd9Sstevel@tonic-gate } 1661*7c478bd9Sstevel@tonic-gate } 1662*7c478bd9Sstevel@tonic-gate } 1663*7c478bd9Sstevel@tonic-gate 1664*7c478bd9Sstevel@tonic-gate static char * 1665*7c478bd9Sstevel@tonic-gate getfslabel(sb) 1666*7c478bd9Sstevel@tonic-gate struct fs *sb; 1667*7c478bd9Sstevel@tonic-gate { 1668*7c478bd9Sstevel@tonic-gate int i; 1669*7c478bd9Sstevel@tonic-gate int blk; 1670*7c478bd9Sstevel@tonic-gate 1671*7c478bd9Sstevel@tonic-gate /* 1672*7c478bd9Sstevel@tonic-gate * is there room for label? 1673*7c478bd9Sstevel@tonic-gate */ 1674*7c478bd9Sstevel@tonic-gate 1675*7c478bd9Sstevel@tonic-gate if (sb->fs_cpc <= 0) 1676*7c478bd9Sstevel@tonic-gate return (nolabel); 1677*7c478bd9Sstevel@tonic-gate 1678*7c478bd9Sstevel@tonic-gate /* 1679*7c478bd9Sstevel@tonic-gate * calculate the available blocks for each rotational position 1680*7c478bd9Sstevel@tonic-gate */ 1681*7c478bd9Sstevel@tonic-gate blk = sb->fs_spc * sb->fs_cpc / sb->fs_nspf; 1682*7c478bd9Sstevel@tonic-gate for (i = 0; i < blk; i += sb->fs_frag) 1683*7c478bd9Sstevel@tonic-gate /* void */; 1684*7c478bd9Sstevel@tonic-gate i -= sb->fs_frag; 1685*7c478bd9Sstevel@tonic-gate blk = i / sb->fs_frag; 1686*7c478bd9Sstevel@tonic-gate 1687*7c478bd9Sstevel@tonic-gate return ((char *)&(fs_rotbl(sb)[blk])); 1688*7c478bd9Sstevel@tonic-gate } 1689*7c478bd9Sstevel@tonic-gate 1690*7c478bd9Sstevel@tonic-gate static char * 1691*7c478bd9Sstevel@tonic-gate getvolabel(sb) 1692*7c478bd9Sstevel@tonic-gate struct fs *sb; 1693*7c478bd9Sstevel@tonic-gate { 1694*7c478bd9Sstevel@tonic-gate char *p; 1695*7c478bd9Sstevel@tonic-gate int i; 1696*7c478bd9Sstevel@tonic-gate 1697*7c478bd9Sstevel@tonic-gate p = getfslabel(sb); 1698*7c478bd9Sstevel@tonic-gate 1699*7c478bd9Sstevel@tonic-gate if (p == nolabel || p == NULL) 1700*7c478bd9Sstevel@tonic-gate return (nolabel); 1701*7c478bd9Sstevel@tonic-gate 1702*7c478bd9Sstevel@tonic-gate for (i = 0; *p && i < 6; p++, i++) 1703*7c478bd9Sstevel@tonic-gate ; 1704*7c478bd9Sstevel@tonic-gate p++; 1705*7c478bd9Sstevel@tonic-gate return (p); 1706*7c478bd9Sstevel@tonic-gate } 1707