00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef lint
00035 #if 0
00036 static char sccsid[] = "@(#)ar_io.c 8.2 (Berkeley) 4/18/94";
00037 #endif
00038 #endif
00039
00040 #include <sys/types.h>
00041 #include <sys/ioctl.h>
00042 #include <sys/mtio.h>
00043 #include <sys/stat.h>
00044 #include <sys/wait.h>
00045 #include <errno.h>
00046 #include <fcntl.h>
00047 #include <signal.h>
00048 #include <stdint.h>
00049 #include <stdio.h>
00050 #include <string.h>
00051 #include <stdlib.h>
00052 #include <unistd.h>
00053 #include "pax.h"
00054 #include "options.h"
00055 #include "extern.h"
00056
00057
00058
00059
00060
00061 #define DMOD 0666
00062 #define EXT_MODE O_RDONLY
00063 #define AR_MODE (O_WRONLY | O_CREAT | O_TRUNC)
00064 #define APP_MODE O_RDWR
00065
00066 static char none[] = "<NONE>";
00067 static char stdo[] = "<STDOUT>";
00068 static char stdn[] = "<STDIN>";
00069 static int arfd = -1;
00070 static int artyp = ISREG;
00071 static int arvol = 1;
00072 static int lstrval = -1;
00073 static int io_ok;
00074 static int did_io;
00075 static int done;
00076 static struct stat arsb;
00077 static int invld_rec;
00078 static int wr_trail = 1;
00079 static int can_unlnk = 0;
00080 const char *arcname;
00081 const char *gzip_program;
00082 static pid_t zpid = -1;
00083
00084 static int get_phys(void);
00085 extern sigset_t s_mask;
00086 static void ar_start_gzip(int, const char *, int);
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 int
00098 ar_open(const char *name)
00099 {
00100 struct mtget mb;
00101
00102 if (arfd != -1)
00103 (void)close(arfd);
00104 arfd = -1;
00105 can_unlnk = did_io = io_ok = invld_rec = 0;
00106 artyp = ISREG;
00107 flcnt = 0;
00108
00109
00110
00111
00112 switch (act) {
00113 case LIST:
00114 case EXTRACT:
00115 if (name == NULL) {
00116 arfd = STDIN_FILENO;
00117 arcname = stdn;
00118 } else if ((arfd = open(name, EXT_MODE, DMOD)) < 0)
00119 syswarn(0, errno, "Failed open to read on %s", name);
00120 if (arfd != -1 && gzip_program != NULL)
00121 ar_start_gzip(arfd, gzip_program, 0);
00122 break;
00123 case ARCHIVE:
00124 if (name == NULL) {
00125 arfd = STDOUT_FILENO;
00126 arcname = stdo;
00127 } else if ((arfd = open(name, AR_MODE, DMOD)) < 0)
00128 syswarn(0, errno, "Failed open to write on %s", name);
00129 else
00130 can_unlnk = 1;
00131 if (arfd != -1 && gzip_program != NULL)
00132 ar_start_gzip(arfd, gzip_program, 1);
00133 break;
00134 case APPND:
00135 if (name == NULL) {
00136 arfd = STDOUT_FILENO;
00137 arcname = stdo;
00138 } else if ((arfd = open(name, APP_MODE, DMOD)) < 0)
00139 syswarn(0, errno, "Failed open to read/write on %s",
00140 name);
00141 break;
00142 case COPY:
00143
00144
00145
00146 arcname = none;
00147 lstrval = 1;
00148 return(0);
00149 }
00150 if (arfd < 0)
00151 return(-1);
00152
00153 if (chdname != NULL)
00154 if (chdir(chdname) != 0) {
00155 syswarn(1, errno, "Failed chdir to %s", chdname);
00156 return(-1);
00157 }
00158
00159
00160
00161 if (fstat(arfd, &arsb) < 0) {
00162 syswarn(0, errno, "Failed stat on %s", arcname);
00163 (void)close(arfd);
00164 arfd = -1;
00165 can_unlnk = 0;
00166 return(-1);
00167 }
00168 if (S_ISDIR(arsb.st_mode)) {
00169 paxwarn(0, "Cannot write an archive on top of a directory %s",
00170 arcname);
00171 (void)close(arfd);
00172 arfd = -1;
00173 can_unlnk = 0;
00174 return(-1);
00175 }
00176
00177 if (S_ISCHR(arsb.st_mode))
00178 artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE;
00179 else if (S_ISBLK(arsb.st_mode))
00180 artyp = ISBLK;
00181 else if ((lseek(arfd, (off_t)0L, SEEK_CUR) == -1) && (errno == ESPIPE))
00182 artyp = ISPIPE;
00183 else
00184 artyp = ISREG;
00185
00186
00187
00188
00189
00190 if (artyp != ISREG)
00191 can_unlnk = 0;
00192
00193
00194
00195 if (act == ARCHIVE) {
00196 blksz = rdblksz = wrblksz;
00197 lstrval = 1;
00198 return(0);
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208 switch(artyp) {
00209 case ISTAPE:
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 blksz = rdblksz = MAXBLK;
00225 break;
00226 case ISPIPE:
00227 case ISBLK:
00228 case ISCHR:
00229
00230
00231
00232
00233
00234
00235
00236
00237 if ((act == APPND) && wrblksz) {
00238 blksz = rdblksz = wrblksz;
00239 break;
00240 }
00241
00242 #if 0
00243 if ((arsb.st_blksize > 0) && (arsb.st_blksize < MAXBLK) &&
00244 ((arsb.st_blksize % BLKMULT) == 0))
00245 rdblksz = arsb.st_blksize;
00246 else
00247 #endif
00248 rdblksz = DEVBLK;
00249
00250
00251
00252 if ((act == APPND) || (artyp == ISCHR))
00253 blksz = rdblksz;
00254 else
00255 blksz = MAXBLK;
00256 break;
00257 case ISREG:
00258
00259
00260
00261
00262 if ((act == APPND) && wrblksz && ((arsb.st_size%wrblksz)==0)){
00263 blksz = rdblksz = wrblksz;
00264 break;
00265 }
00266
00267
00268
00269 for (rdblksz = MAXBLK; rdblksz > 0; rdblksz -= BLKMULT)
00270 if ((arsb.st_size % rdblksz) == 0)
00271 break;
00272
00273
00274
00275 if (rdblksz <= 0)
00276 rdblksz = FILEBLK;
00277
00278
00279
00280 if (act == APPND)
00281 blksz = rdblksz;
00282 else
00283 blksz = MAXBLK;
00284 break;
00285 default:
00286
00287
00288
00289 blksz = rdblksz = BLKMULT;
00290 break;
00291 }
00292 lstrval = 1;
00293 return(0);
00294 }
00295
00296
00297
00298
00299
00300 void
00301 ar_close(void)
00302 {
00303 int status;
00304
00305 if (arfd < 0) {
00306 did_io = io_ok = flcnt = 0;
00307 return;
00308 }
00309
00310
00311
00312
00313
00314
00315
00316 if (vflag && (artyp == ISTAPE)) {
00317 if (vfpart)
00318 (void)putc('\n', listf);
00319 (void)fprintf(listf,
00320 "%s: Waiting for tape drive close to complete...",
00321 argv0);
00322 (void)fflush(listf);
00323 }
00324
00325
00326
00327
00328
00329 if (can_unlnk && (fstat(arfd, &arsb) == 0) && (S_ISREG(arsb.st_mode)) &&
00330 (arsb.st_size == 0)) {
00331 (void)unlink(arcname);
00332 can_unlnk = 0;
00333 }
00334
00335
00336
00337
00338
00339 if ((act == LIST || act == EXTRACT) && nflag && zpid > 0)
00340 kill(zpid, SIGINT);
00341
00342 (void)close(arfd);
00343
00344
00345 if (zpid > 0)
00346 waitpid(zpid, &status, 0);
00347
00348 if (vflag && (artyp == ISTAPE)) {
00349 (void)fputs("done.\n", listf);
00350 vfpart = 0;
00351 (void)fflush(listf);
00352 }
00353 arfd = -1;
00354
00355 if (!io_ok && !did_io) {
00356 flcnt = 0;
00357 return;
00358 }
00359 did_io = io_ok = 0;
00360
00361
00362
00363
00364
00365 if (frmt != NULL)
00366 ++arvol;
00367
00368 if (!vflag) {
00369 flcnt = 0;
00370 return;
00371 }
00372
00373
00374
00375
00376 if (vfpart) {
00377 (void)putc('\n', listf);
00378 vfpart = 0;
00379 }
00380
00381
00382
00383
00384
00385
00386 if (frmt == NULL) {
00387 # ifdef NET2_STAT
00388 (void)fprintf(listf, "%s: unknown format, %lu bytes skipped.\n",
00389 argv0, rdcnt);
00390 # else
00391 (void)fprintf(listf, "%s: unknown format, %ju bytes skipped.\n",
00392 argv0, (uintmax_t)rdcnt);
00393 # endif
00394 (void)fflush(listf);
00395 flcnt = 0;
00396 return;
00397 }
00398
00399 if (strcmp(NM_CPIO, argv0) == 0)
00400 (void)fprintf(listf, "%llu blocks\n",
00401 (unsigned long)((rdcnt ? rdcnt : wrcnt) / 5120));
00402 else if (strcmp(NM_TAR, argv0) != 0)
00403 (void)fprintf(listf,
00404 # ifdef NET2_STAT
00405 "%s: %s vol %d, %lu files, %lu bytes read, %lu bytes written.\n",
00406 argv0, frmt->name, arvol-1, flcnt, rdcnt, wrcnt);
00407 # else
00408 "%s: %s vol %d, %ju files, %ju bytes read, %ju bytes written.\n",
00409 argv0, frmt->name, arvol-1, (uintmax_t)flcnt,
00410 (uintmax_t)rdcnt, (uintmax_t)wrcnt);
00411 # endif
00412 (void)fflush(listf);
00413 flcnt = 0;
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423 void
00424 ar_drain(void)
00425 {
00426 int res;
00427 char drbuf[MAXBLK];
00428
00429
00430
00431
00432
00433
00434 if ((artyp != ISPIPE) || (lstrval <= 0))
00435 return;
00436
00437
00438
00439
00440 while ((res = read(arfd, drbuf, sizeof(drbuf))) > 0)
00441 ;
00442 lstrval = res;
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 int
00456 ar_set_wr(void)
00457 {
00458 off_t cpos;
00459
00460
00461
00462
00463
00464 wr_trail = 0;
00465
00466
00467
00468
00469 if (artyp != ISREG)
00470 return(0);
00471
00472
00473
00474
00475
00476 if (((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) ||
00477 (ftruncate(arfd, cpos) < 0)) {
00478 syswarn(1, errno, "Unable to truncate archive file");
00479 return(-1);
00480 }
00481 return(0);
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493 int
00494 ar_app_ok(void)
00495 {
00496 if (artyp == ISPIPE) {
00497 paxwarn(1, "Cannot append to an archive obtained from a pipe.");
00498 return(-1);
00499 }
00500
00501 if (!invld_rec)
00502 return(0);
00503 paxwarn(1,"Cannot append, device record size %d does not support %s spec",
00504 rdblksz, argv0);
00505 return(-1);
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517 int
00518 ar_read(char *buf, int cnt)
00519 {
00520 int res = 0;
00521
00522
00523
00524
00525 if (lstrval <= 0)
00526 return(lstrval);
00527
00528
00529
00530
00531 switch (artyp) {
00532 case ISTAPE:
00533 if ((res = read(arfd, buf, cnt)) > 0) {
00534
00535
00536
00537
00538
00539
00540
00541 io_ok = 1;
00542 if (res != rdblksz) {
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 rdblksz = res;
00553 if (rdblksz % BLKMULT)
00554 invld_rec = 1;
00555 }
00556 return(res);
00557 }
00558 break;
00559 case ISREG:
00560 case ISBLK:
00561 case ISCHR:
00562 case ISPIPE:
00563 default:
00564
00565
00566
00567
00568
00569
00570
00571 if ((res = read(arfd, buf, cnt)) > 0) {
00572 io_ok = 1;
00573 return(res);
00574 }
00575 break;
00576 }
00577
00578
00579
00580
00581 lstrval = res;
00582 if (res < 0)
00583 syswarn(1, errno, "Failed read on archive volume %d", arvol);
00584 else
00585 paxwarn(0, "End of archive volume %d reached", arvol);
00586 return(res);
00587 }
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 int
00601 ar_write(char *buf, int bsz)
00602 {
00603 int res;
00604 off_t cpos;
00605
00606
00607
00608
00609
00610 if (lstrval <= 0)
00611 return(lstrval);
00612
00613 if ((res = write(arfd, buf, bsz)) == bsz) {
00614 wr_trail = 1;
00615 io_ok = 1;
00616 return(bsz);
00617 }
00618
00619
00620
00621
00622 if (res < 0)
00623 lstrval = res;
00624 else
00625 lstrval = 0;
00626
00627 switch (artyp) {
00628 case ISREG:
00629 if ((res > 0) && (res % BLKMULT)) {
00630
00631
00632
00633
00634
00635 if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
00636 break;
00637 cpos -= (off_t)res;
00638 if (ftruncate(arfd, cpos) < 0)
00639 break;
00640 res = lstrval = 0;
00641 break;
00642 }
00643 if (res >= 0)
00644 break;
00645
00646
00647
00648 if ((errno == ENOSPC) || (errno == EFBIG)
00649 #ifdef EDQUOT
00650 || (errno == EDQUOT)
00651 #endif
00652 )
00653 res = lstrval = 0;
00654 break;
00655 case ISTAPE:
00656 case ISCHR:
00657 case ISBLK:
00658 if (res >= 0)
00659 break;
00660 if (errno == EACCES) {
00661 paxwarn(0, "Write failed, archive is write protected.");
00662 res = lstrval = 0;
00663 return(0);
00664 }
00665
00666
00667
00668
00669 if ((errno == ENOSPC) || (errno == EIO) || (errno == ENXIO))
00670 res = lstrval = 0;
00671 break;
00672 case ISPIPE:
00673 default:
00674
00675
00676
00677 break;
00678 }
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688 if (res >= 0) {
00689 if (res > 0)
00690 wr_trail = 1;
00691 io_ok = 1;
00692 }
00693
00694
00695
00696
00697
00698 if (!wr_trail && (res <= 0)) {
00699 paxwarn(1,"Unable to append, trailer re-write failed. Quitting.");
00700 return(res);
00701 }
00702
00703 if (res == 0)
00704 paxwarn(0, "End of archive volume %d reached", arvol);
00705 else if (res < 0)
00706 syswarn(1, errno, "Failed write to archive volume: %d", arvol);
00707 else if (!frmt->blkalgn || ((res % frmt->blkalgn) == 0))
00708 paxwarn(0,"WARNING: partial archive write. Archive MAY BE FLAWED");
00709 else
00710 paxwarn(1,"WARNING: partial archive write. Archive IS FLAWED");
00711 return(res);
00712 }
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722 int
00723 ar_rdsync(void)
00724 {
00725 long fsbz;
00726 off_t cpos;
00727 off_t mpos;
00728 struct mtop mb;
00729
00730
00731
00732
00733
00734
00735 if ((done > 0) || (lstrval == 0))
00736 return(-1);
00737
00738 if ((act == APPND) || (act == ARCHIVE)) {
00739 paxwarn(1, "Cannot allow updates to an archive with flaws.");
00740 return(-1);
00741 }
00742 if (io_ok)
00743 did_io = 1;
00744
00745 switch(artyp) {
00746 case ISTAPE:
00747
00748
00749
00750
00751
00752
00753
00754
00755 if (io_ok) {
00756 io_ok = 0;
00757 lstrval = 1;
00758 break;
00759 }
00760 mb.mt_op = MTFSR;
00761 mb.mt_count = 1;
00762 if (ioctl(arfd, MTIOCTOP, &mb) < 0)
00763 break;
00764 lstrval = 1;
00765 break;
00766 case ISREG:
00767 case ISCHR:
00768 case ISBLK:
00769
00770
00771
00772 io_ok = 0;
00773 #if 0
00774
00775 if (((fsbz = arsb.st_blksize) <= 0) || (artyp != ISREG))
00776 #endif
00777 fsbz = BLKMULT;
00778 if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0)
00779 break;
00780 mpos = fsbz - (cpos % (off_t)fsbz);
00781 if (lseek(arfd, mpos, SEEK_CUR) < 0)
00782 break;
00783 lstrval = 1;
00784 break;
00785 case ISPIPE:
00786 default:
00787
00788
00789
00790 io_ok = 0;
00791 break;
00792 }
00793 if (lstrval <= 0) {
00794 paxwarn(1, "Unable to recover from an archive read failure.");
00795 return(-1);
00796 }
00797 paxwarn(0, "Attempting to recover from an archive read failure.");
00798 return(0);
00799 }
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 int
00812 ar_fow(off_t sksz, off_t *skipped)
00813 {
00814 off_t cpos;
00815 off_t mpos;
00816
00817 *skipped = 0;
00818 if (sksz <= 0)
00819 return(0);
00820
00821
00822
00823
00824 if (lstrval <= 0)
00825 return(lstrval);
00826
00827
00828
00829
00830
00831
00832
00833 if (artyp != ISREG)
00834 return(0);
00835
00836
00837
00838
00839 if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) >= 0) {
00840
00841
00842
00843
00844
00845
00846 if ((mpos = cpos + sksz) > arsb.st_size) {
00847 *skipped = arsb.st_size - cpos;
00848 mpos = arsb.st_size;
00849 } else
00850 *skipped = sksz;
00851 if (lseek(arfd, mpos, SEEK_SET) >= 0)
00852 return(0);
00853 }
00854 syswarn(1, errno, "Forward positioning operation on archive failed");
00855 lstrval = -1;
00856 return(-1);
00857 }
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870 int
00871 ar_rev(off_t sksz)
00872 {
00873 off_t cpos;
00874 struct mtop mb;
00875 int phyblk;
00876
00877
00878
00879
00880 if (lstrval < 0)
00881 return(lstrval);
00882
00883 switch(artyp) {
00884 case ISPIPE:
00885 if (sksz <= 0)
00886 break;
00887
00888
00889
00890 paxwarn(1, "Reverse positioning on pipes is not supported.");
00891 lstrval = -1;
00892 return(-1);
00893 case ISREG:
00894 case ISBLK:
00895 case ISCHR:
00896 default:
00897 if (sksz <= 0)
00898 break;
00899
00900
00901
00902
00903
00904
00905
00906
00907 if ((cpos = lseek(arfd, (off_t)0L, SEEK_CUR)) < 0) {
00908 syswarn(1, errno,
00909 "Unable to obtain current archive byte offset");
00910 lstrval = -1;
00911 return(-1);
00912 }
00913
00914
00915
00916
00917
00918
00919
00920
00921 if ((cpos -= sksz) < (off_t)0L) {
00922 if (arvol > 1) {
00923
00924
00925
00926 paxwarn(1,"Reverse position on previous volume.");
00927 lstrval = -1;
00928 return(-1);
00929 }
00930 cpos = (off_t)0L;
00931 }
00932 if (lseek(arfd, cpos, SEEK_SET) < 0) {
00933 syswarn(1, errno, "Unable to seek archive backwards");
00934 lstrval = -1;
00935 return(-1);
00936 }
00937 break;
00938 case ISTAPE:
00939
00940
00941
00942
00943
00944
00945
00946 if ((phyblk = get_phys()) <= 0) {
00947 lstrval = -1;
00948 return(-1);
00949 }
00950
00951
00952
00953
00954
00955 rdblksz = phyblk;
00956
00957
00958
00959
00960
00961 if (sksz <= 0)
00962 break;
00963
00964
00965
00966
00967 if (sksz % phyblk) {
00968 paxwarn(1,
00969 "Tape drive unable to backspace requested amount");
00970 lstrval = -1;
00971 return(-1);
00972 }
00973
00974
00975
00976
00977 mb.mt_op = MTBSR;
00978 mb.mt_count = sksz/phyblk;
00979 if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
00980 syswarn(1,errno, "Unable to backspace tape %d blocks.",
00981 mb.mt_count);
00982 lstrval = -1;
00983 return(-1);
00984 }
00985 break;
00986 }
00987 lstrval = 1;
00988 return(0);
00989 }
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002 static int
01003 get_phys(void)
01004 {
01005 int padsz = 0;
01006 int res;
01007 int phyblk;
01008 struct mtop mb;
01009 char scbuf[MAXBLK];
01010
01011
01012
01013
01014
01015 if (lstrval == 1) {
01016
01017
01018
01019
01020 while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
01021 padsz += res;
01022 if (res < 0) {
01023 syswarn(1, errno, "Unable to locate tape filemark.");
01024 return(-1);
01025 }
01026 }
01027
01028
01029
01030
01031
01032 mb.mt_op = MTBSF;
01033 mb.mt_count = 1;
01034 if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
01035 syswarn(1, errno, "Unable to backspace over tape filemark.");
01036 return(-1);
01037 }
01038
01039
01040
01041
01042
01043 mb.mt_op = MTBSR;
01044 mb.mt_count = 1;
01045 if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
01046 syswarn(1, errno, "Unable to backspace over last tape block.");
01047 return(-1);
01048 }
01049 if ((phyblk = read(arfd, scbuf, sizeof(scbuf))) <= 0) {
01050 syswarn(1, errno, "Cannot determine archive tape blocksize.");
01051 return(-1);
01052 }
01053
01054
01055
01056
01057
01058 while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
01059 ;
01060 if (res < 0) {
01061 syswarn(1, errno, "Unable to locate tape filemark.");
01062 return(-1);
01063 }
01064 mb.mt_op = MTBSF;
01065 mb.mt_count = 1;
01066 if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
01067 syswarn(1, errno, "Unable to backspace over tape filemark.");
01068 return(-1);
01069 }
01070
01071
01072
01073
01074 lstrval = 1;
01075
01076
01077
01078
01079 if (padsz == 0)
01080 return(phyblk);
01081
01082
01083
01084
01085
01086 if (padsz % phyblk) {
01087 paxwarn(1, "Tape drive unable to backspace requested amount");
01088 return(-1);
01089 }
01090
01091
01092
01093
01094
01095 mb.mt_op = MTBSR;
01096 mb.mt_count = padsz/phyblk;
01097 if (ioctl(arfd, MTIOCTOP, &mb) < 0) {
01098 syswarn(1,errno,"Unable to backspace tape over %d pad blocks",
01099 mb.mt_count);
01100 return(-1);
01101 }
01102 return(phyblk);
01103 }
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115 int
01116 ar_next(void)
01117 {
01118 char buf[PAXPATHLEN+2];
01119 static int freeit = 0;
01120 sigset_t o_mask;
01121
01122
01123
01124
01125
01126
01127 if (sigprocmask(SIG_BLOCK, &s_mask, &o_mask) < 0)
01128 syswarn(0, errno, "Unable to set signal mask");
01129 ar_close();
01130 if (sigprocmask(SIG_SETMASK, &o_mask, NULL) < 0)
01131 syswarn(0, errno, "Unable to restore signal mask");
01132
01133 if (done || !wr_trail || strcmp(NM_TAR, argv0) == 0)
01134 return(-1);
01135
01136 tty_prnt("\nATTENTION! %s archive volume change required.\n", argv0);
01137
01138
01139
01140
01141
01142 if (strcmp(arcname, stdo) && strcmp(arcname, stdn) && (artyp != ISREG)
01143 && (artyp != ISPIPE)) {
01144 if (artyp == ISTAPE) {
01145 tty_prnt("%s ready for archive tape volume: %d\n",
01146 arcname, arvol);
01147 tty_prnt("Load the NEXT TAPE on the tape drive");
01148 } else {
01149 tty_prnt("%s ready for archive volume: %d\n",
01150 arcname, arvol);
01151 tty_prnt("Load the NEXT STORAGE MEDIA (if required)");
01152 }
01153
01154 if ((act == ARCHIVE) || (act == APPND))
01155 tty_prnt(" and make sure it is WRITE ENABLED.\n");
01156 else
01157 tty_prnt("\n");
01158
01159 for(;;) {
01160 tty_prnt("Type \"y\" to continue, \".\" to quit %s,",
01161 argv0);
01162 tty_prnt(" or \"s\" to switch to new device.\nIf you");
01163 tty_prnt(" cannot change storage media, type \"s\"\n");
01164 tty_prnt("Is the device ready and online? > ");
01165
01166 if ((tty_read(buf,sizeof(buf))<0) || !strcmp(buf,".")){
01167 done = 1;
01168 lstrval = -1;
01169 tty_prnt("Quitting %s!\n", argv0);
01170 vfpart = 0;
01171 return(-1);
01172 }
01173
01174 if ((buf[0] == '\0') || (buf[1] != '\0')) {
01175 tty_prnt("%s unknown command, try again\n",buf);
01176 continue;
01177 }
01178
01179 switch (buf[0]) {
01180 case 'y':
01181 case 'Y':
01182
01183
01184
01185 if (ar_open(arcname) >= 0)
01186 return(0);
01187 tty_prnt("Cannot re-open %s, try again\n",
01188 arcname);
01189 continue;
01190 case 's':
01191 case 'S':
01192
01193
01194
01195 tty_prnt("Switching to a different archive\n");
01196 break;
01197 default:
01198 tty_prnt("%s unknown command, try again\n",buf);
01199 continue;
01200 }
01201 break;
01202 }
01203 } else
01204 tty_prnt("Ready for archive volume: %d\n", arvol);
01205
01206
01207
01208
01209 for (;;) {
01210 tty_prnt("Input archive name or \".\" to quit %s.\n", argv0);
01211 tty_prnt("Archive name > ");
01212
01213 if ((tty_read(buf, sizeof(buf)) < 0) || !strcmp(buf, ".")) {
01214 done = 1;
01215 lstrval = -1;
01216 tty_prnt("Quitting %s!\n", argv0);
01217 vfpart = 0;
01218 return(-1);
01219 }
01220 if (buf[0] == '\0') {
01221 tty_prnt("Empty file name, try again\n");
01222 continue;
01223 }
01224 if (!strcmp(buf, "..")) {
01225 tty_prnt("Illegal file name: .. try again\n");
01226 continue;
01227 }
01228 if (strlen(buf) > PAXPATHLEN) {
01229 tty_prnt("File name too long, try again\n");
01230 continue;
01231 }
01232
01233
01234
01235
01236 if (ar_open(buf) >= 0) {
01237 if (freeit) {
01238 (void)free((char *)(uintptr_t)arcname);
01239 freeit = 0;
01240 }
01241 if ((arcname = strdup(buf)) == NULL) {
01242 done = 1;
01243 lstrval = -1;
01244 paxwarn(0, "Cannot save archive name.");
01245 return(-1);
01246 }
01247 freeit = 1;
01248 break;
01249 }
01250 tty_prnt("Cannot open %s, try again\n", buf);
01251 continue;
01252 }
01253 return(0);
01254 }
01255
01256
01257
01258
01259
01260
01261 static void
01262 ar_start_gzip(int fd, const char *gzip_prog, int wr)
01263 {
01264 int fds[2];
01265 const char *gzip_flags;
01266
01267 if (pipe(fds) < 0)
01268 err(1, "could not pipe");
01269 zpid = fork();
01270 if (zpid < 0)
01271 err(1, "could not fork");
01272
01273
01274 if (zpid) {
01275 if (wr)
01276 dup2(fds[1], fd);
01277 else
01278 dup2(fds[0], fd);
01279 close(fds[0]);
01280 close(fds[1]);
01281 } else {
01282 if (wr) {
01283 dup2(fds[0], STDIN_FILENO);
01284 dup2(fd, STDOUT_FILENO);
01285 gzip_flags = "-c";
01286 } else {
01287 dup2(fds[1], STDOUT_FILENO);
01288 dup2(fd, STDIN_FILENO);
01289 gzip_flags = "-dc";
01290 }
01291 close(fds[0]);
01292 close(fds[1]);
01293 if (execlp(gzip_prog, gzip_prog, gzip_flags,
01294 (char *)NULL) < 0)
01295 err(1, "could not exec");
01296
01297 }
01298 }