From 40bf83fed3260cbe00f8bd41f2f5a5f622d625be Mon Sep 17 00:00:00 2001 From: Apple Date: Fri, 10 Jul 2009 23:35:59 +0000 Subject: [PATCH] file_cmds-202.2.tar.gz --- Makefile | 12 +- chflags/Makefile | 3 +- chflags/chflags.c | 4 +- chmod/Makefile | 3 +- chmod/chmod.1 | 15 ++ chmod/chmod.c | 26 ++- chmod/chmod_acl.c | 116 ++++++----- chmod/chmod_acl.h | 4 +- chown/Makefile | 3 +- chown/chgrp.1 | 11 +- chown/chown.8 | 4 +- chown/chown.c | 11 +- cksum/Makefile | 3 +- compress/Makefile | 3 +- compress/zopen.c | 2 +- cp/Makefile | 3 +- cp/cp.1 | 18 +- cp/cp.c | 59 +++--- cp/utils.c | 11 +- dd/Makefile | 3 +- dd/dd.1 | 1 - dd/position.c | 22 -- df/Makefile | 2 +- df/df.1 | 3 + df/df.c | 2 +- du/Makefile | 3 +- du/du.1 | 7 + du/du.c | 152 +++++++++++++- install/Makefile | 5 +- ipcrm/Makefile | 3 +- ipcs/Makefile | 7 +- ipcs/ipcs.c | 8 +- ln/Makefile | 3 +- ln/symlink.7 | 6 +- ls/Makefile | 2 +- ls/cmp.c | 33 +++ ls/extern.h | 2 + ls/ls.1 | 67 +++--- ls/ls.c | 28 ++- ls/ls.h | 1 + ls/print.c | 10 +- ls/util.c | 4 +- mkdir/Makefile | 3 +- mkfifo/Makefile | 3 +- mkfifo/mkfifo.1 | 3 + mkfifo/mkfifo.c | 2 +- mknod/Makefile | 3 +- mknod/mknod.8 | 23 +-- mtree/Makefile | 7 +- mtree/create.c | 4 +- mv/Makefile | 3 +- mv/mv.1 | 3 + mv/mv.c | 8 +- pathchk/Makefile | 3 +- pax/Makefile | 8 +- pax/ar_io.c | 47 +++-- pax/ar_subs.c | 284 ++++++++++++++++++-------- pax/buf_subs.c | 6 +- pax/cpio.1 | 29 ++- pax/cpio.c | 6 +- pax/extern.h | 19 +- pax/file_subs.c | 90 ++++++-- pax/ftree.c | 40 +++- pax/ftree.h | 3 +- pax/gen_subs.c | 96 +++++---- pax/getoldopt.c | 2 +- pax/options.c | 160 ++++++++------- pax/pat_rep.c | 18 +- pax/pat_rep.h | 2 +- pax/pax.1 | 598 ++++++++++++++++++++++-------------------------------- pax/pax.c | 18 +- pax/pax.h | 6 +- pax/pax_format.c | 465 +----------------------------------------- pax/sel_subs.c | 2 +- pax/tables.c | 31 +-- pax/tables.h | 4 +- pax/tar.c | 51 +++-- pax/tty_subs.c | 11 +- rm/Makefile | 3 +- rm/rm.c | 19 +- rmdir/Makefile | 3 +- rmt/Makefile | 3 +- stat/Makefile | 3 +- stat/stat.c | 6 - touch/Makefile | 3 +- touch/touch.c | 1 + 86 files changed, 1337 insertions(+), 1450 deletions(-) diff --git a/Makefile b/Makefile index f240add..0f1207b 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,7 @@ Project = file_cmds -Embedded = $(shell tconf --test TARGET_OS_EMBEDDED) - SubProjects = chflags chmod chown cksum compress cp dd df du install \ - ipcrm ipcs ln ls\ - mkdir mkfifo mknod mv pathchk pax rm rmdir rmt shar stat\ - touch - -ifeq ($(Embedded),NO) -#libcrypto missing -SubProjects += mtree -endif + ipcrm ipcs ln ls mkdir mkfifo mknod mtree mv pathchk pax rm \ + rmdir shar stat touch include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/chflags/Makefile b/chflags/Makefile index 46cdbe1..00f6bf6 100644 --- a/chflags/Makefile +++ b/chflags/Makefile @@ -4,8 +4,7 @@ Install_Dir = /usr/bin CFILES = chflags.c MANPAGES = chflags.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/chflags/chflags.c b/chflags/chflags.c index d90a339..216b945 100644 --- a/chflags/chflags.c +++ b/chflags/chflags.c @@ -64,7 +64,7 @@ main(int argc, char *argv[]) long val; int Hflag, Lflag, Rflag, hflag, ch, fts_options, oct, rval; char *flags, *ep; - int (*change_flags)(const char *, unsigned long); + int (*change_flags)(const char *, u_int); Hflag = Lflag = Rflag = hflag = 0; #ifdef __APPLE__ @@ -119,7 +119,7 @@ main(int argc, char *argv[]) /* XXX: Why don't chflags and lchflags have compatible prototypes? */ #ifndef __APPLE__ if (hflag) - change_flags = (int (*)(const char *, unsigned long))lchflags; + change_flags = (int (*)(const char *, u_int))lchflags; else #endif /* !__APPLE__ */ change_flags = chflags; diff --git a/chmod/Makefile b/chmod/Makefile index 49f5bbc..1109dc0 100644 --- a/chmod/Makefile +++ b/chmod/Makefile @@ -4,8 +4,7 @@ Install_Dir = /bin CFILES = chmod.c chmod_acl.c MANPAGES = chmod.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/chmod/chmod.1 b/chmod/chmod.1 index ec6e2fd..dccb953 100644 --- a/chmod/chmod.1 +++ b/chmod/chmod.1 @@ -335,6 +335,9 @@ In cases where a user and a group exist with the same name, the user/group name can be prefixed with "user:" or "group:" in order to specify the type of name. .Pp +If the user or group name contains spaces you can use ':' as the delimiter +between name and permission. +.Pp The following permissions are applicable to all filesystem objects: .Bl -tag -width 6n -compact -offset indent .It delete @@ -429,6 +432,13 @@ two entries are combined. owner: juser 1: guest deny read 2: admin allow write,delete + # chmod +a "User 1:allow:read" file + # ls -le + -rw-r--r--+ 1 juser wheel 0 Apr 28 14:06 file1 + owner: juser + 1: guest deny read + 2: User 1 allow read + 3: admin allow write,delete .Pp The +a mode strives to maintain correct canonical form for the ACL. local deny @@ -506,6 +516,11 @@ removed. Entries may also be deleted by index using the -a# mode. .Pp Inheritance is not considered when processing the -a mode; rights and entries will be removed regardless of their inherited state. +.Pp +If the user or group name contains spaces you can use ':' as the delimiter +.Pp +\fBExample\fR + # chmod +a "User 1:allow:read" file .It \fB=a#\fR Individual entries are rewritten using the =a# mode. .Pp diff --git a/chmod/chmod.c b/chmod/chmod.c index 7801340..6f54683 100644 --- a/chmod/chmod.c +++ b/chmod/chmod.c @@ -75,7 +75,7 @@ main(int argc, char *argv[]) mode_t *set = NULL; long val = 0; int oct = 0; - int Hflag, Lflag, Rflag, ch, fts_options, hflag, rval; + int Hflag, Lflag, Pflag, Rflag, ch, fts_options, hflag, rval; int vflag; char *ep, *mode; mode_t newmode, omode; @@ -89,7 +89,7 @@ main(int argc, char *argv[]) set = NULL; omode = 0; - Hflag = Lflag = Rflag = fflag = hflag = vflag = 0; + Hflag = Lflag = Pflag = Rflag = fflag = hflag = vflag = 0; #ifndef __APPLE__ while ((ch = getopt(argc, argv, "HLPRXfghorstuvwx")) != -1) #else @@ -99,13 +99,16 @@ main(int argc, char *argv[]) case 'H': Hflag = 1; Lflag = 0; + Pflag = 0; break; case 'L': Lflag = 1; Hflag = 0; + Pflag = 0; break; case 'P': Hflag = Lflag = 0; + Pflag = 1; break; case 'R': Rflag = 1; @@ -189,10 +192,12 @@ done: argv += optind; #ifdef __APPLE__ if (argc < ((acloptflags & ACL_FLAG) ? 1 : 2)) usage(); -#else + if (!Rflag && (Hflag || Lflag || Pflag)) + warnx("options -H, -L, -P only useful with -R"); +#else /* !__APPLE__ */ if (argc < 2) usage(); -#endif +#endif /* __APPLE__ */ #ifdef __APPLE__ if (!(acloptflags & ACL_FLAG) && ((acloptlen = strlen(argv[0])) > 1) && (argv[0][1] == 'a')) { @@ -233,7 +238,7 @@ done: argv += optind; || aclpos < 0) errno = ERANGE; if (errno || *ep) - err(1, "Invalid ACL entry number: %s", aclpos); + errx(1, "Invalid ACL entry number: %d", aclpos); if (acloptflags & ACL_DELETE_FLAG) ace_arg_not_required = 1; @@ -246,7 +251,7 @@ done: argv += optind; */ inheritance_level++; if (inheritance_level > 1) - warn("Inheritance across more than one generation is not currently supported"); + warnx("Inheritance across more than one generation is not currently supported"); if (inheritance_level >= MAX_INHERITANCE_LEVEL) goto apdone; break; @@ -297,7 +302,7 @@ apnoacl: } while ((readval > 0) && (readtotal <= MAX_ACL_TEXT_SIZE)); if (0 == readtotal) - err(1, "-E specified, but read from STDIN failed"); + errx(1, "-E specified, but read from STDIN failed"); else mode[readtotal - 1] = '\0'; --argv; @@ -321,8 +326,7 @@ apnoacl: /* Parse the text into an ACL*/ acl_input = parse_acl_entries(mode); if (acl_input == NULL) { - errno = EINVAL; - err(1, "Invalid ACL specification: %s", mode); + errx(1, "Invalid ACL specification: %s", mode); } } } @@ -394,7 +398,7 @@ apnoacl: if ((newmode & ALLPERMS) == (p->fts_statp->st_mode & ALLPERMS)) continue; if ((*change_mode)(p->fts_accpath, newmode) && !fflag) { - warn("%s", p->fts_path); + warn("Unable to change file mode on %s", p->fts_path); rval = 1; } else { if (vflag) { @@ -440,7 +444,7 @@ usage(void) #ifdef __APPLE__ (void)fprintf(stderr, "usage:\tchmod [-fhv] [-R [-H | -L | -P]] [-a | +a | =a [i][# [ n]]] mode|entry file ...\n" - "\tchmod [-fhv] [-R [-H | -L | -P]] [-E | -C | -i | -I] file ...\n"); /* add -A and -V when implemented */ + "\tchmod [-fhv] [-R [-H | -L | -P]] [-E | -C | -N | -i | -I] file ...\n"); /* add -A and -V when implemented */ #else (void)fprintf(stderr, "usage: chmod [-fhv] [-R [-H | -L | -P]] mode file ...\n"); diff --git a/chmod/chmod_acl.c b/chmod/chmod_acl.c index f09f304..16ed9f2 100644 --- a/chmod/chmod_acl.c +++ b/chmod/chmod_acl.c @@ -502,10 +502,12 @@ find_matching_entry (acl_t acl, acl_entry_t modifier, acl_entry_t *rentryp, /* Remove all perms specified in modifier from rentry*/ int -subtract_from_entry(acl_entry_t rentry, acl_entry_t modifier) +subtract_from_entry(acl_entry_t rentry, acl_entry_t modifier, int* valid_perms) { acl_permset_t rperms, mperms; acl_flagset_t rflags, mflags; + if (valid_perms) + *valid_perms = 0; int i; if ((acl_get_permset(rentry, &rperms) != 0) || @@ -517,6 +519,8 @@ subtract_from_entry(acl_entry_t rentry, acl_entry_t modifier) for (i = 0; acl_perms[i].name != NULL; i++) { if (acl_get_perm_np(mperms, acl_perms[i].perm)) acl_delete_perm(rperms, acl_perms[i].perm); + else if (valid_perms && acl_get_perm_np(rperms, acl_perms[i].perm)) + (*valid_perms)++; } for (i = 0; acl_flags[i].name != NULL; i++) { if (acl_get_flag_np(mflags, acl_flags[i].flag)) @@ -556,7 +560,7 @@ merge_entry_perms(acl_entry_t rentry, acl_entry_t modifier) int modify_acl(acl_t *oaclp, acl_entry_t modifier, unsigned int optflags, int position, int inheritance_level, - unsigned flag_new_acl) { + unsigned flag_new_acl, const char* path) { unsigned cpos = 0; acl_entry_t newent = NULL; @@ -579,8 +583,7 @@ modify_acl(acl_t *oaclp, acl_entry_t modifier, unsigned int optflags, if (0 != acl_create_entry_np(&oacl, &newent, position)) err(1, "acl_create_entry() failed"); acl_copy_entry(newent, modifier); - } - else { + } else { /* If an entry exists, add the new permissions to it, else add an * entry in the canonical position. */ @@ -604,64 +607,65 @@ modify_acl(acl_t *oaclp, acl_entry_t modifier, unsigned int optflags, err(1, "acl_create_entry() failed"); acl_copy_entry(newent, modifier); } - } - else - if (optflags & ACL_DELETE_FLAG) { - - if (flag_new_acl) { - errx(1, "No ACL present"); - } - if (position != -1 ) { - if (0 != acl_get_entry(oacl, position, &rentry)) - err(1, "Invalid entry number"); + } else if (optflags & ACL_DELETE_FLAG) { + if (flag_new_acl) { + warnx("No ACL present '%s'", path); + retval = 1; + } else if (position != -1 ) { + if (0 != acl_get_entry(oacl, position, &rentry)) { + warnx("Invalid entry number '%s'", path); + retval = 1; + } else { acl_delete_entry(oacl, rentry); } - else { - unsigned match_found = 0, aindex; - for (aindex = 0; - acl_get_entry(oacl, rentry == NULL ? - ACL_FIRST_ENTRY : - ACL_NEXT_ENTRY, &rentry) - == 0; aindex++) { - unsigned cmp; - cmp = compare_acl_entries(rentry, - modifier); - if ((cmp == MATCH_EXACT) || - (cmp == MATCH_PARTIAL)) { - match_found++; - if (cmp == MATCH_EXACT) - acl_delete_entry(oacl, rentry); - else + } else { + unsigned match_found = 0, aindex; + for (aindex = 0; + acl_get_entry(oacl, rentry == NULL ? + ACL_FIRST_ENTRY : + ACL_NEXT_ENTRY, &rentry) == 0; + aindex++) { + unsigned cmp; + cmp = compare_acl_entries(rentry, modifier); + if ((cmp == MATCH_EXACT) || + (cmp == MATCH_PARTIAL)) { + match_found++; + if (cmp == MATCH_EXACT) + acl_delete_entry(oacl, rentry); + else { + int valid_perms; /* In the event of a partial match, remove the specified perms from the * entry */ - subtract_from_entry(rentry, modifier); + subtract_from_entry(rentry, modifier, &valid_perms); + /* if no perms survived then delete the entry */ + if (valid_perms == 0) + acl_delete_entry(oacl, rentry); } } - if (0 == match_found) { - warnx("Entry not found when attempting delete"); - retval = 1; - } } - } - else - if (optflags & ACL_REWRITE_FLAG) { - acl_entry_t rentry; - - if (-1 == position) { - usage(); - } - if (0 == flag_new_acl) { - if (0 != acl_get_entry(oacl, position, - &rentry)) - err(1, "Invalid entry number"); - - if (0 != acl_delete_entry(oacl, rentry)) - err(1, "Unable to delete entry"); - } - if (0!= acl_create_entry_np(&oacl, &newent, position)) - err(1, "acl_create_entry() failed"); - acl_copy_entry(newent, modifier); + if (0 == match_found) { + warnx("Entry not found when attempting delete '%s'",path); + retval = 1; } + } + } else if (optflags & ACL_REWRITE_FLAG) { + acl_entry_t rentry; + + if (-1 == position) { + usage(); + } + if (0 == flag_new_acl) { + if (0 != acl_get_entry(oacl, position, + &rentry)) + err(1, "Invalid entry number '%s'", path); + + if (0 != acl_delete_entry(oacl, rentry)) + err(1, "Unable to delete entry '%s'", path); + } + if (0!= acl_create_entry_np(&oacl, &newent, position)) + err(1, "acl_create_entry() failed"); + acl_copy_entry(newent, modifier); + } ma_exit: *oaclp = oacl; return retval; @@ -774,7 +778,7 @@ modify_file_acl(unsigned int optflags, const char *path, acl_t modifier, int pos } else if (((optflags & ACL_DELETE_FLAG) && (position != -1)) || (optflags & ACL_CHECK_CANONICITY)) { retval = modify_acl(&oacl, NULL, optflags, position, - inheritance_level, flag_new_acl); + inheritance_level, flag_new_acl, path); } else if ((optflags & (ACL_REMOVE_INHERIT_FLAG|ACL_REMOVE_INHERITED_ENTRIES)) && flag_new_acl) { warnx("No ACL currently associated with file '%s'", path); retval = 1; @@ -790,7 +794,7 @@ modify_file_acl(unsigned int optflags, const char *path, acl_t modifier, int pos retval += modify_acl(&oacl, entry, optflags, position, inheritance_level, - flag_new_acl); + flag_new_acl, path); } } } diff --git a/chmod/chmod_acl.h b/chmod/chmod_acl.h index 0833be4..31fe143 100644 --- a/chmod/chmod_acl.h +++ b/chmod/chmod_acl.h @@ -78,8 +78,8 @@ extern int compare_acl_entries(acl_entry_t a, acl_entry_t b); extern unsigned is_canonical(acl_t acl); extern int find_matching_entry (acl_t acl, acl_entry_t modifier, acl_entry_t *rentry, unsigned match_inherited); extern unsigned find_canonical_position(acl_t acl, acl_entry_t modifier); -extern int subtract_from_entry(acl_entry_t rentry, acl_entry_t modifier); -extern int modify_acl(acl_t *oaclp, acl_entry_t modifier, unsigned int optflags, int position, int inheritance_level, unsigned flag_new_acl); +extern int subtract_from_entry(acl_entry_t rentry, acl_entry_t modifier, int *valid_perms); +extern int modify_acl(acl_t *oaclp, acl_entry_t modifier, unsigned int optflags, int position, int inheritance_level, unsigned flag_new_acl, const char* path); extern int modify_file_acl(unsigned int optflags, const char *path, acl_t modifier, int position, int inheritance_level); extern uuid_t *name_to_uuid(char *tok, int nametype); #endif /* __APPLE__*/ diff --git a/chown/Makefile b/chown/Makefile index 9d811a0..a399809 100644 --- a/chown/Makefile +++ b/chown/Makefile @@ -4,8 +4,7 @@ Install_Dir = /usr/sbin CFILES = chown.c MANPAGES = chgrp.1 chown.8 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/chown/chgrp.1 b/chown/chgrp.1 index 6621698..769c3d5 100644 --- a/chown/chgrp.1 +++ b/chown/chgrp.1 @@ -61,36 +61,31 @@ ID specified by the group operand. .Pp The following options are available: .Bl -tag -width indent -.\" ========== .It Fl f The force option ignores errors, except for usage errors and doesn't query about strange modes (unless the user does not have proper permissions). -.\" ========== .It Fl H If the .Fl R option is specified, symbolic links on the command line are followed. (Symbolic links encountered in the tree traversal are not followed). -.\" ========== .It Fl h If the file is a symbolic link, the group ID of the link itself is changed rather than the file that is pointed to. -.\" ========== .It Fl L If the .Fl R option is specified, all symbolic links are followed. -.\" ========== .It Fl P If the .Fl R option is specified, no symbolic links are followed. -This is the default. -.\" ========== +This is the default. Use +.Fl h +to change the group ID of a symbolic link. .It Fl R Change the group ID for the file hierarchies rooted in the files instead of just the files themselves. -.\" ========== .It Fl v Cause .Nm chgrp diff --git a/chown/chown.8 b/chown/chown.8 index fc991ce..a3ffa09 100644 --- a/chown/chown.8 +++ b/chown/chown.8 @@ -85,7 +85,9 @@ If the .Fl R option is specified, no symbolic links are followed. Instead, the user and/or group ID of the link itself are modified. -This is the default. +This is the default. Use +.Fl h +to change the user ID and/or the group of symbolic links. .It Fl R Change the user ID and/or the group ID for the file hierarchies rooted in the files instead of just the files themselves. diff --git a/chown/chown.c b/chown/chown.c index 8af78c5..8391f7a 100644 --- a/chown/chown.c +++ b/chown/chown.c @@ -82,7 +82,7 @@ main(int argc, char **argv) { FTS *ftsp; FTSENT *p; - int Hflag, Lflag, Rflag, fflag, hflag, vflag; + int Hflag, Lflag, Pflag, Rflag, fflag, hflag, vflag; int ch, fts_options, rval; char *cp; int unix2003_compat = 0; @@ -94,18 +94,19 @@ main(int argc, char **argv) cp = (cp != NULL) ? cp + 1 : argv[0]; ischown = (strcmp(cp, "chown") == 0); - Hflag = Lflag = Rflag = fflag = hflag = vflag = 0; + Hflag = Lflag = Pflag = Rflag = fflag = hflag = vflag = 0; while ((ch = getopt(argc, argv, "HLPRfhv")) != -1) switch (ch) { case 'H': Hflag = 1; - Lflag = 0; + Lflag = Pflag = 0; break; case 'L': Lflag = 1; - Hflag = 0; + Hflag = Pflag = 0; break; case 'P': + Pflag = 1; Hflag = Lflag = 0; break; case 'R': @@ -129,6 +130,8 @@ main(int argc, char **argv) if (argc < 2) usage(); + if (!Rflag && (Hflag || Lflag || Pflag)) + warnx("options -H, -L, -P only useful with -R"); if (Rflag) { fts_options = FTS_PHYSICAL; diff --git a/cksum/Makefile b/cksum/Makefile index a43c0ec..8f3bb25 100644 --- a/cksum/Makefile +++ b/cksum/Makefile @@ -4,8 +4,7 @@ Install_Dir = /usr/bin CFILES = cksum.c crc.c print.c sum1.c sum2.c crc32.c MANPAGES = cksum.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/compress/Makefile b/compress/Makefile index 11660d0..3ed5f11 100644 --- a/compress/Makefile +++ b/compress/Makefile @@ -4,8 +4,7 @@ Install_Dir = /usr/bin CFILES = compress.c zopen.c MANPAGES = compress.1 uncompress.1 zopen.3 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/compress/zopen.c b/compress/zopen.c index 3ec7163..030755f 100644 --- a/compress/zopen.c +++ b/compress/zopen.c @@ -250,7 +250,7 @@ zwrite(void *cookie, const char *wbp, int num) zs = cookie; count = num; - bp = wbp; + bp = (const u_char *)wbp; if (state == S_MIDDLE) goto middle; state = S_MIDDLE; diff --git a/cp/Makefile b/cp/Makefile index 7ca7ec8..9a7b78d 100644 --- a/cp/Makefile +++ b/cp/Makefile @@ -4,8 +4,7 @@ Install_Dir = /bin CFILES = cp.c utils.c MANPAGES = cp.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/cp/cp.1 b/cp/cp.1 index 17ecd81..6f5507d 100644 --- a/cp/cp.1 +++ b/cp/cp.1 @@ -45,7 +45,7 @@ .Op Fl H | Fl L | Fl P .Oc .Op Fl fi | n -.Op Fl pvX +.Op Fl apvX .Ar source_file target_file .Nm cp .Oo @@ -53,7 +53,7 @@ .Op Fl H | Fl L | Fl P .Oc .Op Fl fi | n -.Op Fl pvX +.Op Fl apvX .Ar source_file ... target_directory .Sh DESCRIPTION In the first synopsis form, the @@ -74,8 +74,14 @@ detects an attempt to copy a file to itself, the copy will fail. .Pp The following options are available: .Bl -tag -width flag +.It Fl a +Same as +.Fl pPR +options. Preserves structure and attributes of files +but not directory structure. .It Fl f -For each existing destination pathname, remove it and +.\"For each existing destination pathname, remove it and +If the destination file cannot be opened, remove it and create a new file, without prompting for confirmation regardless of its permissions. (The @@ -130,7 +136,8 @@ Cause to preserve the following attributes of each source file in the copy: modification time, access time, file flags, file mode, user ID, and group ID, as allowed by permissions. -Access Control Lists (ACLs) will also be preserved. +Access Control Lists (ACLs) and Extended Attributes (EAs), +including resource forks, will also be preserved. .Pp If the user ID and group ID cannot be preserved, no error message is displayed and the exit value is not altered. @@ -279,6 +286,9 @@ Thus, new access rights will always be set. In .Fl R mode, copying will terminate if an error is encountered. +.Pp +For more information about legacy mode, see +.Xr compat 5 . .Sh SEE ALSO .Xr mv 1 , .Xr rcp 1 , diff --git a/cp/cp.c b/cp/cp.c index c08ec23..1c3d642 100644 --- a/cp/cp.c +++ b/cp/cp.c @@ -100,7 +100,6 @@ volatile sig_atomic_t info; enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE }; static int copy(char *[], enum op, int); -static int mastercmp(const FTSENT * const *, const FTSENT * const *); static void siginfo(int __unused); int @@ -112,7 +111,7 @@ main(int argc, char *argv[]) char *target; Hflag = Lflag = Pflag = 0; - while ((ch = getopt(argc, argv, "HLPRXfinprv")) != -1) + while ((ch = getopt(argc, argv, "HLPRXafinprv")) != -1) switch (ch) { case 'H': Hflag = 1; @@ -160,6 +159,11 @@ main(int argc, char *argv[]) case 'v': vflag = 1; break; + case 'a': + pflag = 1; + Pflag = 1; + Rflag = 1; + break; default: usage(); break; @@ -308,7 +312,27 @@ copy(char *argv[], enum op type, int fts_options) default: ; } - +#ifdef __APPLE__ + /* Skip ._ when using copyfile and exists */ + if ((pflag || !Xflag) && (curr->fts_level != FTS_ROOTLEVEL) && + (curr->fts_namelen > 2) && /* ._\0 is not AppleDouble */ + (curr->fts_name[0] == '.') && (curr->fts_name[1] == '_')) { + struct stat statbuf; + char path[PATH_MAX]; + char *p = strrchr(curr->fts_path, '/'); + if (p) { + size_t s = p + 2 - curr->fts_path; + if (s > sizeof(path)) s = sizeof(path); + strlcpy(path, curr->fts_path, s); + strlcat(path, curr->fts_name+2, sizeof(path)); + } else { + strlcpy(path, curr->fts_name+2, sizeof(path)); + } + if (!lstat(path, &statbuf)) { + continue; + } + } +#endif /* __APPLE__ */ /* * If we are in case (2) or (3) above, we need to append the * source name to the target name. @@ -460,12 +484,13 @@ copy(char *argv[], enum op type, int fts_options) */ if (dne) { if (mkdir(to.p_path, - curr->fts_statp->st_mode | S_IRWXU) < 0) + curr->fts_statp->st_mode | S_IRWXU) < 0) { if (COMPAT_MODE("bin/cp", "unix2003")) { warn("%s", to.p_path); } else { err(1, "%s", to.p_path); } + } } else if (!S_ISDIR(to_stat.st_mode)) { errno = ENOTDIR; if (COMPAT_MODE("bin/cp", "unix2003")) { @@ -521,32 +546,6 @@ copy(char *argv[], enum op type, int fts_options) return (rval); } -/* - * mastercmp -- - * The comparison function for the copy order. The order is to copy - * non-directory files before directory files. The reason for this - * is because files tend to be in the same cylinder group as their - * parent directory, whereas directories tend not to be. Copying the - * files first reduces seeking. - */ -static int -mastercmp(const FTSENT * const *a, const FTSENT * const *b) -{ - int a_info, b_info; - - a_info = (*a)->fts_info; - if (a_info == FTS_ERR || a_info == FTS_NS || a_info == FTS_DNR) - return (0); - b_info = (*b)->fts_info; - if (b_info == FTS_ERR || b_info == FTS_NS || b_info == FTS_DNR) - return (0); - if (a_info == FTS_D) - return (-1); - if (b_info == FTS_D) - return (1); - return (0); -} - static void siginfo(int sig __unused) { diff --git a/cp/utils.c b/cp/utils.c index 75d53d6..5535688 100644 --- a/cp/utils.c +++ b/cp/utils.c @@ -177,7 +177,8 @@ copy_file(const FTSENT *entp, int dne) mode = to_stat.st_mode; if ((mode & (S_IRWXG|S_IRWXO)) && fchmod(to_fd, mode & ~(S_IRWXG|S_IRWXO))) { - warn("%s: fchmod failed", to.p_path); + if (errno != EPERM) /* we have write access but do not own the file */ + warn("%s: fchmod failed", to.p_path); mode = 0; } } else { @@ -498,13 +499,13 @@ usage(void) if (COMPAT_MODE("bin/cp", "unix2003")) { (void)fprintf(stderr, "%s\n%s\n", -"usage: cp [-R [-H | -L | -P]] [-fi | -n] [-pvX] source_file target_file", -" cp [-R [-H | -L | -P]] [-fi | -n] [-pvX] source_file ... " +"usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file target_file", +" cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... " "target_directory"); } else { (void)fprintf(stderr, "%s\n%s\n", -"usage: cp [-R [-H | -L | -P]] [-f | -i | -n] [-pvX] source_file target_file", -" cp [-R [-H | -L | -P]] [-f | -i | -n] [-pvX] source_file ... " +"usage: cp [-R [-H | -L | -P]] [-f | -i | -n] [-apvX] source_file target_file", +" cp [-R [-H | -L | -P]] [-f | -i | -n] [-apvX] source_file ... " "target_directory"); } exit(EX_USAGE); diff --git a/dd/Makefile b/dd/Makefile index 4b9c70f..caf5162 100644 --- a/dd/Makefile +++ b/dd/Makefile @@ -4,8 +4,7 @@ Install_Dir = /bin CFILES = args.c conv.c conv_tab.c dd.c misc.c position.c MANPAGES = dd.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/dd/dd.1 b/dd/dd.1 index 3c6c5a5..8460813 100644 --- a/dd/dd.1 +++ b/dd/dd.1 @@ -360,7 +360,6 @@ will exit. .Ex -std .Sh SEE ALSO .Xr cp 1 , -.Xr mt 1 , .Xr tr 1 .Sh STANDARDS The diff --git a/dd/position.c b/dd/position.c index 2669a16..1fc13f8 100644 --- a/dd/position.c +++ b/dd/position.c @@ -44,7 +44,6 @@ static const char rcsid[] = #endif /* not lint */ #include -#include #ifdef __APPLE__ #include @@ -129,7 +128,6 @@ pos_in(void) void pos_out(void) { - struct mtop t_op; off_t cnt; ssize_t n; @@ -150,16 +148,6 @@ pos_out(void) if (out.offset < 0) errx(1, "%s: illegal offset", "oseek/seek"); - /* If no read access, try using mtio. */ - if (out.flags & NOREAD) { - t_op.mt_op = MTFSR; - t_op.mt_count = out.offset; - - if (ioctl(out.fd, MTIOCTOP, &t_op) == -1) - err(1, "%s", out.name); - return; - } - /* Read it. */ for (cnt = 0; cnt < out.offset; ++cnt) { if ((n = read(out.fd, out.db, out.dbsz)) > 0) @@ -168,16 +156,6 @@ pos_out(void) if (n == -1) err(1, "%s", out.name); - /* - * If reach EOF, fill with NUL characters; first, back up over - * the EOF mark. Note, cnt has not yet been incremented, so - * the EOF read does not count as a seek'd block. - */ - t_op.mt_op = MTBSR; - t_op.mt_count = 1; - if (ioctl(out.fd, MTIOCTOP, &t_op) == -1) - err(1, "%s", out.name); - while (cnt++ < out.offset) { n = write(out.fd, out.db, out.dbsz); if (n == -1) diff --git a/df/Makefile b/df/Makefile index 67896b1..106c8bf 100644 --- a/df/Makefile +++ b/df/Makefile @@ -4,7 +4,7 @@ Install_Dir = /bin CFILES = df.c vfslist.c MANPAGES = df.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic \ -D__FBSDID=__RCSID \ "-I$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders" \ -D_DARWIN_USE_64_BIT_INODE diff --git a/df/df.1 b/df/df.1 index 9067fcb..cb0a276 100644 --- a/df/df.1 +++ b/df/df.1 @@ -192,6 +192,9 @@ option is normally a no-op (Mac OS X already prints the total allocated-space figures). In legacy mode, it is equivalent to .Fl T . +.Pp +For more information about legacy mode, see +.Xr compat 5 . .Sh SEE ALSO .Xr lsvfs 1 , .Xr quota 1 , diff --git a/df/df.c b/df/df.c index e83cb39..e7c03cc 100644 --- a/df/df.c +++ b/df/df.c @@ -480,7 +480,7 @@ prtstat(struct statfs *sfsp, struct maxwidths *mwp) if (hflag) { prthuman(sfsp, used); } else { - (void)printf(" %*lld %*lld %*lld", mwp->total, + (void)printf(" %*jd %*jd %*jd", mwp->total, fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize, sfsp->f_mntonname), mwp->used, fsbtoblk(used, sfsp->f_bsize, blocksize, sfsp->f_mntonname), mwp->avail, fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize, sfsp->f_mntonname)); diff --git a/du/Makefile b/du/Makefile index 637be1b..ca11e95 100644 --- a/du/Makefile +++ b/du/Makefile @@ -4,8 +4,7 @@ Install_Dir = /usr/bin CFILES = du.c MANPAGES = du.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/du/du.1 b/du/du.1 index 993a5ab..1bc6b2b 100644 --- a/du/du.1 +++ b/du/du.1 @@ -126,6 +126,10 @@ Files having multiple hard links are counted (and displayed) a single time per .Nm du execution. +Directories having multiple hard links (typically Time Machine backups) are +counted a single time per +.Nm du +execution. .Sh ENVIRONMENT .Bl -tag -width BLOCKSIZE .It Ev BLOCKSIZE @@ -152,6 +156,9 @@ options may be specified. The command will detect and report a SYMLOOP error (loop involving symbolic links). In legacy mode, this is not the case. +.Pp +For more information about legacy mode, see +.Xr compat 5 . .Sh SEE ALSO .Xr df 1 , .Xr fts 3 , diff --git a/du/du.c b/du/du.c index 99564da..966a986 100644 --- a/du/du.c +++ b/du/du.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD: src/usr.bin/du/du.c,v 1.38 2005/04/09 14:31:40 stefanf Exp $ #include #include #include +#include #include #include @@ -107,6 +108,7 @@ struct ignentry { }; static int linkchk(FTSENT *); +static int dirlinkchk(FTSENT *); static void usage(void); void prthumanval(double); unit_t unit_adjust(double *); @@ -134,7 +136,7 @@ main(int argc, char *argv[]) Hflag = Lflag = Pflag = aflag = sflag = dflag = cflag = hflag = 0; save = argv; - ftsoptions = 0; + ftsoptions = FTS_NOCHDIR; depth = INT_MAX; SLIST_INIT(&ignores); @@ -259,8 +261,8 @@ main(int argc, char *argv[]) while ((p = fts_read(fts)) != NULL) { switch (p->fts_info) { - case FTS_D: /* Ignore. */ - if (ignorep(p)) + case FTS_D: + if (ignorep(p) || dirlinkchk(p)) fts_set(fts, p, FTS_SKIP); break; case FTS_DP: @@ -494,6 +496,150 @@ linkchk(FTSENT *p) return (0); } +static int +dirlinkchk(FTSENT *p) +{ + struct links_entry { + struct links_entry *next; + struct links_entry *previous; + int links; + dev_t dev; + ino_t ino; + }; + static const size_t links_hash_initial_size = 8192; + static struct links_entry **buckets; + static struct links_entry *free_list; + static size_t number_buckets; + static unsigned long number_entries; + static char stop_allocating; + struct links_entry *le, **new_buckets; + struct stat *st; + size_t i, new_size; + int hash; + struct attrbuf { + int size; + int linkcount; + } buf; + struct attrlist attrList; + + memset(&attrList, 0, sizeof(attrList)); + attrList.bitmapcount = ATTR_BIT_MAP_COUNT; + attrList.dirattr = ATTR_DIR_LINKCOUNT; + if (-1 == getattrlist(p->fts_path, &attrList, &buf, sizeof(buf), 0)) + return 0; + if (buf.linkcount == 1) + return 0; + st = p->fts_statp; + + /* If necessary, initialize the hash table. */ + if (buckets == NULL) { + number_buckets = links_hash_initial_size; + buckets = malloc(number_buckets * sizeof(buckets[0])); + if (buckets == NULL) + errx(1, "No memory for directory hardlink detection"); + for (i = 0; i < number_buckets; i++) + buckets[i] = NULL; + } + + /* If the hash table is getting too full, enlarge it. */ + if (number_entries > number_buckets * 10 && !stop_allocating) { + new_size = number_buckets * 2; + new_buckets = malloc(new_size * sizeof(struct links_entry *)); + + /* Try releasing the free list to see if that helps. */ + if (new_buckets == NULL && free_list != NULL) { + while (free_list != NULL) { + le = free_list; + free_list = le->next; + free(le); + } + new_buckets = malloc(new_size * sizeof(new_buckets[0])); + } + + if (new_buckets == NULL) { + stop_allocating = 1; + warnx("No more memory for tracking directory hard links"); + } else { + memset(new_buckets, 0, + new_size * sizeof(struct links_entry *)); + for (i = 0; i < number_buckets; i++) { + while (buckets[i] != NULL) { + /* Remove entry from old bucket. */ + le = buckets[i]; + buckets[i] = le->next; + + /* Add entry to new bucket. */ + hash = (le->dev ^ le->ino) % new_size; + + if (new_buckets[hash] != NULL) + new_buckets[hash]->previous = + le; + le->next = new_buckets[hash]; + le->previous = NULL; + new_buckets[hash] = le; + } + } + free(buckets); + buckets = new_buckets; + number_buckets = new_size; + } + } + + /* Try to locate this entry in the hash table. */ + hash = ( st->st_dev ^ st->st_ino ) % number_buckets; + for (le = buckets[hash]; le != NULL; le = le->next) { + if (le->dev == st->st_dev && le->ino == st->st_ino) { + /* + * Save memory by releasing an entry when we've seen + * all of it's links. + */ + if (--le->links <= 0) { + if (le->previous != NULL) + le->previous->next = le->next; + if (le->next != NULL) + le->next->previous = le->previous; + if (buckets[hash] == le) + buckets[hash] = le->next; + number_entries--; + /* Recycle this node through the free list */ + if (stop_allocating) { + free(le); + } else { + le->next = free_list; + free_list = le; + } + } + return (1); + } + } + + if (stop_allocating) + return (0); + /* Add this entry to the links cache. */ + if (free_list != NULL) { + /* Pull a node from the free list if we can. */ + le = free_list; + free_list = le->next; + } else + /* Malloc one if we have to. */ + le = malloc(sizeof(struct links_entry)); + if (le == NULL) { + stop_allocating = 1; + warnx("No more memory for tracking hard links"); + return (0); + } + le->dev = st->st_dev; + le->ino = st->st_ino; + le->links = buf.linkcount - 1; + number_entries++; + le->next = buckets[hash]; + le->previous = NULL; + if (buckets[hash] != NULL) + buckets[hash]->previous = le; + buckets[hash] = le; + return (0); +} + /* * Output in "human-readable" format. Uses 3 digits max and puts * unit suffixes at the end. Makes output compact and easy to read, diff --git a/install/Makefile b/install/Makefile index 8b29738..bd8a807 100644 --- a/install/Makefile +++ b/install/Makefile @@ -4,9 +4,8 @@ Install_Dir = /usr/bin CFILES = xinstall.c MANPAGES = install.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID \ - -include TargetConditionals.h +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID \ + -include TargetConditionals.h -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/ipcrm/Makefile b/ipcrm/Makefile index eedfdbb..5b64948 100644 --- a/ipcrm/Makefile +++ b/ipcrm/Makefile @@ -4,8 +4,7 @@ Install_Dir = /usr/bin CFILES = ipcrm.c MANPAGES = ipcrm.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/ipcs/Makefile b/ipcs/Makefile index 0d77995..ae8c819 100644 --- a/ipcs/Makefile +++ b/ipcs/Makefile @@ -4,12 +4,13 @@ Install_Dir = /usr/bin CFILES = ipcs.c MANPAGES = ipcs.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic \ -D__FBSDID=__RCSID \ -iquote \ - "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders" \ + "$(SDKROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders" \ -iquote \ - "$(SDKROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders" + "$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders" \ + -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/ipcs/ipcs.c b/ipcs/ipcs.c index 480a3c6..72e176a 100644 --- a/ipcs/ipcs.c +++ b/ipcs/ipcs.c @@ -42,7 +42,7 @@ #include #include -#include +#include "sys/types.h" #include #include #include @@ -275,7 +275,7 @@ main(argc, argv) cvt_time(msqptr->msg_ctime, ctime_buf); printf("q %6d 0x%08x %s %8s %8s", - IXSEQ_TO_IPCID(ic.ipcs_cursor-1, msqptr->msg_perm), + IXSEQ_TO_IPCID((ic.ipcs_cursor-1), msqptr->msg_perm), (int)msqptr->msg_perm._key, fmt_perm(msqptr->msg_perm.mode, 'w'), user_from_uid(msqptr->msg_perm.uid, 0), @@ -396,7 +396,7 @@ main(argc, argv) cvt_time(shmptr->shm_ctime, ctime_buf); printf("m %6d 0x%08x %s %8s %8s", - IXSEQ_TO_IPCID(ic.ipcs_cursor-1, shmptr->shm_perm), + IXSEQ_TO_IPCID((ic.ipcs_cursor-1), shmptr->shm_perm), (int)shmptr->shm_perm._key, fmt_perm(shmptr->shm_perm.mode, 'w'), user_from_uid(shmptr->shm_perm.uid, 0), @@ -525,7 +525,7 @@ else cvt_time(semaptr->sem_ctime, ctime_buf); printf("s %6d 0x%08x %s %8s %8s", - IXSEQ_TO_IPCID(ic.ipcs_cursor-1, semaptr->sem_perm), + IXSEQ_TO_IPCID((ic.ipcs_cursor-1), semaptr->sem_perm), (int)semaptr->sem_perm._key, fmt_perm(semaptr->sem_perm.mode, 'a'), user_from_uid(semaptr->sem_perm.uid, 0), diff --git a/ln/Makefile b/ln/Makefile index 8716c95..42c5c46 100644 --- a/ln/Makefile +++ b/ln/Makefile @@ -4,8 +4,7 @@ Install_Dir = /bin CFILES = ln.c MANPAGES = ln.1 symlink.7 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/ln/symlink.7 b/ln/symlink.7 index 726f583..7c6c757 100644 --- a/ln/symlink.7 +++ b/ln/symlink.7 @@ -110,7 +110,7 @@ They are: .Xr lchmod 2 , .Xr lchown 2 , .Xr lstat 2 , -.Xr lutimes 2 , +.Xr lutimes 3 , .Xr readlink 2 , .Xr rename 2 , .Xr rmdir 2 , @@ -136,7 +136,7 @@ an existing symbolic link can be changed by means of the .Xr lchmod 2 , .Xr lchown 2 , and -.Xr lutimes 2 +.Xr lutimes 3 system calls, respectively. Of these, only the flags are used by the system; the access permissions and ownership are ignored. @@ -447,7 +447,7 @@ whether specified on the command line or encountered in the tree walk. .Xr lchmod 2 , .Xr lchown 2 , .Xr lstat 2 , -.Xr lutimes 2 , +.Xr lutimes 3 , .Xr readlink 2 , .Xr rename 2 , .Xr symlink 2 , diff --git a/ls/Makefile b/ls/Makefile index 8523d35..77669a2 100644 --- a/ls/Makefile +++ b/ls/Makefile @@ -4,7 +4,7 @@ Install_Dir = /bin CFILES = cmp.c ls.c print.c util.c humanize_number.c MANPAGES = ls.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic \ -D__FBSDID=__RCSID \ "-I$(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders" \ -DCOLORLS \ diff --git a/ls/cmp.c b/ls/cmp.c index 6650036..2ad5edd 100644 --- a/ls/cmp.c +++ b/ls/cmp.c @@ -57,6 +57,7 @@ __RCSID("$FreeBSD: src/bin/ls/cmp.c,v 1.12 2002/06/30 05:13:54 obrien Exp $"); #define ATIMENSEC_CMP(x, op, y) ((x)->st_atimensec op (y)->st_atimensec) #define CTIMENSEC_CMP(x, op, y) ((x)->st_ctimensec op (y)->st_ctimensec) #define MTIMENSEC_CMP(x, op, y) ((x)->st_mtimensec op (y)->st_mtimensec) +#define BTIMENSEC_CMP(x, op, y) ((x)->st_birthtimensec op (y)->st_birthtimensec) #else #define ATIMENSEC_CMP(x, op, y) \ ((x)->st_atimespec.tv_nsec op (y)->st_atimespec.tv_nsec) @@ -64,6 +65,8 @@ __RCSID("$FreeBSD: src/bin/ls/cmp.c,v 1.12 2002/06/30 05:13:54 obrien Exp $"); ((x)->st_ctimespec.tv_nsec op (y)->st_ctimespec.tv_nsec) #define MTIMENSEC_CMP(x, op, y) \ ((x)->st_mtimespec.tv_nsec op (y)->st_mtimespec.tv_nsec) +#define BTIMENSEC_CMP(x, op, y) \ + ((x)->st_birthtimespec.tv_nsec op (y)->st_birthtimespec.tv_nsec) #endif int @@ -191,3 +194,33 @@ revsizecmp(a, b) else return (revnamecmp(a, b)); } + +int +birthcmp(const FTSENT *a, const FTSENT *b) +{ + if (b->fts_statp->st_birthtime > a->fts_statp->st_birthtime) + return (1); + else if (b->fts_statp->st_birthtime < a->fts_statp->st_birthtime) + return (-1); + else if (BTIMENSEC_CMP(b->fts_statp, >, a->fts_statp)) + return (1); + else if (BTIMENSEC_CMP(b->fts_statp, <, a->fts_statp)) + return (-1); + else + return (namecmp(a, b)); +} + +int +revbirthcmp(const FTSENT *a, const FTSENT *b) +{ + if (b->fts_statp->st_birthtime > a->fts_statp->st_birthtime) + return (-1); + else if (b->fts_statp->st_birthtime < a->fts_statp->st_birthtime) + return (1); + else if (BTIMENSEC_CMP(b->fts_statp, >, a->fts_statp)) + return (-1); + else if (BTIMENSEC_CMP(b->fts_statp, <, a->fts_statp)) + return (1); + else + return (revnamecmp(a, b)); +} diff --git a/ls/extern.h b/ls/extern.h index 9d16436..48d3a47 100644 --- a/ls/extern.h +++ b/ls/extern.h @@ -45,6 +45,8 @@ int revstatcmp(const FTSENT *, const FTSENT *); int sizecmp (const FTSENT *, const FTSENT *); int revsizecmp (const FTSENT *, const FTSENT *); int humanize_number(char *, size_t, int64_t, const char *, int, int); +int birthcmp(const FTSENT *, const FTSENT *); +int revbirthcmp(const FTSENT *, const FTSENT *); void printcol(DISPLAY *); void printlong(DISPLAY *); diff --git a/ls/ls.1 b/ls/ls.1 index c59ac1f..12e8af5 100644 --- a/ls/ls.1 +++ b/ls/ls.1 @@ -43,7 +43,7 @@ .Nd list directory contents .Sh SYNOPSIS .Nm ls -.Op Fl ABCFGHLPRSTW@abcdefghiklmnopqrstuwx1 +.Op Fl ABCFGHLOPRSTUW@abcdefghiklmnopqrstuwx1 .Op Ar .Sh DESCRIPTION For each operand that names a @@ -70,9 +70,10 @@ lexicographical order. .Pp The following options are available: .Bl -tag -width indent -.\" ========== .It Fl @ -Display extended attribute keys and sizes. +Display extended attribute keys and sizes in long +.Pq Fl l +output. .It Fl 1 (The numeric digit .Dq one . ) @@ -80,19 +81,16 @@ Force output to be one entry per line. This is the default when output is not to a terminal. -.\" ========== .It Fl A List all entries except for .Pa \&. and .Pa .. . Always set for the super-user. -.\" ========== .It Fl a Include directory entries whose names begin with a dot .Pq Pa \&. . -.\" ========== .It Fl B Force printing of non-printable characters (as defined by .Xr ctype 3 @@ -101,26 +99,25 @@ and current locale settings) in file names as where .Va xxx is the numeric value of the character in octal. -.\" ========== .It Fl b As .Fl B , but use .Tn C escape codes whenever possible. -.\" ========== .It Fl C Force multi-column output; this is the default when output is to a terminal. -.\" ========== .It Fl c -Use time when file status was last changed for sorting or printing. -.\" ========== +Use time when file status was last changed for sorting +.Pq Fl t +or long printing +.Pq Fl l . .It Fl d Directories are listed as plain files (not searched recursively). -.\" ========== .It Fl e -Print the Access Control List (ACL) associated with the file, if present. -.\" ========== +Print the Access Control List (ACL) associated with the file, if present, in long +.Pq Fl l +output. .It Fl F Display a slash .Pq Ql / @@ -141,26 +138,22 @@ and a vertical bar .Pq Ql \&| after each that is a .Tn FIFO . -.\" ========== .It Fl f Output is not sorted. This option turns on the .Fl a option. -.\" ========== .It Fl G Enable colorized output. This option is equivalent to defining .Ev CLICOLOR in the environment. (See below.) -.\" ========== .It Fl g This option is only available for compatibility with POSIX; it is used to display the group name in the long .Pq Fl l format output (the owner name is suppressed). -.\" ========== .It Fl H Symbolic links on the command line are followed. This option is assumed if @@ -169,17 +162,14 @@ none of the or .Fl l options are specified. -.\" ========== .It Fl h When used with the .Fl l option, use unit suffixes: Byte, Kilobyte, Megabyte, Gigabyte, Terabyte and Petabyte in order to reduce the number of digits to three or less using base 2 for sizes. -.\" ========== .It Fl i For each file, print the file's file serial number (inode number). -.\" ========== .It Fl k If the .Fl s @@ -187,14 +177,12 @@ option is specified, print the file size allocation in kilobytes, not blocks. This option overrides the environment variable .Ev BLOCKSIZE . -.\" ========== .It Fl L -If argument is a symbolic link, list the file or directory the link references +Follow all symbolic links to final target and list the file or directory the link references rather than the link itself. This option cancels the .Fl P option. -.\" ========== .It Fl l (The lowercase letter .Dq ell . ) @@ -202,10 +190,8 @@ List in long format. (See below.) If the output is to a terminal, a total sum for all the file sizes is output on a line before the long listing. -.\" ========== .It Fl m Stream output format; list files across the page, separated by commas. -.\" ========== .It Fl n Display user and group IDs numerically, rather than converting to a user or group name in a long @@ -214,15 +200,12 @@ output. This option turns on the .Fl l option. -.\" ========== .It Fl O Include the file flags in a long .Pq Fl l output. -.\" ========== .It Fl o List in long format, but omit the group id. -.\" ========== .It Fl P If argument is a symbolic link, list the link itself rather than the object the link references. @@ -231,29 +214,23 @@ This option cancels the and .Fl L options. -.\" ========== .It Fl p Write a slash .Pq Ql / after each filename if that file is a directory. -.\" ========== .It Fl q Force printing of non-graphic characters in file names as the character .Ql \&? ; this is the default when output is to a terminal. -.\" ========== .It Fl R Recursively list subdirectories encountered. -.\" ========== .It Fl r Reverse the order of the sort to get reverse lexicographical order or the oldest entries first (or largest files last, if combined with sort by size -.\" ========== .It Fl S Sort files by size -.\" ========== .It Fl s Display the number of file system blocks actually used by each file, in units of 512 bytes, where partial units are rounded up to the next integer value. @@ -262,7 +239,6 @@ sizes is output on a line before the listing. The environment variable .Ev BLOCKSIZE overrides the unit size of 512 bytes. -.\" ========== .It Fl T When used with the .Fl l @@ -270,34 +246,33 @@ When used with the .Dq ell ) option, display complete time information for the file, including month, day, hour, minute, second, and year. -.\" ========== .It Fl t Sort by time modified (most recently modified first) before sorting the operands by lexicographical order. -.\" ========== .It Fl u Use time of last access, instead of last modification of the file for sorting .Pq Fl t -or printing +or long printing +.Pq Fl l . +.It Fl U +Use time of file creation, instead of last modification for sorting +.Pq Fl t +or long output .Pq Fl l . -.\" ========== .It Fl v Force unedited printing of non-graphic characters; this is the default when output is not to a terminal. -.\" ========== .It Fl W Display whiteouts when scanning directories. .Pq Fl S flag). -.\" ========== .It Fl w Force raw printing of non-printable characters. This is the default when output is not to a terminal. -.\" ========== .It Fl x The same as .Fl C , @@ -369,7 +344,8 @@ If the file or directory has extended attributes, the permissions field printed by the .Fl l option is followed by a '@' character. -Otherwise, if the file or directory has extended security information, +Otherwise, if the file or directory has extended security information +(such as an access control list), the permissions field printed by the .Fl l option is followed by a '+' character. @@ -703,6 +679,9 @@ that resolves to a non-directory file, the output will reflect the nature of the link, rather than that of the file. In legacy operation, the output will describe the file. +.Pp +For more information about legacy mode, see +.Xr compat 5 . .Sh SEE ALSO .Xr chflags 1 , .Xr chmod 1 , diff --git a/ls/ls.c b/ls/ls.c index 749af98..6b53ca5 100644 --- a/ls/ls.c +++ b/ls/ls.c @@ -96,6 +96,7 @@ int termwidth = 80; /* default terminal width */ /* flags */ int f_accesstime; /* use time of last access */ + int f_birthtime; /* use time of file birth */ int f_flags; /* show flags associated with a file */ int f_humanval; /* show human-readable file sizes */ int f_inode; /* print inode */ @@ -177,7 +178,7 @@ main(int argc, char *argv[]) f_listdot = 1; fts_options = FTS_PHYSICAL; - while ((ch = getopt(argc, argv, "1@ABCFGHLOPRSTWabcdefghiklmnopqrstuvwx")) + while ((ch = getopt(argc, argv, "1@ABCFGHLOPRSTUWabcdefghiklmnopqrstuvwx")) != -1) { switch (ch) { /* @@ -210,11 +211,15 @@ main(int argc, char *argv[]) /* The -c and -u options override each other. */ case 'c': f_statustime = 1; - f_accesstime = 0; + f_accesstime = f_birthtime = 0; break; case 'u': f_accesstime = 1; - f_statustime = 0; + f_statustime = f_birthtime = 0; + break; + case 'U': + f_birthtime = 1; + f_statustime = f_accesstime = 0; break; case 'F': f_type = 1; @@ -446,6 +451,8 @@ main(int argc, char *argv[]) sortfcn = revacccmp; else if (f_statustime) sortfcn = revstatcmp; + else if (f_birthtime) + sortfcn = revbirthcmp; else /* Use modification time. */ sortfcn = revmodcmp; } else { @@ -457,6 +464,8 @@ main(int argc, char *argv[]) sortfcn = acccmp; else if (f_statustime) sortfcn = statcmp; + else if (f_birthtime) + sortfcn = birthcmp; else /* Use modification time. */ sortfcn = modcmp; } @@ -539,6 +548,13 @@ traverse(int argc, char *argv[], int options) output = 1; } chp = fts_children(ftsp, ch_options); + if (COMPAT_MODE("bin/ls", "Unix2003") && ((options & FTS_LOGICAL)!=0)) { + FTSENT *curr; + for (curr = chp; curr; curr = curr->fts_link) { + if (curr->fts_info == FTS_SLNONE) + curr->fts_number = NO_PRINT; + } + } display(p, chp); if (!f_recursive && chp != NULL) @@ -547,10 +563,8 @@ traverse(int argc, char *argv[], int options) case FTS_SLNONE: /* Same as default unless Unix conformance */ if (COMPAT_MODE("bin/ls", "Unix2003")) { if ((options & FTS_LOGICAL)!=0) { /* -L was specified */ - if (p->fts_errno) { - warnx("%s: %s", p->fts_name, strerror(p->fts_errno)); - rval = 1; - } + warnx("%s: %s", p->fts_name, strerror(p->fts_errno ?: ENOENT)); + rval = 1; } } break; diff --git a/ls/ls.h b/ls/ls.h index 6bb1aa2..137c793 100644 --- a/ls/ls.h +++ b/ls/ls.h @@ -51,6 +51,7 @@ extern long blocksize; /* block size units */ extern int f_accesstime; /* use time of last access */ +extern int f_birthtime; /* use time of file birth */ extern int f_flags; /* show flags associated with a file */ extern int f_humanval; /* show human-readable file sizes */ extern int f_inode; /* print inode */ diff --git a/ls/print.c b/ls/print.c index 5f222cd..31e06d6 100644 --- a/ls/print.c +++ b/ls/print.c @@ -72,7 +72,7 @@ __RCSID("$FreeBSD: src/bin/ls/print.c,v 1.57 2002/08/29 14:29:09 keramida Exp $" #include #include #endif - +#include /* intmax_t */ #ifdef __APPLE__ #include #else @@ -458,6 +458,8 @@ printlong(DISPLAY *dp) printtime(sp->st_atime); else if (f_statustime) printtime(sp->st_ctime); + else if (f_birthtime) + printtime(sp->st_birthtime); else printtime(sp->st_mtime); #ifdef COLORLS @@ -617,7 +619,11 @@ printaname(FTSENT *p, u_long inodefield, u_long sizefield) sp = p->fts_statp; chcnt = 0; if (f_inode) +#if _DARWIN_FEATURE_64_BIT_INODE + chcnt += printf("%*llu ", (int)inodefield, (u_quad_t)sp->st_ino); +#else chcnt += printf("%*lu ", (int)inodefield, (u_long)sp->st_ino); +#endif if (f_size) chcnt += printf("%*qu ", (int)sizefield, (u_int64_t)howmany(sp->st_blocks, blocksize)); @@ -886,5 +892,5 @@ printsize(size_t width, off_t bytes) HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL); (void)printf("%5s ", buf); } else - (void)printf("%*jd ", (u_int)width, bytes); + (void)printf("%*jd ", (u_int)width, (intmax_t)bytes); } diff --git a/ls/util.c b/ls/util.c index 7f8830a..de79f13 100644 --- a/ls/util.c +++ b/ls/util.c @@ -222,9 +222,9 @@ usage(void) { (void)fprintf(stderr, #ifdef COLORLS - "usage: ls [-ABCFGHLPRSTWabcdefghiklmnopqrstuwx1]" + "usage: ls [-ABCFGHLOPRSTUWabcdefghiklmnopqrstuwx1]" #else - "usage: ls [-ABCFHLPRSTWabcdefghiklmnopqrstuwx1]" + "usage: ls [-ABCFHLOPRSTUWabcdefghiklmnopqrstuwx1]" #endif " [file ...]\n"); exit(1); diff --git a/mkdir/Makefile b/mkdir/Makefile index bf85a88..f5dcf8d 100644 --- a/mkdir/Makefile +++ b/mkdir/Makefile @@ -4,8 +4,7 @@ Install_Dir = /bin CFILES = mkdir.c MANPAGES = mkdir.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/mkfifo/Makefile b/mkfifo/Makefile index 9cd7b57..11447dc 100644 --- a/mkfifo/Makefile +++ b/mkfifo/Makefile @@ -4,8 +4,7 @@ Install_Dir = /usr/bin CFILES = mkfifo.c MANPAGES = mkfifo.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/mkfifo/mkfifo.1 b/mkfifo/mkfifo.1 index 1656503..39ca982 100644 --- a/mkfifo/mkfifo.1 +++ b/mkfifo/mkfifo.1 @@ -80,6 +80,9 @@ exits with 0 if successful, and with >0 if an error occurred. .Sh LEGACY DESCRIPTION In legacy mode, the fifo's file permission bits are always limited by the current umask. +.Pp +For more information about legacy mode, see +.Xr compat 5 . .Sh SEE ALSO .Xr mkdir 1 , .Xr rm 1 , diff --git a/mkfifo/mkfifo.c b/mkfifo/mkfifo.c index 0abbd70..17cd5aa 100644 --- a/mkfifo/mkfifo.c +++ b/mkfifo/mkfifo.c @@ -71,7 +71,7 @@ main(argc, argv) { int ch, exitval; void * set; - mode_t mode; + mode_t mode = 0; int m_used = 0; setlocale (LC_ALL, ""); diff --git a/mknod/Makefile b/mknod/Makefile index e764c7b..4eb0d6d 100644 --- a/mknod/Makefile +++ b/mknod/Makefile @@ -4,8 +4,7 @@ Install_Dir = /sbin CFILES = mknod.c MANPAGES = mknod.8 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/mknod/mknod.8 b/mknod/mknod.8 index 9e5e9eb..eb4f292 100644 --- a/mknod/mknod.8 +++ b/mknod/mknod.8 @@ -61,12 +61,6 @@ The .Nm command creates device special files. -Normally the shell script -.Pa /dev/MAKEDEV -is used to create special files for commonly known devices; it executes -.Nm -with the appropriate arguments and can make all the files required for the -device. .Pp To make nodes manually, the required arguments are: .Pp @@ -90,17 +84,7 @@ and pseudo devices, and are type .Cm c . .It Ar major The major device number is an integer number which tells the kernel -which device driver entry point to use. To learn what -major device number to use for a particular device, check the file -.Pa /dev/MAKEDEV -to see if the device is known, or check -the system dependent device configuration file: -.Bd -filled -offset indent -.Dq Pa /usr/src/sys/conf/device. Ns Em architecture -.Ed -.Pp -(for example -.Pa device.hp300 ) . +which device driver entry point to use. .It Ar minor The minor device number tells the kernel which one of several similar devices the node corresponds to; for example, it may be a specific serial @@ -112,7 +96,7 @@ that disk. (Currently this form of specification is only supported by the .Ar bsdos format, for compatibility with the .Bsx -.Xr mknod 8 .) +.Xr mknod 8 . ) .El .Pp Device numbers for different operating systems may be packed in a different @@ -141,8 +125,7 @@ Alternatively, a single opaque device number may be specified. .Sh SEE ALSO .Xr mkfifo 1 , .Xr mkfifo 2 , -.Xr mknod 2 , -.Xr MAKEDEV 8 +.Xr mknod 2 .Sh HISTORY A .Nm diff --git a/mtree/Makefile b/mtree/Makefile index 0f859bd..1139f00 100644 --- a/mtree/Makefile +++ b/mtree/Makefile @@ -6,12 +6,13 @@ CFILES = compare.c create.c excludes.c misc.c mtree.c spec.c specspec.c \ ../cksum/crc.c MANPAGES = mtree.8 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic \ -D__FBSDID=__RCSID \ -DENABLE_MD5 \ -DENABLE_RMD160 \ - -DENABLE_SHA1 + -DENABLE_SHA1 \ + -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip \ - -lmd -lcrypto + -lmd include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/mtree/create.c b/mtree/create.c index 8860955..0801838 100644 --- a/mtree/create.c +++ b/mtree/create.c @@ -72,7 +72,7 @@ static uid_t uid; static mode_t mode; static u_long flags = 0xffffffff; -static int dsort(const FTSENT * const *, const FTSENT * const *); +static int dsort(const FTSENT **, const FTSENT **); static void output(int, int *, const char *, ...) __printflike(3, 4); static int statd(FTS *, FTSENT *, uid_t *, gid_t *, mode_t *, u_long *); static void statf(int, FTSENT *); @@ -399,7 +399,7 @@ statd(FTS *t, FTSENT *parent, uid_t *puid, gid_t *pgid, mode_t *pmode, u_long *p } static int -dsort(const FTSENT * const *a, const FTSENT * const *b) +dsort(const FTSENT **a, const FTSENT **b) { if (S_ISDIR((*a)->fts_statp->st_mode)) { if (!S_ISDIR((*b)->fts_statp->st_mode)) diff --git a/mv/Makefile b/mv/Makefile index 635b9ab..9f8f930 100644 --- a/mv/Makefile +++ b/mv/Makefile @@ -4,8 +4,7 @@ Install_Dir = /bin CFILES = mv.c MANPAGES = mv.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/mv/mv.1 b/mv/mv.1 index 3c57d15..569e5c5 100644 --- a/mv/mv.1 +++ b/mv/mv.1 @@ -148,6 +148,9 @@ The command "mv dir/afile dir" will abort with an error message. .Sh LEGACY DIAGNOSTICS In legacy mode, the command "mv dir/afile dir" will fail silently, returning an exit code of 0. +.Pp +For more information about legacy mode, see +.Xr compat 5 . .Sh SEE ALSO .Xr cp 1 , .Xr rm 1 , diff --git a/mv/mv.c b/mv/mv.c index 31acc39..c7df391 100644 --- a/mv/mv.c +++ b/mv/mv.c @@ -452,11 +452,11 @@ copy(char *from, char *to) return (1); } if (!WIFEXITED(status)) { - warn("%s: did not terminate normally", _PATH_CP); + warnx("%s: did not terminate normally", _PATH_CP); return (1); } if (WEXITSTATUS(status)) { - warn("%s: terminated with %d (non-zero) status", + warnx("%s: terminated with %d (non-zero) status", _PATH_CP, WEXITSTATUS(status)); return (1); } @@ -470,11 +470,11 @@ copy(char *from, char *to) return (1); } if (!WIFEXITED(status)) { - warn("%s: did not terminate normally", _PATH_RM); + warnx("%s: did not terminate normally", _PATH_RM); return (1); } if (WEXITSTATUS(status)) { - warn("%s: terminated with %d (non-zero) status", + warnx("%s: terminated with %d (non-zero) status", _PATH_RM, WEXITSTATUS(status)); return (1); } diff --git a/pathchk/Makefile b/pathchk/Makefile index c32e972..511c2d5 100644 --- a/pathchk/Makefile +++ b/pathchk/Makefile @@ -4,8 +4,7 @@ Install_Dir = /usr/bin CFILES = pathchk.c MANPAGES = pathchk.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/pax/Makefile b/pax/Makefile index 1176049..f2863cc 100644 --- a/pax/Makefile +++ b/pax/Makefile @@ -4,13 +4,9 @@ Install_Dir = /bin CFILES = ar_io.c ar_subs.c buf_subs.c cache.c cpio.c file_subs.c\ ftree.c gen_subs.c getoldopt.c options.c pat_rep.c pax.c\ sel_subs.c tables.c tar.c tty_subs.c pax_format.c -MANPAGES = pax.1 cpio.1 +MANPAGES = pax.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make - -after_install: - $(LN) -f $(DSTROOT)$(Install_Dir)/pax $(DSTROOT)/usr/bin/cpio diff --git a/pax/ar_io.c b/pax/ar_io.c index caff56c..99b1dfd 100644 --- a/pax/ar_io.c +++ b/pax/ar_io.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar_io.c,v 1.36 2004/06/20 16:22:08 niklas Exp $ */ +/* $OpenBSD: ar_io.c,v 1.38 2008/06/11 00:49:08 pvalchev Exp $ */ /* $NetBSD: ar_io.c,v 1.5 1996/03/26 23:54:13 mrg Exp $ */ /*- @@ -38,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)ar_io.c 8.2 (Berkeley) 4/18/94"; #else -static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: ar_io.c,v 1.36 2004/06/20 16:22:08 niklas Exp $"; +static const char rcsid[] = "$OpenBSD: ar_io.c,v 1.38 2008/06/11 00:49:08 pvalchev Exp $"; #endif #endif /* not lint */ @@ -46,7 +46,9 @@ static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: ar_io.c,v 1.3 #include #include #include +#ifndef __APPLE__ #include +#endif /* !__APPLE__ */ #include #include #include @@ -57,6 +59,7 @@ static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: ar_io.c,v 1.3 #include #include #include +#include #include "pax.h" #include "options.h" #include "extern.h" @@ -71,6 +74,7 @@ static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: ar_io.c,v 1.3 #define APP_MODE O_RDWR /* mode for append */ #define STDO "" /* pseudo name for stdout */ #define STDN "" /* pseudo name for stdin */ +#define _NONE "" /* pseudo name for no files */ static int arfd = -1; /* archive file descriptor */ static int artyp = ISREG; /* archive type: file/FIFO/tape */ static int arvol = 1; /* archive volume number */ @@ -87,7 +91,9 @@ const char *gzip_program; /* name of gzip program */ static pid_t zpid = -1; /* pid of child process */ int force_one_volume; /* 1 if we ignore volume changes */ +#ifndef __APPLE__ static int get_phys(void); +#endif /* __APPLE__ */ extern sigset_t s_mask; static void ar_start_gzip(int, const char *, int); @@ -103,8 +109,9 @@ static void ar_start_gzip(int, const char *, int); int ar_open(const char *name) { +#ifndef __APPLE__ struct mtget mb; - +#endif /* __APPLE__ */ if (arfd != -1) (void)close(arfd); arfd = -1; @@ -149,7 +156,7 @@ ar_open(const char *name) /* * arfd not used in COPY mode */ - arcname = ""; + arcname = _NONE; lstrval = 1; return(0); } @@ -157,8 +164,7 @@ ar_open(const char *name) return(-1); if (chdname != NULL) - if (chdir(chdname) != 0) { - syswarn(1, errno, "Failed chdir to %s", chdname); + if (dochdir(chdname) == -1) { return(-1); } /* @@ -180,9 +186,12 @@ ar_open(const char *name) return(-1); } +#ifndef __APPLE__ if (S_ISCHR(arsb.st_mode)) artyp = ioctl(arfd, MTIOCGET, &mb) ? ISCHR : ISTAPE; - else if (S_ISBLK(arsb.st_mode)) + else +#endif /* !__APPLE__ */ + if (S_ISBLK(arsb.st_mode)) artyp = ISBLK; else if ((lseek(arfd, (off_t)0L, SEEK_CUR) == -1) && (errno == ESPIPE)) artyp = ISPIPE; @@ -405,10 +414,11 @@ ar_close(void) (void)fprintf(listf, # ifdef LONG_OFF_T "%s: %s vol %d, %lu files, %lu bytes read, %lu bytes written.\n", + argv0, frmt->name, arvol-1, flcnt, rdcnt, wrcnt); # else - "%s: %s vol %d, %lu files, %qu bytes read, %qu bytes written.\n", + "%s: %s vol %d, %lu files, %ju bytes read, %ju bytes written.\n", + argv0, frmt->name, arvol-1, flcnt, (uintmax_t)rdcnt, (uintmax_t)wrcnt); # endif - argv0, frmt->name, arvol-1, flcnt, rdcnt, wrcnt); (void)fflush(listf); flcnt = 0; } @@ -663,7 +673,7 @@ ar_write(char *buf, int bsz) break; if (errno == EACCES) { paxwarn(0, "Write failed, archive is write protected."); - res = lstrval = 0; + lstrval = 0; return(0); } /* @@ -729,7 +739,9 @@ ar_rdsync(void) long fsbz; off_t cpos; off_t mpos; +#ifndef __APPLE__ struct mtop mb; +#endif /* !__APPLE__ */ /* * Fail resync attempts at user request (done) or if this is going to be @@ -747,6 +759,7 @@ ar_rdsync(void) did_io = 1; switch (artyp) { +#ifndef __APPLE__ case ISTAPE: /* * if the last i/o was a successful data transfer, we assume @@ -767,6 +780,7 @@ ar_rdsync(void) break; lstrval = 1; break; +#endif /* !__APPLE__ */ case ISREG: case ISCHR: case ISBLK: @@ -872,8 +886,10 @@ int ar_rev(off_t sksz) { off_t cpos; +#ifndef __APPLE__ struct mtop mb; int phyblk; +#endif /* __APPLE__ */ /* * make sure we do not have try to reverse on a flawed archive @@ -936,6 +952,7 @@ ar_rev(off_t sksz) return(-1); } break; +#ifndef __APPLE__ case ISTAPE: /* * Calculate and move the proper number of PHYSICAL tape @@ -984,11 +1001,12 @@ ar_rev(off_t sksz) return(-1); } break; +#endif /* !__APPLE__ */ } lstrval = 1; return(0); } - +#ifndef __APPLE__ /* * get_phys() * Determine the physical block size on a tape drive. We need the physical @@ -1102,7 +1120,7 @@ get_phys(void) } return(phyblk); } - +#endif /* !__APPLE__ */ /* * ar_next() * prompts the user for the next volume in this archive. For some devices @@ -1131,9 +1149,8 @@ ar_next(void) if (sigprocmask(SIG_SETMASK, &o_mask, NULL) < 0) syswarn(0, errno, "Unable to restore signal mask"); - /* Don't query for new volume if format is unknown */ if (frmt == NULL || done || !wr_trail || force_one_volume || strcmp(NM_TAR, argv0) == 0 || - strcmp(NM_PAX, argv0) == 0) + strcmp(NM_PAX, argv0) == 0) return(-1); tty_prnt("\nATTENTION! %s archive volume change required.\n", argv0); @@ -1294,7 +1311,7 @@ ar_start_gzip(int fd, const char *gzip_program, int wr) close(fds[0]); close(fds[1]); if (execlp(gzip_program, gzip_program, gzip_flags, (char *)NULL) < 0) - err(1, "could not exec"); + err(1, "could not exec %s", gzip_program); /* NOTREACHED */ } } diff --git a/pax/ar_subs.c b/pax/ar_subs.c index afa11d2..056f483 100644 --- a/pax/ar_subs.c +++ b/pax/ar_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar_subs.c,v 1.28 2004/04/16 22:50:23 deraadt Exp $ */ +/* $OpenBSD: ar_subs.c,v 1.32 2008/05/06 06:54:28 henning Exp $ */ /* $NetBSD: ar_subs.c,v 1.5 1995/03/21 09:07:06 cgd Exp $ */ /*- @@ -38,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)ar_subs.c 8.2 (Berkeley) 4/18/94"; #else -static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: ar_subs.c,v 1.28 2004/04/16 22:50:23 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: ar_subs.c,v 1.32 2008/05/06 06:54:28 henning Exp $"; #endif #endif /* not lint */ @@ -54,20 +54,21 @@ static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: ar_subs.c,v 1 #include #include #ifdef __APPLE__ +#include #include #include #include #endif #include "pax.h" +#include "options.h" #include "extern.h" +static int path_check(ARCHD *, int); static void wr_archive(ARCHD *, int is_app); static int get_arc(void); static int next_head(ARCHD *); extern sigset_t s_mask; -char *chdname; - /* * Routines which control the overall operation modes of pax as specified by * the user: list, append, read ... @@ -76,6 +77,73 @@ char *chdname; static char hdbuf[BLKMULT]; /* space for archive header on read */ u_long flcnt; /* number of files processed */ +static char cwdpath[MAXPATHLEN]; /* current working directory path */ +static size_t cwdpathlen; /* current working directory path len */ + +int +updatepath(void) +{ + if (getcwd(cwdpath, sizeof(cwdpath)) == NULL) { + syswarn(1, errno, "Cannot get working directory"); + return -1; + } + cwdpathlen = strlen(cwdpath); + return 0; +} + +int +fdochdir(int fcwd) +{ + if (fchdir(fcwd) == -1) { + syswarn(1, errno, "Cannot chdir to `.'"); + return -1; + } + return updatepath(); +} + +int +dochdir(const char *name) +{ + if (chdir(name) == -1) + syswarn(1, errno, "Cannot chdir to `%s'", name); + return updatepath(); +} + +static int +path_check(ARCHD *arcn, int level) +{ + char buf[MAXPATHLEN]; + char *p; + + if ((p = strrchr(arcn->name, '/')) == NULL) + return 0; + *p = '\0'; + + if (realpath(arcn->name, buf) == NULL) { + int error; + error = path_check(arcn, level + 1); + *p = '/'; + if (error == 0) + return 0; + if (level == 0) + syswarn(1, 0, "Cannot resolve `%s'", arcn->name); + return -1; + } + if (cwdpathlen == 1) { /* We're in the root */ + *p = '/'; + return 0; + } + if ((strncmp(buf, cwdpath, cwdpathlen) != 0) || (buf[cwdpathlen] != '\0' && buf[cwdpathlen] != '/')) { + *p = '/'; + syswarn(1, 0, "Attempt to write file `%s' that resolves into " + "`%s/%s' outside current working directory `%s' ignored", + arcn->name, buf, p + 1, cwdpath); + return -1; + } + *p = '/'; + return 0; +} + /* * list() * list the contents of an archive which match user supplied pattern(s) @@ -180,6 +248,7 @@ extract(void) struct stat sb; int fd; time_t now; + #ifdef __APPLE__ int copyfile_disable = (getenv(COPYFILE_DISABLE_VAR) != NULL); LIST_HEAD(copyfile_list_t, copyfile_list_entry_t) copyfile_list; @@ -320,9 +389,12 @@ extract(void) * if required, chdir around. */ if ((arcn->pat != NULL) && (arcn->pat->chdname != NULL)) - if (chdir(arcn->pat->chdname) != 0) - syswarn(1, errno, "Cannot chdir to %s", - arcn->pat->chdname); + dochdir(arcn->pat->chdname); + + if (secure && path_check(arcn, 0) != 0) { + (void)rd_skip(arcn->skip + arcn->pad); + continue; + } /* * all ok, extract this member based on type @@ -392,19 +464,20 @@ extract(void) * if required, chdir around. */ if ((arcn->pat != NULL) && (arcn->pat->chdname != NULL)) - if (fchdir(cwdfd) != 0) - syswarn(1, errno, - "Can't fchdir to starting directory"); + fdochdir(cwdfd); } - #ifdef __APPLE__ LIST_FOREACH(cle, ©file_list, link) { if(copyfile_disable || copyfile(cle->tmp, cle->dst, NULL, - COPYFILE_UNPACK | COPYFILE_XATTR | COPYFILE_ACL)) + COPYFILE_UNPACK | COPYFILE_XATTR | COPYFILE_ACL)) { + if (!copyfile_disable) { + syswarn(1, errno, "Unable to set metadata on %s", cle->dst); + } rename(cle->tmp, cle->src); - else + } else { unlink(cle->tmp); + } free(cle->dst); free(cle->src); free(cle->tmp); @@ -439,6 +512,7 @@ wr_archive(ARCHD *arcn, int is_app) int (*wrf)(ARCHD *); int fd = -1; time_t now; + #ifdef __APPLE__ int metadata = 0; char *md_fname = NULL; @@ -452,6 +526,7 @@ wr_archive(ARCHD *arcn, int is_app) */ if (((hlk = frmt->hlk) == 1) && (lnk_start() < 0)) return; + if (hlk && want_linkdata) hlk=0; /* Treat hard links as individual files */ /* @@ -483,66 +558,10 @@ wr_archive(ARCHD *arcn, int is_app) /* * check if this file meets user specified options match. */ - if (sel_chk(arcn) != 0) + if (sel_chk(arcn) != 0) { + ftree_notsel(); continue; -#ifdef __APPLE__ - /* - * synthesize ._ files for each node we encounter - */ - if (getenv(COPYFILE_DISABLE_VAR) == NULL - && copyfile(arcn->name, NULL, NULL, - COPYFILE_CHECK | COPYFILE_XATTR | COPYFILE_ACL) - && arcn->nlen + 2 < sizeof(arcn->name)) - { - int size; - char *new; - - md_fname = strdup("/tmp/pax.md.XXXX"); - memcpy(&arcn_copy, arcn, sizeof(ARCHD)); - strncpy(arcn_copy_name, arcn->name, PAXPATHLEN+1); - - arcn->skip = 0; - arcn->pad = 0; - arcn->ln_nlen = 0; - arcn->ln_name[0] = '\0'; - arcn->type = PAX_REG; - - if(md_fname && mktemp(md_fname)) - if(copyfile(arcn->name, md_fname, NULL, - COPYFILE_PACK | COPYFILE_XATTR | COPYFILE_ACL) < 0) - { - syswarn(1,EPERM, - "Unable to preserve metadata on %s", arcn->name); - goto next; - } - - stat(md_fname, &arcn->sb); - arcn->skip = arcn->sb.st_size; - - if (!strncmp(dirname(arcn->name), ".", 2)) - size = asprintf(&new, "._%s", - basename(arcn->name)); - else - size = asprintf(&new, "%s/._%s", - dirname(arcn->name), basename(arcn->name)); - - if (size != -1 && size < sizeof arcn->name) - { - strncpy(arcn->name, new, PAXPATHLEN+1); - } else { - goto next; - } - arcn->nlen = strlen(arcn->name); - arcn->org_name = arcn->name; - free(new); - metadata = 1; - } else if (metadata) { -next: - metadata = 0; - memcpy(arcn, &arcn_copy, sizeof(ARCHD)); - strncpy(arcn->name, arcn_copy_name, PAXPATHLEN+1); } -#endif fd = -1; if (uflag) { /* @@ -555,13 +574,99 @@ next: continue; } +#ifdef __APPLE__ + /* + * synthesize ._ files for each node we encounter + */ + if (getenv(COPYFILE_DISABLE_VAR) == NULL + && copyfile(arcn->name, NULL, NULL, + COPYFILE_CHECK | COPYFILE_XATTR | COPYFILE_ACL) + && arcn->nlen + 2 < sizeof(arcn->name)) { + char *tmpdir = P_tmpdir, *TMPDIR; + int fd_src, fd_dst; + + if (!issetugid() && (TMPDIR = getenv("TMPDIR"))) { + tmpdir = TMPDIR; + } + asprintf(&md_fname, "%s%s", tmpdir, "/pax-md-XXXXXX"); + if (!md_fname) { + syswarn(1, errno, "Unable to create temporary file name"); + return; + } + memcpy(&arcn_copy, arcn, sizeof(ARCHD)); + strncpy(arcn_copy_name, arcn->name, PAXPATHLEN+1); + + arcn->skip = 0; + arcn->pad = 0; + arcn->ln_nlen = 0; + arcn->ln_name[0] = '\0'; + arcn->type = PAX_REG; + fd_dst = mkstemp(md_fname); + if (fd_dst >= 0) { + fd_src = open(arcn->name, O_RDONLY, 0); + if (fd_src < 0) { + syswarn(1, errno, "Unable to open %s for reading", arcn->name); + close(fd_dst); + unlink(md_fname); + free(md_fname); + md_fname = NULL; + goto next; + } + if(fcopyfile(fd_src, fd_dst, NULL, + COPYFILE_PACK | COPYFILE_XATTR | COPYFILE_ACL) < 0) { + syswarn(1, errno, + "Unable to preserve metadata on %s", arcn->name); + close(fd_src); + close(fd_dst); + unlink(md_fname); + free(md_fname); + md_fname = NULL; + goto next; + } + close(fd_src); + fstat(fd_dst, &arcn->sb); + close(fd_dst); + } else { + syswarn(1, errno, "Unable to create temporary file %s", md_fname); + free(md_fname); + goto next; + } + arcn->skip = arcn->sb.st_size; + + if (!strncmp(dirname(arcn->name), ".", 2)) { + snprintf(arcn->name, sizeof(arcn->name), + "._%s", basename(arcn->name)); + } else { + snprintf(arcn->name, sizeof(arcn->name), + "%s/._%s", + dirname(arcn->name), basename(arcn->name)); + } + arcn->nlen = strlen(arcn->name); + arcn->org_name = arcn->name; + metadata = 1; + } else if (metadata) { +next: + metadata = 0; + memcpy(arcn, &arcn_copy, sizeof(ARCHD)); + strncpy(arcn->name, arcn_copy_name, PAXPATHLEN+1); + } +#endif /* __APPLE__ */ + + fd = -1; + /* * this file is considered selected now. see if this is a hard * link to a file already stored */ ftree_sel(arcn); - if (hlk && (chk_lnk(arcn) < 0)) + if (hlk && (chk_lnk(arcn) < 0)) { + if (md_fname) { + unlink(md_fname); + free(md_fname); + md_fname = NULL; + } break; + } if ((arcn->type == PAX_REG) || (arcn->type == PAX_HRG) || (arcn->type == PAX_CTG)) { @@ -572,18 +677,17 @@ next: * the link table). */ #ifdef __APPLE__ - if (metadata) - { - fd = open(md_fname, O_RDONLY, 0); - unlink(md_fname); - free(md_fname); + if (metadata) { + fd = open(md_fname, O_RDONLY, 0); + unlink(md_fname); + free(md_fname); + md_fname = NULL; } else - fd = open(arcn->org_name, O_RDONLY, 0); + fd = open(arcn->org_name, O_RDONLY, 0); if (fd < 0) { -#else +#else /* !__APPLE__ */ if ((fd = open(arcn->org_name, O_RDONLY, 0)) < 0) { -#endif - /* suppress set if size==0 ?? */ +#endif /* __APPLE__ */ syswarn(1,errno, "Unable to open %s to read", arcn->org_name); purg_lnk(arcn); @@ -671,8 +775,8 @@ next: break; #ifdef __APPLE__ if (metadata) - goto next; -#endif + goto next; +#endif /* __APPLE__ */ } /* @@ -709,7 +813,7 @@ next: * It is really difficult to splice in members without either re-writing * the entire archive (from the point were the old version was), or having * assistance of the format specification in terms of a special update - * header that invalidates a previous archive record. The posix spec left + * header that invalidates a previous archive record. The POSIX spec left * the method used to implement -u unspecified. This pax is able to * over write existing files that it creates. */ @@ -891,8 +995,7 @@ copy(void) char dirbuf[PAXPATHLEN+1]; arcn = &archd; - - if (frmt && strcmp(frmt->name, "pax")==0) { + if (frmt && strcmp(frmt->name, NM_PAX)==0) { /* Copy using pax format: must check if any -o options */ if ((*frmt->options)() < 0) return; @@ -960,8 +1063,10 @@ copy(void) /* * check if this file meets user specified options */ - if (sel_chk(arcn) != 0) + if (sel_chk(arcn) != 0) { + ftree_notsel(); continue; + } /* * if there is already a file in the destination directory with @@ -1106,8 +1211,9 @@ copy(void) #ifdef __APPLE__ /* do this before file close so that mtimes are correct regardless */ if (getenv(COPYFILE_DISABLE_VAR) == NULL) { - if (copyfile(arcn->org_name, arcn->name, NULL, COPYFILE_ACL | COPYFILE_XATTR) < 0) - paxwarn(1, "File %s had metadata that could not be copied", arcn->org_name); + if (fcopyfile(fdsrc, fddest, NULL, COPYFILE_ACL | COPYFILE_XATTR) < 0) + paxwarn(1, "File %s had metadata that could not be copied: %s", arcn->org_name, + strerror(errno)); } #endif file_close(arcn, fddest); diff --git a/pax/buf_subs.c b/pax/buf_subs.c index 501b9fb..aff311a 100644 --- a/pax/buf_subs.c +++ b/pax/buf_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: buf_subs.c,v 1.20 2004/04/16 22:50:23 deraadt Exp $ */ +/* $OpenBSD: buf_subs.c,v 1.21 2005/11/09 19:59:06 otto Exp $ */ /* $NetBSD: buf_subs.c,v 1.5 1995/03/21 09:07:08 cgd Exp $ */ /*- @@ -38,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)buf_subs.c 8.2 (Berkeley) 4/18/94"; #else -static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: buf_subs.c,v 1.20 2004/04/16 22:50:23 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: buf_subs.c,v 1.21 2005/11/09 19:59:06 otto Exp $"; #endif #endif /* not lint */ @@ -677,7 +677,7 @@ rd_wrfile(ARCHD *arcn, int ofd, off_t *left) int rem; int sz = MINFBSZ; struct stat sb; - u_long crc = 0L; + u_int32_t crc = 0; /* * pass the blocksize of the file being written to the write routine, diff --git a/pax/cpio.1 b/pax/cpio.1 index 296205a..b518a02 100644 --- a/pax/cpio.1 +++ b/pax/cpio.1 @@ -1,5 +1,4 @@ -.\" $OpenBSD: cpio.1,v 1.20 2003/11/21 20:54:02 jmc Exp $ -.\" +.\"- .\" Copyright (c) 1997 SigmaSoft, Th. Lockert .\" All rights reserved. .\" @@ -23,7 +22,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: cpio.1,v 1.20 2003/11/21 20:54:02 jmc Exp $ +.\" $OpenBSD: cpio.1,v 1.16 2001/05/01 17:58:01 aaron Exp $ +.\" $FreeBSD: src/bin/pax/cpio.1,v 1.6 2005/02/09 18:02:29 ru Exp $ .\" .Dd February 16, 1997 .Dt CPIO 1 @@ -55,7 +55,7 @@ .Fl p .Op Fl adlLmuv .Ar destination-directory -.Ar "< name-list" +.No < Ar name-list .Sh DESCRIPTION The .Nm cpio @@ -106,8 +106,9 @@ SVR4 hex format. .It Ar tar Old tar format. -.It Ar ustar -POSIX ustar format. +.It Cm ustar +.Tn POSIX +ustar format. .El .It Fl L Follow symbolic links. @@ -178,8 +179,9 @@ SVR4 hex format. .It Ar tar Old tar format. -.It Ar ustar -POSIX ustar format. +.It Cm ustar +.Tn POSIX +ustar format. .El .It Fl I Ar archive Use the specified file as the input for the archive. @@ -208,6 +210,14 @@ format. Uncompress archive using .Xr gzip 1 format. +.It Fl Z +Uncompress archive using +.Xr compress 1 +format. +.It Fl 6 +Process old-style +.Nm +format archives. .El .It Fl p Copy files from one location to another in a single pass. @@ -284,7 +294,8 @@ specific archive format specification. .Xr pax 1 , .Xr tar 1 .Sh AUTHORS -Keith Muller at the University of California, San Diego. +.An Keith Muller +at the University of California, San Diego. .Sh BUGS The .Fl s diff --git a/pax/cpio.c b/pax/cpio.c index 058b8e3..4a97960 100644 --- a/pax/cpio.c +++ b/pax/cpio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpio.c,v 1.17 2004/04/16 22:50:23 deraadt Exp $ */ +/* $OpenBSD: cpio.c,v 1.18 2008/01/01 16:22:44 tobias Exp $ */ /* $NetBSD: cpio.c,v 1.5 1995/03/21 09:07:13 cgd Exp $ */ /*- @@ -38,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)cpio.c 8.1 (Berkeley) 5/31/93"; #else -static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: cpio.c,v 1.17 2004/04/16 22:50:23 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: cpio.c,v 1.18 2008/01/01 16:22:44 tobias Exp $"; #endif #endif /* not lint */ @@ -152,7 +152,7 @@ com_rd(ARCHD *arcn) } /* - * cpio_end_wr() + * cpio_endwr() * write the special file with the name trailer in the proper format * Return: * result of the write of the trailer from the cpio specific write func diff --git a/pax/extern.h b/pax/extern.h index 01f4f2a..6f09be3 100644 --- a/pax/extern.h +++ b/pax/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.29 2004/11/29 16:23:22 otto Exp $ */ +/* $OpenBSD: extern.h,v 1.33 2008/05/06 06:54:28 henning Exp $ */ /* $NetBSD: extern.h,v 1.5 1996/03/26 23:54:16 mrg Exp $ */ /*- @@ -64,6 +64,9 @@ int ar_next(void); * ar_subs.c */ extern u_long flcnt; +int updatepath(void); +int dochdir(const char *); +int fdochdir(int); void list(void); void extract(void); void append(void); @@ -145,9 +148,12 @@ int node_creat(ARCHD *); int unlnk_exist(char *, int); int chk_path(char *, uid_t, gid_t, char **); void set_ftime(char *fnm, time_t mtime, time_t atime, int frc); +void fset_ftime(char *fnm, int, time_t mtime, time_t atime, int frc); int set_ids(char *, uid_t, gid_t); +int fset_ids(char *, int, uid_t, gid_t); int set_lids(char *, uid_t, gid_t); void set_pmode(char *, mode_t); +void fset_pmode(char *, int, mode_t); int file_write(int, char *, int, int *, int *, int, char *); void file_flush(int, char *, int); void rdfile_close(ARCHD *, int *); @@ -159,6 +165,8 @@ int set_crc(ARCHD *, int); int ftree_start(void); int ftree_add(char *, int); void ftree_sel(ARCHD *); +void ftree_notsel(void); +void ftree_skipped_newer(ARCHD *); void ftree_chk(void); int next_file(ARCHD *); @@ -174,6 +182,7 @@ int ul_asc(u_long, char *, int, int); u_quad_t asc_uqd(char *, int, int); int uqd_asc(u_quad_t, char *, int, int); #endif +size_t fieldcpy(char *, size_t, const char *, size_t); /* * getoldopt.c @@ -189,9 +198,9 @@ void options(int, char **); OPLIST * opt_next(void); int opt_add(const char *); int bad_opt(void); -int pax_format_opt_add (char *); +int pax_format_opt_add(char *); int pax_opt(void); -extern char *chdname; +char *chdname; /* * pat_rep.c @@ -233,6 +242,7 @@ extern int nodirs; extern int pmode; extern int pids; extern int rmleadslash; +extern int secure; extern int exit_val; extern int docrc; extern char *dirptr; @@ -241,6 +251,7 @@ extern char *argv0; extern FILE *listf; extern char *tempfile; extern char *tempbase; +extern int havechd; int main(int, char **); void sig_cleanup(int); @@ -273,7 +284,7 @@ void atdir_end(void); void add_atdir(char *, dev_t, ino_t, time_t, time_t); int get_atdir(dev_t, ino_t, time_t *, time_t *); int dir_start(void); -void add_dir(char *, struct stat *, int); +void add_dir(char *, size_t, struct stat *, int); void proc_dir(void); u_int st_hash(char *, int, int); diff --git a/pax/file_subs.c b/pax/file_subs.c index c8e4ee5..23114e9 100644 --- a/pax/file_subs.c +++ b/pax/file_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: file_subs.c,v 1.28 2004/11/29 16:23:22 otto Exp $ */ +/* $OpenBSD: file_subs.c,v 1.30 2005/11/09 19:59:06 otto Exp $ */ /* $NetBSD: file_subs.c,v 1.4 1995/03/21 09:07:18 cgd Exp $ */ /*- @@ -38,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)file_subs.c 8.1 (Berkeley) 5/31/93"; #else -static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: file_subs.c,v 1.28 2004/11/29 16:23:22 otto Exp $"; +static const char rcsid[] = "$OpenBSD: file_subs.c,v 1.30 2005/11/09 19:59:06 otto Exp $"; #endif #endif /* not lint */ @@ -123,7 +123,7 @@ file_creat(ARCHD *arcn) * it cannot fix anything, we will skip the last attempt */ if ((fd = open(path_to_open, O_WRONLY | O_CREAT | O_TRUNC, - file_mode)) >= 0) { + file_mode)) >= 0) { /* clean up the invalid_action */ if (pax_invalid_action>0) { record_pax_invalid_action_results(arcn, path_to_open); @@ -140,7 +140,7 @@ file_creat(ARCHD *arcn) } } /* rc == 2 reserved for -o invalid_action=write */ - if (nodirs || chk_path(path_to_open,arcn->sb.st_uid,arcn->sb.st_gid, + if (nodirs || chk_path(path_to_open,arcn->sb.st_uid,arcn->sb.st_gid, (rc==2) ? &new_path: NULL) < 0) { syswarn((pax_invalid_action==0), oerrno, "Unable to create %s", arcn->name); fd = -1; @@ -149,7 +149,7 @@ file_creat(ARCHD *arcn) if (new_path) path_to_open = new_path; /* try again */ } if (strcmp(new_path, arcn->name)!=0) { - chdir(cwd); /* go back to original directory */ + dochdir(cwd); /* go back to original directory */ } return(fd); } @@ -169,6 +169,7 @@ file_close(ARCHD *arcn, int fd) if (fd < 0) return; + if (close(fd) < 0) syswarn(0, errno, "Unable to close file descriptor on %s", arcn->name); @@ -179,7 +180,8 @@ file_close(ARCHD *arcn, int fd) * modification times. */ if (pids) - res = set_ids(arcn->name, arcn->sb.st_uid, arcn->sb.st_gid); + res = set_ids(arcn->name, arcn->sb.st_uid, + arcn->sb.st_gid); else res = 1; /* without pids, pax should NOT set s bits */ @@ -403,6 +405,7 @@ node_creat(ARCHD *arcn) struct stat sb; char target[MAXPATHLEN]; char *nm = arcn->name; + int nmlen = arcn->nlen; int len; /* @@ -435,6 +438,7 @@ node_creat(ARCHD *arcn) } target[len] = '\0'; nm = target; + nmlen = len; } } res = mkdir(nm, file_mode); @@ -515,7 +519,7 @@ badlink: #endif set_ids(nm, arcn->sb.st_uid, arcn->sb.st_gid)); else - res = 1; /* without pids, pax should NOT set s bits */ + res = 1; /* without pids, pax should NOT set s bits */ /* * symlinks are done now. @@ -565,9 +569,9 @@ badlink: * we have to force the mode to what was set here, * since we changed it from the default as created. */ - add_dir(nm, &(arcn->sb), 1); + add_dir(nm, nmlen, &(arcn->sb), 1); } else if (pmode || patime || pmtime) - add_dir(nm, &(arcn->sb), 0); + add_dir(nm, nmlen, &(arcn->sb), 0); } if (patime || pmtime) @@ -645,6 +649,7 @@ int chk_path(char *name, uid_t st_uid, gid_t st_gid, char ** new_name) { char *spt = name; + int namelen = strlen(name); struct stat sb; int retval = -1; @@ -707,13 +712,12 @@ chk_path(char *name, uid_t st_uid, gid_t st_gid, char ** new_name) if ((access(name, R_OK | W_OK | X_OK) < 0) && (lstat(name, &sb) == 0)) { set_pmode(name, ((sb.st_mode & FILEBITS) | S_IRWXU)); - add_dir(name, &sb, 1); + add_dir(name, namelen, &sb, 1); } *(spt++) = '/'; if (new_name==NULL) continue; break; } - if ((new_name != NULL) && retval==0) { /* save the new path */ *(--spt) = '\0'; @@ -727,7 +731,7 @@ chk_path(char *name, uid_t st_uid, gid_t st_gid, char ** new_name) */ *new_name = spt; } else - *spt++ = '/'; + *spt = '/'; } return(retval); } @@ -769,7 +773,6 @@ set_ftime(char *fnm, time_t mtime, time_t atime, int frc) /* * set the times */ - if (pax_invalid_action_write_cwd) { char cwd_buff[MAXPATHLEN]; char * cwd; @@ -788,6 +791,36 @@ set_ftime(char *fnm, time_t mtime, time_t atime, int frc) return; } +void +fset_ftime(char *fnm, int fd, time_t mtime, time_t atime, int frc) +{ + static struct timeval tv[2] = {{0L, 0L}, {0L, 0L}}; + struct stat sb; + + tv[0].tv_sec = (long)atime; + tv[1].tv_sec = (long)mtime; + if (!frc && (!patime || !pmtime)) { + /* + * if we are not forcing, only set those times the user wants + * set. We get the current values of the times if we need them. + */ + if (fstat(fd, &sb) == 0) { + if (!patime) + tv[0].tv_sec = (long)sb.st_atime; + if (!pmtime) + tv[1].tv_sec = (long)sb.st_mtime; + } else + syswarn(0,errno,"Unable to obtain file stats %s", fnm); + } + /* + * set the times + */ + if (futimes(fd, tv) < 0) + syswarn(1, errno, "Access/modification time set failed on: %s", + fnm); + return; +} + /* * set_ids() * set the uid and gid of a file system node @@ -812,8 +845,24 @@ set_ids(char *fnm, uid_t uid, gid_t gid) return(0); } +int +fset_ids(char *fnm, int fd, uid_t uid, gid_t gid) +{ + if (fchown(fd, uid, gid) < 0) { + /* + * ignore EPERM unless in verbose mode or being run by root. + * if running as pax, POSIX requires a warning. + */ + if (strcmp(NM_PAX, argv0) == 0 || errno != EPERM || vflag || + geteuid() == 0) + syswarn(1, errno, "Unable to set file uid/gid of %s", + fnm); + return(-1); + } + return(0); +} + #if !defined(__APPLE__) -/* Mac OS X doesn't have lchown */ /* * set_lids() * set the uid and gid of a file system node @@ -837,7 +886,7 @@ set_lids(char *fnm, uid_t uid, gid_t gid) } return(0); } -#endif +#endif /* !__APPLE__ */ /* * set_pmode() @@ -853,6 +902,15 @@ set_pmode(char *fnm, mode_t mode) return; } +void +fset_pmode(char *fnm, int fd, mode_t mode) +{ + mode &= ABITS; + if (fchmod(fd, mode) < 0) + syswarn(1, errno, "Could not set permissions on %s", fnm); + return; +} + /* * file_write() * Write/copy a file (during copy or archive extract). This routine knows @@ -1074,7 +1132,7 @@ set_crc(ARCHD *arcn, int fd) int res; off_t cpcnt = 0L; u_long size; - unsigned long crc = 0L; + u_int32_t crc = 0; char tbuf[FILEBLK]; struct stat sb; diff --git a/pax/ftree.c b/pax/ftree.c index 14d1712..7bb4a80 100644 --- a/pax/ftree.c +++ b/pax/ftree.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ftree.c,v 1.25 2004/04/16 22:50:23 deraadt Exp $ */ +/* $OpenBSD: ftree.c,v 1.28 2008/05/06 06:54:28 henning Exp $ */ /* $NetBSD: ftree.c,v 1.4 1995/03/21 09:07:21 cgd Exp $ */ /*- @@ -38,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)ftree.c 8.2 (Berkeley) 4/18/94"; #else -static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: ftree.c,v 1.25 2004/04/16 22:50:23 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: ftree.c,v 1.28 2008/05/06 06:54:28 henning Exp $"; #endif #endif /* not lint */ @@ -170,6 +170,7 @@ ftree_add(char *str, int chflg) str[len] = '\0'; ft->fname = str; ft->refcnt = 0; + ft->newercnt = 0; ft->chflg = chflg; ft->fow = NULL; if (fthead == NULL) { @@ -215,6 +216,31 @@ ftree_sel(ARCHD *arcn) } /* + * ftree_notsel() + * this entry has not been selected by pax. + */ + +void +ftree_notsel() +{ + if (ftent != NULL) + (void)fts_set(ftsp, ftent, FTS_SKIP); +} + +/* + * ftree_skipped_newer() + * file has been skipped because a newer file exists and -u/-D given + */ + +void +ftree_skipped_newer(ARCHD *arcn) +{ + /* skipped due to -u/-D, mark accordingly */ + if (ftcur != NULL) + ftcur->newercnt = 1; +} + +/* * ftree_chk() * called at end on pax execution. Prints all those file args that did not * have a selected member (reference count still 0) @@ -237,7 +263,7 @@ ftree_chk(void) * that never had a match */ for (ft = fthead; ft != NULL; ft = ft->fow) { - if ((ft->refcnt > 0) || ft->chflg) + if ((ft->refcnt > 0) || ft->newercnt > 0 || ft->chflg) continue; if (wban == 0) { paxwarn(1,"WARNING! These file names were not selected:"); @@ -291,12 +317,12 @@ ftree_arg(void) return(-1); if (ftcur->chflg) { /* First fchdir() back... */ - if (fchdir(cwdfd) < 0) { + if (fdochdir(cwdfd) < 0) { syswarn(1, errno, "Can't fchdir to starting directory"); return(-1); } - if (chdir(ftcur->fname) < 0) { + if (dochdir(ftcur->fname) < 0) { syswarn(1, errno, "Can't chdir to %s", ftcur->fname); return(-1); @@ -355,6 +381,8 @@ next_file(ARCHD *arcn) */ for (;;) { if ((ftent = fts_read(ftsp)) == NULL) { + if (errno) + syswarn(1, errno, "next_file"); /* * out of files in this tree, go to next arg, if none * we are done @@ -501,6 +529,8 @@ next_file(ARCHD *arcn) * copy file name, set file name length */ arcn->nlen = strlcpy(arcn->name, ftent->fts_path, sizeof(arcn->name)); + if (arcn->nlen >= sizeof(arcn->name)) + arcn->nlen = sizeof(arcn->name) - 1; /* XXX truncate? */ arcn->org_name = ftent->fts_path; return(0); } diff --git a/pax/ftree.h b/pax/ftree.h index 0507aab..9b4cffc 100644 --- a/pax/ftree.h +++ b/pax/ftree.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ftree.h,v 1.4 2003/06/02 23:32:08 millert Exp $ */ +/* $OpenBSD: ftree.h,v 1.5 2008/05/06 06:54:28 henning Exp $ */ /* $NetBSD: ftree.h,v 1.3 1995/03/21 09:07:23 cgd Exp $ */ /*- @@ -45,6 +45,7 @@ typedef struct ftree { char *fname; /* file tree name */ int refcnt; /* has tree had a selected file? */ + int newercnt; /* skipped due to -u/-D */ int chflg; /* change directory flag */ struct ftree *fow; /* pointer to next entry on list */ } FTREE; diff --git a/pax/gen_subs.c b/pax/gen_subs.c index 36bbb41..79438e0 100644 --- a/pax/gen_subs.c +++ b/pax/gen_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gen_subs.c,v 1.17 2003/06/13 17:51:14 millert Exp $ */ +/* $OpenBSD: gen_subs.c,v 1.19 2007/04/04 21:55:10 millert Exp $ */ /* $NetBSD: gen_subs.c,v 1.5 1995/03/21 09:07:26 cgd Exp $ */ /*- @@ -38,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)gen_subs.c 8.1 (Berkeley) 5/31/93"; #else -static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: gen_subs.c,v 1.17 2003/06/13 17:51:14 millert Exp $"; +static const char rcsid[] = "$OpenBSD: gen_subs.c,v 1.19 2007/04/04 21:55:10 millert Exp $"; #endif #endif /* not lint */ @@ -48,11 +48,11 @@ static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: gen_subs.c,v #include #include #include -#include #include #include #include #include +#include #include "pax.h" #include "extern.h" @@ -66,38 +66,13 @@ static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: gen_subs.c,v #define MODELEN 20 #define DATELEN 64 #define SIXMONTHS ((DAYSPERNYEAR / 2) * SECSPERDAY) -#define CURFRMT "%b %e %H:%M" -#define OLDFRMT "%b %e %Y" +#define CURFRMTM "%b %e %H:%M" +#define OLDFRMTM "%b %e %Y" +#define CURFRMTD "%e %b %H:%M" +#define OLDFRMTD "%e %b %Y" #define NAME_WIDTH 8 -/* - * format_date - * format date of file for printing - */ - -static void -format_date(char * f_date, time_t file_time, time_t current) -{ - const char *timefrmt; - - if (ltmfrmt == NULL) { - /* - * no locale specified format. - */ - /* use the same format that ls -l uses */ - if ((file_time + SIXMONTHS) <= current || file_time > current) - timefrmt = OLDFRMT; - else - timefrmt = CURFRMT; - } else - timefrmt = ltmfrmt; - - /* - * convert time to string for printing - */ - if (strftime(f_date,DATELEN,timefrmt,localtime((const time_t *)&(file_time))) == 0) - *f_date = '\0'; -} +static int d_first = -1; /* * ls_list() @@ -110,6 +85,7 @@ ls_list(ARCHD *arcn, time_t now, FILE *fp) struct stat *sbp; char f_mode[MODELEN]; char f_date[DATELEN]; + const char *timefrmt; int term; term = zeroflag ? '\0' : '\n'; /* path termination character */ @@ -131,17 +107,30 @@ ls_list(ARCHD *arcn, time_t now, FILE *fp) pax_format_list_output(arcn, now, fp, term); return; } + + if (d_first < 0) + d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); /* * user wants long mode */ sbp = &(arcn->sb); strmode(sbp->st_mode, f_mode); - format_date(&f_date[0], sbp->st_mtime, now); + /* + * time format based on age compared to the time pax was started. + */ + if ((sbp->st_mtime + SIXMONTHS) <= now || + sbp->st_mtime > now) + timefrmt = d_first ? OLDFRMTD : OLDFRMTM; + else + timefrmt = d_first ? CURFRMTD : CURFRMTM; /* * print file mode, link count, uid, gid and time */ + if (strftime(f_date,DATELEN,timefrmt,localtime(&(sbp->st_mtime))) == 0) + f_date[0] = '\0'; +#define UT_NAMESIZE 8 (void)fprintf(fp, "%s%2u %-*.*s %-*.*s ", f_mode, sbp->st_nlink, NAME_WIDTH, UT_NAMESIZE, name_uid(sbp->st_uid, 1), NAME_WIDTH, UT_NAMESIZE, name_gid(sbp->st_gid, 1)); @@ -174,7 +163,7 @@ ls_list(ARCHD *arcn, time_t now, FILE *fp) fputs(" == ", fp); safe_print(arcn->ln_name, fp); } else if (arcn->type == PAX_SLK) { - fputs(" => ", fp); + fputs(" -> ", fp); safe_print(arcn->ln_name, fp); } (void)putc(term, fp); @@ -192,9 +181,22 @@ ls_tty(ARCHD *arcn) { char f_date[DATELEN]; char f_mode[MODELEN]; + const char *timefrmt; - format_date(&f_date[0], arcn->sb.st_mtime, time(NULL)); + if (d_first < 0) + d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); + if ((arcn->sb.st_mtime + SIXMONTHS) <= time(NULL)) + timefrmt = d_first ? OLDFRMTD : OLDFRMTM; + else + timefrmt = d_first ? CURFRMTD : CURFRMTM; + + /* + * convert time to string, and print + */ + if (strftime(f_date, DATELEN, timefrmt, + localtime(&(arcn->sb.st_mtime))) == 0) + f_date[0] = '\0'; strmode(arcn->sb.st_mode, f_mode); tty_prnt("%s%s %s\n", f_mode, f_date, arcn->name); return; @@ -412,3 +414,25 @@ uqd_asc(u_quad_t val, char *str, int len, int base) return(0); } #endif + +/* + * Copy at max min(bufz, fieldsz) chars from field to buf, stopping + * at the first NUL char. NUL terminate buf if there is room left. + */ +size_t +fieldcpy(char *buf, size_t bufsz, const char *field, size_t fieldsz) +{ + char *p = buf; + const char *q = field; + size_t i = 0; + + if (fieldsz > bufsz) + fieldsz = bufsz; + while (i < fieldsz && *q != '\0') { + *p++ = *q++; + i++; + } + if (i < bufsz) + *p = '\0'; + return(i); +} diff --git a/pax/getoldopt.c b/pax/getoldopt.c index 6b62092..45fdbf2 100644 --- a/pax/getoldopt.c +++ b/pax/getoldopt.c @@ -11,7 +11,7 @@ */ #ifndef lint -static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: getoldopt.c,v 1.8 2003/07/02 21:19:33 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: getoldopt.c,v 1.8 2003/07/02 21:19:33 deraadt Exp $"; #endif /* not lint */ #include diff --git a/pax/options.c b/pax/options.c index feb97e2..854d8dc 100644 --- a/pax/options.c +++ b/pax/options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options.c,v 1.61 2004/04/16 22:50:23 deraadt Exp $ */ +/* $OpenBSD: options.c,v 1.70 2008/06/11 00:49:08 pvalchev Exp $ */ /* $NetBSD: options.c,v 1.6 1996/03/26 23:54:18 mrg Exp $ */ /*- @@ -38,14 +38,17 @@ #if 0 static const char sccsid[] = "@(#)options.c 8.2 (Berkeley) 4/18/94"; #else -static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: options.c,v 1.61 2004/04/16 22:50:23 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: options.c,v 1.70 2008/06/11 00:49:08 pvalchev Exp $"; #endif #endif /* not lint */ #include #include #include +#include +#ifndef __APPLE__ #include +#endif /* __APPLE__ */ #include #include #include @@ -54,7 +57,7 @@ static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: options.c,v 1 #include #include #include -#include +#include #include "pax.h" #include "options.h" #include "cpio.h" @@ -89,6 +92,7 @@ static int getline_error; #define GZIP_CMD "gzip" /* command to run as gzip */ #define COMPRESS_CMD "compress" /* command to run as compress */ +#define BZIP2_CMD "bzip2" /* command to run as bzip2 */ /* * Format specific routine table - MUST BE IN SORTED ORDER BY NAME @@ -140,7 +144,7 @@ FSUB fsub[] = { #define F_CPIO 3 /* format when called as cpio */ #define F_OTAR 4 /* format when called as tar -o */ #define F_TAR 5 /* format when called as tar */ -#define F_PAX 6 /* format when called as pax -x pax */ +#define F_PAX 6 /* format for pax */ #define DEFLT 5 /* default write format from list above */ /* @@ -151,6 +155,11 @@ FSUB fsub[] = { int ford[] = {6, 5, 4, 3, 2, 1, 0, -1 }; /* + * Do we have -C anywhere? + */ +int havechd = 0; + +/* * options() * figure out if we are pax, tar or cpio. Call the appropriate options * parser @@ -182,6 +191,12 @@ options(int argc, char **argv) pax_options(argc, argv); } +#define OPT_INSECURE 1 +struct option pax_longopts[] = { + { "insecure", no_argument, 0, OPT_INSECURE }, + { 0, 0, 0, 0 }, +}; + /* * pax_options() * look at the user specified flags. set globals as required and check if @@ -192,7 +207,7 @@ static void pax_options(int argc, char **argv) { int c; - int i; + size_t i; unsigned int flg = 0; unsigned int bflg = 0; char *pt; @@ -204,9 +219,16 @@ pax_options(int argc, char **argv) /* * process option flags */ - while ((c=getopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:zB:DE:G:HLPT:U:XYZ0")) - != -1) { + while ((c=getopt_long(argc,argv,"0ab:cdf:ijklno:p:rs:tuvwx:zB:DE:G:HLOPT:U:XYZ", pax_longopts, NULL)) != -1) { switch (c) { + case '0': + /* + * Use \0 as pathname terminator. + * (For use with the -print0 option of find(1).) + */ + zeroflag = 1; + flg |= C0F; + break; case 'a': /* * append @@ -258,6 +280,12 @@ pax_options(int argc, char **argv) iflag = 1; flg |= IF; break; + case 'j': + /* + * use bzip2. Non standard option. + */ + gzip_program = BZIP2_CMD; + break; case 'k': /* * do not clobber files that exist @@ -384,13 +412,9 @@ pax_options(int argc, char **argv) * specify an archive format on write */ tmp.name = optarg; -/* - if ((frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub, - sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt)) != NULL) { -*/ n_fsub = sizeof(fsub)/sizeof(FSUB); - if ((frmt = (FSUB *)lsearch((void *)&tmp, (void *)fsub, - &n_fsub, sizeof(FSUB), c_frmt)) != NULL) { + if ((frmt = (FSUB *)lsearch(&tmp, fsub, &n_fsub, sizeof(FSUB), + c_frmt)) != NULL) { flg |= XF; break; } @@ -532,13 +556,8 @@ pax_options(int argc, char **argv) Zflag = 1; flg |= CZF; break; - case '0': - /* - * Use \0 as pathname terminator. - * (For use with the -print0 option of find(1).) - */ - zeroflag = 1; - flg |= C0F; + case OPT_INSECURE: + secure = 0; break; default: pax_usage(); @@ -669,7 +688,7 @@ tar_options(int argc, char **argv) * process option flags */ while ((c = getoldopt(argc, argv, - "b:cef:hmopqruts:vwxzBC:HI:LOPXZ014578")) != -1) { + "b:cef:hjmopqruts:vwxzBC:HI:LOPXZ014578")) != -1) { switch (c) { case 'b': /* @@ -714,6 +733,12 @@ tar_options(int argc, char **argv) */ Lflag = 1; break; + case 'j': + /* + * use bzip2. Non standard option. + */ + gzip_program = BZIP2_CMD; + break; case 'm': /* * do not preserve modification time @@ -793,6 +818,7 @@ tar_options(int argc, char **argv) */ break; case 'C': + havechd++; chdname = optarg; break; case 'H': @@ -884,7 +910,7 @@ tar_options(int argc, char **argv) default: { int sawpat = 0; - char *file, *dir; + char *file, *dir = NULL; while (nincfiles || *argv != NULL) { /* @@ -931,6 +957,7 @@ tar_options(int argc, char **argv) if (*++argv == NULL) break; chdname = *argv++; + havechd++; } else if (pat_add(*argv++, chdname) < 0) tar_usage(); else @@ -958,7 +985,7 @@ tar_options(int argc, char **argv) } while (nincfiles || *argv != NULL) { - char *file, *dir; + char *file, *dir = NULL; /* * If we queued up any include files, pull them in @@ -1010,6 +1037,7 @@ tar_options(int argc, char **argv) break; if (ftree_add(*argv++, 1) < 0) tar_usage(); + havechd++; } else if (ftree_add(*argv++, 0) < 0) tar_usage(); } @@ -1076,9 +1104,7 @@ cpio_options(int argc, char **argv) FILE *fp; size_t n_fsub; - listf = stderr; - kflag = 0; - uflag = 1; + kflag = 1; pids = 1; pmode = 1; pmtime = 0; @@ -1086,7 +1112,7 @@ cpio_options(int argc, char **argv) dflag = 1; act = -1; nodirs = 1; - while ((c=getopt(argc,argv,"abcdfiklmoprstuvzABC:E:F:H:I:LO:SZ6")) != -1) + while ((c=getopt(argc,argv,"abcdfijklmoprstuvzABC:E:F:H:I:LO:SZ6")) != -1) switch (c) { case 'a': /* @@ -1123,6 +1149,12 @@ cpio_options(int argc, char **argv) */ act = EXTRACT; break; + case 'j': + /* + * use bzip2. Non standard option. + */ + gzip_program = BZIP2_CMD; + break; case 'k': break; case 'l': @@ -1172,7 +1204,7 @@ cpio_options(int argc, char **argv) /* * replace newer files */ - uflag = 0; + kflag = 0; break; case 'v': /* @@ -1241,10 +1273,6 @@ cpio_options(int argc, char **argv) * specify an archive format on write */ tmp.name = optarg; -/* - if ((frmt = (FSUB *)bsearch((void *)&tmp, (void *)fsub, - sizeof(fsub)/sizeof(FSUB), sizeof(FSUB), c_frmt)) != NULL) -*/ n_fsub = sizeof(fsub)/sizeof(FSUB); if ((frmt = (FSUB *)lsearch((void *)&tmp, (void *)fsub, &n_fsub, sizeof(FSUB), c_frmt)) != NULL) @@ -1359,7 +1387,7 @@ printflg(unsigned int flg) static int c_frmt(const void *a, const void *b) { - return(strcmp(((FSUB *)a)->name, ((FSUB *)b)->name)); + return(strcmp(((const FSUB *)a)->name, ((const FSUB *)b)->name)); } /* @@ -1412,11 +1440,11 @@ bad_opt(void) /* * opt_add() - * breaks the value supplied to -o into a option name and value. options + * breaks the value supplied to -o into an option name and value. Options * are given to -o in the form -o name-value,name=value * multiple -o may be specified. * Return: - * 0 if format in name=value format, -1 if -o is passed junk + * 0 if format in name=value format, -1 if -o is passed junk. */ int @@ -1425,8 +1453,8 @@ opt_add(const char *str) OPLIST *opt; char *frpt; char *pt; - char *endpt; char *dstr; + char *endpt; if ((str == NULL) || (*str == '\0')) { paxwarn(0, "Invalid option name"); @@ -1436,7 +1464,7 @@ opt_add(const char *str) paxwarn(0, "Unable to allocate space for option list"); return(-1); } - frpt = endpt = dstr; + frpt = dstr; /* * break into name and values pieces and stuff each one into a @@ -1475,7 +1503,6 @@ opt_add(const char *str) return(0); } - /* * pax_format_opt_add() * breaks the value supplied to -o into a option name and value. options @@ -1502,7 +1529,7 @@ pax_format_opt_add(register char *str) paxwarn(0, "Unable to allocate space for option list"); return(-1); } - frpt = endpt = str; + frpt = str; /* * break into name and values pieces and stuff each one into a @@ -1667,29 +1694,17 @@ no_op(void) void pax_usage(void) { - (void)fputs("usage: pax [-cdnvzO] [-E limit] [-f archive] ", stderr); - (void)fputs("[-s replstr] ... [-U user] ...", stderr); - (void)fputs("\n [-G group] ... ", stderr); - (void)fputs("[-T [from_date][,to_date]] ... ", stderr); - (void)fputs("[pattern ...]\n", stderr); - (void)fputs(" pax -r [-cdiknuvzDOYZ] [-E limit] ", stderr); - (void)fputs("[-f archive] [-o options] ... \n", stderr); - (void)fputs(" [-p string] ... [-s replstr] ... ", stderr); - (void)fputs("[-U user] ... [-G group] ...\n ", stderr); - (void)fputs("[-T [from_date][,to_date]] ... ", stderr); - (void)fputs(" [pattern ...]\n", stderr); - (void)fputs(" pax -w [-dituvzHLOPX] [-b blocksize] ", stderr); - (void)fputs("[ [-a] [-f archive] ] [-x format] \n", stderr); - (void)fputs(" [-B bytes] [-s replstr] ... ", stderr); - (void)fputs("[-o options] ... [-U user] ...", stderr); - (void)fputs("\n [-G group] ... ", stderr); - (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr); - (void)fputs("[file ...]\n", stderr); - (void)fputs(" pax -r -w [-diklntuvDHLOPXYZ] ", stderr); - (void)fputs("[-p string] ... [-s replstr] ...", stderr); - (void)fputs("\n [-U user] ... [-G group] ... ", stderr); - (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr); - (void)fputs("\n [file ...] directory\n", stderr); + (void)fputs( + "usage: pax [-0cdjnOvz] [-E limit] [-f archive] [-G group] [-s replstr]\n" + " [-T range] [-U user] [--insecure] [pattern ...]\n" + " pax -r [-0cDdijknOuvYZz] [-E limit] [-f archive] [-G group] [-o options]\n" + " [-p string] [-s replstr] [-T range] [-U user] [--insecure] [pattern ...]\n" + " pax -w [-0adHijLOPtuvXz] [-B bytes] [-b blocksize] [-f archive]\n" + " [-G group] [-o options] [-s replstr] [-T range] [-U user]\n" + " [-x format] [--insecure] [file ...]\n" + " pax -rw [-0DdHikLlnOPtuvXYZ] [-G group] [-p string] [-s replstr]\n" + " [-T range] [-U user] [--insecure] [file ...] directory\n", + stderr); exit(1); } @@ -1701,9 +1716,12 @@ pax_usage(void) void tar_usage(void) { - (void)fputs("usage: tar [-]{crtux}[-befhmopqsvwzHLOPXZ014578] [blocksize] ", - stderr); - (void)fputs("[archive] [replstr] [-C directory] [-I file] [file ...]\n", + (void)fputs( + "usage: tar {crtux}[014578befHhjLmOoPpqsvwXZz]\n" + " [blocking-factor | archive | replstr] [-C directory] [-I file]\n" + " [file ...]\n" + " tar {-crtux} [-014578eHhjLmOoPpqvwXZz] [-b blocking-factor]\n" + " [-C directory] [-f archive] [-I file] [-s replstr] [file ...]\n", stderr); exit(1); } @@ -1716,10 +1734,12 @@ tar_usage(void) void cpio_usage(void) { - (void)fputs("usage: cpio -o [-aABcLvVzZ] [-C bytes] [-H format] [-O archive]\n", stderr); - (void)fputs(" [-F archive] < name-list [> archive]\n", stderr); - (void)fputs(" cpio -i [-bBcdfmnrsStuvVzZ6] [-C bytes] [-E file] [-H format]\n", stderr); - (void)fputs(" [-I archive] [-F archive] [pattern...] [< archive]\n", stderr); - (void)fputs(" cpio -p [-adlLmuvV] destination-directory < name-list\n", stderr); + (void)fputs( + "usage: cpio -o [-AaBcjLvZz] [-C bytes] [-F archive] [-H format]\n" + " [-O archive] < name-list [> archive]\n" + " cpio -i [-6BbcdfjmrSstuvZz] [-C bytes] [-E file] [-F archive] [-H format]\n" + " [-I archive] [pattern ...] [< archive]\n" + " cpio -p [-adLlmuv] destination-directory < name-list\n", + stderr); exit(1); } diff --git a/pax/pat_rep.c b/pax/pat_rep.c index 5f46864..8bfedc5 100644 --- a/pax/pat_rep.c +++ b/pax/pat_rep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pat_rep.c,v 1.28 2004/06/11 03:10:43 millert Exp $ */ +/* $OpenBSD: pat_rep.c,v 1.30 2005/08/05 08:30:10 djm Exp $ */ /* $NetBSD: pat_rep.c,v 1.4 1995/03/21 09:07:33 cgd Exp $ */ /*- @@ -38,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)pat_rep.c 8.2 (Berkeley) 4/18/94"; #else -static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: pat_rep.c,v 1.28 2004/06/11 03:10:43 millert Exp $"; +static const char rcsid[] = "$OpenBSD: pat_rep.c,v 1.30 2005/08/05 08:30:10 djm Exp $"; #endif #endif /* not lint */ @@ -468,7 +468,7 @@ pat_match(ARCHD *arcn) /* * we had a match, now when we invert the sense (-c) we reject this * member. However we have to tag the pattern a being successful, (in a - * match, not in selecting a archive member) so we call pat_sel() here. + * match, not in selecting an archive member) so we call pat_sel() here. */ arcn->pat = pt; if (!cflag) @@ -518,7 +518,7 @@ fn_match(char *pattern, char *string, char **pend) *pend = string; return(0); case '?': - if ((test = *string++) == '\0') + if ((*string++) == '\0') return (-1); break; case '*': @@ -538,7 +538,7 @@ fn_match(char *pattern, char *string, char **pend) /* * General case, use recursion. */ - while ((test = *string) != '\0') { + while ((*string) != '\0') { if (!fn_match(pattern, string, pend)) return (0); ++string; @@ -614,7 +614,7 @@ mod_name(ARCHD *arcn) * Strip off leading '/' if appropriate. * Currently, this option is only set for the tar format. */ - if (rmleadslash && arcn->name[0] == '/') { + while (rmleadslash && arcn->name[0] == '/') { if (arcn->name[1] == '\0') { arcn->name[0] = '.'; } else { @@ -627,7 +627,7 @@ mod_name(ARCHD *arcn) paxwarn(0, "Removing leading / from absolute path names in the archive"); } } - if (rmleadslash && arcn->ln_name[0] == '/' && + while (rmleadslash && arcn->ln_name[0] == '/' && (arcn->type == PAX_HLK || arcn->type == PAX_HRG)) { if (arcn->ln_name[1] == '\0') { arcn->ln_name[0] = '.'; @@ -750,6 +750,8 @@ tty_rename(ARCHD *arcn) tty_prnt("Processing continues, name changed to: %s\n", tmpname); res = add_name(arcn->name, arcn->nlen, tmpname); arcn->nlen = strlcpy(arcn->name, tmpname, sizeof(arcn->name)); + if (arcn->nlen >= sizeof(arcn->name)) + arcn->nlen = sizeof(arcn->name) - 1; /* XXX truncate? */ if (res < 0) return(-1); return(0); @@ -1051,7 +1053,7 @@ resub(regex_t *rp, regmatch_t *pm, char *src, char *inpt, char *dest, * fail if we run out of space or the match string is damaged */ if (len > (destend - dpt)) - return (-1); + len = destend - dpt; strncpy(dpt, inpt + pmpt->rm_so, len); dpt += len; } diff --git a/pax/pat_rep.h b/pax/pat_rep.h index 72b8bee..9138d22 100644 --- a/pax/pat_rep.h +++ b/pax/pat_rep.h @@ -48,4 +48,4 @@ typedef struct replace { struct replace *fow; /* pointer to next pattern */ } REPLACE; -int tty_rename(ARCHD *); /* Used for -o invalid=rename recovery */ +int tty_rename(ARCHD *); /* used for -o invalid=rename recovery */ diff --git a/pax/pax.1 b/pax/pax.1 index 0ad62b3..e79cc4b 100644 --- a/pax/pax.1 +++ b/pax/pax.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pax.1,v 1.44 2004/02/19 19:15:32 jmc Exp $ +.\" $OpenBSD: pax.1,v 1.54 2008/06/11 07:42:50 jmc Exp $ .\" $NetBSD: pax.1,v 1.3 1995/03/21 09:07:37 cgd Exp $ .\" .\" Copyright (c) 1992 Keith Muller. @@ -34,154 +34,65 @@ .\" .\" @(#)pax.1 8.4 (Berkeley) 4/18/94 .\" -.Dd April 18, 1994 +.Dd $Mdocdate: June 11 2008 $ .Dt PAX 1 .Os .Sh NAME .Nm pax .Nd read and write file archives and copy directory hierarchies .Sh SYNOPSIS -.Nm pax -.Op Fl 0cdnvz .Bk -words +.Nm pax +.Op Fl 0cdjnOvz +.Op Fl E Ar limit .Op Fl f Ar archive -.Ek -.Bk -words +.Op Fl G Ar group .Op Fl s Ar replstr -.Ar ... -.Ek -.Bk -words +.Op Fl T Ar range .Op Fl U Ar user -.Ar ... -.Ek -.Bk -words -.Op Fl G Ar group -.Ar ... -.Ek -.Bk -words -.Oo -.Fl T -.Op Ar from_date -.Op Ar ,to_date -.Oc -.Ar ... -.Ek .Op Ar pattern ... .Nm pax .Fl r -.Op Fl cdiknuvzDYZ -.Bk -words +.Op Fl 0cDdijknOuvYZz +.Op Fl E Ar limit .Op Fl f Ar archive -.Ek -.Bk -words +.Op Fl G Ar group .Op Fl o Ar options -.Ar ... -.Ek -.Bk -words .Op Fl p Ar string -.Ar ... -.Ek -.Bk -words .Op Fl s Ar replstr -.Ar ... -.Ek -.Op Fl E Ar limit -.Bk -words +.Op Fl T Ar range .Op Fl U Ar user -.Ar ... -.Ek -.Bk -words -.Op Fl G Ar group -.Ar ... -.Ek -.Bk -words -.Oo -.Fl T -.Op Ar from_date -.Op Ar ,to_date -.Oc -.Ar ... -.Ek .Op Ar pattern ... .Nm pax .Fl w -.Op Fl 0dituvzHLPX -.Bk -words +.Op Fl 0adHijLOPtuvXz +.Op Fl B Ar bytes .Op Fl b Ar blocksize -.Ek -.Oo -.Op Fl a .Op Fl f Ar archive -.Oc -.Bk -words -.Op Fl x Ar format -.Ek -.Bk -words -.Op Fl s Ar replstr -.Ar ... -.Ek -.Bk -words +.Op Fl G Ar group .Op Fl o Ar options -.Ar ... -.Ek -.Bk -words +.Op Fl s Ar replstr +.Op Fl T Ar range .Op Fl U Ar user -.Ar ... -.Ek -.Bk -words -.Op Fl G Ar group -.Ar ... -.Ek -.Bk -words -.Op Fl B Ar bytes -.Ek -.Bk -words -.Oo -.Fl T -.Op Ar from_date -.Op Ar ,to_date -.Op Ar /[c][m] -.Oc -.Ar ... -.Ek +.Op Fl x Ar format .Op Ar file ... .Nm pax -.Fl r -.Fl w -.Op Fl 0diklntuvDHLPXYZ -.Bk -words +.Fl rw +.Op Fl 0DdHijkLlnOPtuvXYZ +.Op Fl G Ar group .Op Fl p Ar string -.Ar ... -.Ek -.Bk -words .Op Fl s Ar replstr -.Ar ... -.Ek -.Bk -words +.Op Fl T Ar range .Op Fl U Ar user -.Ar ... -.Ek -.Bk -words -.Op Fl G Ar group -.Ar ... -.Ek -.Bk -words -.Oo -.Fl T -.Op Ar from_date -.Op Ar ,to_date -.Op Ar /[c][m] -.Oc -.Ar ... -.Ek .Op Ar file ... .Ar directory +.Ek .Sh DESCRIPTION -.Nm pax -will read, write, and list the members of an archive file, +.Nm +will read, write, and list the members of an archive file and will copy directory hierarchies. -.Nm pax -operation is independent of the specific archive format, +.Nm +operation is independent of the specific archive format and supports a wide variety of different archive formats. A list of supported archive formats can be found under the description of the .Fl x @@ -192,40 +103,46 @@ The presence of the and the .Fl w options specifies which of the following functional modes -.Nm pax +.Nm will operate under: .Em list , read , write , and .Em copy . .Bl -tag -width 6n -.It +.It \*(Ltnone\*(Gt .Em List . -.Nm pax +.Nm will write to standard output a table of contents of the members of the archive file read from standard input, whose pathnames match the specified -.Ar patterns . +.Ar pattern +arguments. The table of contents contains one filename per line and is written using single line buffering. -.\" ========== .It Fl r .Em Read . -.Nm pax +.Nm extracts the members of the archive file read from the standard input, with pathnames matching the specified -.Ar patterns . +.Ar pattern +arguments. The archive format and blocking is automatically determined on input. When an extracted file is a directory, the entire file hierarchy rooted at that directory is extracted. -All extracted files are created relative to the current file hierarchy. +Extracted files are created either at absolute paths (those that begin +with a / character) or relative to the current file hierarchy unless the +.Fl s +option is used to remove leading slashes or add a relative path prefix. +Files being extracted to absolute paths may overwrite +files outside of the current working directory, +so care should be taken when extracting untrusted archives. The setting of ownership, access and modification times, and file mode of the extracted files are discussed in more detail under the .Fl p option. -.\" ========== .It Fl w .Em Write . -.Nm pax +.Nm writes an archive containing the .Ar file operands to standard output @@ -238,10 +155,9 @@ When a .Ar file operand is also a directory, the entire file hierarchy rooted at that directory will be included. -.\" ========== -.It Fl r Fl w +.It Fl rw .Em Copy . -.Nm pax +.Nm copies the .Ar file operands to the destination @@ -262,7 +178,7 @@ the original and the copied files (see the .Fl l option below). .Pp -.Em Warning : +.Sy Warning : The destination .Ar directory must not be one of the @@ -280,7 +196,7 @@ While processing a damaged archive during a or .Em list operation, -.Nm pax +.Nm will attempt to recover from media defects and will search through the archive to locate and process the largest number of archive members possible (see the .Fl E @@ -293,7 +209,7 @@ If the .Ar directory operand does not exist, or it is not writable by the user, or it is not of type directory, -.Nm pax +.Nm will exit with a non-zero exit status. .Pp The @@ -301,7 +217,7 @@ The operand is used to select one or more pathnames of archive members. Archive members are selected using the pattern matching notation described by -.Xr fnmatch 3 . +.Xr glob 3 . When the .Ar pattern operand is not supplied, all members of the archive will be selected. @@ -312,7 +228,7 @@ be selected. When a .Ar pattern operand does not select at least one archive member, -.Nm pax +.Nm will write these .Ar pattern operands in a diagnostic message to standard error @@ -324,7 +240,7 @@ operand specifies the pathname of a file to be copied or archived. When a .Ar file operand does not select at least one archive member, -.Nm pax +.Nm will write these .Ar file operand pathnames in a diagnostic message to standard error @@ -332,7 +248,6 @@ and then exit with a non-zero exit status. .Pp The options are as follows: .Bl -tag -width Ds -.\" ========== .It Fl 0 Use the NUL .Pq Ql \e0 @@ -349,23 +264,23 @@ or the .Fl 0 flag in .Xr xargs 1 . -.\" ========== .It Fl a -Append -.Ar files +Append the given +.Ar file +operands to the end of an archive that was previously written. If an archive format is not specified with a .Fl x option, the format currently being used in the archive will be selected. Any attempt to append to an archive in a format different from the format already used in the archive will cause -.Nm pax +.Nm to exit immediately with a non-zero exit status. The blocking size used in the archive volume where writing starts will continue to be used for the remainder of that archive volume. .Pp -.Em Warning : +.Sy Warning : Many storage devices are not able to support the operations necessary to perform an append operation. Any attempt to append to an archive stored on such a device may damage the @@ -373,7 +288,6 @@ archive or have other unpredictable results. Tape drives in particular are more likely to not support an append operation. An archive stored in a regular file system file or on a disk device will usually support an append operation. -.\" ========== .It Fl B Ar bytes Limit the number of bytes written to a single archive volume to .Ar bytes . @@ -396,7 +310,6 @@ Only use this option when writing an archive to a device which supports an end of file read condition based on last (or largest) write offset (such as a regular file or a tape drive). The use of this option with a floppy or hard disk is not recommended. -.\" ========== .It Fl b Ar blocksize When .Em writing @@ -406,7 +319,7 @@ bytes per write to the archive file. The .Ar blocksize must be a multiple of 512 bytes with a maximum of 64512 bytes. -Archives larger than 32256 bytes violate the +Archive block sizes larger than 32256 bytes violate the .Tn POSIX standard and will not be portable to all systems. A @@ -428,7 +341,6 @@ When blocking is not specified, the default is dependent on the specific archive format being used (see the .Fl x option). -.\" ========== .It Fl c Match all file or archive members .Em except @@ -437,7 +349,6 @@ those specified by the and .Ar file operands. -.\" ========== .It Fl D This option is the same as the .Fl u @@ -446,32 +357,30 @@ file modification time. The file inode change time can be used to select files whose inode information (e.g., UID, GID, etc.) is newer than a copy of the file in the destination .Ar directory . -.\" ========== .It Fl d Cause files of type directory being copied or archived, or archive members of type directory being extracted, to match only the directory file or archive member and not the file hierarchy rooted at the directory. -.\" ========== .It Fl E Ar limit Limit the number of consecutive read faults while trying to read a flawed archive to .Ar limit . With a positive .Ar limit , -.Nm pax +.Nm will attempt to recover from an archive read error and will continue processing starting with the next file stored in the archive. A .Ar limit of 0 will cause -.Nm pax +.Nm to stop operation after the first read error is detected on an archive volume. A .Ar limit of .Li NONE will cause -.Nm pax +.Nm to attempt to recover from read errors forever. The default .Ar limit @@ -481,9 +390,8 @@ is a small positive number of retries. Using this option with .Li NONE should be used with extreme caution as -.Nm pax +.Nm may get stuck in an infinite loop on a very badly flawed archive. -.\" ========== .It Fl f Ar archive Specify .Ar archive @@ -497,16 +405,15 @@ or standard output .Em write ) . A single archive may span multiple files and different archive devices. When required, -.Nm pax +.Nm will prompt for the pathname of the file or device of the next volume in the archive. -.\" ========== .It Fl G Ar group Select a file based on its .Ar group name, or when starting with a .Cm # , -a numeric gid. +a numeric GID. A .Ql \e can be used to escape the @@ -514,11 +421,9 @@ can be used to escape the Multiple .Fl G options may be supplied and checking stops with the first match. -.\" ========== .It Fl H Follow only command-line symbolic links while performing a physical file system traversal. -.\" ========== .It Fl i Interactively rename files or archive members. For each archive member matching a @@ -526,33 +431,35 @@ For each archive member matching a operand or each file matching a .Ar file operand, -.Nm pax +.Nm will prompt to .Pa /dev/tty giving the name of the file, its file mode, and its modification time. -.Nm pax +.Nm will then read a line from .Pa /dev/tty . If this line is blank, the file or archive member is skipped. If this line consists of a single period, the file or archive member is processed with no modification to its name. Otherwise, its name is replaced with the contents of the line. -.Nm pax +.Nm will immediately exit with a non-zero exit status if .Dv EOF is encountered when reading a response or if .Pa /dev/tty cannot be opened for reading and writing. -.\" ========== +.It Fl j +Use bzip2 to compress (decompress) the archive while writing (reading). +The bzip2 utility must be installed separately. +Incompatible with +.Fl a . .It Fl k Do not overwrite existing files. -.\" ========== .It Fl L Follow all symbolic links to perform a logical file system traversal. -.\" ========== .It Fl l (The lowercase letter -.Dq ell. ) +.Dq ell . ) Link files. In the .Em copy @@ -560,7 +467,6 @@ mode .Pq Fl r Fl w , hard links are made between the source and destination file hierarchies whenever possible. -.\" ========== .It Fl n Select the first archive member that matches each .Ar pattern @@ -571,15 +477,13 @@ When members of type directory are matched, the file hierarchy rooted at that directory is also matched (unless .Fl d is also specified). -.\" ========== .It Fl O Force the archive to be one volume. If a volume ends prematurely, -.Nm pax +.Nm will not prompt for a new volume. This option can be useful for automated tasks where error recovery cannot be performed by a human. -.\" ========== .It Fl o Ar options Information to modify the algorithm for extracting or writing archive files which is specific to the archive format specified by @@ -589,54 +493,19 @@ In general, take the form: .Ar name Ns = Ns Ar value . .Pp -If the "-x pax" option is used, -the ":=" form of keyword specification is supported. -Also, the following new keywords are implemented: -.Bl -bullet -.It -delete= -.It -exthdr.name= -.It -globexhdr.name= -.It -invalid= for actions -bypass, rename, utf-8 (recognized, but ignored), and write -.It -linkdata -.It -listopt= -for the 'F' conversion specifier -(not the 'D', 'T', 'M', or 'L' specifiers) -.It -times -.It -all keywords in pax Extended Header, -with the following restrictions: -.Bl -tag -.It charset -keyword recognized, but ignored -.It realtime.any -keyword not recognized -.It security.any -keyword not recognized -.El -.El +The following options are available for the old +.Bx +.Em tar +format: .Pp -In "copy mode", only the following new keywords are supported: -.Bl -bullet -.It -delete= -.It -invalid= -.It -path= (from pax Extended Header description) +.Bl -tag -width Ds -compact +.It Cm nodir +.It Cm write_opt=nodir +When writing archives, omit the storage of directories. .El -.\" ========== .It Fl P Do not follow symbolic links, perform a physical file system traversal. This is the default mode. -.\" ========== .It Fl p Ar string Specify one or more file characteristic options (privileges). The @@ -657,7 +526,7 @@ The meanings of the specification characters are as follows: Do not preserve file access times. By default, file access times are preserved whenever possible. .It Cm e -.Sq Preserve everything , +.Dq Preserve everything , the user ID, group ID, file mode bits, file access time, and file modification time. This is intended to be used by @@ -677,7 +546,7 @@ By default, file modification times are preserved whenever possible. .It Cm o Preserve the user ID and group ID. .It Cm p -.Sq Preserve +.Dq Preserve the file mode bits. This is intended to be used by a .Em user @@ -700,7 +569,7 @@ nor the .Cm o specification character is specified, or the user ID and group ID are not preserved for any reason, -.Nm pax +.Nm will not set the .Dv S_ISUID .Em ( setuid ) @@ -709,7 +578,7 @@ and .Em ( setgid ) bits of the file mode. If the preservation of any of these items fails for any reason, -.Nm pax +.Nm will write a diagnostic message to standard error. Failure to preserve these items will affect the final exit status, but will not cause the extracted file to be deleted. @@ -717,12 +586,13 @@ If the file characteristic letters in any of the string option-arguments are duplicated or conflict with each other, the one(s) given last will take precedence. For example, if -.Dl Fl p Ar eme +.Fl p Ar eme is specified, file modification times are still preserved. .It Fl r Read an archive file from standard input and extract the specified -.Ar files . +.Ar file +operands. If any intermediate directories are needed in order to extract an archive member, these directories will be created as if .Xr mkdir 2 @@ -735,35 +605,41 @@ and as the mode argument. When the selected archive format supports the specification of linked files and these files cannot be linked while the archive is being extracted, -.Nm pax +.Nm will write a diagnostic message to standard error and exit with a non-zero exit status at the completion of operation. .It Fl s Ar replstr -Modify the file or archive member names specified by the -.Ar pattern -or -.Ar file -operands according to the substitution expression +Modify the archive member names according to the substitution expression .Ar replstr , using the syntax of the .Xr ed 1 utility regular expressions. +.Ar file +or +.Ar pattern +arguments may be given to restrict the list of archive members to those +specified. +.Pp The format of these regular expressions is: +.Pp .Dl /old/new/[gp] +.Pp As in .Xr ed 1 , -.Cm old -is a basic regular expression and -.Cm new +.Ar old +is a basic regular expression (see +.Xr re_format 7 ) +and +.Ar new can contain an ampersand .Pq Ql & , -.Ql \en +.Ql \e Ns Em n (where -.Ar n +.Em n is a digit) back-references, or subexpression matching. The -.Cm old +.Ar old string may also contain newline characters. Any non-null character can be used as a delimiter .Po @@ -775,6 +651,7 @@ Multiple expressions can be specified. The expressions are applied in the order they are specified on the command line, terminating with the first successful substitution. +.Pp The optional trailing .Cm g continues to apply the substitution expression to the pathname substring, @@ -787,16 +664,28 @@ The optional trailing .Cm p will cause the final result of a successful substitution to be written to standard error in the following format: -.Dl >> +.Pp +.D1 Em original-pathname No \*(Gt\*(Gt Em new-pathname +.Pp File or archive member names that substitute to the empty string are not selected and will be skipped. -.It Fl T Ar [from_date][,to_date][/[c][m]] +.It Fl T Ar range Allow files to be selected based on a file modification or inode change -time falling within a specified time range of +time falling within the specified time range. +The range has the format: +.Sm off +.Bd -filled -offset indent +.Oo Ar from_date Oc Oo , +.Ar to_date Oc Oo / +.Oo Cm c Oc Op Cm m Oc +.Ed +.Sm on +.Pp +The dates specified by .Ar from_date to .Ar to_date -(the dates are inclusive). +are inclusive. If only a .Ar from_date is supplied, all files with a modification or inode change time @@ -813,86 +702,86 @@ only files with a modification or inode change time of exactly that time will be selected. .Pp When -.Nm pax +.Nm is in the .Em write or .Em copy mode, the optional trailing field -.Ar [c][m] +.Oo Cm c Oc Op Cm m can be used to determine which file time (inode change, file modification or both) are used in the comparison. If neither is specified, the default is to use file modification time only. The -.Ar m +.Cm m specifies the comparison of file modification time (the time when the file was last written). The -.Ar c +.Cm c specifies the comparison of inode change time (the time when the file inode was last changed; e.g., a change of owner, group, mode, etc). When -.Ar c +.Cm c and -.Ar m +.Cm m are both specified, then the modification and inode change times are both compared. +.Pp The inode change time comparison is useful in selecting files whose attributes were recently changed or selecting files which were recently created and had their modification time reset to an older time (as what happens when a file is extracted from an archive and the modification time is preserved). Time comparisons using both file times is useful when -.Nm pax +.Nm is used to create a time based incremental archive (only files that were changed during a specified time range will be archived). .Pp A time range is made up of six different fields and each field must contain two digits. The format is: +.Pp .Dl [[[[[cc]yy]mm]dd]HH]MM[.SS] +.Pp Where -.Cm cc +.Ar cc is the first two digits of the year (the century), -.Cm yy +.Ar yy is the last two digits of the year, the first -.Cm mm +.Ar mm is the month (from 01 to 12), -.Cm dd +.Ar dd is the day of the month (from 01 to 31), -.Cm HH +.Ar HH is the hour of the day (from 00 to 23), -.Cm MM +.Ar MM is the minute (from 00 to 59), and -.Cm SS +.Ar SS is the seconds (from 00 to 59). The minute field -.Cm MM +.Ar MM is required, while the other fields are optional and must be added in the following order: -.br -.Cm \& HH , dd , mm , -.Cm yy , cc . -.br +.Ar HH , dd , mm , +.Ar yy , cc . +.Pp The -.Cm SS +.Ar SS field may be added independently of the other fields. Time ranges are relative to the current time, so -.Dl Fl T Ar 1234/cm +.Ic -T 1234/cm would select all files with a modification or inode change time of 12:34 PM today or later. Multiple .Fl T time range can be supplied and checking stops with the first match. -.\" ========== .It Fl t Reset the access times of any file or directory read or accessed by -.Nm pax +.Nm to be the same as they were before being read or accessed by .Nm pax . -.\" ========== .It Fl U Ar user Select a file based on its .Ar user @@ -906,7 +795,6 @@ can be used to escape the Multiple .Fl U options may be supplied and checking stops with the first match. -.\" ========== .It Fl u Ignore files that are older (having a less recent file modification time) than a pre-existing file or archive member with the same name. @@ -923,7 +811,6 @@ During the file in the destination hierarchy is replaced by the file in the source hierarchy or by a link to the file in the source hierarchy if the file in the source hierarchy is newer. -.\" ========== .It Fl v During a .Em list @@ -934,16 +821,22 @@ utility with the option. For pathnames representing a hard link to a previous member of the archive, the output has the format: -.Dl == +.Pp +.Dl Em ls -l listing Li == Em link-name +.Pp For pathnames representing a symbolic link, the output has the format: -.Dl => -Where is the output format specified by the +.Pp +.Dl Em ls -l listing Li =\*(Gt Em link-name +.Pp +Where +.Em ls -l listing +is the output format specified by the .Xr ls 1 utility when used with the .Fl l option. Otherwise for all the other operational modes -.Po Em read , write , Li and Em copy +.Po Em read , write , No and Em copy .Pc , pathnames are written and flushed to standard error without a trailing newline @@ -951,7 +844,6 @@ as soon as processing begins on that file or archive member. The trailing newline is not buffered and is written only after the file has been read or written. -.\" ========== .It Fl w Write files to the standard output in the specified archive format. @@ -961,7 +853,6 @@ operands are specified, standard input is read for a list of pathnames with one per line without any leading or trailing .Aq blanks . -.\" ========== .It Fl X When traversing the file hierarchy specified by a pathname, do not descend into directories that have a different device ID. @@ -970,61 +861,49 @@ See the field as described in .Xr stat 2 for more information about device IDs. -.\" ========== .It Fl x Ar format Specify the output archive format, with the default format being -.Ar ustar . -.Nm pax +.Cm ustar . +.Nm currently supports the following formats: .Bl -tag -width "sv4cpio" -.\" ========== -.It Ar bcpio +.It Cm bcpio The old binary cpio format. The default blocksize for this format is 5120 bytes. This format is not very portable and should not be used when other formats are available. Inode and device information about a file (used for detecting file hard links by this format), which may be truncated by this format, is detected by -.Nm pax +.Nm and is repaired. -.\" ========== -.It Ar cpio +.It Cm cpio The extended cpio interchange format specified in the .St -p1003.2 standard. The default blocksize for this format is 5120 bytes. Inode and device information about a file (used for detecting file hard links by this format), which may be truncated by this format, is detected by -.Nm pax +.Nm and is repaired. -.\" ========== -.It Ar pax -"pax interchange format", described in the -EXTENDED DESCRIPTION of the pax interchange format -in The Open Group's SUSv3 specification. -Includes support for pax Header Block, -pax Extended Header, -pax Extended Header Keyword Precedence, and -pax Extended Header File Times. -.\" ========== -.It Ar sv4cpio +.It Cm sv4cpio The System V release 4 cpio. The default blocksize for this format is 5120 bytes. Inode and device information about a file (used for detecting file hard links by this format), which may be truncated by this format, is detected by -.Nm pax +.Nm and is repaired. -.\" ========== -.It Ar sv4crc -The System V release 4 cpio with file crc checksums. +.It Cm sv4crc +The System V release 4 cpio with file CRC checksums. The default blocksize for this format is 5120 bytes. Inode and device information about a file (used for detecting file hard links by this format), which may be truncated by this format, is detected by -.Nm pax +.Nm and is repaired. -.\" ========== -.It Ar tar -The old BSD tar format as found in BSD4.3. +.It Cm tar +The old +.Bx +tar format as found in +.Bx 4.3 . The default blocksize for this format is 10240 bytes. Pathnames stored by this format must be 100 characters or less in length. Only @@ -1038,9 +917,9 @@ For backwards compatibility with even older tar formats, a .Fl o option can be used when writing an archive to omit the storage of directories. This option takes the form: +.Pp .Dl Fl o Cm write_opt=nodir -.\" ========== -.It Ar ustar +.It Cm ustar The extended tar interchange format specified in the .St -p1003.2 standard. @@ -1049,37 +928,45 @@ Filenames stored by this format must be 100 characters or less in length; the total pathname must be 255 characters or less. .El .Pp -.Nm pax +.Nm will detect and report any file that it is unable to store or extract as the result of any specific archive format restrictions. The individual archive formats may impose additional restrictions on use. Typical archive format restrictions include (but are not limited to): file pathname length, file size, link pathname length, and the type of the file. -.\" ========== .It Fl Y This option is the same as the .Fl D option, except that the inode change time is checked using the pathname created after all the file name modifications have completed. -.\" ========== .It Fl Z This option is the same as the .Fl u option, except that the modification time is checked using the pathname created after all the file name modifications have completed. -.\" ========== .It Fl z Use .Xr gzip 1 to compress (decompress) the archive while writing (reading). Incompatible with .Fl a . +.It Fl -insecure +Normally +.Nm +ignores filenames or symbolic links that contain +.Dq .. +as a path component. +With this option, +files that contain +.Dq .. +can be processed. .El .Pp The options that operate on the names of files or archive members .Po Fl c , .Fl i , +.Fl j , .Fl n , .Fl s , .Fl u , @@ -1168,40 +1055,40 @@ than the file to which it is compared. Path in which to store temporary files. .El .Sh EXAMPLES -.Li $ pax -w -f /dev/rst0 \&. -.Pp -Copies the contents of the current directory to the device -.Pa /dev/rst0 . +Copy the contents of the current directory to the device +.Pa /dev/rst0 : .Pp -.Li $ pax -v -f filename +.Dl $ pax -w -f /dev/rst0 \&. .Pp -Gives the verbose table of contents for an archive stored in -.Pa filename . +Give the verbose table of contents for an archive stored in +.Pa filename : .Pp -.Li $ mkdir newdir ; -.Li cd olddir ; -.Li pax -rw \&. newdir +.Dl $ pax -v -f filename .Pp This sequence of commands will copy the entire .Pa olddir directory hierarchy to -.Pa newdir . -.Pp -.Li $ pax -r -s ',^//*usr//*,,' -f a.pax +.Pa newdir : +.Bd -literal -offset indent +$ mkdir newdir +$ cd olddir +$ pax -rw . ../newdir +.Ed .Pp -Reads the archive -.Pa a.pax , -with all files rooted in +Extract files from the archive +.Pa a.pax . +Files rooted in .Pa /usr -into the archive extracted relative to the current directory. +are extracted relative to the current working directory; +all other files are extracted to their unmodified path. .Pp -.Li $ pax -rw -i \&. dest_dir +.Dl $ pax -r -s ',^/usr/,,' -f a.pax .Pp -Can be used to interactively select the files to copy from the current -directory to -.Pa dest_dir . +This can be used to interactively select the files to copy from the +current directory to +.Pa dest_dir : .Pp -.Li "$ pax -r -pe -U root -G bin -f a.pax" +.Dl $ pax -rw -i \&. dest_dir .Pp Extract all files from the archive .Pa a.pax @@ -1209,19 +1096,21 @@ which are owned by .Em root with group .Em bin -and preserve all file permissions. +and preserve all file permissions: .Pp -.Li "$ pax -r -w -v -Y -Z home /backup" +.Dl "$ pax -r -pe -U root -G bin -f a.pax" .Pp Update (and list) only those files in the destination directory .Pa /backup which are older (less recent inode change or file modification times) than files with the same name found in the source file tree -.Pa home . +.Pa home : +.Pp +.Dl "$ pax -r -w -v -Y -Z home /backup" .Sh DIAGNOSTICS -.Nm pax +.Nm will exit with one of the following values: -.Bl -tag -width 2n +.Bl -tag -width 2n -offset indent .It 0 All files were processed successfully. .It 1 @@ -1229,7 +1118,7 @@ An error occurred. .El .Pp Whenever -.Nm pax +.Nm cannot create a file or a link when reading an archive or cannot find a file when writing an archive, or cannot preserve the user ID, group ID, or file mode when the @@ -1237,31 +1126,31 @@ group ID, or file mode when the option is specified, a diagnostic message is written to standard error and a non-zero exit status will be returned, but processing will continue. In the case where -.Nm pax +.Nm cannot create a link to a file, -.Nm pax +.Nm will not create a second copy of the file. .Pp If the extraction of a file from an archive is prematurely terminated by a signal or error, -.Nm pax +.Nm may have only partially extracted a file the user wanted. Additionally, the file modes of extracted files and directories may have incorrect file bits, and the modification and access times may be wrong. .Pp If the creation of an archive is prematurely terminated by a signal or error, -.Nm pax +.Nm may have only partially created the archive, which may violate the specific archive format specification. .Pp -If, while doing a +If while doing a .Em copy , -.Nm pax +.Nm detects a file is about to overwrite itself, the file is not copied, a diagnostic message is written to standard error and when -.Nm pax +.Nm completes it will exit with a non-zero exit status. .Sh SEE ALSO .Xr cpio 1 , @@ -1274,34 +1163,23 @@ pax(1) manual page, http://heirloom.sourceforge.net/man/pax.1.html .Sh STANDARDS The -.Nm pax -utility is a superset of the -.St -p1003.2 -standard. -The options -.Fl B , -.Fl D , -.Fl E , -.Fl G , -.Fl H , -.Fl L , -.Fl O , -.Fl P , -.Fl T , -.Fl U , -.Fl Y , -.Fl Z , +.Nm +utility is compliant with the +.St -p1003.1-2004 +specification. +.Pp +The flags +.Op Fl 0BDEGHjLOPTUYZz , the archive formats -.Ar bcpio , -.Ar sv4cpio , -.Ar sv4crc , -.Ar tar , +.Em bcpio , +.Em sv4cpio , +.Em sv4crc , +.Em tar , and the flawed archive handling during -.Ar list +.Em list and -.Ar read -operations are extensions to the -.Tn POSIX -standard. +.Em read +operations +are extensions to that specification. .Sh AUTHORS Keith Muller at the University of California, San Diego. diff --git a/pax/pax.c b/pax/pax.c index e312833..b59ba18 100644 --- a/pax/pax.c +++ b/pax/pax.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pax.c,v 1.27 2004/04/16 22:50:23 deraadt Exp $ */ +/* $OpenBSD: pax.c,v 1.28 2005/08/04 10:02:44 mpf Exp $ */ /* $NetBSD: pax.c,v 1.5 1996/03/26 23:54:20 mrg Exp $ */ /*- @@ -35,7 +35,7 @@ */ #ifndef lint -static const char copyright[] __attribute__((__unused__)) = +static const char copyright[] = "@(#) Copyright (c) 1992, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ @@ -44,7 +44,7 @@ static const char copyright[] __attribute__((__unused__)) = #if 0 static const char sccsid[] = "@(#)pax.c 8.2 (Berkeley) 4/18/94"; #else -static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: pax.c,v 1.27 2004/04/16 22:50:23 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: pax.c,v 1.28 2005/08/04 10:02:44 mpf Exp $"; #endif #endif /* not lint */ @@ -99,13 +99,14 @@ int nodirs; /* do not create directories as needed */ int pmode; /* preserve file mode bits */ int pids; /* preserve file uid/gid */ int rmleadslash = 0; /* remove leading '/' from pathnames */ +int secure = 1; /* don't extract names that contain .. */ int exit_val; /* exit value */ int docrc; /* check/create file crc */ char *dirptr; /* destination dir in a copy */ char *ltmfrmt; /* -v locale time format (if any) */ char *argv0; /* root of argv[0] */ sigset_t s_mask; /* signal mask for cleanup critical sect */ -FILE *listf; /* file pointer to print file list to */ +FILE *listf; /* file pointer to print file list to */ char *tempfile; /* tempfile to use for mkstemp(3) */ char *tempbase; /* basename of tempfile to use for mkstemp(3) */ @@ -229,25 +230,24 @@ char *tempbase; /* basename of tempfile to use for mkstemp(3) */ * Return: 0 if ok, 1 otherwise */ -extern void pax_usage(); - int main(int argc, char **argv) { char *tmpdir; size_t tdlen; - if (argc < 1) - pax_usage(); + listf = stderr; /* * Keep a reference to cwd, so we can always come back home. */ cwdfd = open(".", O_RDONLY); if (cwdfd < 0) { - syswarn(0, errno, "Can't open current working directory."); + syswarn(1, errno, "Can't open current working directory."); return(exit_val); } + if (updatepath() == -1) + return exit_val; /* * Where should we put temporary files? */ diff --git a/pax/pax.h b/pax/pax.h index b951b55..4d74aa0 100644 --- a/pax/pax.h +++ b/pax/pax.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pax.h,v 1.16 2003/10/20 06:22:27 jmc Exp $ */ +/* $OpenBSD: pax.h,v 1.17 2005/11/09 19:59:06 otto Exp $ */ /* $NetBSD: pax.h,v 1.3 1995/03/21 09:07:41 cgd Exp $ */ /*- @@ -111,7 +111,7 @@ typedef struct { /* IMPORTANT. The st_size field does */ /* not always indicate the amount of */ /* data following the header. */ - u_long crc; /* file crc */ + u_int32_t crc; /* file crc */ int type; /* type of file node */ #define PAX_DIR 1 /* directory */ #define PAX_CHR 2 /* character device */ @@ -226,10 +226,10 @@ typedef struct oplist { int separator; /* 2 means := separator; 1 means = separator 0 means no separator */ } OPLIST; - #define SEP_COLONEQ 2 #define SEP_EQ 1 #define SEP_NONE 0 + /* * General Macros */ diff --git a/pax/pax_format.c b/pax/pax_format.c index af2d8ab..ad9cf7d 100644 --- a/pax/pax_format.c +++ b/pax/pax_format.c @@ -1,6 +1,3 @@ -/* $OpenBSD: tar.c,v 1.34 2004/10/23 19:34:14 otto Exp $ */ -/* $NetBSD: tar.c,v 1.5 1995/03/21 09:07:49 cgd Exp $ */ - /*- * Copyright (c) 1992 Keith Muller. * Copyright (c) 1992, 1993 @@ -192,7 +189,7 @@ int ext_header_entry [4*sizeof(o_option_table)/sizeof(O_OPTION_TYPE)], static size_t expandname(char *, size_t, char **, const char *, size_t); static u_long pax_chksm(char *, int); -char *name_split(char *, int); +static char *name_split(char *, int); static int ul_oct(u_long, char *, int, int); #ifndef LONG_OFF_T static int uqd_oct(u_quad_t, char *, int, int); @@ -207,81 +204,6 @@ static gid_t gid_warn; * Routines common to all versions of pax */ -#if 0 -static int tar_nodir; /* do not write dirs under old tar */ -char *gnu_name_string; /* GNU ././@LongLink hackery name */ -char *gnu_link_string; /* GNU ././@LongLink hackery link */ - -/* - * tar_endwr() - * add the tar trailer of two null blocks - * Return: - * 0 if ok, -1 otherwise (what wr_skip returns) - */ - -int -tar_endwr(void) -{ - return(wr_skip((off_t)(NULLCNT*BLKMULT))); -} - -/* - * tar_endrd() - * no cleanup needed here, just return size of trailer (for append) - * Return: - * size of trailer (2 * BLKMULT) - */ - -off_t -tar_endrd(void) -{ - return((off_t)(NULLCNT*BLKMULT)); -} - -/* - * tar_trail() - * Called to determine if a header block is a valid trailer. We are passed - * the block, the in_sync flag (which tells us we are in resync mode; - * looking for a valid header), and cnt (which starts at zero) which is - * used to count the number of empty blocks we have seen so far. - * Return: - * 0 if a valid trailer, -1 if not a valid trailer, or 1 if the block - * could never contain a header. - */ - -int -tar_trail(ARCHD *ignore, char *buf, int in_resync, int *cnt) -{ - int i; - - /* - * look for all zero, trailer is two consecutive blocks of zero - */ - for (i = 0; i < BLKMULT; ++i) { - if (buf[i] != '\0') - break; - } - - /* - * if not all zero it is not a trailer, but MIGHT be a header. - */ - if (i != BLKMULT) - return(-1); - - /* - * When given a zero block, we must be careful! - * If we are not in resync mode, check for the trailer. Have to watch - * out that we do not mis-identify file data as the trailer, so we do - * NOT try to id a trailer during resync mode. During resync mode we - * might as well throw this block out since a valid header can NEVER be - * a block of all 0 (we must have a valid file name). - */ - if (!in_resync && (++*cnt >= NULLCNT)) - return(0); - return(1); -} -#endif - /* * ul_oct() * convert an unsigned long to an octal string. many oddball field @@ -430,50 +352,6 @@ pax_chksm(char *blk, int len) return(chksm); } -#if 0 -/* - * Routines for old BSD style tar (also made portable to sysV tar) - */ - -/* pax_id must be derived from ustar, NOT tar */ -/* - * tar_id() - * determine if a block given to us is a valid tar header (and not a USTAR - * header). We have to be on the lookout for those pesky blocks of all - * zero's. - * Return: - * 0 if a tar header, -1 otherwise - */ - -int -tar_id(char *blk, int size) -{ - HD_TAR *hd; - HD_USTAR *uhd; - - if (size < BLKMULT) - return(-1); - hd = (HD_TAR *)blk; - uhd = (HD_USTAR *)blk; - - /* - * check for block of zero's first, a simple and fast test, then make - * sure this is not a ustar header by looking for the ustar magic - * cookie. We should use TMAGLEN, but some USTAR archive programs are - * wrong and create archives missing the \0. Last we check the - * checksum. If this is ok we have to assume it is a valid header. - */ - if (hd->name[0] == '\0') - return(-1); - if (strncmp(uhd->magic, TMAGIC, TMAGLEN - 1) == 0) - return(-1); - if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT)) - return(-1); - force_one_volume = 1; - return(0); -} -#endif - void pax_format_list_output(ARCHD *arcn, time_t now, FILE *fp, int term) { @@ -729,338 +607,6 @@ pax_opt(void) return(0); } - -#if 0 -/* pax_rd is derived from ustar_rd NOT tar_rd */ -/* - * tar_rd() - * extract the values out of block already determined to be a tar header. - * store the values in the ARCHD parameter. - * Return: - * 0 - */ - -int -tar_rd(ARCHD *arcn, char *buf) -{ - HD_TAR *hd; - char *pt; - - /* - * we only get proper sized buffers passed to us - */ - if (tar_id(buf, BLKMULT) < 0) - return(-1); - memset(arcn, 0, sizeof(*arcn)); - arcn->org_name = arcn->name; - arcn->sb.st_nlink = 1; - - /* - * copy out the name and values in the stat buffer - */ - hd = (HD_TAR *)buf; - if (hd->linkflag != LONGLINKTYPE && hd->linkflag != LONGNAMETYPE) { - arcn->nlen = expandname(arcn->name, sizeof(arcn->name), - &gnu_name_string, hd->name, sizeof(hd->name)); - arcn->ln_nlen = expandname(arcn->ln_name, sizeof(arcn->ln_name), - &gnu_link_string, hd->linkname, sizeof(hd->linkname)); - } - arcn->sb.st_mode = (mode_t)(asc_ul(hd->mode,sizeof(hd->mode),OCT) & - 0xfff); - arcn->sb.st_uid = (uid_t)asc_ul(hd->uid, sizeof(hd->uid), OCT); - arcn->sb.st_gid = (gid_t)asc_ul(hd->gid, sizeof(hd->gid), OCT); -#ifdef LONG_OFF_T - arcn->sb.st_size = (off_t)asc_ul(hd->size, sizeof(hd->size), OCT); -#else - arcn->sb.st_size = (off_t)asc_uqd(hd->size, sizeof(hd->size), OCT); -#endif - arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT); - arcn->sb.st_ctime = arcn->sb.st_atime = arcn->sb.st_mtime; - - /* - * have to look at the last character, it may be a '/' and that is used - * to encode this as a directory - */ - pt = &(arcn->name[arcn->nlen - 1]); - arcn->pad = 0; - arcn->skip = 0; - switch (hd->linkflag) { - case SYMTYPE: - /* - * symbolic link, need to get the link name and set the type in - * the st_mode so -v printing will look correct. - */ - arcn->type = PAX_SLK; - arcn->sb.st_mode |= S_IFLNK; - break; - case LNKTYPE: - /* - * hard link, need to get the link name, set the type in the - * st_mode and st_nlink so -v printing will look better. - */ - arcn->type = PAX_HLK; - arcn->sb.st_nlink = 2; - - /* - * no idea of what type this thing really points at, but - * we set something for printing only. - */ - arcn->sb.st_mode |= S_IFREG; - break; - case LONGLINKTYPE: - case LONGNAMETYPE: - /* - * GNU long link/file; we tag these here and let the - * pax internals deal with it -- too ugly otherwise. - */ - arcn->type = - hd->linkflag == LONGLINKTYPE ? PAX_GLL : PAX_GLF; - arcn->pad = TAR_PAD(arcn->sb.st_size); - arcn->skip = arcn->sb.st_size; - break; - case DIRTYPE: - /* - * It is a directory, set the mode for -v printing - */ - arcn->type = PAX_DIR; - arcn->sb.st_mode |= S_IFDIR; - arcn->sb.st_nlink = 2; - break; - case AREGTYPE: - case REGTYPE: - default: - /* - * If we have a trailing / this is a directory and NOT a file. - */ - arcn->ln_name[0] = '\0'; - arcn->ln_nlen = 0; - if (*pt == '/') { - /* - * it is a directory, set the mode for -v printing - */ - arcn->type = PAX_DIR; - arcn->sb.st_mode |= S_IFDIR; - arcn->sb.st_nlink = 2; - } else { - /* - * have a file that will be followed by data. Set the - * skip value to the size field and calculate the size - * of the padding. - */ - arcn->type = PAX_REG; - arcn->sb.st_mode |= S_IFREG; - arcn->pad = TAR_PAD(arcn->sb.st_size); - arcn->skip = arcn->sb.st_size; - } - break; - } - - /* - * strip off any trailing slash. - */ - if (*pt == '/') { - *pt = '\0'; - --arcn->nlen; - } - return(0); -} - -/* pax_wr is derived from ustar_wr NOT tar_wr */ -/* - * tar_wr() - * write a tar header for the file specified in the ARCHD to the archive. - * Have to check for file types that cannot be stored and file names that - * are too long. Be careful of the term (last arg) to ul_oct, each field - * of tar has it own spec for the termination character(s). - * ASSUMED: space after header in header block is zero filled - * Return: - * 0 if file has data to be written after the header, 1 if file has NO - * data to write after the header, -1 if archive write failed - */ - -int -tar_wr(ARCHD *arcn) -{ - HD_TAR *hd; - int len; - char hdblk[sizeof(HD_TAR)]; - - /* - * check for those file system types which tar cannot store - */ - switch (arcn->type) { - case PAX_DIR: - /* - * user asked that dirs not be written to the archive - */ - if (tar_nodir) - return(1); - break; - case PAX_CHR: - paxwarn(1, "Tar cannot archive a character device %s", - arcn->org_name); - return(1); - case PAX_BLK: - paxwarn(1, "Tar cannot archive a block device %s", arcn->org_name); - return(1); - case PAX_SCK: - paxwarn(1, "Tar cannot archive a socket %s", arcn->org_name); - return(1); - case PAX_FIF: - paxwarn(1, "Tar cannot archive a fifo %s", arcn->org_name); - return(1); - case PAX_SLK: - case PAX_HLK: - case PAX_HRG: - if (arcn->ln_nlen > sizeof(hd->linkname)) { - paxwarn(1,"Link name too long for tar %s", arcn->ln_name); - return(1); - } - break; - case PAX_REG: - case PAX_CTG: - default: - break; - } - - /* - * check file name len, remember extra char for dirs (the / at the end) - */ - len = arcn->nlen; - if (arcn->type == PAX_DIR) - ++len; - if (len >= sizeof(hd->name)) { - paxwarn(1, "File name too long for tar %s", arcn->name); - return(1); - } - - /* - * Copy the data out of the ARCHD into the tar header based on the type - * of the file. Remember, many tar readers want all fields to be - * padded with zero so we zero the header first. We then set the - * linkflag field (type), the linkname, the size, and set the padding - * (if any) to be added after the file data (0 for all other types, - * as they only have a header). - */ - memset(hdblk, 0, sizeof(hdblk)); - hd = (HD_TAR *)hdblk; - strlcpy(hd->name, arcn->name, sizeof(hd->name)); - arcn->pad = 0; - - if (arcn->type == PAX_DIR) { - /* - * directories are the same as files, except have a filename - * that ends with a /, we add the slash here. No data follows - * dirs, so no pad. - */ - hd->linkflag = AREGTYPE; - hd->name[len-1] = '/'; - if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1)) - goto out; - } else if (arcn->type == PAX_SLK) { - /* - * no data follows this file, so no pad - */ - hd->linkflag = SYMTYPE; - strlcpy(hd->linkname, arcn->ln_name, sizeof(hd->linkname)); - if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1)) - goto out; - } else if ((arcn->type == PAX_HLK) || (arcn->type == PAX_HRG)) { - /* - * no data follows this file, so no pad - */ - hd->linkflag = LNKTYPE; - strlcpy(hd->linkname, arcn->ln_name, sizeof(hd->linkname)); - if (ul_oct((u_long)0L, hd->size, sizeof(hd->size), 1)) - goto out; - } else { - /* - * data follows this file, so set the pad - */ - hd->linkflag = AREGTYPE; -# ifdef LONG_OFF_T - if (ul_oct((u_long)arcn->sb.st_size, hd->size, - sizeof(hd->size), 1)) { -# else - if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size, - sizeof(hd->size), 1)) { -# endif - paxwarn(1,"File is too large for tar %s", arcn->org_name); - return(1); - } - arcn->pad = TAR_PAD(arcn->sb.st_size); - } - - /* - * copy those fields that are independent of the type - */ - if (ul_oct((u_long)arcn->sb.st_mode, hd->mode, sizeof(hd->mode), 0) || - ul_oct((u_long)arcn->sb.st_uid, hd->uid, sizeof(hd->uid), 0) || - ul_oct((u_long)arcn->sb.st_gid, hd->gid, sizeof(hd->gid), 0) || - ul_oct((u_long)arcn->sb.st_mtime, hd->mtime, sizeof(hd->mtime), 1)) - goto out; - - /* - * calculate and add the checksum, then write the header. A return of - * 0 tells the caller to now write the file data, 1 says no data needs - * to be written - */ - if (ul_oct(tar_chksm(hdblk, sizeof(HD_TAR)), hd->chksum, - sizeof(hd->chksum), 3)) - goto out; - if (wr_rdbuf(hdblk, sizeof(HD_TAR)) < 0) - return(-1); - if (wr_skip((off_t)(BLKMULT - sizeof(HD_TAR))) < 0) - return(-1); - if ((arcn->type == PAX_CTG) || (arcn->type == PAX_REG)) - return(0); - return(1); - - out: - /* - * header field is out of range - */ - paxwarn(1, "Tar header field is too small for %s", arcn->org_name); - return(1); -} -#endif - -#if 0 -/* - * Routines for POSIX ustar - */ - -/* - * ustar_strd() - * initialization for ustar read - * Return: - * 0 if ok, -1 otherwise - */ - -int -ustar_strd(void) -{ - if ((usrtb_start() < 0) || (grptb_start() < 0)) - return(-1); - return(0); -} - -/* - * ustar_stwr() - * initialization for ustar write - * Return: - * 0 if ok, -1 otherwise - */ - -int -ustar_stwr(void) -{ - if ((uidtb_start() < 0) || (gidtb_start() < 0)) - return(-1); - return(0); -} -#endif - int expand_extended_headers(ARCHD *arcn, HD_USTAR *hd) { @@ -1252,7 +798,7 @@ expand_extended_headers(ARCHD *arcn, HD_USTAR *hd) current_value, len); if (len != header_len) { /* pad with ? */ - p[o_option_table[i].header_inx+len+1] = '\0'; + p[o_option_table[i].header_inx+len] = '\0'; } } } @@ -1366,7 +912,7 @@ pax_rd(ARCHD *arcn, char *buf) } if (hd->typeflag != LONGLINKTYPE && hd->typeflag != LONGNAMETYPE) { - arcn->nlen = expandname(dest, sizeof(arcn->name) - cnt, + arcn->nlen = cnt + expandname(dest, sizeof(arcn->name) - cnt, &gnu_name_string, hd->name, sizeof(hd->name)); arcn->ln_nlen = expandname(arcn->ln_name, sizeof(arcn->ln_name), &gnu_link_string, hd->linkname, sizeof(hd->linkname)); @@ -1624,7 +1170,6 @@ generate_pax_ext_header_and_data(ARCHD *arcn, int nfields, int *table, times might be wanted */ term_char = 1; - records_size = 0; memset(hdblk, 0, sizeof(hdblk)); hd = (HD_USTAR *)hdblk; memset(pax_eh_datablk, 0, sizeof(pax_eh_datablk)); @@ -1952,7 +1497,6 @@ pax_wr(ARCHD *arcn) return(1); } -#if 0 /* * name_split() * see if the name has to be split for storage in a ustar header. We try @@ -1986,6 +1530,8 @@ name_split(char *name, int len) * prefix we can find) */ start = name + len - TNMSZ -1; + if ((*start == '/') && (start == name)) + ++start; /* 101 byte paths with leading '/' are dinged otherwise */ while ((*start != '\0') && (*start != '/')) ++start; @@ -2011,7 +1557,6 @@ name_split(char *name, int len) */ return(start); } -#endif /* if 0 */ static size_t expandname(char *buf, size_t len, char **gnu_name, const char *name, size_t name_len) diff --git a/pax/sel_subs.c b/pax/sel_subs.c index 86ba9ed..55d3a00 100644 --- a/pax/sel_subs.c +++ b/pax/sel_subs.c @@ -38,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)sel_subs.c 8.1 (Berkeley) 5/31/93"; #else -static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: sel_subs.c,v 1.18 2004/04/16 22:50:23 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: sel_subs.c,v 1.18 2004/04/16 22:50:23 deraadt Exp $"; #endif #endif /* not lint */ diff --git a/pax/tables.c b/pax/tables.c index 6b067e8..9787951 100644 --- a/pax/tables.c +++ b/pax/tables.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tables.c,v 1.22 2004/11/29 16:23:22 otto Exp $ */ +/* $OpenBSD: tables.c,v 1.25 2007/09/02 15:19:08 deraadt Exp $ */ /* $NetBSD: tables.c,v 1.4 1995/03/21 09:07:45 cgd Exp $ */ /*- @@ -38,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)tables.c 8.1 (Berkeley) 5/31/93"; #else -static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: tables.c,v 1.22 2004/11/29 16:23:22 otto Exp $"; +static const char rcsid[] = "$OpenBSD: tables.c,v 1.25 2007/09/02 15:19:08 deraadt Exp $"; #endif #endif /* not lint */ @@ -146,18 +146,12 @@ chk_lnk(ARCHD *arcn) return(0); /* - * Conformance tests: ignore symlink because cannot create hard link to it - */ - if ((arcn->type == PAX_SLK)) - return(0); - - /* * hash inode number and look for this file */ indx = ((unsigned)arcn->sb.st_ino) % L_TAB_SZ; if ((pt = ltab[indx]) != NULL) { /* - * it's hash chain in not empty, walk down looking for it + * its hash chain in not empty, walk down looking for it */ ppt = &(ltab[indx]); while (pt != NULL) { @@ -177,6 +171,9 @@ chk_lnk(ARCHD *arcn) */ arcn->ln_nlen = strlcpy(arcn->ln_name, pt->name, sizeof(arcn->ln_name)); + /* XXX truncate? */ + if (arcn->nlen >= sizeof(arcn->name)) + arcn->nlen = sizeof(arcn->name) - 1; if (arcn->type == PAX_REG) arcn->type = PAX_HRG; else @@ -607,6 +604,8 @@ sub_name(char *oname, int *onamelen, size_t onamesize) * and return (we know that oname has enough space) */ *onamelen = strlcpy(oname, pt->nname, onamesize); + if (*onamelen >= onamesize) + *onamelen = onamesize - 1; /* XXX truncate? */ return; } pt = pt->fow; @@ -1103,7 +1102,7 @@ dir_start(void) return(0); dirsize = DIRP_SIZE; - if ((dirp = malloc(dirsize * sizeof(DIRDATA))) == NULL) { + if ((dirp = calloc(dirsize, sizeof(DIRDATA))) == NULL) { paxwarn(1, "Unable to allocate memory for directory times"); return(-1); } @@ -1124,13 +1123,21 @@ dir_start(void) */ void -add_dir(char *name, struct stat *psb, int frc_mode) +add_dir(char *name, size_t nlen, struct stat *psb, int frc_mode) { DIRDATA *dblk; + char realname[MAXPATHLEN], *rp; if (dirp == NULL) return; + if (havechd && *name != '/') { + if ((rp = realpath(name, realname)) == NULL) { + paxwarn(1, "Cannot canonicalize %s", name); + return; + } + name = rp; + } if (dircnt == dirsize) { dblk = realloc(dirp, 2 * dirsize * sizeof(DIRDATA)); if (dblk == NULL) { @@ -1218,7 +1225,7 @@ st_hash(char *name, int len, int tabsz) u_int key = 0; int steps; int res; - u_int val; + u_int val = 0; /* * only look at the tail up to MAXKEYLEN, we do not need to waste diff --git a/pax/tables.h b/pax/tables.h index e065387..bc19f06 100644 --- a/pax/tables.h +++ b/pax/tables.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tables.h,v 1.7 2004/11/29 16:23:22 otto Exp $ */ +/* $OpenBSD: tables.h,v 1.8 2006/08/05 23:05:13 ray Exp $ */ /* $NetBSD: tables.h,v 1.3 1995/03/21 09:07:47 cgd Exp $ */ /*- @@ -135,7 +135,7 @@ typedef struct dlist { } DLIST; /* - * ftree directory access time reset table. When we are done with with a + * ftree directory access time reset table. When we are done with a * subtree we reset the access and mod time of the directory when the tflag is * set. Not really explicitly specified in the pax spec, but easy and fast to * do (and this may have even been intended in the spec, it is not clear). diff --git a/pax/tar.c b/pax/tar.c index b8f9b42..2cc800c 100644 --- a/pax/tar.c +++ b/pax/tar.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tar.c,v 1.34 2004/10/23 19:34:14 otto Exp $ */ +/* $OpenBSD: tar.c,v 1.41 2006/03/04 20:24:55 otto Exp $ */ /* $NetBSD: tar.c,v 1.5 1995/03/21 09:07:49 cgd Exp $ */ /*- @@ -38,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)tar.c 8.2 (Berkeley) 4/18/94"; #else -static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: tar.c,v 1.34 2004/10/23 19:34:14 otto Exp $"; +static const char rcsid[] = "$OpenBSD: tar.c,v 1.41 2006/03/04 20:24:55 otto Exp $"; #endif #endif /* not lint */ @@ -60,7 +60,7 @@ static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: tar.c,v 1.34 static size_t expandname(char *, size_t, char **, const char *, size_t); static u_long tar_chksm(char *, int); -char *name_split(char *, int); +static char *name_split(char *, int); static int ul_oct(u_long, char *, int, int); #ifndef LONG_OFF_T static int uqd_oct(u_quad_t, char *, int, int); @@ -433,6 +433,7 @@ tar_rd(ARCHD *arcn, char *buf) */ arcn->type = PAX_SLK; arcn->sb.st_mode |= S_IFLNK; + arcn->ln_nlen = strlcpy(arcn->ln_name, hd->linkname, sizeof(arcn->ln_name)); break; case LNKTYPE: /* @@ -441,6 +442,7 @@ tar_rd(ARCHD *arcn, char *buf) */ arcn->type = PAX_HLK; arcn->sb.st_nlink = 2; + arcn->ln_nlen = strlcpy(arcn->ln_name, hd->linkname, sizeof(arcn->ln_name)); /* * no idea of what type this thing really points at, but @@ -523,7 +525,7 @@ tar_wr(ARCHD *arcn) { HD_TAR *hd; int len; - char hdblk[sizeof(HD_TAR)]; + HD_TAR hdblk; /* * check for those file system types which tar cannot store @@ -552,8 +554,9 @@ tar_wr(ARCHD *arcn) case PAX_SLK: case PAX_HLK: case PAX_HRG: - if (arcn->ln_nlen > sizeof(hd->linkname)) { - paxwarn(1,"Link name too long for tar %s", arcn->ln_name); + if (arcn->ln_nlen >= sizeof(hd->linkname)) { + paxwarn(1, "Link name too long for tar %s", + arcn->ln_name); return(1); } break; @@ -582,9 +585,9 @@ tar_wr(ARCHD *arcn) * (if any) to be added after the file data (0 for all other types, * as they only have a header). */ - memset(hdblk, 0, sizeof(hdblk)); - hd = (HD_TAR *)hdblk; - strlcpy(hd->name, arcn->name, sizeof(hd->name)); + memset(&hdblk, 0, sizeof(hdblk)); + hd = (HD_TAR *)&hdblk; + strlcpy(hd->name, arcn->name, sizeof(hd->name)); arcn->pad = 0; if (arcn->type == PAX_DIR) { @@ -645,10 +648,10 @@ tar_wr(ARCHD *arcn) * 0 tells the caller to now write the file data, 1 says no data needs * to be written */ - if (ul_oct(tar_chksm(hdblk, sizeof(HD_TAR)), hd->chksum, + if (ul_oct(tar_chksm((char *)&hdblk, sizeof(HD_TAR)), hd->chksum, sizeof(hd->chksum), 3)) goto out; - if (wr_rdbuf(hdblk, sizeof(HD_TAR)) < 0) + if (wr_rdbuf((char *)&hdblk, sizeof(HD_TAR)) < 0) return(-1); if (wr_skip((off_t)(BLKMULT - sizeof(HD_TAR))) < 0) return(-1); @@ -772,7 +775,7 @@ ustar_rd(ARCHD *arcn, char *buf) } if (hd->typeflag != LONGLINKTYPE && hd->typeflag != LONGNAMETYPE) { - arcn->nlen = expandname(dest, sizeof(arcn->name) - cnt, + arcn->nlen = cnt + expandname(dest, sizeof(arcn->name) - cnt, &gnu_name_string, hd->name, sizeof(hd->name)); arcn->ln_nlen = expandname(arcn->ln_name, sizeof(arcn->ln_name), &gnu_link_string, hd->linkname, sizeof(hd->linkname)); @@ -796,7 +799,7 @@ ustar_rd(ARCHD *arcn, char *buf) * If we can find the ascii names for gname and uname in the password * and group files we will use the uid's and gid they bind. Otherwise * we use the uid and gid values stored in the header. (This is what - * the posix spec wants). + * the POSIX spec wants). */ hd->gname[sizeof(hd->gname) - 1] = '\0'; if (gid_name(hd->gname, &(arcn->sb.st_gid)) < 0) @@ -949,6 +952,7 @@ ustar_wr(ARCHD *arcn) memset(hdblk, 0, sizeof(hdblk)); hd = (HD_USTAR *)hdblk; arcn->pad = 0L; + /* To pass conformance tests 274/301, always set these fields to "zero" */ ul_oct(0, hd->devmajor, sizeof(hd->devmajor), term_char); ul_oct(0, hd->devminor, sizeof(hd->devminor), term_char); @@ -968,7 +972,7 @@ ustar_wr(ARCHD *arcn) /* * copy the name part. this may be the whole path or the part after - * the prefix + * the prefix. both the name and prefix may fill the entire field. */ if (strlen(pt) == sizeof(hd->name)) { /* must account for name just fits in buffer */ strncpy(hd->name, pt, sizeof(hd->name)); @@ -1094,7 +1098,7 @@ ustar_wr(ARCHD *arcn) if (ul_oct(tar_chksm(hdblk, sizeof(HD_USTAR)), hd->chksum, sizeof(hd->chksum), term_char)) goto out; - if (wr_rdbuf(hdblk, sizeof(HD_USTAR)) < 0) + if (wr_rdbuf((char *)&hdblk, sizeof(HD_USTAR)) < 0) return(-1); if (wr_skip((off_t)(BLKMULT - sizeof(HD_USTAR))) < 0) return(-1); @@ -1122,7 +1126,7 @@ ustar_wr(ARCHD *arcn) * the file name is too long */ -char * +static char * name_split(char *name, int len) { char *start; @@ -1130,19 +1134,22 @@ name_split(char *name, int len) /* * check to see if the file name is small enough to fit in the name * field. if so just return a pointer to the name. + * The strings can fill the complete name and prefix fields + * without a NUL terminator. */ if (len <= TNMSZ) return(name); - if (len > (TPFSZ + TNMSZ)) + if (len > (TPFSZ + TNMSZ + 1)) return(NULL); /* * we start looking at the biggest sized piece that fits in the name * field. We walk forward looking for a slash to split at. The idea is * to find the biggest piece to fit in the name field (or the smallest - * prefix we can find) + * prefix we can find) (the -1 is correct the biggest piece would + * include the slash between the two parts that gets thrown away) */ - start = name + len - TNMSZ -1; + start = name + len - TNMSZ - 1; if ((*start == '/') && (start == name)) ++start; /* 101 byte paths with leading '/' are dinged otherwise */ while ((*start != '\0') && (*start != '/')) @@ -1162,7 +1169,7 @@ name_split(char *name, int len) * the file would then expand on extract to //str. The len == 0 below * makes this special case follow the spec to the letter. */ - if ((len >= TPFSZ) || (len == 0)) + if ((len > TPFSZ) || (len == 0)) return(NULL); /* @@ -1172,11 +1179,13 @@ name_split(char *name, int len) } static size_t -expandname(char *buf, size_t len, char **gnu_name, const char *name, size_t name_len) +expandname(char *buf, size_t len, char **gnu_name, const char *name, + size_t name_len) { size_t nlen; if (*gnu_name) { + /* *gnu_name is NUL terminated */ if ((nlen = strlcpy(buf, *gnu_name, len)) >= len) nlen = len - 1; free(*gnu_name); diff --git a/pax/tty_subs.c b/pax/tty_subs.c index c72ec8e..5a78a71 100644 --- a/pax/tty_subs.c +++ b/pax/tty_subs.c @@ -38,7 +38,7 @@ #if 0 static const char sccsid[] = "@(#)tty_subs.c 8.2 (Berkeley) 4/18/94"; #else -static const char rcsid[] __attribute__((__unused__)) = "$OpenBSD: tty_subs.c,v 1.12 2003/06/02 23:32:09 millert Exp $"; +static const char rcsid[] = "$OpenBSD: tty_subs.c,v 1.12 2003/06/02 23:32:09 millert Exp $"; #endif #endif /* not lint */ @@ -101,12 +101,9 @@ void tty_prnt(const char *fmt, ...) { va_list ap; - - va_start(ap, fmt); - if (ttyoutf == NULL) { - va_end(ap); + if (ttyoutf == NULL) return; - } + va_start(ap, fmt); (void)vfprintf(ttyoutf, fmt, ap); va_end(ap); (void)fflush(ttyoutf); @@ -197,6 +194,6 @@ syswarn(int set, int errnum, const char *fmt, ...) * format and print the errno */ if (errnum > 0) - (void)fprintf(stderr, ": %s", strerror(errnum)); + (void)fprintf(stderr, " <%s>", strerror(errnum)); (void)fputc('\n', stderr); } diff --git a/rm/Makefile b/rm/Makefile index d37084b..5e8cf03 100644 --- a/rm/Makefile +++ b/rm/Makefile @@ -4,8 +4,7 @@ Install_Dir = /bin CFILES = rm.c MANPAGES = rm.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/rm/rm.c b/rm/rm.c index def4a2f..1c5c198 100644 --- a/rm/rm.c +++ b/rm/rm.c @@ -61,6 +61,7 @@ static const char rcsid[] = #include #ifdef __APPLE__ +#include #include #include #include "get_compat.h" @@ -107,6 +108,7 @@ main(argc, argv) p = argv[0]; else ++p; + uid = geteuid(); if (strcmp(p, "unlink") == 0) { if (argc == 2) { rm_file(&argv[1]); @@ -155,7 +157,6 @@ main(argc, argv) } checkdot(argv); - uid = geteuid(); if (*argv) { stdin_ok = isatty(STDIN_FILENO); @@ -298,9 +299,17 @@ rm_tree(argv) break; default: +#ifdef __APPLE__ + if (Pflag) { + if (removefile(p->fts_accpath, NULL, REMOVEFILE_SECURE_7_PASS)) /* overwrites and unlinks */ + eval = rval = 1; + } else + rval = unlink(p->fts_accpath); +#else /* !__APPLE_ */ if (Pflag) rm_overwrite(p->fts_accpath, NULL); rval = unlink(p->fts_accpath); +#endif /* __APPLE__ */ if (rval == 0 || (fflag && errno == ENOENT)) { if (rval == 0 && vflag) (void)printf("%s\n", @@ -366,9 +375,17 @@ rm_file(argv) else if (S_ISDIR(sb.st_mode)) rval = rmdir(f); else { +#ifdef __APPLE__ + if (Pflag) { + if (removefile(f, NULL, REMOVEFILE_SECURE_7_PASS)) /* overwrites and unlinks */ + eval = rval = 1; + } else + rval = unlink(f); +#else /* !__APPLE__ */ if (Pflag) rm_overwrite(f, &sb); rval = unlink(f); +#endif /* __APPLE__ */ } } if (rval && (!fflag || errno != ENOENT)) { diff --git a/rmdir/Makefile b/rmdir/Makefile index 3e0b933..d959064 100644 --- a/rmdir/Makefile +++ b/rmdir/Makefile @@ -4,8 +4,7 @@ Install_Dir = /bin CFILES = rmdir.c MANPAGES = rmdir.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/rmt/Makefile b/rmt/Makefile index f372506..a0874d1 100644 --- a/rmt/Makefile +++ b/rmt/Makefile @@ -4,8 +4,7 @@ Install_Dir = /usr/sbin CFILES = rmt.c MANPAGES = rmt.8 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/stat/Makefile b/stat/Makefile index 9afcd22..3b4de1d 100644 --- a/stat/Makefile +++ b/stat/Makefile @@ -4,8 +4,7 @@ Install_Dir = /usr/bin CFILES = stat.c MANPAGES = stat.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/stat/stat.c b/stat/stat.c index 5603a05..e19bb22 100644 --- a/stat/stat.c +++ b/stat/stat.c @@ -67,12 +67,6 @@ __FBSDID("$FreeBSD: src/usr.bin/stat/stat.c,v 1.6 2003/10/06 01:55:17 dougb Exp #include #include -#ifdef __APPLE__ -#define stat stat64 -#define fstat fstat64 -#define lstat lstat64 -#endif /* __APPLE__ */ - #if HAVE_STRUCT_STAT_ST_FLAGS #define DEF_F "%#Xf " #define RAW_F "%f " diff --git a/touch/Makefile b/touch/Makefile index ad77a26..780be63 100644 --- a/touch/Makefile +++ b/touch/Makefile @@ -4,8 +4,7 @@ Install_Dir = /usr/bin CFILES = touch.c MANPAGES = touch.1 -Extra_CC_Flags = -Wall -mdynamic-no-pic \ - -D__FBSDID=__RCSID +Extra_CC_Flags = -Werror -Wall -mdynamic-no-pic -D__FBSDID=__RCSID -D_DARWIN_USE_64_BIT_INODE Extra_LD_Flags = -dead_strip include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make diff --git a/touch/touch.c b/touch/touch.c index 8909d79..ea40b26 100644 --- a/touch/touch.c +++ b/touch/touch.c @@ -177,6 +177,7 @@ main(int argc, char *argv[]) if (timeset) { rval = 1; warn("%s", *argv); + continue; } /* -- 2.7.4