1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 27 /* All Rights Reserved */ 28 29 /* 30 * Portions of this source code were derived from Berkeley 4.3 BSD 31 * under license from the Regents of the University of California. 32 */ 33 34 #pragma ident "%Z%%M% %I% %E% SMI" 35 36 #include <stdio.h> 37 #include <sys/types.h> 38 #include <errno.h> 39 #include <unistd.h> 40 #include <stdlib.h> 41 #include <fcntl.h> 42 #include <memory.h> 43 #include <string.h> 44 #include <stdarg.h> 45 #include <sys/stat.h> 46 #include <sys/statvfs.h> 47 #include <sys/mkdev.h> 48 #include <sys/param.h> 49 #include <utime.h> 50 #include <pwd.h> 51 #include <grp.h> 52 #include <signal.h> 53 #include <ctype.h> 54 #include <archives.h> 55 #include <locale.h> 56 #include <sys/ioctl.h> 57 #include <sys/mtio.h> 58 #include <sys/fdio.h> 59 #include "cpio.h" 60 #include <sys/acl.h> 61 #include <sys/time.h> 62 #include <sys/resource.h> 63 #include <fnmatch.h> 64 #include <libgen.h> 65 #include <libintl.h> 66 #include <dirent.h> 67 #include <limits.h> 68 #include <aclutils.h> 69 #if defined(_PC_SATTR_ENABLED) 70 #include <libnvpair.h> 71 #include <attr.h> 72 #include <libcmdutils.h> 73 #endif /* _PC_SATTR_ENABLED */ 74 #ifdef SOLARIS_PRIVS 75 #include <priv.h> 76 #endif /* SOLARIS_PRIVS */ 77 78 /* 79 * Special kludge for off_t being a signed quantity. 80 */ 81 #if _FILE_OFFSET_BITS == 64 82 typedef u_longlong_t u_off_t; 83 #else 84 typedef ulong_t u_off_t; 85 #endif 86 87 #define SECMODE 0xe080 88 89 #define DEVNULL "/dev/null" 90 #define XATTRHDR ".hdr" 91 92 #define NAMELEN 32 93 #define TYPELEN 16 94 #define PERMLEN 4 95 96 #define FILE_COPIED 1 97 #define FILE_LINKED 2 98 #define FILE_PASS_ERR -1 99 100 #define ARCHIVE_NORMAL 0 101 #define ARCHIVE_ACL 1 102 #define ARCHIVE_XATTR 2 103 104 #ifndef VIEW_READONLY 105 #define VIEW_READONLY "SUNWattr_ro" 106 #endif 107 108 #ifndef VIEW_READWRITE 109 #define VIEW_READWRITE "SUNWattr_rw" 110 #endif 111 112 113 #define LSTAT(dir, path, statbuf) fstatat(dir, \ 114 get_component((Gen.g_attrnam_p == NULL) ? \ 115 path : Gen.g_attrnam_p), statbuf, AT_SYMLINK_NOFOLLOW) 116 #define STAT(dir, path, statbuf) fstatat(dir, \ 117 get_component((Gen.g_attrnam_p == NULL) ? \ 118 path : Gen.g_attrnam_p), statbuf, 0) 119 120 /* 121 * These limits reflect the maximum size regular file that 122 * can be archived, depending on the archive type. For archives 123 * with character-format headers (odc, tar, ustar) we use 124 * CHAR_OFFSET_MAX. For archives with SVR4 ASCII headers (-c, -H crc) 125 * we store filesize in an 8-char hexadecimal string and use 126 * ASC_OFFSET_MAX. Otherwise, we are limited to the size that will 127 * fit in a signed long value. 128 */ 129 #define CHAR_OFFSET_MAX 077777777777ULL /* 11 octal digits */ 130 #define ASC_OFFSET_MAX 0XFFFFFFFF /* 8 hexadecimal digits */ 131 #define BIN_OFFSET_MAX LONG_MAX /* signed long max value */ 132 133 #define POSIXMODES 07777 134 135 static char aclchar = ' '; 136 137 static struct Lnk *add_lnk(struct Lnk **); 138 static int bfill(void); 139 static void bflush(void); 140 static int chgreel(int dir); 141 static int ckname(int); 142 static void ckopts(long mask); 143 static long cksum(char hdr, int byt_cnt, int *err); 144 static int creat_hdr(void); 145 static int creat_lnk(int dirfd, char *name1_p, char *name2_p); 146 static int creat_spec(int dirfd); 147 static int creat_tmp(char *nam_p); 148 static void data_in(int proc_mode); 149 static void data_out(void); 150 static void data_pass(void); 151 static void file_in(void); 152 static int file_out(void); 153 static int file_pass(void); 154 static void flush_lnks(void); 155 static int gethdr(void); 156 static int getname(void); 157 static void getpats(int largc, char **largv); 158 static void ioerror(int dir); 159 static int matched(void); 160 static int missdir(char *nam_p); 161 static long mklong(short v[]); 162 static void mkshort(short sval[], long v); 163 static void msg(int severity, const char *fmt, ...); 164 static int openout(int dirfd); 165 static int read_hdr(int hdr); 166 static void reclaim(struct Lnk *l_p); 167 static void rstbuf(void); 168 static void setpasswd(char *nam); 169 static void rstfiles(int over, int dirfd); 170 static void scan4trail(void); 171 static void setup(int largc, char **largv); 172 static void set_tym(int dirfd, char *nam_p, time_t atime, time_t mtime); 173 static void sigint(int sig); 174 static void swap(char *buf_p, int cnt); 175 static void usage(void); 176 static void verbose(char *nam_p); 177 static void write_hdr(int secflag, off_t len); 178 static void write_trail(void); 179 static int ustar_dir(void); 180 static int ustar_spec(void); 181 static struct stat *convert_to_old_stat(struct stat *, char *, char *); 182 static void read_bar_vol_hdr(void); 183 static void read_bar_file_hdr(void); 184 static void setup_uncompress(FILE **); 185 static void skip_bar_volhdr(void); 186 static void bar_file_in(void); 187 static int g_init(int *devtype, int *fdes); 188 static int g_read(int, int, char *, unsigned); 189 static int g_write(int, int, char *, unsigned); 190 static int is_floppy(int); 191 static int is_tape(int); 192 static void write_ancillary(char *secinfo, int len); 193 static int remove_dir(char *); 194 static int save_cwd(void); 195 static void rest_cwd(int cwd); 196 197 static void xattrs_out(int (*func)()); 198 static void get_parent(char *path, char *dir); 199 static void prepare_xattr_hdr(char **attrbuf, char *filename, 200 char *attrname, char typeflag, struct Lnk *linkinfo, int *rlen); 201 static char tartype(int type); 202 static int openfile(int omode); 203 static mode_t attrmode(char type); 204 static char *get_component(char *path); 205 static int open_dir(char *name); 206 static int open_dirfd(); 207 static void close_dirfd(); 208 static void write_xattr_hdr(); 209 static char *skipslashes(char *string, char *start); 210 static int read_xattr_hdr(); 211 static void chop_endslashes(char *path); 212 213 214 /* helpful types */ 215 216 static 217 struct passwd *Curpw_p, /* Current password entry for -t option */ 218 *Rpw_p, /* Password entry for -R option */ 219 *dpasswd; 220 221 static 222 struct group *Curgr_p, /* Current group entry for -t option */ 223 *dgroup; 224 225 /* Data structure for buffered I/O. */ 226 227 static 228 struct buf_info { 229 char *b_base_p, /* Pointer to base of buffer */ 230 *b_out_p, /* Position to take bytes from buffer at */ 231 *b_in_p, /* Position to put bytes into buffer at */ 232 *b_end_p; /* Pointer to end of buffer */ 233 long b_cnt, /* Count of unprocessed bytes */ 234 b_size; /* Size of buffer in bytes */ 235 } Buffr; 236 237 /* Generic header format */ 238 239 static 240 struct gen_hdr { 241 ulong_t g_magic, /* Magic number field */ 242 g_ino, /* Inode number of file */ 243 g_mode, /* Mode of file */ 244 g_uid, /* Uid of file */ 245 g_gid, /* Gid of file */ 246 g_nlink, /* Number of links */ 247 g_mtime; /* Modification time */ 248 off_t g_filesz; /* Length of file */ 249 ulong_t g_dev, /* File system of file */ 250 g_rdev, /* Major/minor numbers of special files */ 251 g_namesz, /* Length of filename */ 252 g_cksum; /* Checksum of file */ 253 char g_gname[32], 254 g_uname[32], 255 g_version[2], 256 g_tmagic[6], 257 g_typeflag; 258 char *g_tname, 259 *g_prefix, 260 *g_nam_p, /* Filename */ 261 *g_attrparent_p, /* attribute parent */ 262 *g_attrpath_p, /* attribute path */ 263 *g_attrnam_p, /* attribute */ 264 *g_attrfnam_p, /* Real file name attr belongs to */ 265 *g_linktoattrfnam_p, /* file linked attribute belongs to */ 266 *g_linktoattrnam_p, /* attribute g_attrnam_p is linked to */ 267 *g_dirpath; /* dirname currently opened */ 268 int g_dirfd; /* directory file descriptor */ 269 int g_passdirfd; /* directory fd to pass to */ 270 int g_rw_sysattr; /* read-write system attribute */ 271 int g_baseparent_fd; /* base file's parent fd */ 272 273 } Gen, *G_p; 274 275 /* Data structure for handling multiply-linked files */ 276 static 277 char prebuf[PRESIZ+1], 278 nambuf[NAMSIZ+1], 279 fullnam[MAXNAM+1]; 280 281 282 static 283 struct Lnk { 284 short L_cnt, /* Number of links encountered */ 285 L_data; /* Data has been encountered if 1 */ 286 struct gen_hdr L_gen; /* gen_hdr information for this file */ 287 struct Lnk *L_nxt_p, /* Next file in list */ 288 *L_bck_p, /* Previous file in list */ 289 *L_lnk_p; /* Next link for this file */ 290 } Lnk_hd; 291 292 static 293 struct hdr_cpio Hdr; 294 295 /* 296 * ------------------------------------------------------------------------- 297 * Stuff needed to pre-view the name stream 298 * 299 * issymlink is used to remember that the current file is a symlink between 300 * getname() and file_pass(); the former trashes this information immediately 301 * when -L is specified. 302 */ 303 304 static 305 int issymlink = 0; 306 307 static 308 FILE *In_p = stdin; /* Where the input comes from */ 309 310 typedef struct sl_info 311 { 312 struct sl_info *llink; /* Left subtree ptr (tree depth in *sl_head) */ 313 struct sl_info *rlink; /* Right subtree ptr */ 314 int bal; /* Subtree balance factor */ 315 ulong_t sl_count; /* Number of symlinks */ 316 int sl_ftype; /* file type of inode */ 317 ino_t sl_ino; /* Inode of file */ 318 ino_t sl_ino2; /* alternate inode for -Hodc */ 319 } sl_info_t; 320 321 typedef struct data_in 322 { 323 int data_in_swapfile; 324 int data_in_proc_mode; 325 int data_in_partialflg; 326 int data_in_compress_flag; 327 long data_in_cksumval; 328 FILE *data_in_pipef; 329 } data_in_t; 330 331 /* 332 * The following structure maintains a hash entry for the 333 * balancing trees which are allocated for each device nodes. 334 */ 335 typedef struct sl_info_link 336 { 337 dev_t dev; 338 sl_info_t *head; 339 struct sl_info_link *next; 340 } sl_info_link_t; 341 342 #define SL_INFO_ALLOC_CHUNK 1024 343 #define NDEVHENTRY 0x40 344 #define DEV_HASHKEY(x) ((x) & (NDEVHENTRY -1)) 345 346 /* 347 * For remapping dev,inode for -Hodc archives. 348 */ 349 350 typedef struct sl_remap 351 { 352 dev_t dev; /* device */ 353 int inode_count; /* # inodes seen on dev */ 354 struct sl_remap *next; /* next in the chain */ 355 } sl_remap_t; 356 357 /* forward declarations */ 358 359 static sl_info_t *sl_info_alloc(void); 360 static sl_info_t *sl_insert(dev_t, ino_t, int); 361 static ulong_t sl_numlinks(dev_t, ino_t, int); 362 static void sl_preview_synonyms(void); 363 static void sl_remember_tgt(const struct stat *, int, int); 364 static sl_info_t *sl_search(dev_t, ino_t, int); 365 static sl_info_t *sl_devhash_lookup(dev_t); 366 static void sl_devhash_insert(dev_t, sl_info_t *); 367 368 extern int sl_compare(ino_t, int, ino_t, int); 369 #define sl_compare(lino, lftype, rino, rftype) (lino < rino ? -1 : \ 370 (lino > rino ? 1 : (lftype < rftype ? -1 : \ 371 (lftype > rftype ? 1 : 0)))) 372 373 /* global storage */ 374 375 static sl_remap_t *sl_remap_head = NULL; /* head of the inode-remap list */ 376 static sl_info_link_t *sl_devhash[NDEVHENTRY]; /* hash table */ 377 378 /* 379 * ------------------------------------------------------------------------- 380 */ 381 382 static 383 struct stat ArchSt, /* stat(2) information of the archive */ 384 SrcSt, /* stat(2) information of source file */ 385 DesSt, /* stat(2) of destination file */ 386 *OldSt = NULL; /* stat info converted to svr32 format */ 387 388 /* 389 * bin_mag: Used to validate a binary magic number, 390 * by combining to bytes into an unsigned short. 391 */ 392 393 static 394 union bin_mag { 395 unsigned char b_byte[2]; 396 ushort_t b_half; 397 } Binmag; 398 399 static 400 union tblock *Thdr_p; /* TAR header pointer */ 401 402 static union b_block *bar_Vhdr; 403 static struct gen_hdr Gen_bar_vol; 404 405 /* 406 * swpbuf: Used in swap() to swap bytes within a halfword, 407 * halfwords within a word, or to reverse the order of the 408 * bytes within a word. Also used in mklong() and mkshort(). 409 */ 410 411 static 412 union swpbuf { 413 unsigned char s_byte[4]; 414 ushort_t s_half[2]; 415 ulong_t s_word; 416 } *Swp_p; 417 418 static 419 char *myname, /* program name */ 420 Adir, /* Flags object as a directory */ 421 Hiddendir, /* Processing hidden attribute directory */ 422 Aspec, /* Flags object as a special file */ 423 Do_rename, /* Indicates rename() is to be used */ 424 Time[50], /* Array to hold date and time */ 425 Ttyname[] = "/dev/tty", /* Controlling console */ 426 T_lname[MAXPATHLEN], /* Array to hold links name for tar */ 427 *Buf_p, /* Buffer for file system I/O */ 428 *Empty, /* Empty block for TARTYP headers */ 429 *Full_p, /* Pointer to full pathname */ 430 *Efil_p, /* -E pattern file string */ 431 *Eom_p = "Change to part %d and press RETURN key. [q] ", 432 *Fullnam_p, /* Full pathname */ 433 *Attrfile_p, /* attribute file */ 434 *Hdr_p, /* -H header type string */ 435 *IOfil_p, /* -I/-O input/output archive string */ 436 *Lnkend_p, /* Pointer to end of Lnknam_p */ 437 *Lnknam_p, /* Buffer for linking files with -p option */ 438 *Nam_p, /* Array to hold filename */ 439 *Savenam_p, /* copy of filename xattr belongs to */ 440 *Own_p, /* New owner login id string */ 441 *Renam_p, /* Buffer for renaming files */ 442 *Renam_attr_p, /* Buffer for renaming attr with sys attrs */ 443 *Renametmp_p, /* Tmp Buffer for renaming files */ 444 *Symlnk_p, /* Buffer for holding symbolic link name */ 445 *Over_p, /* Holds temporary filename when overwriting */ 446 **Pat_pp = 0, /* Pattern strings */ 447 bar_linkflag, /* flag to indicate if the file is a link */ 448 bar_linkname[MAXPATHLEN]; /* store the name of the link */ 449 450 static 451 int Append = 0, /* Flag set while searching to end of archive */ 452 Archive, /* File descriptor of the archive */ 453 Buf_error = 0, /* I/O error occurred during buffer fill */ 454 Def_mode = 0777, /* Default file/directory protection modes */ 455 Device, /* Device type being accessed (used with libgenIO) */ 456 Error_cnt = 0, /* Cumulative count of I/O errors */ 457 Finished = 1, /* Indicates that a file transfer has completed */ 458 Hdrsz = ASCSZ, /* Fixed length portion of the header */ 459 Hdr_type, /* Flag to indicate type of header selected */ 460 Ifile, /* File des. of file being archived */ 461 Ofile, /* File des. of file being extracted from archive */ 462 Use_old_stat = 0, /* Create an old style -Hodc hdr (small dev's) */ 463 Onecopy = 0, /* Flags old vs. new link handling */ 464 Pad_val = 0, /* Indicates the number of bytes to pad (if any) */ 465 PageSize = 0, /* The native page size, used for figuring block size */ 466 Volcnt = 1, /* Number of archive volumes processed */ 467 Verbcnt = 0, /* Count of number of dots '.' output */ 468 Eomflag = 0, 469 Dflag = 0, 470 Atflag = 0, /* Archive/restore extended attributes */ 471 SysAtflag = 0, /* Archive/restore extended system attributes */ 472 Compressed, /* Flag to indicate if the bar archive is compressed */ 473 Bar_vol_num = 0, /* Volume number count for bar archive */ 474 privileged = 0, /* Flag set if running with higher privileges */ 475 attr_baseparent_fd = -1; /* attribute's base file descriptor */ 476 477 478 static 479 gid_t Lastgid = (gid_t)-1; /* Used with -t & -v to record current gid */ 480 481 static 482 uid_t Lastuid = (uid_t)-1; /* Used with -t & -v to record current uid */ 483 484 static 485 long Args, /* Mask of selected options */ 486 Max_namesz = CPATH; /* Maximum size of pathnames/filenames */ 487 488 static 489 int Bufsize = BUFSZ; /* Default block size */ 490 491 492 static u_longlong_t Blocks; /* full blocks transferred */ 493 static u_longlong_t SBlocks; /* cumulative char count from short reads */ 494 495 496 static off_t Max_offset = BIN_OFFSET_MAX; /* largest file size */ 497 static off_t Max_filesz; /* from getrlimit */ 498 499 static ulong_t Savedev; 500 501 static 502 FILE *Ef_p, /* File pointer of pattern input file */ 503 *Err_p = stderr, /* File pointer for error reporting */ 504 *Out_p = stdout, /* File pointer for non-archive output */ 505 *Rtty_p, /* Input file pointer for interactive rename */ 506 *Wtty_p; /* Output file ptr for interactive rename */ 507 508 static 509 ushort_t Ftype = S_IFMT; /* File type mask */ 510 511 /* ACL support */ 512 static struct sec_attr { 513 char attr_type; 514 char attr_len[7]; 515 char attr_info[1]; 516 } *attr; 517 518 static int Pflag = 0; /* flag indicates that acl is preserved */ 519 static int acl_is_set = 0; /* True if an acl was set on the file */ 520 521 acl_t *aclp; 522 523 #if defined(O_XATTR) 524 typedef enum { 525 ATTR_OK, 526 ATTR_SKIP, 527 ATTR_CHDIR_ERR, 528 ATTR_OPEN_ERR, 529 ATTR_XATTR_ERR, 530 ATTR_SATTR_ERR 531 } attr_status_t; 532 #endif 533 534 #if defined(O_XATTR) 535 typedef enum { 536 ARC_CREATE, 537 ARC_RESTORE 538 } arc_action_t; 539 #endif 540 541 542 /* 543 * 544 * cpio has been changed to support extended attributes. 545 * 546 * As part of this change cpio has been changed to use the new *at() syscalls 547 * such as openat, fchownat(), unlinkat()... 548 * 549 * This was done so that attributes can be handled with as few code changes 550 * as possible. 551 * 552 * What this means is that cpio now opens the directory that a file or directory 553 * resides in and then performs *at() functions to manipulate the entry. 554 * 555 * For example a new file is now created like this: 556 * 557 * dfd = open(<some dir path>) 558 * fd = openat(dfd, <name>,....); 559 * 560 * or in the case of an extended attribute 561 * 562 * dfd = attropen(<pathname>, ".", ....) 563 * 564 * Once we have a directory file descriptor all of the *at() functions can 565 * be applied to it. 566 * 567 * unlinkat(dfd, <component name>,...) 568 * fchownat(dfd, <component name>,..) 569 * 570 * This works for both normal namespace files and extended attribute file 571 * 572 */ 573 574 /* 575 * Extended attribute layout 576 * 577 * Extended attributes are stored in two pieces. 578 * 1. An attribute header which has information about 579 * what file the attribute is for and what the attribute 580 * is named. 581 * 2. The attribute record itself. Stored as a normal file type 582 * of entry. 583 * Both the header and attribute record have special modes/typeflags 584 * associated with them. 585 * 586 * The names of the header in the archive look like: 587 * /dev/null/attr.hdr 588 * 589 * The name of the attribute looks like: 590 * /dev/null/attr. 591 * 592 * This is done so that an archiver that doesn't understand these formats 593 * can just dispose of the attribute records unless the user chooses to 594 * rename them via cpio -r or pax -i 595 * 596 * The format is composed of a fixed size header followed 597 * by a variable sized xattr_buf. If the attribute is a hard link 598 * to another attribute, then another xattr_buf section is included 599 * for the link. 600 * 601 * The xattr_buf is used to define the necessary "pathing" steps 602 * to get to the extended attribute. This is necessary to support 603 * a fully recursive attribute model where an attribute may itself 604 * have an attribute. 605 * 606 * The basic layout looks like this. 607 * 608 * -------------------------------- 609 * | | 610 * | xattr_hdr | 611 * | | 612 * -------------------------------- 613 * -------------------------------- 614 * | | 615 * | xattr_buf | 616 * | | 617 * -------------------------------- 618 * -------------------------------- 619 * | | 620 * | (optional link info) | 621 * | | 622 * -------------------------------- 623 * -------------------------------- 624 * | | 625 * | attribute itself | 626 * | stored as normal tar | 627 * | or cpio data with | 628 * | special mode or | 629 * | typeflag | 630 * | | 631 * -------------------------------- 632 * 633 */ 634 635 /* 636 * Extended attributes structures 637 * 638 * xattrhead is the complete extended attribute header, as read of off 639 * disk/tape. It includes the variable xattr_buf portion. 640 * 641 * xattrp is basically an offset into xattrhead that points to the 642 * "pathing" section which defines how to get to the attribute. 643 * 644 * xattr_linkp is identical to xattrp except that it is used for linked 645 * attributes. It provides the pathing steps to get to the linked 646 * attribute. 647 * 648 * These structures are updated when an extended attribute header is read off 649 * of disk/tape. 650 */ 651 static struct xattr_hdr *xattrhead; 652 static struct xattr_buf *xattrp; 653 static struct xattr_buf *xattr_linkp; 654 static int xattrbadhead; /* is extended attribute header bad? */ 655 656 static int append_secattr(char **, int *, acl_t *); 657 static void write_ancillary(char *, int); 658 659 /* 660 * Note regarding cpio and changes to ensure cpio doesn't try to second 661 * guess whether it runs with sufficient privileges or not: 662 * 663 * cpio has been changed so that it doesn't carry a second implementation of 664 * the kernel's policy with respect to privileges. Instead of attempting 665 * to restore uid and gid from an archive only if cpio is run as uid 0, 666 * cpio now *always* tries to restore the uid and gid from the archive 667 * except when the -R option is specified. When the -R is specified, 668 * the uid and gid of the restored file will be changed to those of the 669 * login id specified. In addition, chown(), set_tym(), and chmod() should 670 * only be executed once during archive extraction, and to ensure 671 * setuid/setgid bits are restored properly, chown() should always be 672 * executed before chmod(). 673 * 674 * Note regarding debugging mechanism for cpio: 675 * 676 * The following mechanism is provided to allow us to debug cpio in complicated 677 * situations, like when it is part of a pipe. The idea is that you compile 678 * with -DWAITAROUND defined, and then add the "-z" command line option to the 679 * target cpio invocation. If stderr is available, it will tell you to which 680 * pid to attach the debugger; otherwise, use ps to find it. Attach to the 681 * process from the debugger, and, *PRESTO*, you are there! 682 * 683 * Simply assign "waitaround = 0" once you attach to the process, and then 684 * proceed from there as usual. 685 */ 686 687 #ifdef WAITAROUND 688 int waitaround = 0; /* wait for rendezvous with the debugger */ 689 #endif 690 691 /* 692 * Allocation wrappers and their flags 693 */ 694 #define E_NORMAL 0x0 /* Return NULL if allocation fails */ 695 #define E_EXIT 0x1 /* Exit if allocation fails */ 696 697 static void *e_realloc(int flag, void *old, size_t newsize); 698 static char *e_strdup(int flag, const char *arg); 699 static void *e_valloc(int flag, size_t size); 700 static void *e_zalloc(int flag, size_t size); 701 702 #define EXIT_CODE (Error_cnt > 255 ? 255 : Error_cnt) 703 704 /* 705 * main: Call setup() to process options and perform initializations, 706 * and then select either copy in (-i), copy out (-o), or pass (-p) action. 707 */ 708 709 int 710 main(int argc, char **argv) 711 { 712 int i; 713 int passret; 714 715 (void) setlocale(LC_ALL, ""); 716 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 717 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 718 #endif 719 (void) textdomain(TEXT_DOMAIN); 720 721 (void) memset(&Gen, 0, sizeof (Gen)); 722 myname = e_strdup(E_EXIT, basename(argv[0])); 723 setup(argc, argv); 724 725 if (signal(SIGINT, sigint) == SIG_IGN) 726 (void) signal(SIGINT, SIG_IGN); 727 switch (Args & (OCi | OCo | OCp)) { 728 case OCi: /* COPY IN */ 729 Hdr_type = NONE; 730 if (Atflag || SysAtflag) { 731 /* 732 * Save the current working directory, so 733 * we can change back here after cd'ing into 734 * the attribute directory when processing 735 * attributes. 736 */ 737 if ((attr_baseparent_fd = save_cwd()) < 0) { 738 msg(EXT, "Unable to open current directory."); 739 } 740 } 741 while ((i = gethdr()) != 0) { 742 Gen.g_dirfd = -1; 743 if (i == 1) { 744 file_in(); 745 /* 746 * Any ACL info for this file would or should 747 * have been used after file_in(); clear out 748 * aclp so it is is not erroneously used on 749 * the next file. 750 */ 751 if (aclp != NULL) { 752 acl_free(aclp); 753 aclp = NULL; 754 } 755 acl_is_set = 0; 756 } 757 (void) memset(&Gen, 0, sizeof (Gen)); 758 } 759 /* Do not count "extra" "read-ahead" buffered data */ 760 if (Buffr.b_cnt > Bufsize) 761 Blocks -= (u_longlong_t)(Buffr.b_cnt / Bufsize); 762 break; 763 case OCo: /* COPY OUT */ 764 if (Args & OCA) { 765 scan4trail(); 766 } 767 768 Gen.g_dirfd = -1; 769 Gen.g_dirpath = NULL; 770 sl_preview_synonyms(); 771 772 while ((i = getname()) != 0) { 773 if (i == 1) { 774 (void) file_out(); 775 if (Atflag || SysAtflag) { 776 if (Gen.g_dirfd != -1) { 777 (void) close(Gen.g_dirfd); 778 } 779 Gen.g_dirfd = -1; 780 xattrs_out(file_out); 781 } 782 } 783 if (aclp != NULL) { 784 acl_free(aclp); 785 aclp = NULL; 786 acl_is_set = 0; 787 } 788 } 789 write_trail(); 790 break; 791 case OCp: /* PASS */ 792 sl_preview_synonyms(); 793 794 Gen.g_dirfd = -1; 795 Gen.g_passdirfd = -1; 796 Gen.g_dirpath = NULL; 797 while (getname()) { 798 /* 799 * If file is a fully qualified path then 800 * file_pass will strip off the leading '/' 801 * and we need to save off the unstripped 802 * name for attribute traversal. 803 */ 804 if (Atflag || SysAtflag) { 805 (void) strcpy(Savenam_p, Gen.g_nam_p); 806 } 807 passret = file_pass(); 808 if (aclp != NULL) { 809 acl_free(aclp); 810 aclp = NULL; 811 acl_is_set = 0; 812 } 813 if (Gen.g_passdirfd != -1) 814 (void) close(Gen.g_passdirfd); 815 Gen.g_passdirfd = -1; 816 if (Atflag || SysAtflag) { 817 if (Gen.g_dirfd != -1) { 818 (void) close(Gen.g_dirfd); 819 } 820 Gen.g_dirfd = -1; 821 if (passret != FILE_LINKED) { 822 Gen.g_nam_p = Savenam_p; 823 xattrs_out(file_pass); 824 } 825 } 826 } 827 break; 828 default: 829 msg(EXT, "Impossible action."); 830 } 831 if (Ofile > 0) { 832 if (close(Ofile) != 0) 833 msg(EXTN, "close error"); 834 } 835 if (Archive > 0) { 836 if (close(Archive) != 0) 837 msg(EXTN, "close error"); 838 } 839 Blocks = (u_longlong_t)(Blocks * Bufsize + SBlocks + 0x1FF) >> 9; 840 msg(EPOST, "%lld blocks", Blocks); 841 if (Error_cnt) 842 msg(EPOST, "%d error(s)", Error_cnt); 843 return (EXIT_CODE); 844 } 845 846 /* 847 * add_lnk: Add a linked file's header to the linked file data structure, by 848 * either adding it to the end of an existing sub-list or starting 849 * a new sub-list. Each sub-list saves the links to a given file. 850 * 851 * Directly returns a pointer to the new entry; returns a pointer to the head 852 * of the sub-list in which that entry is located through the argument. 853 */ 854 855 static struct Lnk * 856 add_lnk(struct Lnk **sublist_return) 857 { 858 struct Lnk *new_entry, *sublist; 859 860 for (sublist = Lnk_hd.L_nxt_p; 861 sublist != &Lnk_hd; 862 sublist = sublist->L_nxt_p) { 863 if (sublist->L_gen.g_ino == G_p->g_ino && 864 sublist->L_gen.g_dev == G_p->g_dev) { 865 /* found */ 866 break; 867 } 868 } 869 870 new_entry = e_zalloc(E_EXIT, sizeof (struct Lnk)); 871 872 new_entry->L_lnk_p = NULL; 873 new_entry->L_gen = *G_p; /* structure copy */ 874 875 new_entry->L_gen.g_nam_p = e_zalloc(E_EXIT, (size_t)G_p->g_namesz); 876 877 (void) strcpy(new_entry->L_gen.g_nam_p, G_p->g_nam_p); 878 879 if (sublist == &Lnk_hd) { 880 /* start new sub-list */ 881 new_entry->L_nxt_p = &Lnk_hd; 882 new_entry->L_bck_p = Lnk_hd.L_bck_p; 883 Lnk_hd.L_bck_p = new_entry->L_bck_p->L_nxt_p = new_entry; 884 new_entry->L_lnk_p = NULL; 885 new_entry->L_cnt = 1; 886 new_entry->L_data = Onecopy ? 0 : 1; 887 sublist = new_entry; 888 } else { 889 /* add to existing sub-list */ 890 struct Lnk *ptr; 891 892 sublist->L_cnt++; 893 894 for (ptr = sublist; 895 ptr->L_lnk_p != NULL; 896 ptr = ptr->L_lnk_p) { 897 ptr->L_gen.g_filesz = G_p->g_filesz; 898 } 899 900 ptr->L_gen.g_filesz = G_p->g_filesz; 901 ptr->L_lnk_p = new_entry; 902 } 903 904 *sublist_return = sublist; 905 return (new_entry); 906 } 907 908 /* 909 * bfill: Read req_cnt bytes (out of filelen bytes) from the I/O buffer, 910 * moving them to rd_buf_p. When there are no bytes left in the I/O buffer, 911 * Fillbuf is set and the I/O buffer is filled. The variable dist is the 912 * distance to lseek if an I/O error is encountered with the -k option set 913 * (converted to a multiple of Bufsize). 914 */ 915 916 static int 917 bfill(void) 918 { 919 int i = 0, rv; 920 static int eof = 0; 921 922 if (!Dflag) { 923 while ((Buffr.b_end_p - Buffr.b_in_p) >= Bufsize) { 924 errno = 0; 925 if ((rv = g_read(Device, Archive, Buffr.b_in_p, Bufsize)) < 0) { 926 if (((Buffr.b_end_p - Buffr.b_in_p) >= Bufsize) && 927 (Eomflag == 0)) { 928 Eomflag = 1; 929 return (1); 930 } 931 if (errno == ENOSPC) { 932 (void) chgreel(INPUT); 933 if (Hdr_type == BAR) { 934 skip_bar_volhdr(); 935 } 936 continue; 937 } else if (Args & OCk) { 938 if (i++ > MX_SEEKS) 939 msg(EXT, "Cannot recover."); 940 if (lseek(Archive, Bufsize, SEEK_REL) < 0) 941 msg(EXTN, "Cannot lseek()"); 942 Error_cnt++; 943 Buf_error++; 944 rv = 0; 945 continue; 946 } else 947 ioerror(INPUT); 948 } /* (rv = g_read(Device, Archive ... */ 949 if (Hdr_type != BAR || rv == Bufsize) { 950 Buffr.b_in_p += rv; 951 Buffr.b_cnt += (long)rv; 952 } 953 if (rv == Bufsize) { 954 eof = 0; 955 Blocks++; 956 } else if (rv == 0) { 957 if (!eof) { 958 eof = 1; 959 break; 960 } 961 (void) chgreel(INPUT); 962 eof = 0; /* reset the eof after chgreel */ 963 964 /* 965 * if spans multiple volume, skip the volume header of 966 * the next volume so that the file currently being 967 * extracted can continue to be extracted. 968 */ 969 if (Hdr_type == BAR) { 970 skip_bar_volhdr(); 971 } 972 973 continue; 974 } else { 975 eof = 0; 976 SBlocks += (u_longlong_t)rv; 977 } 978 } /* (Buffr.b_end_p - Buffr.b_in_p) <= Bufsize */ 979 980 } else { /* Dflag */ 981 errno = 0; 982 if ((rv = g_read(Device, Archive, Buffr.b_in_p, Bufsize)) < 0) { 983 return (-1); 984 } /* (rv = g_read(Device, Archive ... */ 985 Buffr.b_in_p += rv; 986 Buffr.b_cnt += (long)rv; 987 if (rv == Bufsize) { 988 eof = 0; 989 Blocks++; 990 } else if (!rv) { 991 if (!eof) { 992 eof = 1; 993 return (rv); 994 } 995 return (-1); 996 } else { 997 eof = 0; 998 SBlocks += (u_longlong_t)rv; 999 } 1000 } 1001 return (rv); 1002 } 1003 1004 /* 1005 * bflush: Move wr_cnt bytes from data_p into the I/O buffer. When the 1006 * I/O buffer is full, Flushbuf is set and the buffer is written out. 1007 */ 1008 1009 static void 1010 bflush(void) 1011 { 1012 int rv; 1013 1014 while (Buffr.b_cnt >= Bufsize) { 1015 errno = 0; 1016 if ((rv = g_write(Device, Archive, Buffr.b_out_p, 1017 Bufsize)) < 0) { 1018 if (errno == ENOSPC && !Dflag) 1019 rv = chgreel(OUTPUT); 1020 else 1021 ioerror(OUTPUT); 1022 } 1023 Buffr.b_out_p += rv; 1024 Buffr.b_cnt -= (long)rv; 1025 if (rv == Bufsize) 1026 Blocks++; 1027 else if (rv > 0) 1028 SBlocks += (u_longlong_t)rv; 1029 } 1030 rstbuf(); 1031 } 1032 1033 /* 1034 * chgreel: Determine if end-of-medium has been reached. If it has, 1035 * close the current medium and prompt the user for the next medium. 1036 */ 1037 1038 static int 1039 chgreel(int dir) 1040 { 1041 int lastchar, tryagain, askagain, rv; 1042 int tmpdev; 1043 char str[APATH]; 1044 struct stat statb; 1045 1046 rv = 0; 1047 if (fstat(Archive, &statb) < 0) 1048 msg(EXTN, "Error during stat() of archive"); 1049 if ((statb.st_mode & S_IFMT) != S_IFCHR) { 1050 if (dir == INPUT) { 1051 msg(EXT, "%s%s\n", 1052 "Can't read input: end of file encountered ", 1053 "prior to expected end of archive."); 1054 } 1055 } 1056 msg(EPOST, "\007End of medium on \"%s\".", dir ? "output" : "input"); 1057 if (is_floppy(Archive)) 1058 (void) ioctl(Archive, FDEJECT, NULL); 1059 if ((close(Archive) != 0) && (dir == OUTPUT)) 1060 msg(EXTN, "close error"); 1061 Archive = 0; 1062 Volcnt++; 1063 for (;;