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
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
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__
/* 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;
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
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
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
.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
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;
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
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;
#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')) {
|| 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;
*/
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;
} 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;
/* 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);
}
}
}
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) {
#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");
/* 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) ||
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))
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;
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.
*/
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;
} 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;
retval += modify_acl(&oacl, entry, optflags,
position, inheritance_level,
- flag_new_acl);
+ flag_new_acl, path);
}
}
}
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__*/
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
.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
.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.
{
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;
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':
if (argc < 2)
usage();
+ if (!Rflag && (Hflag || Lflag || Pflag))
+ warnx("options -H, -L, -P only useful with -R");
if (Rflag) {
fts_options = FTS_PHYSICAL;
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
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
zs = cookie;
count = num;
- bp = wbp;
+ bp = (const u_char *)wbp;
if (state == S_MIDDLE)
goto middle;
state = S_MIDDLE;
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
.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
.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
.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
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.
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 ,
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
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;
case 'v':
vflag = 1;
break;
+ case 'a':
+ pflag = 1;
+ Pflag = 1;
+ Rflag = 1;
+ break;
default:
usage();
break;
default:
;
}
-
+#ifdef __APPLE__
+ /* Skip ._<file> when using copyfile and <file> 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.
*/
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")) {
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)
{
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 {
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);
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
.Ex -std
.Sh SEE ALSO
.Xr cp 1 ,
-.Xr mt 1 ,
.Xr tr 1
.Sh STANDARDS
The
#endif /* not lint */
#include <sys/types.h>
-#include <sys/mtio.h>
#ifdef __APPLE__
#include <sys/ioctl.h>
void
pos_out(void)
{
- struct mtop t_op;
off_t cnt;
ssize_t n;
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)
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)
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
(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 ,
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));
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
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
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 ,
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/stat.h>
+#include <sys/attr.h>
#include <err.h>
#include <errno.h>
};
static int linkchk(FTSENT *);
+static int dirlinkchk(FTSENT *);
static void usage(void);
void prthumanval(double);
unit_t unit_adjust(double *);
Hflag = Lflag = Pflag = aflag = sflag = dflag = cflag = hflag = 0;
save = argv;
- ftsoptions = 0;
+ ftsoptions = FTS_NOCHDIR;
depth = INT_MAX;
SLIST_INIT(&ignores);
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:
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,
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
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
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
#include <unistd.h>
#include <sysexits.h>
-#include <sys/types.h>
+#include "sys/types.h"
#include <sys/ucred.h>
#include <sys/time.h>
#include <sys/proc.h>
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),
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),
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),
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
.Xr lchmod 2 ,
.Xr lchown 2 ,
.Xr lstat 2 ,
-.Xr lutimes 2 ,
+.Xr lutimes 3 ,
.Xr readlink 2 ,
.Xr rename 2 ,
.Xr rmdir 2 ,
.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.
.Xr lchmod 2 ,
.Xr lchown 2 ,
.Xr lstat 2 ,
-.Xr lutimes 2 ,
+.Xr lutimes 3 ,
.Xr readlink 2 ,
.Xr rename 2 ,
.Xr symlink 2 ,
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 \
#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)
((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
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));
+}
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 *);
.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
.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 . )
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
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 /
.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
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
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 . )
(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
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.
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.
The environment variable
.Ev BLOCKSIZE
overrides the unit size of 512 bytes.
-.\" ==========
.It Fl T
When used with the
.Fl l
.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 ,
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.
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 ,
/* 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 */
f_listdot = 1;
fts_options = FTS_PHYSICAL;
- while ((ch = getopt(argc, argv, "1@ABCFGHLOPRSTWabcdefghiklmnopqrstuvwx"))
+ while ((ch = getopt(argc, argv, "1@ABCFGHLOPRSTUWabcdefghiklmnopqrstuvwx"))
!= -1) {
switch (ch) {
/*
/* 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;
sortfcn = revacccmp;
else if (f_statustime)
sortfcn = revstatcmp;
+ else if (f_birthtime)
+ sortfcn = revbirthcmp;
else /* Use modification time. */
sortfcn = revmodcmp;
} else {
sortfcn = acccmp;
else if (f_statustime)
sortfcn = statcmp;
+ else if (f_birthtime)
+ sortfcn = birthcmp;
else /* Use modification time. */
sortfcn = modcmp;
}
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)
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;
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 */
#include <termcap.h>
#include <signal.h>
#endif
-
+#include <stdint.h> /* intmax_t */
#ifdef __APPLE__
#include <get_compat.h>
#else
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
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));
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);
}
{
(void)fprintf(stderr,
#ifdef COLORLS
- "usage: ls [-ABCFGHLPRSTWabcdefghiklmnopqrstuwx1]"
+ "usage: ls [-ABCFGHLOPRSTUWabcdefghiklmnopqrstuwx1]"
#else
- "usage: ls [-ABCFHLPRSTWabcdefghiklmnopqrstuwx1]"
+ "usage: ls [-ABCFHLOPRSTUWabcdefghiklmnopqrstuwx1]"
#endif
" [file ...]\n");
exit(1);
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
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
.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 ,
{
int ch, exitval;
void * set;
- mode_t mode;
+ mode_t mode = 0;
int m_used = 0;
setlocale (LC_ALL, "");
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
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
.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
.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
.Sh SEE ALSO
.Xr mkfifo 1 ,
.Xr mkfifo 2 ,
-.Xr mknod 2 ,
-.Xr MAKEDEV 8
+.Xr mknod 2
.Sh HISTORY
A
.Nm
../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
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 *);
}
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))
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
.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 ,
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);
}
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);
}
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
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
-/* $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 $ */
/*-
#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 */
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
+#ifndef __APPLE__
#include <sys/mtio.h>
+#endif /* !__APPLE__ */
#include <sys/param.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include <err.h>
+#include <stdint.h>
#include "pax.h"
#include "options.h"
#include "extern.h"
#define APP_MODE O_RDWR /* mode for append */
#define STDO "<STDOUT>" /* pseudo name for stdout */
#define STDN "<STDIN>" /* pseudo name for stdin */
+#define _NONE "<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 */
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);
int
ar_open(const char *name)
{
+#ifndef __APPLE__
struct mtget mb;
-
+#endif /* __APPLE__ */
if (arfd != -1)
(void)close(arfd);
arfd = -1;
/*
* arfd not used in COPY mode
*/
- arcname = "<NONE>";
+ arcname = _NONE;
lstrval = 1;
return(0);
}
return(-1);
if (chdname != NULL)
- if (chdir(chdname) != 0) {
- syswarn(1, errno, "Failed chdir to %s", chdname);
+ if (dochdir(chdname) == -1) {
return(-1);
}
/*
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;
(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;
}
break;
if (errno == EACCES) {
paxwarn(0, "Write failed, archive is write protected.");
- res = lstrval = 0;
+ lstrval = 0;
return(0);
}
/*
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
did_io = 1;
switch (artyp) {
+#ifndef __APPLE__
case ISTAPE:
/*
* if the last i/o was a successful data transfer, we assume
break;
lstrval = 1;
break;
+#endif /* !__APPLE__ */
case ISREG:
case ISCHR:
case ISBLK:
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
return(-1);
}
break;
+#ifndef __APPLE__
case ISTAPE:
/*
* Calculate and move the proper number of PHYSICAL tape
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
}
return(phyblk);
}
-
+#endif /* !__APPLE__ */
/*
* ar_next()
* prompts the user for the next volume in this archive. For some devices
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);
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 */
}
}
-/* $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 $ */
/*-
#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 */
#include <unistd.h>
#include <stdlib.h>
#ifdef __APPLE__
+#include <sys/param.h>
#include <copyfile.h>
#include <libgen.h>
#include <sys/queue.h>
#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 ...
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)
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;
* 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
* 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);
int (*wrf)(ARCHD *);
int fd = -1;
time_t now;
+
#ifdef __APPLE__
int metadata = 0;
char *md_fname = NULL;
*/
if (((hlk = frmt->hlk) == 1) && (lnk_start() < 0))
return;
+
if (hlk && want_linkdata) hlk=0; /* Treat hard links as individual files */
/*
/*
* 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) {
/*
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)) {
* 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);
break;
#ifdef __APPLE__
if (metadata)
- goto next;
-#endif
+ goto next;
+#endif /* __APPLE__ */
}
/*
* 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.
*/
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;
/*
* 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
#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);
-/* $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 $ */
/*-
#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 */
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,
-.\" $OpenBSD: cpio.1,v 1.20 2003/11/21 20:54:02 jmc Exp $
-.\"
+.\"-
.\" Copyright (c) 1997 SigmaSoft, Th. Lockert
.\" All rights reserved.
.\"
.\" (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
.Fl p
.Op Fl adlLmuv
.Ar destination-directory
-.Ar "< name-list"
+.No < Ar name-list
.Sh DESCRIPTION
The
.Nm cpio
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.
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.
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.
.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
-/* $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 $ */
/*-
#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 */
}
/*
- * 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
-/* $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 $ */
/*-
* 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);
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 *);
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 *);
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
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
extern int pmode;
extern int pids;
extern int rmleadslash;
+extern int secure;
extern int exit_val;
extern int docrc;
extern char *dirptr;
extern FILE *listf;
extern char *tempfile;
extern char *tempbase;
+extern int havechd;
int main(int, char **);
void sig_cleanup(int);
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);
-/* $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 $ */
/*-
#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 */
* 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);
}
}
/* 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;
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);
}
if (fd < 0)
return;
+
if (close(fd) < 0)
syswarn(0, errno, "Unable to close file descriptor on %s",
arcn->name);
* 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 */
struct stat sb;
char target[MAXPATHLEN];
char *nm = arcn->name;
+ int nmlen = arcn->nlen;
int len;
/*
}
target[len] = '\0';
nm = target;
+ nmlen = len;
}
}
res = mkdir(nm, file_mode);
#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.
* 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)
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;
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';
*/
*new_name = spt;
} else
- *spt++ = '/';
+ *spt = '/';
}
return(retval);
}
/*
* set the times
*/
-
if (pax_invalid_action_write_cwd) {
char cwd_buff[MAXPATHLEN];
char * cwd;
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
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
}
return(0);
}
-#endif
+#endif /* !__APPLE__ */
/*
* set_pmode()
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
int res;
off_t cpcnt = 0L;
u_long size;
- unsigned long crc = 0L;
+ u_int32_t crc = 0;
char tbuf[FILEBLK];
struct stat sb;
-/* $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 $ */
/*-
#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 */
str[len] = '\0';
ft->fname = str;
ft->refcnt = 0;
+ ft->newercnt = 0;
ft->chflg = chflg;
ft->fow = NULL;
if (fthead == NULL) {
(void)fts_set(ftsp, ftent, FTS_SKIP);
}
+/*
+ * 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
* 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:");
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);
*/
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
* 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);
}
-/* $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 $ */
/*-
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;
-/* $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 $ */
/*-
#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 */
#include <sys/param.h>
#include <stdio.h>
#include <tzfile.h>
-#include <utmp.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <vis.h>
+#include <langinfo.h>
#include "pax.h"
#include "extern.h"
#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()
struct stat *sbp;
char f_mode[MODELEN];
char f_date[DATELEN];
+ const char *timefrmt;
int term;
term = zeroflag ? '\0' : '\n'; /* path termination character */
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));
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);
{
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;
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);
+}
*/
#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 <sys/types.h>
-/* $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 $ */
/*-
#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 <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
+#include <search.h>
+#ifndef __APPLE__
#include <sys/mtio.h>
+#endif /* __APPLE__ */
#include <sys/param.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <paths.h>
-#include <search.h>
+#include <getopt.h>
#include "pax.h"
#include "options.h"
#include "cpio.h"
#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
#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 */
/*
*/
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
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
pax_options(int argc, char **argv)
{
int c;
- int i;
+ size_t i;
unsigned int flg = 0;
unsigned int bflg = 0;
char *pt;
/*
* 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
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
* 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;
}
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();
* 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':
/*
*/
Lflag = 1;
break;
+ case 'j':
+ /*
+ * use bzip2. Non standard option.
+ */
+ gzip_program = BZIP2_CMD;
+ break;
case 'm':
/*
* do not preserve modification time
*/
break;
case 'C':
+ havechd++;
chdname = optarg;
break;
case 'H':
default:
{
int sawpat = 0;
- char *file, *dir;
+ char *file, *dir = NULL;
while (nincfiles || *argv != NULL) {
/*
if (*++argv == NULL)
break;
chdname = *argv++;
+ havechd++;
} else if (pat_add(*argv++, chdname) < 0)
tar_usage();
else
}
while (nincfiles || *argv != NULL) {
- char *file, *dir;
+ char *file, *dir = NULL;
/*
* If we queued up any include files, pull them in
break;
if (ftree_add(*argv++, 1) < 0)
tar_usage();
+ havechd++;
} else if (ftree_add(*argv++, 0) < 0)
tar_usage();
}
FILE *fp;
size_t n_fsub;
- listf = stderr;
- kflag = 0;
- uflag = 1;
+ kflag = 1;
pids = 1;
pmode = 1;
pmtime = 0;
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':
/*
*/
act = EXTRACT;
break;
+ case 'j':
+ /*
+ * use bzip2. Non standard option.
+ */
+ gzip_program = BZIP2_CMD;
+ break;
case 'k':
break;
case 'l':
/*
* replace newer files
*/
- uflag = 0;
+ kflag = 0;
break;
case 'v':
/*
* 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)
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));
}
/*
/*
* 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
OPLIST *opt;
char *frpt;
char *pt;
- char *endpt;
char *dstr;
+ char *endpt;
if ((str == NULL) || (*str == '\0')) {
paxwarn(0, "Invalid option name");
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
return(0);
}
-
/*
* pax_format_opt_add()
* breaks the value supplied to -o into a option name and value. options
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
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);
}
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);
}
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);
}
-/* $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 $ */
/*-
#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 */
/*
* 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)
*pend = string;
return(0);
case '?':
- if ((test = *string++) == '\0')
+ if ((*string++) == '\0')
return (-1);
break;
case '*':
/*
* General case, use recursion.
*/
- while ((test = *string) != '\0') {
+ while ((*string) != '\0') {
if (!fn_match(pattern, string, pend))
return (0);
++string;
* 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 {
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] = '.';
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);
* 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;
}
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 */
-.\" $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.
.\"
.\" @(#)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
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 <none>
+.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
.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
.Fl l
option below).
.Pp
-.Em Warning :
+.Sy Warning :
The destination
.Ar directory
must not be one of the
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
.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
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.
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
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
.Pp
The options are as follows:
.Bl -tag -width Ds
-.\" ==========
.It Fl 0
Use the NUL
.Pq Ql \e0
.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
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 .
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
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
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
and
.Ar file
operands.
-.\" ==========
.It Fl D
This option is the same as the
.Fl u
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
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
.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
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
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
.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
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
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=<pattern>
-.It
-exthdr.name=<string>
-.It
-globexhdr.name=<string>
-.It
-invalid=<action> for actions
-bypass, rename, utf-8 (recognized, but ignored), and write
-.It
-linkdata
-.It
-listopt=<format>
-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
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
.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
.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 )
.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.
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
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
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,
.Cm p
will cause the final result of a successful substitution to be written to
standard error in the following format:
-.Dl <original pathname> >> <new pathname>
+.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
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
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.
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
option.
For pathnames representing a hard link to a previous member of the archive,
the output has the format:
-.Dl <ls -l listing> == <link name>
+.Pp
+.Dl Em ls -l listing Li == Em link-name
+.Pp
For pathnames representing a symbolic link, the output has the format:
-.Dl <ls -l listing> => <link name>
-Where <ls -l listing> 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
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.
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.
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
.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.
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 ,
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
.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
.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
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 ,
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.
-/* $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 $ */
/*-
*/
#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 */
#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 */
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) */
* 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?
*/
-/* $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 $ */
/*-
/* 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 */
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
*/
-/* $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
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);
* 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
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)
{
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)
{
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';
}
}
}
}
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));
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));
return(1);
}
-#if 0
/*
* name_split()
* see if the name has to be split for storage in a ustar header. We try
* 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;
*/
return(start);
}
-#endif /* if 0 */
static size_t
expandname(char *buf, size_t len, char **gnu_name, const char *name, size_t name_len)
#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 */
-/* $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 $ */
/*-
#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 */
if ((arcn->type == PAX_DIR) || (arcn->sb.st_nlink <= 1))
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) {
*/
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
* 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;
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);
}
*/
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) {
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
-/* $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 $ */
/*-
} 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).
-/* $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 $ */
/*-
#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 */
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);
*/
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:
/*
*/
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
{
HD_TAR *hd;
int len;
- char hdblk[sizeof(HD_TAR)];
+ HD_TAR hdblk;
/*
* check for those file system types which tar cannot store
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;
* (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) {
* 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);
}
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));
* 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)
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);
/*
* 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));
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);
* the file name is too long
*/
-char *
+static char *
name_split(char *name, int len)
{
char *start;
/*
* 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 != '/'))
* 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);
/*
}
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);
#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 */
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);
* format and print the errno
*/
if (errnum > 0)
- (void)fprintf(stderr, ": %s", strerror(errnum));
+ (void)fprintf(stderr, " <%s>", strerror(errnum));
(void)fputc('\n', stderr);
}
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
#include <unistd.h>
#ifdef __APPLE__
+#include <removefile.h>
#include <pwd.h>
#include <grp.h>
#include "get_compat.h"
p = argv[0];
else
++p;
+ uid = geteuid();
if (strcmp(p, "unlink") == 0) {
if (argc == 2) {
rm_file(&argv[1]);
}
checkdot(argv);
- uid = geteuid();
if (*argv) {
stdin_ok = isatty(STDIN_FILENO);
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",
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)) {
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
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
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
#include <time.h>
#include <unistd.h>
-#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 "
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
if (timeset) {
rval = 1;
warn("%s", *argv);
+ continue;
}
/*