file_cmds-287.40.2

This commit is contained in:
Ariel Abreu 2020-08-01 22:31:21 -04:00
parent a5777529f0
commit e5a9a3aefd
No known key found for this signature in database
GPG Key ID: ECF8C2B9E8AD3E6B
49 changed files with 1385 additions and 383 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
*~
# /
/build
# /file_cmds.xcodeproj/
/file_cmds.xcodeproj/xcuserdata
/file_cmds.xcodeproj/*.xcworkspace

2
.upstream_base_commits Normal file
View File

@ -0,0 +1,2 @@
#freebsd = https://github.com/freebsd/freebsd.git
chmod/chmod.1 freebsd bin/chmod/chmod.1 14889ebf5bdeaead21c00f70044d9acbb923f6b0

View File

@ -120,14 +120,6 @@ set the hidden flag
[Hide item from GUI]
.El
.Pp
As discussed in
.Xr chflags 2 ,
the
.Ar sappnd
and
.Ar schg
flags may only be unset when the system is in single-user mode.
.Pp
Putting the letters
.Dq Ar no
before or removing the letters

View File

@ -1,3 +1,4 @@
.\"-
.\" Copyright (c) 1989, 1990, 1993, 1994
.\" The Regents of the University of California. All rights reserved.
.\"
@ -12,11 +13,7 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" 3. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
@ -33,9 +30,9 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)chmod.1 8.4 (Berkeley) 3/31/94
.\" $FreeBSD: src/bin/chmod/chmod.1,v 1.33 2002/10/01 20:32:59 trhodes Exp $
.\" $FreeBSD$
.\"
.Dd July 08, 2004
.Dd January 7, 2017
.Dt CHMOD 1
.Os
.Sh NAME
@ -49,23 +46,23 @@
.Ar
.Nm chmod
.Op Fl fv
.Op Fl R Op Fl H | L | P
.Op Fl R Op Fl H | L | P
.Op -a | +a | =a
.Ar ACE
.Ar
.Nm chmod
.Op Fl fhv
.Op Fl R Op Fl H | L | P
.Op Fl R Op Fl H | L | P
.Op Fl E
.Ar
.Nm chmod
.Op Fl fhv
.Op Fl R Op Fl H | L | P
.Op Fl R Op Fl H | L | P
.Op Fl C
.Ar
.Nm chmod
.Op Fl fhv
.Op Fl R Op Fl H | L | P
.Op Fl R Op Fl H | L | P
.Op Fl N
.Ar
.Sh DESCRIPTION
@ -78,18 +75,19 @@ operand. It may also be used to modify the Access Control
Lists (ACLs) associated with the listed files.
.Pp
The generic options are as follows:
.Bl -tag -width Ds
.Bl -tag -width indent
.It Fl f
Do not display a diagnostic message if
.Nm chmod
could not modify the mode for
.Va file .
.Va file ,
nor modify the exit status to reflect such failures.
.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 by
default.)
option is specified, symbolic links on the command line are followed
and hence unaffected by the command.
(Symbolic links encountered during tree traversal are not followed.)
.It Fl h
If the file is a symbolic link, change the mode of the link itself
rather than the file that the link points to.
@ -103,8 +101,12 @@ If the
option is specified, no symbolic links are followed.
This is the default.
.It Fl R
Change the modes of the file hierarchies rooted in the files
Change the modes of the file hierarchies rooted in the files,
instead of just the files themselves.
Beware of unintentionally matching the
.Dq Pa ".."
hard link to the parent directory when using wildcards like
.Dq Li ".*" .
.It Fl v
Cause
.Nm chmod
@ -126,9 +128,19 @@ option is specified.
In addition, these options override each other and the
command's actions are determined by the last one specified.
.Pp
If
.Nm chmod
receives a
.Dv SIGINFO
signal (see the
.Cm status
argument for
.Xr stty 1 ) ,
then the current filename as well as the old and new modes are displayed.
.Pp
Only the owner of a file or the super-user is permitted to change
the mode of a file.
.Sh DIAGNOSTICS
.Sh EXIT STATUS
.Ex -std
.Sh MODES
Modes may be absolute or symbolic.
@ -137,26 +149,28 @@ one or more of the following values:
.Pp
.Bl -tag -width 6n -compact -offset indent
.It Li 4000
(the set-user-ID-on-execution bit) Executable files with this bit set
(the setuid bit).
Executable files with this bit set
will run with effective uid set to the uid of the file owner.
Directories with the set-user-id bit set will force all files and
Directories with this bit set will force all files and
sub-directories created in them to be owned by the directory owner
and not by the uid of the creating process, if the underlying file
system supports this feature: see
.Xr chmod 2
and the
.Ar suiddir
.Cm suiddir
option to
.Xr mount 8 .
.It Li 2000
(the set-group-ID-on-execution bit) Executable files with this bit set
(the setgid bit).
Executable files with this bit set
will run with effective gid set to the gid of the file owner.
.It Li 1000
(the sticky bit)
(the sticky bit).
See
.Xr chmod 2
and
.Xr sticky 8 .
.Xr sticky 7 .
.It Li 0400
Allow read by owner.
.It Li 0200
@ -250,6 +264,8 @@ If no value is supplied for
each permission bit specified in
.Ar perm ,
for which the corresponding bit in the file mode creation mask
(see
.Xr umask 2 )
is clear, is set.
Otherwise, the mode bits represented by the specified
.Ar who
@ -265,7 +281,7 @@ If no value is supplied for
each permission bit specified in
.Ar perm ,
for which the corresponding bit in the file mode creation mask
is clear, is cleared.
is set, is cleared.
Otherwise, the mode bits represented by the specified
.Ar who
and
@ -274,7 +290,9 @@ values are cleared.
.It =
The mode bits specified by the
.Ar who
value are cleared, or, if no who value is specified, the owner, group
value are cleared, or, if no
.Ar who
value is specified, the owner, group
and other mode bits are cleared.
Then, if no value is supplied for
.Ar who ,
@ -299,6 +317,10 @@ Operations upon the other permissions only (specified by the symbol
``o'' by itself), in combination with the
.Ar perm
symbols ``s'' or ``t'', are ignored.
.Pp
The ``w'' permission on directories will permit file creation, relocation,
and copy into that directory.
Files created within the directory itself will inherit its group ID.
.Sh EXAMPLES OF VALID MODES
.Bl -tag -width "u=rwx,go=u-w" -compact
.It Li 644
@ -344,7 +366,7 @@ The following permissions are applicable to all filesystem objects:
Delete the item. Deletion may be granted by either this permission
on an object or the delete_child right on the containing directory.
.It readattr
Read an objects basic attributes. This is implicitly granted if
Read an object's basic attributes. This is implicitly granted if
the object can be looked up and not explicitly denied.
.It writeattr
Write an object's basic attributes.
@ -536,7 +558,7 @@ Individual entries are rewritten using the =a# mode.
1: admin allow write,chown
.Pp
This mode may not be used to add new entries.
.It Fl E
.It Fl E
Reads the ACL information from stdin, as a sequential list
of ACEs, separated by newlines. If the information parses correctly,
the existing information is replaced.
@ -555,17 +577,16 @@ The
option is non-standard and its use in scripts is not recommended.
.Sh SEE ALSO
.Xr chflags 1 ,
.Xr fsaclctl 1 ,
.Xr install 1 ,
.Xr chmod 2 ,
.Xr stat 2 ,
.Xr umask 2 ,
.Xr fts 3 ,
.Xr setmode 3 ,
.Xr sticky 7 ,
.Xr symlink 7 ,
.Xr chown 8 ,
.Xr mount 8 ,
.Xr sticky 8
.Xr mount 8
.Sh STANDARDS
The
.Nm chmod

View File

@ -676,7 +676,7 @@ modify_file_acl(unsigned int optflags, const char *path, acl_t modifier, int pos
unsigned aindex = 0, flag_new_acl = 0;
acl_entry_t newent = NULL;
acl_entry_t entry = NULL;
unsigned retval = 0 ;
unsigned retval = 0;
extern int fflag;
@ -699,17 +699,36 @@ modify_file_acl(unsigned int optflags, const char *path, acl_t modifier, int pos
if (optflags & ACL_CLEAR_FLAG) {
filesec_t fsec = filesec_init();
if (fsec == NULL)
if (fsec == NULL) {
err(1, "filesec_init() failed");
if (filesec_set_property(fsec, FILESEC_ACL,
_FILESEC_REMOVE_ACL) != 0)
}
if (filesec_set_property(fsec, FILESEC_ACL, _FILESEC_REMOVE_ACL) != 0) {
err(1, "filesec_set_property() failed");
if (chmodx_np(path, fsec) != 0) {
if (!fflag)
warn("Failed to clear ACL on file %s", path);
retval = 1;
} else
retval = 0;
}
if (follow) {
if (chmodx_np(path, fsec) != 0) {
if (!fflag) {
warn("Failed to clear ACL on file %s", path);
}
retval = 1;
}
} else {
int fd = open(path, O_SYMLINK);
if (fd != -1) {
if (fchmodx_np(fd, fsec) != 0) {
if (!fflag) {
warn("Failed to clear ACL on file %s", path);
}
retval = 1;
}
close(fd);
} else {
if (!fflag) {
warn("Failed to open file %s", path);
}
retval = 1;
}
}
filesec_free(fsec);
return (retval);
}

View File

@ -43,7 +43,7 @@
.Nd change group
.Sh SYNOPSIS
.Nm chgrp
.Op Fl fhv
.Op Fl fhnv
.Oo
.Fl R
.Op Fl H | Fl L | Fl P
@ -86,6 +86,8 @@ 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 n
Interpret the group ID as numeric, avoiding the name lookup.
.It Fl v
Cause
.Nm chgrp

View File

@ -40,7 +40,7 @@
.Nd change file owner and group
.Sh SYNOPSIS
.Nm chown
.Op Fl fhv
.Op Fl fhnv
.Oo
.Fl R
.Op Fl H | Fl L | Fl P
@ -48,7 +48,7 @@
.Ar owner Ns Op : Ns Ar group
.Ar
.Nm chown
.Op Fl fhv
.Op Fl fhnv
.Oo
.Fl R
.Op Fl H | Fl L | Fl P
@ -91,6 +91,8 @@ 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.
.It Fl n
Interpret user ID and group ID as numeric, avoiding name lookups.
.It Fl v
Cause
.Nm chown

View File

@ -76,6 +76,9 @@ void usage(void);
uid_t uid;
gid_t gid;
int ischown;
#ifdef __APPLE__
int isnumeric = 0;
#endif
const char *gname;
int
@ -96,7 +99,11 @@ main(int argc, char **argv)
ischown = (strcmp(cp, "chown") == 0);
Hflag = Lflag = Pflag = Rflag = fflag = hflag = vflag = 0;
#ifdef __APPLE__
while ((ch = getopt(argc, argv, "HLPRfhnv")) != -1)
#else
while ((ch = getopt(argc, argv, "HLPRfhv")) != -1)
#endif
switch (ch) {
case 'H':
Hflag = 1;
@ -119,6 +126,11 @@ main(int argc, char **argv)
case 'h':
hflag = 1;
break;
#ifdef __APPLE__
case 'n':
isnumeric = 1;
break;
#endif
case 'v':
vflag = 1;
break;
@ -246,7 +258,11 @@ a_gid(const char *s)
if (*s == '\0') /* Argument was "uid[:.]". */
return;
gname = s;
#ifdef __APPLE__
gid = (!isnumeric && ((gr = getgrnam(s)) != NULL)) ? gr->gr_gid : id(s, "group");
#else
gid = ((gr = getgrnam(s)) != NULL) ? gr->gr_gid : id(s, "group");
#endif
}
void
@ -256,7 +272,11 @@ a_uid(const char *s)
if (*s == '\0') /* Argument was "[:.]gid". */
return;
#ifdef __APPLE__
uid = (!isnumeric && ((pw = getpwnam(s)) != NULL)) ? pw->pw_uid : id(s, "user");
#else
uid = ((pw = getpwnam(s)) != NULL) ? pw->pw_uid : id(s, "user");
#endif
}
static uid_t
@ -305,11 +325,21 @@ usage(void)
if (ischown)
(void)fprintf(stderr, "%s\n%s\n",
#ifdef __APPLE__
"usage: chown [-fhnv] [-R [-H | -L | -P]] owner[:group]"
" file ...",
" chown [-fhnv] [-R [-H | -L | -P]] :group file ...");
#else
"usage: chown [-fhv] [-R [-H | -L | -P]] owner[:group]"
" file ...",
" chown [-fhv] [-R [-H | -L | -P]] :group file ...");
#endif
else
(void)fprintf(stderr, "%s\n",
#ifdef __APPLE__
"usage: chgrp [-fhnv] [-R [-H | -L | -P]] group file ...");
#else
"usage: chgrp [-fhv] [-R [-H | -L | -P]] group file ...");
#endif
exit(1);
}

View File

@ -47,13 +47,13 @@
.Nm
.Fl c
.Op Fl b Ar bits
.Op Ar file
.Op Ar
.Nm uncompress
.Op Fl fv
.Op Ar
.Nm uncompress
.Fl c
.Op Ar file
.Op Ar
.Sh DESCRIPTION
The
.Nm

View File

@ -54,6 +54,7 @@ __FBSDID("$FreeBSD: src/usr.bin/compress/compress.c,v 1.23 2010/12/11 08:32:16 j
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <locale.h>
#include "zopen.h"
@ -132,8 +133,9 @@ main(int argc, char *argv[])
exit (eval);
}
if (cat == 1 && argc > 1)
errx(1, "the -c option permits only a single file argument");
/*
* The UNIX standard requires that `uncompress -c` be able to have multiple file parameters given.
*/
for (; *argv; ++argv)
switch(style) {
@ -411,14 +413,23 @@ int
permission(const char *fname)
{
int ch, first;
char resp[] = {'\0', '\0'};
if (!isatty(fileno(stderr)))
return (0);
(void)fprintf(stderr, "overwrite %s? ", fname);
/* Load user specified locale */
setlocale(LC_MESSAGES, "");
first = ch = getchar();
while (ch != '\n' && ch != EOF)
ch = getchar();
return (first == 'y');
/* only care about first character */
resp[0] = first;
return (rpmatch(resp) == 1);
}
void
@ -429,7 +440,7 @@ usage(int iscompress)
"usage: compress [-cfv] [-b bits] [file ...]\n");
else
(void)fprintf(stderr,
"usage: uncompress [-cfv] [-b bits] [file ...]\n");
"usage: uncompress [-cfv] [file ...]\n");
exit(1);
}

View File

@ -192,6 +192,8 @@ Cause
to be verbose, showing files as they are copied.
.It Fl X
Do not copy Extended Attributes (EAs) or resource forks.
.It Fl c
copy files using clonefile(2)
.El
.Pp
For each destination file that already exists, its contents are

10
cp/cp.c
View File

@ -95,6 +95,7 @@ int fflag, iflag, nflag, pflag, vflag;
int Xflag;
#endif /* __APPLE__ */
static int Rflag, rflag;
int cflag = 0;
volatile sig_atomic_t info;
enum op { FILE_TO_FILE, FILE_TO_DIR, DIR_TO_DNE };
@ -111,8 +112,11 @@ main(int argc, char *argv[])
char *target;
Hflag = Lflag = Pflag = 0;
while ((ch = getopt(argc, argv, "HLPRXafinprv")) != -1)
while ((ch = getopt(argc, argv, "cHLPRXafinprv")) != -1)
switch (ch) {
case 'c':
cflag = 1;
break;
case 'H':
Hflag = 1;
Lflag = Pflag = 0;
@ -174,6 +178,10 @@ main(int argc, char *argv[])
if (argc < 2)
usage();
if (cflag && Xflag) {
errx(1, "the -c and -X options may not be specified together");
}
fts_options = FTS_NOCHDIR | FTS_PHYSICAL;
if (rflag) {
if (Rflag)

View File

@ -41,6 +41,7 @@ extern int fflag, iflag, nflag, pflag, vflag;
#ifdef __APPLE__
extern int Xflag;
#endif /* __APPLE__ */
extern int cflag;
extern volatile sig_atomic_t info;
__BEGIN_DECLS

View File

@ -52,6 +52,7 @@ __FBSDID("$FreeBSD: src/bin/cp/utils.c,v 1.46 2005/09/05 04:36:08 csjp Exp $");
#include <stdlib.h>
#include <sysexits.h>
#include <unistd.h>
#include <locale.h>
#ifdef __APPLE__
#include <sys/time.h>
@ -59,6 +60,8 @@ __FBSDID("$FreeBSD: src/bin/cp/utils.c,v 1.46 2005/09/05 04:36:08 csjp Exp $");
#include <string.h>
#include <sys/mount.h>
#include <get_compat.h>
#include <sys/attr.h>
#include <sys/clonefile.h>
#else
#define COMPAT_MODE(a,b) (1)
#endif /* __APPLE__ */
@ -77,6 +80,7 @@ copy_file(const FTSENT *entp, int dne)
size_t wresid;
off_t wtotal;
char *bufp;
char resp[] = {'\0', '\0'};
#ifdef VM_AND_BUFFER_CACHE_SYNCHRONIZED
char *p;
#endif
@ -108,16 +112,33 @@ copy_file(const FTSENT *entp, int dne)
} else if (iflag) {
(void)fprintf(stderr, "overwrite %s? %s",
to.p_path, YESNO);
/* Load user specified locale */
setlocale(LC_MESSAGES, "");
checkch = ch = getchar();
while (ch != '\n' && ch != EOF)
ch = getchar();
if (checkch != 'y' && checkch != 'Y') {
/* only care about the first character */
resp[0] = checkch;
if (rpmatch(resp) != 1) {
(void)close(from_fd);
(void)fprintf(stderr, "not overwritten\n");
return (1);
}
}
if (cflag) {
(void)unlink(to.p_path);
int error = clonefile(entp->fts_path, to.p_path, 0);
if (error)
warn("%s: clonefile failed", to.p_path);
(void)close(from_fd);
return error == 0 ? 0 : 1;
}
if (COMPAT_MODE("bin/cp", "unix2003")) {
/* first try to overwrite existing destination file name */
to_fd = open(to.p_path, O_WRONLY | O_TRUNC, 0);
@ -140,9 +161,19 @@ copy_file(const FTSENT *entp, int dne)
/* overwrite existing destination file name */
to_fd = open(to.p_path, O_WRONLY | O_TRUNC, 0);
}
} else
} else {
if (cflag) {
int error = clonefile(entp->fts_path, to.p_path, 0);
if (error)
warn("%s: clonefile failed", to.p_path);
(void)close(from_fd);
return error == 0 ? 0 : 1;
}
to_fd = open(to.p_path, O_WRONLY | O_TRUNC | O_CREAT,
fs->st_mode & ~(S_ISUID | S_ISGID));
}
if (to_fd == -1) {
warn("%s", to.p_path);
@ -497,13 +528,13 @@ usage(void)
if (COMPAT_MODE("bin/cp", "unix2003")) {
(void)fprintf(stderr, "%s\n%s\n",
"usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file target_file",
" cp [-R [-H | -L | -P]] [-fi | -n] [-apvX] source_file ... "
"usage: cp [-R [-H | -L | -P]] [-fi | -n] [-apvXc] source_file target_file",
" cp [-R [-H | -L | -P]] [-fi | -n] [-apvXc] source_file ... "
"target_directory");
} else {
(void)fprintf(stderr, "%s\n%s\n",
"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 ... "
"usage: cp [-R [-H | -L | -P]] [-f | -i | -n] [-apvXc] source_file target_file",
" cp [-R [-H | -L | -P]] [-f | -i | -n] [-apvXc] source_file ... "
"target_directory");
}
exit(EX_USAGE);

View File

@ -3,7 +3,7 @@ set -e
set -x
case "$PLATFORM_NAME" in
iphoneos|appletvos|watchos)
iphoneos|appletvos|watchos|bridgeos)
ln -hfs /usr/local/bin/dd "$DSTROOT"/bin/dd
;;
macosx)

33
du/du.c
View File

@ -70,6 +70,7 @@ __FBSDID("$FreeBSD: src/usr.bin/du/du.c,v 1.38 2005/04/09 14:31:40 stefanf Exp $
#ifdef __APPLE__
#include <get_compat.h>
#include <sys/sysctl.h>
#else
#define COMPAT_MODE(func, mode) (1)
#endif
@ -92,8 +93,6 @@ __FBSDID("$FreeBSD: src/usr.bin/du/du.c,v 1.38 2005/04/09 14:31:40 stefanf Exp $
#define TERA_SI_SZ (TERA_SZ(1000ULL))
#define PETA_SI_SZ (PETA_SZ(1000ULL))
#define TWO_TB (2LL * 1024LL * 1024LL * 1024LL * 1024LL)
unsigned long long vals_si [] = {1, KILO_SI_SZ, MEGA_SI_SZ, GIGA_SI_SZ, TERA_SI_SZ, PETA_SI_SZ};
unsigned long long vals_base2[] = {1, KILO_2_SZ, MEGA_2_SZ, GIGA_2_SZ, TERA_2_SZ, PETA_2_SZ};
unsigned long long *valp;
@ -255,6 +254,13 @@ main(int argc, char *argv[])
(void) getbsize(&notused, &blocksize);
blocksize /= 512;
#ifdef __APPLE__
// "du" should not have any side effect on disk usage,
// so prevent materializing dataless directories upon traversal
rval = 1;
(void) sysctlbyname("vfs.nspace.prevent_materialization", NULL, NULL, &rval, sizeof(rval));
#endif /* __APPLE__ */
rval = 0;
if ((fts = fts_open(argv, ftsoptions, NULL)) == NULL)
@ -272,11 +278,7 @@ main(int argc, char *argv[])
ftsparnum = (off_t *)&p->fts_parent->fts_number;
ftsnum = (off_t *)&p->fts_number;
if (p->fts_statp->st_size < TWO_TB) {
ftsparnum[0] += ftsnum[0] += p->fts_statp->st_blocks;
} else {
ftsparnum[0] += ftsnum[0] += howmany(p->fts_statp->st_size, 512LL);
}
ftsparnum[0] += ftsnum[0] += p->fts_statp->st_blocks;
if (p->fts_level <= depth) {
if (hflag) {
@ -317,33 +319,18 @@ main(int argc, char *argv[])
if (listall || p->fts_level == 0) {
if (hflag) {
if (p->fts_statp->st_size < TWO_TB) {
(void) prthumanval(howmany(p->fts_statp->st_blocks,
blocksize));
} else {
(void) prthumanval(howmany(howmany(p->fts_statp->st_size, 512LL),
blocksize));
}
(void) printf("\t%s\n", p->fts_path);
} else {
if (p->fts_statp->st_size < TWO_TB) {
(void) printf("%jd\t%s\n",
(intmax_t)howmany(p->fts_statp->st_blocks, blocksize),
p->fts_path);
} else {
(void) printf("%jd\t%s\n",
(intmax_t)howmany(howmany(p->fts_statp->st_size, 512LL), blocksize),
p->fts_path);
}
}
}
ftsparnum = (off_t *)&p->fts_parent->fts_number;
if (p->fts_statp->st_size < TWO_TB) {
ftsparnum[0] += p->fts_statp->st_blocks;
} else {
ftsparnum[0] += p->fts_statp->st_size / 512LL;
}
ftsparnum[0] += p->fts_statp->st_blocks;
}
savednumber = ((off_t *)&p->fts_parent->fts_number)[0];
}

View File

@ -7,6 +7,18 @@
objects = {
/* Begin PBXAggregateTarget section */
3E966CE71FB2211F0019F7A1 /* tests */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 3E966CE91FB2211F0019F7A1 /* Build configuration list for PBXAggregateTarget "tests" */;
buildPhases = (
3E966CED1FB2215C0019F7A1 /* CopyFiles */,
3E966CEF1FB221740019F7A1 /* CopyFiles */,
);
dependencies = (
);
name = tests;
productName = tests;
};
FC8A8C3C14B64A9D001B97AD /* shar */ = {
isa = PBXAggregateTarget;
buildConfigurationList = FC8A8C3D14B64A9D001B97AD /* Build configuration list for PBXAggregateTarget "shar" */;
@ -185,6 +197,9 @@
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
3E59B9311D4A767600D3128C /* futimens.c in Sources */ = {isa = PBXBuildFile; fileRef = 3E59B9301D4A767600D3128C /* futimens.c */; };
3E966CEE1FB2216F0019F7A1 /* file_cmds.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3E966CEC1FB2214F0019F7A1 /* file_cmds.plist */; };
3E966CF01FB2218A0019F7A1 /* chgrp.sh in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3E966CEB1FB2214F0019F7A1 /* chgrp.sh */; };
FC8A8A2814B6486E001B97AD /* chflags.c in Sources */ = {isa = PBXBuildFile; fileRef = FCB1BDCC14B6460C0070FACB /* chflags.c */; };
FC8A8BE414B6494B001B97AD /* chflags.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = FCB1BDCB14B6460C0070FACB /* chflags.1 */; };
FC8A8BE514B64958001B97AD /* chmod.c in Sources */ = {isa = PBXBuildFile; fileRef = FCB1BDD014B6460C0070FACB /* chmod.c */; };
@ -199,7 +214,6 @@
FC8A8BEF14B6497A001B97AD /* sum1.c in Sources */ = {isa = PBXBuildFile; fileRef = FCB1BDE114B6460C0070FACB /* sum1.c */; };
FC8A8BF014B6497D001B97AD /* sum2.c in Sources */ = {isa = PBXBuildFile; fileRef = FCB1BDE214B6460C0070FACB /* sum2.c */; };
FC8A8BF114B64982001B97AD /* compress.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = FCB1BDE414B6460C0070FACB /* compress.1 */; };
FC8A8BF214B64984001B97AD /* uncompress.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = FCB1BDEB14B6460C0070FACB /* uncompress.1 */; };
FC8A8BF314B64988001B97AD /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = FCB1BDE514B6460C0070FACB /* compress.c */; };
FC8A8BF414B6498A001B97AD /* zopen.c in Sources */ = {isa = PBXBuildFile; fileRef = FCB1BDEE14B6460C0070FACB /* zopen.c */; };
FC8A8BF514B64995001B97AD /* cp.c in Sources */ = {isa = PBXBuildFile; fileRef = FCB1BDF214B6460C0070FACB /* cp.c */; };
@ -797,6 +811,26 @@
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
3E966CED1FB2215C0019F7A1 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /AppleInternal/CoreOS/BATS/unit_tests;
dstSubfolderSpec = 0;
files = (
3E966CEE1FB2216F0019F7A1 /* file_cmds.plist in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
3E966CEF1FB221740019F7A1 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /AppleInternal/Tests/file_cmds;
dstSubfolderSpec = 0;
files = (
3E966CF01FB2218A0019F7A1 /* chgrp.sh in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
FC8A8B0F14B648D7001B97AD /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -833,7 +867,6 @@
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
FC8A8BF214B64984001B97AD /* uncompress.1 in CopyFiles */,
FC8A8BF114B64982001B97AD /* compress.1 in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
@ -1144,6 +1177,9 @@
/* Begin PBXFileReference section */
0773099A1A3A4DFE00E9B4EA /* dd.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = dd.entitlements; sourceTree = "<group>"; };
3E59B9301D4A767600D3128C /* futimens.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = futimens.c; sourceTree = "<group>"; };
3E966CEB1FB2214F0019F7A1 /* chgrp.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = chgrp.sh; sourceTree = "<group>"; };
3E966CEC1FB2214F0019F7A1 /* file_cmds.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = file_cmds.plist; sourceTree = "<group>"; };
FC8A8B1214B648D7001B97AD /* chmod */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = chmod; sourceTree = BUILT_PRODUCTS_DIR; };
FC8A8B1A14B648E0001B97AD /* chown */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = chown; sourceTree = BUILT_PRODUCTS_DIR; };
FC8A8B2214B648E3001B97AD /* cksum */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = cksum; sourceTree = BUILT_PRODUCTS_DIR; };
@ -1233,7 +1269,7 @@
FCB1BE1D14B6460C0070FACB /* symlink.7 */ = {isa = PBXFileReference; lastKnownFileType = text; path = symlink.7; sourceTree = "<group>"; };
FCB1BE1F14B6460C0070FACB /* cmp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = cmp.c; sourceTree = "<group>"; };
FCB1BE2014B6460C0070FACB /* extern.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = extern.h; sourceTree = "<group>"; };
FCB1BE2114B6460C0070FACB /* ls.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = ls.1; sourceTree = "<group>"; };
FCB1BE2114B6460C0070FACB /* ls.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; lineEnding = 0; path = ls.1; sourceTree = "<group>"; };
FCB1BE2214B6460C0070FACB /* ls.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ls.c; sourceTree = "<group>"; };
FCB1BE2314B6460C0070FACB /* ls.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ls.h; sourceTree = "<group>"; };
FCB1BE2514B6460C0070FACB /* print.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = print.c; sourceTree = "<group>"; };
@ -1526,9 +1562,19 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
3E966CEA1FB221330019F7A1 /* tests */ = {
isa = PBXGroup;
children = (
3E966CEB1FB2214F0019F7A1 /* chgrp.sh */,
3E966CEC1FB2214F0019F7A1 /* file_cmds.plist */,
);
path = tests;
sourceTree = "<group>";
};
FCB1BDAD14B645D00070FACB = {
isa = PBXGroup;
children = (
3E966CEA1FB221330019F7A1 /* tests */,
FCB1BDCA14B6460C0070FACB /* chflags */,
FCB1BDCE14B6460C0070FACB /* chmod */,
FCB1BDD414B6460C0070FACB /* chown */,
@ -1955,6 +2001,7 @@
FDAD947F1808BB3A00B4D5A0 /* gzip */ = {
isa = PBXGroup;
children = (
3E59B9301D4A767600D3128C /* futimens.c */,
FDAD94801808BB3A00B4D5A0 /* gzexe */,
FDAD94811808BB3A00B4D5A0 /* gzexe.1 */,
FDAD94821808BB3A00B4D5A0 /* gzip.1 */,
@ -2445,12 +2492,19 @@
attributes = {
LastUpgradeCheck = 0610;
ORGANIZATIONNAME = "Apple Inc.";
TargetAttributes = {
3E966CE71FB2211F0019F7A1 = {
CreatedOnToolsVersion = 9.2;
ProvisioningStyle = Automatic;
};
};
};
buildConfigurationList = FCB1BDB214B645D00070FACB /* Build configuration list for PBXProject "file_cmds" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
);
mainGroup = FCB1BDAD14B645D00070FACB;
@ -2493,6 +2547,7 @@
FC8A8BCC14B648F0001B97AD /* touch */,
FC8A8CC814B65F92001B97AD /* uncompress */,
FC8A8C5014B650CF001B97AD /* unlink */,
3E966CE71FB2211F0019F7A1 /* tests */,
);
};
/* End PBXProject section */
@ -2899,6 +2954,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3E59B9311D4A767600D3128C /* futimens.c in Sources */,
FDAD949F1808BBB900B4D5A0 /* gzip.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -3264,6 +3320,14 @@
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
3E966CE81FB2211F0019F7A1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
FC8A8B1114B648D7001B97AD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -3559,6 +3623,14 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
3E966CE91FB2211F0019F7A1 /* Build configuration list for PBXAggregateTarget "tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3E966CE81FB2211F0019F7A1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
FC8A8B1014B648D7001B97AD /* Build configuration list for PBXNativeTarget "chmod" */ = {
isa = XCConfigurationList;
buildConfigurations = (

100
gzip/futimens.c Normal file
View File

@ -0,0 +1,100 @@
/*-
* Copyright (c) 2015 Jilles Tjoelker
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#include <sys/time.h>
#ifndef UTIME_NOW
#define UTIME_NOW -1
#endif
#ifndef UTIME_OMIT
#define UTIME_OMIT -2
#endif
int futimens(int fd, const struct timespec times[2]);
int
futimens(int fd, const struct timespec times[2])
{
struct timeval now, tv[2], *tvp;
struct stat sb;
if (times == NULL || (times[0].tv_nsec == UTIME_NOW &&
times[1].tv_nsec == UTIME_NOW))
tvp = NULL;
else if (times[0].tv_nsec == UTIME_OMIT &&
times[1].tv_nsec == UTIME_OMIT)
return (0);
else {
if ((times[0].tv_nsec < 0 || times[0].tv_nsec > 999999999) &&
times[0].tv_nsec != UTIME_NOW &&
times[0].tv_nsec != UTIME_OMIT) {
errno = EINVAL;
return (-1);
}
if ((times[1].tv_nsec < 0 || times[1].tv_nsec > 999999999) &&
times[1].tv_nsec != UTIME_NOW &&
times[1].tv_nsec != UTIME_OMIT) {
errno = EINVAL;
return (-1);
}
tv[0].tv_sec = times[0].tv_sec;
tv[0].tv_usec = times[0].tv_nsec / 1000;
tv[1].tv_sec = times[1].tv_sec;
tv[1].tv_usec = times[1].tv_nsec / 1000;
tvp = tv;
if (times[0].tv_nsec == UTIME_OMIT ||
times[1].tv_nsec == UTIME_OMIT) {
if (fstat(fd, &sb) == -1)
return (-1);
if (times[0].tv_nsec == UTIME_OMIT) {
tv[0].tv_sec = sb.st_atimespec.tv_sec;
tv[0].tv_usec = sb.st_atimespec.tv_nsec / 1000;
}
if (times[1].tv_nsec == UTIME_OMIT) {
tv[1].tv_sec = sb.st_mtimespec.tv_sec;
tv[1].tv_usec = sb.st_mtimespec.tv_nsec / 1000;
}
}
if (times[0].tv_nsec == UTIME_NOW ||
times[1].tv_nsec == UTIME_NOW) {
if (gettimeofday(&now, NULL) == -1)
return (-1);
if (times[0].tv_nsec == UTIME_NOW)
tv[0] = now;
if (times[1].tv_nsec == UTIME_NOW)
tv[1] = now;
}
}
return (futimes(fd, tvp));
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: gzip.1,v 1.21 2011/06/19 02:22:36 christos Exp $
.\" $NetBSD: gzip.1,v 1.26 2015/10/27 07:36:18 mrg Exp $
.\"
.\" Copyright (c) 1997, 2003, 2004 Matthew R. Green
.\" All rights reserved.
@ -24,8 +24,8 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD: src/usr.bin/gzip/gzip.1,v 1.11 2011/10/10 06:37:32 delphij Exp $
.Dd October 9, 2011
.\" $FreeBSD: head/usr.bin/gzip/gzip.1 290073 2015-10-27 21:26:05Z delphij $
.Dd October 26, 2015
.Dt GZIP 1
.Os
.Sh NAME
@ -101,17 +101,14 @@ then both the
and
.Fl d
options are enabled.
When invoked as
.Nm zcat ,
.Dq .Z
will be appended to all filenames that do not have that suffix.
.Pp
This version of
.Nm
is also capable of decompressing files compressed using
.Xr compress 1
.Xr compress 1 ,
.Xr bzip2 1 ,
or
.Xr bzip2 1 .
.Xr xz 1 .
.Sh OPTIONS
The following options are available:
.Bl -tag -width XXrXXXrecursiveX
@ -139,7 +136,7 @@ option, allowing non-compressed data to pass through unchanged.
.It Fl h , -help
This option prints a usage summary and exits.
.It Fl k , -keep
Keep (don't delete) input files during compression
Keep (do not delete) input files during compression
or decompression.
.It Fl L , -license
This option prints
@ -186,13 +183,18 @@ is set, it is parsed as a white-space separated list of options
handled before any options on the command line.
Options on the command line will override anything in
.Ev GZIP .
.Sh EXIT STATUS
The
.Nm
utility exits 0 on success,
1 on errors,
and 2 if a warning occurs.
.Sh SEE ALSO
.Xr bzip2 1 ,
.Xr compress 1 ,
.Xr xz 1 ,
.Xr fts 3 ,
.Xr zlib 3 ,
.Xr compat 5
.Xr zlib 3
.Sh HISTORY
The
.Nm
@ -219,12 +221,12 @@ and first appeared in
This implementation of
.Nm
was written by
.An Matthew R. Green Aq mrg@eterna.com.au
.An Matthew R. Green Aq Mt mrg@eterna.com.au
with unpack support written by
.An Xin LI Aq delphij@FreeBSD.org .
.An Xin LI Aq Mt delphij@FreeBSD.org .
.Sh BUGS
According to RFC 1952, the recorded file size is stored in a 32-bit
integer, therefore, it can not represent files larger than 4GB.
integer, therefore, it cannot represent files larger than 4GB.
This limitation also applies to
.Fl l
option of

View File

@ -1,4 +1,4 @@
/* $NetBSD: gzip.c,v 1.105 2011/08/30 23:06:00 joerg Exp $ */
/* $NetBSD: gzip.c,v 1.109 2015/10/27 07:36:18 mrg Exp $ */
/*-
* Copyright (c) 1997, 1998, 2003, 2004, 2006 Matthew R. Green
@ -31,7 +31,7 @@
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1997, 1998, 2003, 2004, 2006\
Matthew R. Green. All rights reserved.");
__FBSDID("$FreeBSD: src/usr.bin/gzip/gzip.c,v 1.25 2011/10/10 06:37:32 delphij Exp $");
__FBSDID("$FreeBSD: head/usr.bin/gzip/gzip.c 290073 2015-10-27 21:26:05Z delphij $");
#endif /* not lint */
/*
@ -69,6 +69,7 @@ __FBSDID("$FreeBSD: src/usr.bin/gzip/gzip.c,v 1.25 2011/10/10 06:37:32 delphij E
#include <sys/attr.h>
#include <copyfile.h>
#include <get_compat.h>
int futimens(int fd, const struct timespec times[2]);
#endif /* __APPLE__ */
/* what type of file are we dealing with */
@ -167,7 +168,7 @@ static suffixes_t suffixes[] = {
#ifdef __APPLE__
static const char gzip_version[] = "Apple gzip " GZIP_APPLE_VERSION;
#else
static const char gzip_version[] = "FreeBSD gzip 20111009";
static const char gzip_version[] = "FreeBSD gzip 20150413";
#endif
#ifndef SMALL
@ -831,6 +832,7 @@ gz_uncompress(int in, int out, char *pre, size_t prelen, off_t *gsizep,
if (in_tot > 0) {
maybe_warnx("%s: trailing garbage "
"ignored", filename);
exit_value = 2;
goto stop;
}
maybe_warnx("input not gziped (MAGIC0)");
@ -1091,7 +1093,7 @@ out2:
static void
copymodes(int fd, const struct stat *sbp, const char *file)
{
struct timeval times[2];
struct timespec times[2];
struct stat sb;
/*
@ -1120,14 +1122,14 @@ copymodes(int fd, const struct stat *sbp, const char *file)
maybe_warn("couldn't fchmod: %s", file);
#ifdef __APPLE__
TIMESPEC_TO_TIMEVAL(&times[0], &sb.st_atimespec);
TIMESPEC_TO_TIMEVAL(&times[1], &sb.st_mtimespec);
times[0] = sb.st_atimespec;
times[1] = sb.st_mtimespec;
#else
TIMESPEC_TO_TIMEVAL(&times[0], &sb.st_atim);
TIMESPEC_TO_TIMEVAL(&times[1], &sb.st_mtim);
times[0] = sb.st_atim;
times[1] = sb.st_mtim;
#endif
if (futimes(fd, times) < 0)
maybe_warn("couldn't utimes: %s", file);
if (futimens(fd, times) < 0)
maybe_warn("couldn't futimens: %s", file);
/* only try flags if they exist already */
if (sb.st_flags != 0 && fchflags(fd, sb.st_flags) < 0)
@ -1412,7 +1414,7 @@ file_uncompress(char *file, char *outfile, size_t outsize)
#ifndef SMALL
ssize_t rv;
time_t timestamp = 0;
unsigned char name[PATH_MAX + 1];
char name[PATH_MAX + 1];
#endif
/* gather the old name info */
@ -1467,21 +1469,33 @@ file_uncompress(char *file, char *outfile, size_t outsize)
timestamp = ts[3] << 24 | ts[2] << 16 | ts[1] << 8 | ts[0];
if (header1[3] & ORIG_NAME) {
rbytes = pread(fd, name, sizeof name, GZIP_ORIGNAME);
rbytes = pread(fd, name, sizeof(name) - 1, GZIP_ORIGNAME);
if (rbytes < 0) {
maybe_warn("can't read %s", file);
goto lose;
}
if (name[0] != 0) {
if (name[0] != '\0') {
char *dp, *nf;
/* Make sure that name is NUL-terminated */
name[rbytes] = '\0';
/* strip saved directory name */
nf = strrchr(name, '/');
if (nf == NULL)
nf = name;
else
nf++;
/* preserve original directory name */
char *dp = strrchr(file, '/');
dp = strrchr(file, '/');
if (dp == NULL)
dp = file;
else
dp++;
snprintf(outfile, outsize, "%.*s%.*s",
(int) (dp - file),
file, (int) rbytes, name);
file, (int) rbytes, nf);
}
}
}
@ -1827,7 +1841,7 @@ handle_stdout(void)
return;
}
#endif
/* If stdin is a file use it's mtime, otherwise use current time */
/* If stdin is a file use its mtime, otherwise use current time */
ret = fstat(STDIN_FILENO, &sb);
#ifndef SMALL
@ -2188,9 +2202,9 @@ display_license(void)
{
#ifdef __APPLE__
fprintf(stderr, "%s (based on FreeBSD gzip 20111009)\n", gzip_version);
fprintf(stderr, "%s (based on FreeBSD gzip 20150113)\n", gzip_version);
#else
fprintf(stderr, "%s (based on NetBSD gzip 20111009)\n", gzip_version);
fprintf(stderr, "%s (based on NetBSD gzip 20150113)\n", gzip_version);
#endif
fprintf(stderr, "%s\n", gzip_copyright);
exit(0);

View File

@ -1,7 +1,8 @@
#!/bin/sh -
#
# $NetBSD: zmore,v 1.3 2004/03/29 09:59:42 wiz Exp $
# $OpenBSD: zmore,v 1.4 2003/07/29 07:42:45 otto Exp $
# $NetBSD: zmore,v 1.5 2013/12/06 13:33:15 pettai Exp $
#
# $OpenBSD: zmore,v 1.6 2008/08/20 09:22:02 mpf Exp $
#
#-
# Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
@ -22,13 +23,7 @@
# Agency (DARPA) and Air Force Research Laboratory, Air Force
# Materiel Command, USAF, under agreement number F39502-99-1-0512.
#
# $FreeBSD: src/usr.bin/gzip/zmore,v 1.1 2007/01/26 10:19:07 delphij Exp $
if [ "$0" = "zless" ]; then
zpager="less"
else
zpager="more"
fi
# $FreeBSD: head/usr.bin/gzip/zmore 273507 2014-10-23 01:22:29Z delphij $
# Pull out any command line flags so we can pass them to more/less
flags=
@ -48,15 +43,21 @@ while test $# -ne 0; do
esac
done
if [ `basename $0` = "zless" ] ; then
pager=${PAGER-less}
else
pager=${PAGER-more}
fi
# No files means read from stdin
if [ $# -eq 0 ]; then
gzip -cdfq 2>&1 | ${PAGER-${zpager}} $flags
gzip -cdfq 2>&1 | $pager $flags
exit 0
fi
oterm=`stty -g 2>/dev/null`
while test $# -ne 0; do
gzip -cdfq "$1" 2>&1 | ${PAGER-${zpager}} $flags
gzip -cdfq "$1" 2>&1 | $pager $flags
prev="$1"
shift
if tty -s && test -n "$oterm" -a $# -gt 0; then

View File

@ -1,5 +1,5 @@
.\" $NetBSD: zmore.1,v 1.3 2003/12/28 12:47:52 wiz Exp $
.\" $OpenBSD: zmore.1,v 1.3 2003/06/23 21:00:48 deraadt Exp $
.\" $NetBSD: zmore.1,v 1.4 2013/11/12 21:58:37 pettai Exp $
.\" $OpenBSD: zmore.1,v 1.10 2009/08/16 09:41:08 sobrado Exp $
.\"
.\" Copyright (c) 2003 Todd C. Miller <Todd.Miller@courtesan.com>
.\"
@ -19,17 +19,21 @@
.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
.\"
.\" $FreeBSD: src/usr.bin/gzip/zmore.1,v 1.3 2012/06/05 03:14:39 eadler Exp $
.Dd February 6, 2011
.\" $FreeBSD: head/usr.bin/gzip/zmore.1 273507 2014-10-23 01:22:29Z delphij $
.Dd October 22, 2014
.Dt ZMORE 1
.Os
.Sh NAME
.Nm zmore
.Nm zmore ,
.Nm zless
.Nd view compressed files
.Sh SYNOPSIS
.Nm zmore
.Op Ar flags
.Op Ar file ...
.Op Ar
.Nm zless
.Op Ar flags
.Op Ar
.Sh DESCRIPTION
.Nm
is a filter that allows the viewing of files compressed with Lempel-Ziv
@ -51,6 +55,14 @@ that are specified are passed to the user's preferred
.Pa /usr/bin/more
by default).
.Pp
.Nm zless
is equivalent to
.Nm zmore
but uses
.Xr less 1
as a pager instead of
.Xr more 1 .
.Pp
When multiple files are specified,
.Nm
will pause at the end of each file and present the following prompt to the user:
@ -86,7 +98,11 @@ style compression since there is no suffix on which to make a decision.
Program used to display files.
If unset,
.Pa /usr/bin/more
is used.
is used
.Pq Nm zmore
or
.Pa /usr/bin/less
.Pq Nm zless .
.El
.Sh SEE ALSO
.Xr compress 1 ,

View File

@ -145,7 +145,7 @@ zuncompress(FILE *in, FILE *out, char *pre, size_t prelen,
else
compressed_pre = NULL;
while ((bin = fread(buf, 1, sizeof(buf), in)) != 0) {
while ((bin = fread(buf, 1, BUFSIZE, in)) != 0) {
if (tflag == 0 && (off_t)fwrite(buf, 1, bin, out) != bin) {
free(buf);
return -1;

View File

@ -529,11 +529,7 @@ install(from_name, to_name, fset, flags)
if (!devnull)
(void)close(from_fd);
}
#if TARGET_OS_EMBEDDED
#define BUFFER_SIZE 128*1024
#else /* !TARGET_OS_EMBEDDED */
#define BUFFER_SIZE MAXBSIZE
#endif /* TARGET_OS_EMBEDDED */
/*
* compare --
* compare two files; non-zero means files differ
@ -569,8 +565,8 @@ compare(int from_fd, const char *from_name, size_t from_len,
}
out:
if (!done_compare) {
char buf1[BUFFER_SIZE];
char buf2[BUFFER_SIZE];
char buf1[MAXBSIZE];
char buf2[MAXBSIZE];
int n1, n2;
rv = 0;
@ -673,7 +669,8 @@ copy(from_fd, from_name, to_fd, to_name, size)
{
register int nr, nw;
int serrno;
char *p, buf[BUFFER_SIZE];
char *p;
char buf[MAXBSIZE];
int done_copy;
/* Rewind file descriptors. */

View File

@ -83,14 +83,12 @@ static int shmrm(key_t key, int id)
static int semrm(key_t key, int id)
{
union semun arg;
if (key) {
id = semget(key, 0, 0);
if (id == -1)
return -1;
}
return semctl(id, 0, IPC_RMID, arg);
return semctl(id, 0, IPC_RMID);
}
static void not_configured(__unused int unused)

View File

@ -92,6 +92,15 @@ main(int argc, char *argv[])
if (argc != 2)
usage();
linkf = link;
/* UNIX conformance requires that both operands be NOT a dir */
for (int i = 0; i < 2; i++) {
if (stat(argv[i], &sb) == 0 && S_ISDIR(sb.st_mode)){
errno = EISDIR;
warn("%s", argv[0]);
return 1;
}
}
exit(linkit(argv[0], argv[1], 0));
}

13
ls/ls.1
View File

@ -43,7 +43,7 @@
.Nd list directory contents
.Sh SYNOPSIS
.Nm ls
.Op Fl ABCFGHLOPRSTUW@abcdefghiklmnopqrstuwx1
.Op Fl ABCFGHLOPRSTUW@abcdefghiklmnopqrstuwx1%
.Op Ar
.Sh DESCRIPTION
For each operand that names a
@ -188,7 +188,7 @@ option.
.Dq ell . )
List in long format.
(See below.)
If the output is to a terminal, a total sum for all the file
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.
@ -278,6 +278,10 @@ The same as
.Fl C ,
except that the multi-column output is produced with entries sorted
across, rather than down, the columns.
.It Fl %
Distinguish dataless files and directories with a '%' character in long
.Pq Fl l
output, and don't materialize dataless directories when listing them.
.El
.Pp
The
@ -349,6 +353,11 @@ Otherwise, if the file or directory has extended security information
the permissions field printed by the
.Fl l
option is followed by a '+' character.
If the
.Fl %
option is given, a '%' character follows the permissions field
for dataless files and directories,
possibly replacing the '@' or '+' character.
.Pp
If the modification time of the file
is more than 6 months in the past or future,

23
ls/ls.c
View File

@ -74,6 +74,8 @@ __RCSID("$FreeBSD: src/bin/ls/ls.c,v 1.66 2002/09/21 01:28:36 wollman Exp $");
#include <sys/xattr.h>
#include <sys/param.h>
#include <get_compat.h>
#include <sys/sysctl.h>
#include <System/sys/fsctl.h>
#else
#define COMPAT_MODE(a,b) (1)
#endif /* __APPLE__ */
@ -131,6 +133,8 @@ static int f_whiteout; /* show whiteout entries */
int f_xattr; /* show extended attributes in long listing */
int f_group; /* show group */
int f_owner; /* show owner */
int f_dataless; /* distinguish dataless files in long listing,
and don't materialize dataless directories. */
#ifdef COLORLS
int f_color; /* add type in color for non-regular files */
@ -182,7 +186,7 @@ main(int argc, char *argv[])
f_listdot = 1;
fts_options = FTS_PHYSICAL;
while ((ch = getopt(argc, argv, "1@ABCFGHLOPRSTUWabcdefghiklmnopqrstuvwx"))
while ((ch = getopt(argc, argv, "1@ABCFGHLOPRSTUWabcdefghiklmnopqrstuvwx%"))
!= -1) {
switch (ch) {
/*
@ -364,6 +368,9 @@ main(int argc, char *argv[])
case 'O':
f_flags = 1;
break;
case '%':
f_dataless = 1;
break;
default:
case '?':
usage();
@ -484,6 +491,17 @@ main(int argc, char *argv[])
else
printfcn = printcol;
#ifdef __APPLE__
if (f_dataless) {
// don't materialize dataless directories from the cloud
// (particularly usefull when listing recursively)
int state = 1;
if (sysctlbyname("vfs.nspace.prevent_materialization", NULL, NULL, &state, sizeof(state)) < 0) {
err(1, "prevent_materialization");
}
}
#endif /* __APPLE__ */
if (argc)
traverse(argc, argv, fts_options);
else
@ -833,6 +851,9 @@ display(FTSENT *p, FTSENT *list)
} else {
np->mode_suffix = ' ';
}
if (f_dataless && (sp->st_flags & SF_DATALESS)) {
np->mode_suffix = '%';
}
if (!f_acl) {
acl_free(np->acl);
np->acl = NULL;

View File

@ -97,7 +97,7 @@ typedef struct {
int *xattr_sizes;
acl_t acl; /* f_acl */
int xattr_count;
char mode_suffix; /* @ | + | <space> */
char mode_suffix; /* @ | + | % | <space> */
#endif /* __APPLE__ */
char data[1];
} NAMES;

View File

@ -51,10 +51,8 @@ __RCSID("$FreeBSD: src/bin/ls/print.c,v 1.57 2002/08/29 14:29:09 keramida Exp $"
#include <grp.h>
#include <pwd.h>
#include <TargetConditionals.h>
#if !TARGET_OS_EMBEDDED
#include <membership.h>
#include <membershipPriv.h>
#endif
#include <uuid/uuid.h>
#endif
@ -203,9 +201,6 @@ static struct {
static char *
uuid_to_name(uuid_t *uu)
{
#if TARGET_OS_EMBEDDED
return strdup("<UNKNOWN>");
#else /* !TARGET_OS_EMBEDDED */
int type;
char *name = NULL;
char *recname = NULL;
@ -233,7 +228,6 @@ errout:
uuid_unparse_upper(*uu, name);
return name;
#endif /* !TARGET_OS_EMBEDDED */
}
static void

View File

@ -222,9 +222,9 @@ usage(void)
{
(void)fprintf(stderr,
#ifdef COLORLS
"usage: ls [-ABCFGHLOPRSTUWabcdefghiklmnopqrstuwx1]"
"usage: ls [-@ABCFGHLOPRSTUWabcdefghiklmnopqrstuwx1%%]"
#else
"usage: ls [-ABCFHLOPRSTUWabcdefghiklmnopqrstuwx1]"
"usage: ls [-@ABCFHLOPRSTUWabcdefghiklmnopqrstuwx1%%]"
#endif
" [file ...]\n");
exit(1);

View File

@ -2,14 +2,29 @@
#include <os/assumes.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/xattr.h>
#include <stdbool.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <sys/attr.h>
#include <unistd.h>
#include "commoncrypto.h"
const int kSHA256NullTerminatedBuffLen = 65;
static const char hex[] = "0123456789abcdef";
/* Functions for SHA256_File_XATTRs */
#define SHA256_Data(d, s, b) Digest_Data(kCCDigestSHA256, d, s, b)
char *Digest_Data(CCDigestAlg algorithm, void *data, size_t size, char *buf);
void Quicksort(char **array, int num);
/* Generic version of libmd's *_File() functions. */
char *
Digest_File(CCDigestAlg algorithm, const char *filename, char *buf)
{
static const char hex[] = "0123456789abcdef";
int fd;
__block CCDigestCtx ctx;
dispatch_queue_t queue;
@ -75,6 +90,150 @@ Digest_File(CCDigestAlg algorithm, const char *filename, char *buf)
buf[i+i+1] = hex[digest[i] & 0x0f];
}
buf[i+i] = '\0';
return buf;
}
char *SHA256_Path_XATTRs(char *path, char *buf)
{
char *xattrsSummary = NULL;
int options = XATTR_SHOWCOMPRESSION | XATTR_NOFOLLOW;
ssize_t nameBufSize = listxattr(path, NULL, 0, options);
if (nameBufSize > 0) {
char *nameBuf = malloc(nameBufSize);
listxattr(path, nameBuf, nameBufSize, options);
size_t xattrsLen = 1;
size_t xattrIndex = 0;
char **xattrs = malloc(xattrsLen * sizeof(char *));
char *nextName = nameBuf;
while (nextName < nameBuf + nameBufSize)
{
char *name = nextName;
if (xattrIndex == xattrsLen) {
xattrsLen *= 2;
xattrs = realloc(xattrs, xattrsLen * sizeof(char *));
}
xattrs[xattrIndex++] = name;
nextName += strlen(name) + 1;
}
// sort the xattr array as they're not guaranteed to come in the same order
qsort_b(xattrs, xattrIndex, sizeof(char *), ^(const void *l, const void *r) {
char *left = *(char **)l;
char *right = *(char **)r;
return strcmp(left, right);
});
// gather the data for the xattrs
bool didAddXATTR = false;
int xattrBufLen = kSHA256NullTerminatedBuffLen;
void *xattrBuf = malloc(xattrBufLen); // resized if necessary
char *digest;
ssize_t result = 0;
char *oldSummary = NULL;
for (int i = 0; i < xattrIndex; i++) {
char *name = xattrs[i];
ssize_t xlen = getxattr(path, name, NULL, 0, 0, options);
if (xlen > xattrBufLen) {
xattrBufLen = xlen;
xattrBuf = realloc(xattrBuf, xattrBufLen);
}
bzero(xattrBuf, xattrBufLen);
result = getxattr(path, name, xattrBuf, xattrBufLen, 0, options);
if (result < 0)
err(1, "SHA256_Path_XATTRs getxattr of \"%s\" at path \"%s\" failed with error", name, path );
digest = SHA256_Data(xattrBuf, xattrBufLen, buf);
if (!digest)
err(1, "%s", xattrsSummary);
if (!didAddXATTR)
{
didAddXATTR = true;
asprintf(&xattrsSummary, "%s:%s", name, digest);
} else {
oldSummary = xattrsSummary;
asprintf(&xattrsSummary, "%s, %s:%s", oldSummary, name, digest);
free(oldSummary);
}
}
free(xattrBuf);
free(nameBuf);
free(xattrs);
digest = SHA256_Data(xattrsSummary, strlen(xattrsSummary) * sizeof(char), buf);
if (!digest)
err(1, "%s", xattrsSummary);
free(xattrsSummary);
return digest;
}
return kNone;
}
char *SHA256_Path_ACL(char *path, char *buf)
{
int result = 0;
char *data = NULL;
char *digest = NULL;
struct attrlist list = {
.bitmapcount = ATTR_BIT_MAP_COUNT,
.commonattr = ATTR_CMN_RETURNED_ATTRS | ATTR_CMN_EXTENDED_SECURITY,
};
struct ACLBuf {
uint32_t len;
attribute_set_t returned_attrs;
attrreference_t acl;
char buf[8192]; // current acls are up to 3116 bytes, but they may increase in the future
} __attribute__((aligned(4), packed));
struct ACLBuf aclBuf;
result = getattrlist(path, &list, &aclBuf, sizeof(aclBuf), FSOPT_NOFOLLOW);
if (result)
err(1, "SHA256_Path_ACL: getattrlist");
// if the path does not have an acl, return none
if ( ( ! ( aclBuf.returned_attrs.commonattr & ATTR_CMN_EXTENDED_SECURITY ) )
|| ( aclBuf.acl.attr_length == 0 ) ) {
return kNone;
}
data = ((char*)&aclBuf.acl) + aclBuf.acl.attr_dataoffset;
digest = SHA256_Data(data, aclBuf.acl.attr_length, buf);
if (!digest)
err(1, "SHA256_Path_ACL: SHA256_Data");
return digest;
}
/* Functions for Digest_Path_* */
char *
Digest_Data(CCDigestAlg algorithm, void *data, size_t size, char *buf) {
uint8_t digest[32]; // SHA256 is the biggest
CCDigestCtx ctx;
size_t i, length;
(void)os_assumes_zero(CCDigestInit(algorithm, &ctx));
(void)os_assumes_zero(CCDigestUpdate(&ctx, data, size));
/* Finalize and convert to hex. */
(void)os_assumes_zero(CCDigestFinal(&ctx, digest));
length = CCDigestOutputSize(&ctx);
os_assert(length <= sizeof(digest));
for (i = 0; i < length; i++) {
buf[i+i] = hex[digest[i] >> 4];
buf[i+i+1] = hex[digest[i] & 0x0f];
}
buf[i+i] = '\0';
return buf;
}

View File

@ -1,8 +1,15 @@
#include <CommonCrypto/CommonDigestSPI.h>
#define kNone "none"
extern const int kSHA256NullTerminatedBuffLen;
#define MD5File(f, b) Digest_File(kCCDigestMD5, f, b)
#define SHA1_File(f, b) Digest_File(kCCDigestSHA1, f, b)
#define RIPEMD160_File(f, b) Digest_File(kCCDigestRMD160, f, b)
#define SHA256_File(f, b) Digest_File(kCCDigestSHA256, f, b)
char *Digest_File(CCDigestAlg algorithm, const char *filename, char *buf);
char *SHA256_Path_XATTRs(char *path, char *buf);
char *SHA256_Path_ACL(char *path, char *buf);

View File

@ -86,7 +86,8 @@ compare(char *name __unused, NODE *s, FTSENT *p)
off_t len;
char *cp;
const char *tab = "";
char *fflags;
char *fflags, *badflags;
u_long flags;
label = 0;
switch(s->type) {
@ -182,18 +183,14 @@ typeerr: LABEL;
(intmax_t)s->st_size, (intmax_t)p->fts_statp->st_size);
tab = "\t";
}
/*
* XXX
* Catches nano-second differences, but doesn't display them.
*/
if ((s->flags & F_TIME) &&
((s->st_mtimespec.tv_sec != p->fts_statp->st_mtimespec.tv_sec) ||
(s->st_mtimespec.tv_nsec != p->fts_statp->st_mtimespec.tv_nsec))) {
LABEL;
(void)printf("%smodification time expected %.24s ",
tab, ctime(&s->st_mtimespec.tv_sec));
(void)printf("found %.24s",
ctime(&p->fts_statp->st_mtimespec.tv_sec));
(void)printf("%smodification time expected %.24s.%09ld ",
tab, ctime(&s->st_mtimespec.tv_sec), s->st_mtimespec.tv_nsec);
(void)printf("found %.24s.%09ld",
ctime(&p->fts_statp->st_mtimespec.tv_sec), p->fts_statp->st_mtimespec.tv_nsec);
if (uflag) {
tv[0].tv_sec = s->st_mtimespec.tv_sec;
tv[0].tv_usec = s->st_mtimespec.tv_nsec / 1000;
@ -229,25 +226,35 @@ typeerr: LABEL;
}
}
}
if ((s->flags & F_FLAGS) && s->st_flags != p->fts_statp->st_flags) {
LABEL;
fflags = flags_to_string(s->st_flags);
(void)printf("%sflags expected \"%s\"", tab, fflags);
if (s->flags & F_FLAGS) {
// There are unpublished flags that should not fail comparison
// we convert to string and back to filter them out
fflags = badflags = flags_to_string(p->fts_statp->st_flags);
if (strcmp("none", fflags) == 0) {
flags = 0;
} else if (strtofflags(&badflags, &flags, NULL) != 0)
errx(1, "invalid flag %s", badflags);
free(fflags);
fflags = flags_to_string(p->fts_statp->st_flags);
(void)printf(" found \"%s\"", fflags);
free(fflags);
if (uflag)
if (chflags(p->fts_accpath, (u_int)s->st_flags))
(void)printf(" not modified: %s\n",
strerror(errno));
else
(void)printf(" modified\n");
else
(void)printf("\n");
tab = "\t";
if (s->st_flags != flags) {
LABEL;
fflags = flags_to_string(s->st_flags);
(void)printf("%sflags expected \"%s\"", tab, fflags);
free(fflags);
fflags = flags_to_string(flags);
(void)printf(" found \"%s\"", fflags);
free(fflags);
if (uflag)
if (chflags(p->fts_accpath, (u_int)s->st_flags))
(void)printf(" not modified: %s\n",
strerror(errno));
else
(void)printf(" modified\n");
else
(void)printf("\n");
tab = "\t";
}
}
#ifdef ENABLE_MD5
if (s->flags & F_MD5) {
@ -305,7 +312,7 @@ typeerr: LABEL;
#endif /* ENABLE_RMD160 */
#ifdef ENABLE_SHA256
if (s->flags & F_SHA256) {
char *new_digest, buf[65];
char *new_digest, buf[kSHA256NullTerminatedBuffLen];
new_digest = SHA256_File(p->fts_accpath, buf);
if (!new_digest) {
@ -328,6 +335,90 @@ typeerr: LABEL;
(void)printf("%slink_ref expected %s found %s\n",
tab, s->slink, cp);
}
if ((s->flags & F_BTIME) &&
((s->st_birthtimespec.tv_sec != p->fts_statp->st_birthtimespec.tv_sec) ||
(s->st_birthtimespec.tv_nsec != p->fts_statp->st_birthtimespec.tv_nsec))) {
LABEL;
(void)printf("%sbirth time expected %.24s.%09ld ",
tab, ctime(&s->st_birthtimespec.tv_sec), s->st_birthtimespec.tv_nsec);
(void)printf("found %.24s.%09ld\n",
ctime(&p->fts_statp->st_birthtimespec.tv_sec), p->fts_statp->st_birthtimespec.tv_nsec);
tab = "\t";
}
if ((s->flags & F_ATIME) &&
((s->st_atimespec.tv_sec != p->fts_statp->st_atimespec.tv_sec) ||
(s->st_atimespec.tv_nsec != p->fts_statp->st_atimespec.tv_nsec))) {
LABEL;
(void)printf("%saccess time expected %.24s.%09ld ",
tab, ctime(&s->st_atimespec.tv_sec), s->st_atimespec.tv_nsec);
(void)printf("found %.24s.%09ld\n",
ctime(&p->fts_statp->st_atimespec.tv_sec), p->fts_statp->st_atimespec.tv_nsec);
tab = "\t";
}
if ((s->flags & F_CTIME) &&
((s->st_ctimespec.tv_sec != p->fts_statp->st_ctimespec.tv_sec) ||
(s->st_ctimespec.tv_nsec != p->fts_statp->st_ctimespec.tv_nsec))) {
LABEL;
(void)printf("%smetadata modification time expected %.24s.%09ld ",
tab, ctime(&s->st_ctimespec.tv_sec), s->st_ctimespec.tv_nsec);
(void)printf("found %.24s.%09ld\n",
ctime(&p->fts_statp->st_ctimespec.tv_sec), p->fts_statp->st_ctimespec.tv_nsec);
tab = "\t";
}
if (s->flags & F_PTIME) {
int supported;
struct timespec ptimespec = ptime(p->fts_accpath, &supported);
if (!supported) {
LABEL;
(void)printf("%stime added to parent folder expected %.24s.%09ld found that it is not supported\n",
tab, ctime(&s->st_ptimespec.tv_sec), s->st_ptimespec.tv_nsec);
tab = "\t";
} else if ((s->st_ptimespec.tv_sec != ptimespec.tv_sec) ||
(s->st_ptimespec.tv_nsec != ptimespec.tv_nsec)) {
LABEL;
(void)printf("%stime added to parent folder expected %.24s.%09ld ",
tab, ctime(&s->st_ptimespec.tv_sec), s->st_ptimespec.tv_nsec);
(void)printf("found %.24s.%09ld\n",
ctime(&ptimespec.tv_sec), ptimespec.tv_nsec);
tab = "\t";
}
}
if (s->flags & F_XATTRS) {
char *new_digest, buf[kSHA256NullTerminatedBuffLen];
new_digest = SHA256_Path_XATTRs(p->fts_accpath, buf);
if (!new_digest) {
LABEL;
printf("%sxattrsdigest missing, expected: %s\n", tab, s->xattrsdigest);
tab = "\t";
} else if (strcmp(new_digest, s->xattrsdigest)) {
LABEL;
printf("%sxattrsdigest expected %s found %s\n",
tab, s->xattrsdigest, new_digest);
tab = "\t";
}
}
if ((s->flags & F_INODE) &&
(p->fts_statp->st_ino != s->st_ino)) {
LABEL;
(void)printf("%sinode expected %llu found %llu\n",
tab, s->st_ino, p->fts_ino);
tab = "\t";
}
if (s->flags & F_ACL) {
char *new_digest, buf[kSHA256NullTerminatedBuffLen];
new_digest = SHA256_Path_ACL(p->fts_accpath, buf);
if (!new_digest) {
LABEL;
printf("%sacldigest missing, expected: %s\n", tab, s->acldigest);
tab = "\t";
} else if (strcmp(new_digest, s->acldigest)) {
LABEL;
printf("%sacldigest expected %s found %s\n",
tab, s->acldigest, new_digest);
tab = "\t";
}
}
return (label);
}

View File

@ -77,10 +77,12 @@ static gid_t gid;
static uid_t uid;
static mode_t mode;
static u_long flags = 0xffffffff;
static char *xattrs = kNone;
static char *acl = kNone;
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 int statd(FTS *, FTSENT *, uid_t *, gid_t *, mode_t *, u_long *, char **, char **);
static void statf(int, FTSENT *);
void
@ -92,6 +94,7 @@ cwalk(void)
char *argv[2], host[MAXHOSTNAMELEN];
char dot[] = ".";
int indent = 0;
char *path;
if (!nflag) {
(void)time(&cl);
@ -119,14 +122,20 @@ cwalk(void)
case FTS_D:
if (!dflag)
(void)printf("\n");
if (!nflag)
(void)printf("# %s\n", p->fts_path);
statd(t, p, &uid, &gid, &mode, &flags);
if (!nflag) {
path = escape_path(p->fts_path);
(void)printf("# %s\n", path);
free(path);
}
statd(t, p, &uid, &gid, &mode, &flags, &xattrs, &acl);
statf(indent, p);
break;
case FTS_DP:
if (!nflag && (p->fts_level > 0))
(void)printf("%*s# %s\n", indent, "", p->fts_path);
if (!nflag && (p->fts_level > 0)) {
path = escape_path(p->fts_path);
(void)printf("%*s# %s\n", indent, "", path);
free(path);
}
(void)printf("%*s..\n", indent, "");
if (!dflag)
(void)printf("\n");
@ -218,7 +227,7 @@ statf(int indent, FTSENT *p)
output(indent, &offset, "size=%jd",
(intmax_t)p->fts_statp->st_size);
if (keys & F_TIME)
output(indent, &offset, "time=%ld.%ld",
output(indent, &offset, "time=%ld.%09ld",
(long)p->fts_statp->st_mtimespec.tv_sec,
p->fts_statp->st_mtimespec.tv_nsec);
if (keys & F_CKSUM && S_ISREG(p->fts_statp->st_mode)) {
@ -260,7 +269,7 @@ statf(int indent, FTSENT *p)
#endif /* ENABLE_RMD160 */
#ifdef ENABLE_SHA256
if (keys & F_SHA256 && S_ISREG(p->fts_statp->st_mode)) {
char *digest, buf[65];
char *digest, buf[kSHA256NullTerminatedBuffLen];
digest = SHA256_File(p->fts_accpath, buf);
if (!digest)
@ -280,6 +289,53 @@ statf(int indent, FTSENT *p)
output(indent, &offset, "flags=%s", fflags);
free(fflags);
}
if (keys & F_BTIME) {
output(indent, &offset, "btime=%ld.%09ld",
p->fts_statp->st_birthtimespec.tv_sec,
p->fts_statp->st_birthtimespec.tv_nsec);
}
// only check access time on regular files, as traversing a folder will update its access time
if (keys & F_ATIME && S_ISREG(p->fts_statp->st_mode)) {
output(indent, &offset, "atime=%ld.%09ld",
p->fts_statp->st_atimespec.tv_sec,
p->fts_statp->st_atimespec.tv_nsec);
}
if (keys & F_CTIME) {
output(indent, &offset, "ctime=%ld.%09ld",
p->fts_statp->st_ctimespec.tv_sec,
p->fts_statp->st_ctimespec.tv_nsec);
}
// date added to parent folder is only supported for files and directories
if (keys & F_PTIME && (S_ISREG(p->fts_statp->st_mode) ||
S_ISDIR(p->fts_statp->st_mode))) {
int supported;
struct timespec ptimespec = ptime(p->fts_accpath, &supported);
if (supported) {
output(indent, &offset, "ptime=%ld.%09ld",
ptimespec.tv_sec,
ptimespec.tv_nsec);
}
}
if (keys & F_XATTRS) {
char *digest, buf[kSHA256NullTerminatedBuffLen];
digest = SHA256_Path_XATTRs(p->fts_accpath, buf);
if (digest && (strcmp(digest, xattrs) != 0)) {
output(indent, &offset, "xattrsdigest=%s", digest);
}
}
if (keys & F_INODE) {
output(indent, &offset, "inode=%llu", p->fts_statp->st_ino);
}
if (keys & F_ACL) {
char *digest, buf[kSHA256NullTerminatedBuffLen];
digest = SHA256_Path_ACL(p->fts_accpath, buf);
if (digest && (strcmp(digest, acl) != 0)) {
output(indent, &offset, "acldigest=%s", digest);
}
}
(void)putchar('\n');
}
@ -290,7 +346,7 @@ statf(int indent, FTSENT *p)
#define MAXS 16
static int
statd(FTS *t, FTSENT *parent, uid_t *puid, gid_t *pgid, mode_t *pmode, u_long *pflags)
statd(FTS *t, FTSENT *parent, uid_t *puid, gid_t *pgid, mode_t *pmode, u_long *pflags, char **pxattrs, char **pacl)
{
FTSENT *p;
gid_t sgid;
@ -303,6 +359,8 @@ statd(FTS *t, FTSENT *parent, uid_t *puid, gid_t *pgid, mode_t *pmode, u_long *p
uid_t saveuid = *puid;
mode_t savemode = *pmode;
u_long saveflags = *pflags;
char *savexattrs = *pxattrs;
char *saveacl = *pacl;
u_short maxgid, maxuid, maxmode, maxflags;
u_short g[MAXGID], u[MAXUID], m[MAXMODE], f[MAXFLAGS];
char *fflags;
@ -337,6 +395,12 @@ statd(FTS *t, FTSENT *parent, uid_t *puid, gid_t *pgid, mode_t *pmode, u_long *p
saveuid = suid;
maxuid = u[suid];
}
/*
* XXX
* note that we don't count the most common xattr/acl digest
* so set will always the default value (none)
*/
/*
* XXX
@ -399,11 +463,17 @@ statd(FTS *t, FTSENT *parent, uid_t *puid, gid_t *pgid, mode_t *pmode, u_long *p
(void)printf(" flags=%s", fflags);
free(fflags);
}
if (keys & F_XATTRS)
(void)printf(" xattrsdigest=%s", savexattrs);
if (keys & F_ACL)
(void)printf(" acldigest=%s", saveacl);
(void)printf("\n");
*puid = saveuid;
*pgid = savegid;
*pmode = savemode;
*pflags = saveflags;
*pxattrs = savexattrs;
*pacl = saveacl;
}
return (0);
}

View File

@ -37,6 +37,8 @@ int compare(char *, NODE *, FTSENT *);
int crc(int, uint32_t *, off_t *);
void cwalk(void);
char *flags_to_string(u_long);
char *escape_path(char *string);
struct timespec ptime(char *path, int *supported);
const char *inotype(u_int);
u_int parsekey(char *, int *);

View File

@ -44,6 +44,8 @@ __FBSDID("$FreeBSD: src/usr.sbin/mtree/misc.c,v 1.16 2005/03/29 11:44:17 tobez E
#include <unistd.h>
#include "mtree.h"
#include "extern.h"
#import <sys/attr.h>
#include <vis.h>
typedef struct _key {
const char *name; /* key name */
@ -55,32 +57,39 @@ typedef struct _key {
/* NB: the following table must be sorted lexically. */
static KEY keylist[] = {
{"cksum", F_CKSUM, NEEDVALUE},
{"flags", F_FLAGS, NEEDVALUE},
{"gid", F_GID, NEEDVALUE},
{"gname", F_GNAME, NEEDVALUE},
{"ignore", F_IGN, 0},
{"link", F_SLINK, NEEDVALUE},
{"acldigest", F_ACL, NEEDVALUE},
{"atime", F_ATIME, NEEDVALUE},
{"btime", F_BTIME, NEEDVALUE},
{"cksum", F_CKSUM, NEEDVALUE},
{"ctime", F_CTIME, NEEDVALUE},
{"flags", F_FLAGS, NEEDVALUE},
{"gid", F_GID, NEEDVALUE},
{"gname", F_GNAME, NEEDVALUE},
{"ignore", F_IGN, 0},
{"inode", F_INODE, NEEDVALUE},
{"link", F_SLINK, NEEDVALUE},
#ifdef ENABLE_MD5
{"md5digest", F_MD5, NEEDVALUE},
{"md5digest", F_MD5, NEEDVALUE},
#endif
{"mode", F_MODE, NEEDVALUE},
{"nlink", F_NLINK, NEEDVALUE},
{"nochange", F_NOCHANGE, 0},
{"mode", F_MODE, NEEDVALUE},
{"nlink", F_NLINK, NEEDVALUE},
{"nochange", F_NOCHANGE, 0},
{"ptime", F_PTIME, NEEDVALUE},
#ifdef ENABLE_RMD160
{"ripemd160digest", F_RMD160, NEEDVALUE},
{"ripemd160digest", F_RMD160, NEEDVALUE},
#endif
#ifdef ENABLE_SHA1
{"sha1digest", F_SHA1, NEEDVALUE},
{"sha1digest", F_SHA1, NEEDVALUE},
#endif
#ifdef ENABLE_SHA256
{"sha256digest", F_SHA256, NEEDVALUE},
{"sha256digest", F_SHA256, NEEDVALUE},
#endif
{"size", F_SIZE, NEEDVALUE},
{"time", F_TIME, NEEDVALUE},
{"type", F_TYPE, NEEDVALUE},
{"uid", F_UID, NEEDVALUE},
{"uname", F_UNAME, NEEDVALUE},
{"size", F_SIZE, NEEDVALUE},
{"time", F_TIME, NEEDVALUE},
{"type", F_TYPE, NEEDVALUE},
{"uid", F_UID, NEEDVALUE},
{"uname", F_UNAME, NEEDVALUE},
{"xattrsdigest", F_XATTRS, NEEDVALUE},
};
int keycompare(const void *, const void *);
@ -122,3 +131,45 @@ flags_to_string(u_long fflags)
return string;
}
// escape path and always return a new string so it can be freed
char *
escape_path(char *string)
{
char *escapedPath = calloc(1, strlen(string) * 4 + 1);
if (escapedPath == NULL)
errx(1, "escape_path(): calloc() failed");
strvis(escapedPath, string, VIS_NL | VIS_CSTYLE | VIS_OCTAL);
return escapedPath;
}
struct ptimebuf {
uint32_t length;
attribute_set_t returned_attrs;
struct timespec st_ptimespec;
} __attribute__((aligned(4), packed));
// ptime is not supported on root filesystems or HFS filesystems older than the feature being introduced
struct timespec
ptime(char *path, int *supported) {
int ret = 0;
struct ptimebuf buf;
struct attrlist list = {
.bitmapcount = ATTR_BIT_MAP_COUNT,
.commonattr = ATTR_CMN_RETURNED_ATTRS | ATTR_CMN_ADDEDTIME,
};
ret = getattrlist(path, &list, &buf, sizeof(buf), FSOPT_NOFOLLOW);
if (ret) {
err(1, "ptime: getattrlist");
}
*supported = 0;
if (buf.returned_attrs.commonattr & ATTR_CMN_ADDEDTIME) {
*supported = 1;
}
return buf.st_ptimespec;
}

View File

@ -246,6 +246,20 @@ The size, in bytes, of the file.
The file the symbolic link is expected to reference.
.It Cm time
The last modification time of the file.
.It Cm btime
The creation (birth) time of the file.
.It Cm atime
The last access time of the file.
.It Cm ctime
The last metadata modification time of the file.
.It Cm ptime
The time the file was added to its parent folder.
.It Cm inode
The inode number of the file.
.It Cm xattrsdigest
Digest of the extended attributes of the file.
.It Cm acldigest
Digest of the access control list of the file.
.It Cm type
The type of the file; may be set to any one of the following:
.Pp

View File

@ -55,29 +55,43 @@ typedef struct _node {
mode_t st_mode; /* mode */
u_long st_flags; /* flags */
nlink_t st_nlink; /* link count */
struct timespec st_birthtimespec; /* birth time (creation time) */
struct timespec st_atimespec; /* access time */
struct timespec st_ctimespec; /* metadata modification time */
struct timespec st_ptimespec; /* time added to parent folder */
char *xattrsdigest; /* digest of extended attributes */
ino_t st_ino; /* inode */
char *acldigest; /* digest of access control list */
#define F_CKSUM 0x0001 /* check sum */
#define F_DONE 0x0002 /* directory done */
#define F_GID 0x0004 /* gid */
#define F_GNAME 0x0008 /* group name */
#define F_IGN 0x0010 /* ignore */
#define F_MAGIC 0x0020 /* name has magic chars */
#define F_MODE 0x0040 /* mode */
#define F_NLINK 0x0080 /* number of links */
#define F_SIZE 0x0100 /* size */
#define F_SLINK 0x0200 /* link count */
#define F_TIME 0x0400 /* modification time */
#define F_TYPE 0x0800 /* file type */
#define F_UID 0x1000 /* uid */
#define F_UNAME 0x2000 /* user name */
#define F_VISIT 0x4000 /* file visited */
#define F_MD5 0x8000 /* MD5 digest */
#define F_NOCHANGE 0x10000 /* If owner/mode "wrong", do */
#define F_CKSUM 0x00000001 /* check sum */
#define F_DONE 0x00000002 /* directory done */
#define F_GID 0x00000004 /* gid */
#define F_GNAME 0x00000008 /* group name */
#define F_IGN 0x00000010 /* ignore */
#define F_MAGIC 0x00000020 /* name has magic chars */
#define F_MODE 0x00000040 /* mode */
#define F_NLINK 0x00000080 /* number of links */
#define F_SIZE 0x00000100 /* size */
#define F_SLINK 0x00000200 /* The file the symbolic link is expected to reference */
#define F_TIME 0x00000400 /* modification time (mtime) */
#define F_TYPE 0x00000800 /* file type */
#define F_UID 0x00001000 /* uid */
#define F_UNAME 0x00002000 /* user name */
#define F_VISIT 0x00004000 /* file visited */
#define F_MD5 0x00008000 /* MD5 digest */
#define F_NOCHANGE 0x00010000 /* If owner/mode "wrong", do */
/* not change */
#define F_SHA1 0x20000 /* SHA-1 digest */
#define F_RMD160 0x40000 /* RIPEMD160 digest */
#define F_FLAGS 0x80000 /* file flags */
#define F_SHA256 0x100000 /* SHA-256 digest */
#define F_SHA1 0x00020000 /* SHA-1 digest */
#define F_RMD160 0x00040000 /* RIPEMD160 digest */
#define F_FLAGS 0x00080000 /* file flags */
#define F_SHA256 0x00100000 /* SHA-256 digest */
#define F_BTIME 0x00200000 /* creation time */
#define F_ATIME 0x00400000 /* access time */
#define F_CTIME 0x00800000 /* metadata modification time (ctime) */
#define F_PTIME 0x01000000 /* time added to parent folder */
#define F_XATTRS 0x02000000 /* digest of extended attributes */
#define F_INODE 0x04000000 /* inode */
#define F_ACL 0x08000000 /* digest of access control list */
u_int flags; /* items set */
#define F_BLOCK 0x001 /* block special */

View File

@ -179,131 +179,189 @@ set(char *t, NODE *ip)
if ((value == 0) || (val = strtok(NULL, " \t\n")) == NULL)
errx(1, "line %d: missing value", lineno);
switch(type) {
case F_CKSUM:
ip->cksum = strtoul(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid checksum %s",
lineno, val);
break;
case F_MD5:
ip->md5digest = strdup(val);
if(!ip->md5digest)
errx(1, "strdup");
break;
case F_SHA1:
ip->sha1digest = strdup(val);
if(!ip->sha1digest)
errx(1, "strdup");
break;
case F_SHA256:
ip->sha256digest = strdup(val);
if(!ip->sha256digest)
errx(1, "strdup");
break;
case F_RMD160:
ip->rmd160digest = strdup(val);
if(!ip->rmd160digest)
errx(1, "strdup");
break;
case F_FLAGS:
if (strcmp("none", val) == 0)
ip->st_flags = 0;
else if (strtofflags(&val, &ip->st_flags, NULL) != 0)
errx(1, "line %d: invalid flag %s",lineno, val);
break;
case F_GID:
ip->st_gid = (gid_t)strtoul(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid gid %s", lineno, val);
break;
case F_GNAME:
if ((gr = getgrnam(val)) == NULL)
errx(1, "line %d: unknown group %s", lineno, val);
ip->st_gid = gr->gr_gid;
break;
case F_IGN:
/* just set flag bit */
break;
case F_MODE:
if ((m = setmode(val)) == NULL)
errx(1, "line %d: invalid file mode %s",
lineno, val);
ip->st_mode = getmode(m, 0);
free(m);
break;
case F_NLINK:
ip->st_nlink = strtoul(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid link count %s",
lineno, val);
break;
case F_SIZE:
ip->st_size = strtoq(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid size %s",
lineno, val);
break;
case F_SLINK:
ip->slink = malloc(strlen(val) + 1);
if (ip->slink == NULL)
errx(1, "malloc");
if (strunvis(ip->slink, val) == -1)
errx(1, "symlink %s is ill-encoded", val);
break;
case F_TIME:
ip->st_mtimespec.tv_sec = strtoul(val, &ep, 10);
if (*ep != '.')
errx(1, "line %d: invalid time %s",
lineno, val);
val = ep + 1;
ip->st_mtimespec.tv_nsec = strtoul(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid time %s",
lineno, val);
break;
case F_TYPE:
switch(*val) {
case 'b':
if (!strcmp(val, "block"))
ip->type = F_BLOCK;
case F_CKSUM:
ip->cksum = strtoul(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid checksum %s",
lineno, val);
break;
case 'c':
if (!strcmp(val, "char"))
ip->type = F_CHAR;
case F_MD5:
ip->md5digest = strdup(val);
if(!ip->md5digest)
errx(1, "strdup");
break;
case 'd':
if (!strcmp(val, "dir"))
ip->type = F_DIR;
case F_SHA1:
ip->sha1digest = strdup(val);
if(!ip->sha1digest)
errx(1, "strdup");
break;
case 'f':
if (!strcmp(val, "file"))
ip->type = F_FILE;
if (!strcmp(val, "fifo"))
ip->type = F_FIFO;
case F_SHA256:
ip->sha256digest = strdup(val);
if(!ip->sha256digest)
errx(1, "strdup");
break;
case 'l':
if (!strcmp(val, "link"))
ip->type = F_LINK;
case F_RMD160:
ip->rmd160digest = strdup(val);
if(!ip->rmd160digest)
errx(1, "strdup");
break;
case 's':
if (!strcmp(val, "socket"))
ip->type = F_SOCK;
case F_FLAGS:
if (strcmp("none", val) == 0)
ip->st_flags = 0;
else if (strtofflags(&val, &ip->st_flags, NULL) != 0)
errx(1, "line %d: invalid flag %s",lineno, val);
break;
default:
errx(1, "line %d: unknown file type %s",
lineno, val);
}
break;
case F_UID:
ip->st_uid = (uid_t)strtoul(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid uid %s", lineno, val);
break;
case F_UNAME:
if ((pw = getpwnam(val)) == NULL)
errx(1, "line %d: unknown user %s", lineno, val);
ip->st_uid = pw->pw_uid;
break;
case F_GID:
ip->st_gid = (gid_t)strtoul(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid gid %s", lineno, val);
break;
case F_GNAME:
if ((gr = getgrnam(val)) == NULL)
errx(1, "line %d: unknown group %s", lineno, val);
ip->st_gid = gr->gr_gid;
break;
case F_IGN:
/* just set flag bit */
break;
case F_MODE:
if ((m = setmode(val)) == NULL)
errx(1, "line %d: invalid file mode %s",
lineno, val);
ip->st_mode = getmode(m, 0);
free(m);
break;
case F_NLINK:
ip->st_nlink = strtoul(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid link count %s",
lineno, val);
break;
case F_SIZE:
ip->st_size = strtoq(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid size %s",
lineno, val);
break;
case F_SLINK:
ip->slink = malloc(strlen(val) + 1);
if (ip->slink == NULL)
errx(1, "malloc");
if (strunvis(ip->slink, val) == -1)
errx(1, "symlink %s is ill-encoded", val);
break;
case F_TIME:
ip->st_mtimespec.tv_sec = strtoul(val, &ep, 10);
if (*ep != '.')
errx(1, "line %d: invalid time %s",
lineno, val);
val = ep + 1;
ip->st_mtimespec.tv_nsec = strtoul(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid time %s",
lineno, val);
break;
case F_TYPE:
switch(*val) {
case 'b':
if (!strcmp(val, "block"))
ip->type = F_BLOCK;
break;
case 'c':
if (!strcmp(val, "char"))
ip->type = F_CHAR;
break;
case 'd':
if (!strcmp(val, "dir"))
ip->type = F_DIR;
break;
case 'f':
if (!strcmp(val, "file"))
ip->type = F_FILE;
if (!strcmp(val, "fifo"))
ip->type = F_FIFO;
break;
case 'l':
if (!strcmp(val, "link"))
ip->type = F_LINK;
break;
case 's':
if (!strcmp(val, "socket"))
ip->type = F_SOCK;
break;
default:
errx(1, "line %d: unknown file type %s",
lineno, val);
}
break;
case F_UID:
ip->st_uid = (uid_t)strtoul(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid uid %s", lineno, val);
break;
case F_UNAME:
if ((pw = getpwnam(val)) == NULL)
errx(1, "line %d: unknown user %s", lineno, val);
ip->st_uid = pw->pw_uid;
break;
case F_BTIME:
ip->st_birthtimespec.tv_sec = strtoul(val, &ep, 10);
if (*ep != '.')
errx(1, "line %d: invalid time %s",
lineno, val);
val = ep + 1;
ip->st_birthtimespec.tv_nsec = strtoul(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid time %s",
lineno, val);
break;
case F_ATIME:
ip->st_atimespec.tv_sec = strtoul(val, &ep, 10);
if (*ep != '.')
errx(1, "line %d: invalid time %s",
lineno, val);
val = ep + 1;
ip->st_atimespec.tv_nsec = strtoul(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid time %s",
lineno, val);
break;
case F_CTIME:
ip->st_ctimespec.tv_sec = strtoul(val, &ep, 10);
if (*ep != '.')
errx(1, "line %d: invalid time %s",
lineno, val);
val = ep + 1;
ip->st_ctimespec.tv_nsec = strtoul(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid time %s",
lineno, val);
break;
case F_PTIME:
ip->st_ptimespec.tv_sec = strtoul(val, &ep, 10);
if (*ep != '.')
errx(1, "line %d: invalid time %s",
lineno, val);
val = ep + 1;
ip->st_ptimespec.tv_nsec = strtoul(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid time %s",
lineno, val);
break;
case F_XATTRS:
ip->xattrsdigest = strdup(val);
if(!ip->xattrsdigest)
err(1, "strdup");
break;
case F_INODE:
ip->st_ino = (ino_t)strtoull(val, &ep, 10);
if (*ep)
errx(1, "line %d: invalid inode %s", lineno, val);
break;
case F_ACL:
ip->acldigest = strdup(val);
if(!ip->acldigest)
err(1, "strdup");
}
}
}

View File

@ -68,6 +68,8 @@ shownode(NODE *n, int f, char const *path)
printf(" nlink=%d", n->st_nlink);
if (f & F_SIZE)
printf(" size=%jd", (intmax_t)n->st_size);
if (f & F_TIME)
printf(" time=%ld.%09ld", n->st_mtimespec.tv_sec, n->st_mtimespec.tv_nsec);
if (f & F_UID)
printf(" uid=%d", n->st_uid);
if (f & F_UNAME) {
@ -87,6 +89,21 @@ shownode(NODE *n, int f, char const *path)
printf(" sha256digest=%s", n->sha256digest);
if (f & F_FLAGS)
printf(" flags=%s", flags_to_string(n->st_flags));
if (f & F_BTIME)
printf(" btime=%ld.%09ld", n->st_birthtimespec.tv_sec, n->st_birthtimespec.tv_nsec);
if (f & F_ATIME)
printf(" atime=%ld.%09ld", n->st_atimespec.tv_sec, n->st_atimespec.tv_nsec);
if (f & F_CTIME)
printf(" ctime=%ld.%09ld", n->st_ctimespec.tv_sec, n->st_ctimespec.tv_nsec);
if (f & F_PTIME)
printf(" ptime=%ld.%09ld", n->st_ptimespec.tv_sec, n->st_ptimespec.tv_nsec);
if (f & F_XATTRS)
printf(" xattrsdigest=%s", n->xattrsdigest);
if (f & F_INODE)
printf(" inode=%llu", n->st_ino);
if (f & F_ACL)
printf(" acldigest=%s", n->acldigest);
printf("\n");
}
@ -167,6 +184,21 @@ compare_nodes(NODE *n1, NODE *n2, char const *path)
differs |= F_SHA256;
if (FF(n1, n2, F_FLAGS, st_flags))
differs |= F_FLAGS;
if (FM(n1, n2, F_BTIME, st_birthtimespec))
differs |= F_BTIME;
if (FM(n1, n2, F_ATIME, st_atimespec))
differs |= F_ATIME;
if (FM(n1, n2, F_CTIME, st_ctimespec))
differs |= F_CTIME;
if (FM(n1, n2, F_PTIME, st_ptimespec))
differs |= F_PTIME;
if (FS(n1, n2, F_XATTRS, xattrsdigest))
differs |= F_XATTRS;
if (FF(n1, n2, F_INODE, st_ino))
differs |= F_INODE;
if (FS(n1, n2, F_ACL, acldigest))
differs |= F_ACL;
if (differs) {
mismatch(n1, n2, differs, path);
return (1);

View File

@ -51,18 +51,22 @@ __FBSDID("$FreeBSD: src/usr.sbin/mtree/verify.c,v 1.24 2005/08/11 15:43:55 brian
static NODE *root;
static char path[MAXPATHLEN];
static void miss(NODE *, char *);
static int miss(NODE *, char *);
static int vwalk(void);
int
mtree_verifyspec(FILE *fi)
{
int rval;
int rval, mval;
root = mtree_readspec(fi);
rval = vwalk();
miss(root, path);
return (rval);
mval = miss(root, path);
if (rval != 0)
return rval;
else
return mval;
}
static int
@ -153,13 +157,15 @@ extra:
return (rval);
}
static void
static int
miss(NODE *p, char *tail)
{
int create;
char *tp;
const char *type, *what;
int serr;
int rval = 0;
int rrval = 0;
for (; p; p = p->next) {
if (p->type != F_DIR && (dflag || p->flags & F_VISIT))
@ -170,10 +176,12 @@ miss(NODE *p, char *tail)
symbolic link and the -q flag is set. */
struct stat statbuf;
if (qflag && stat(path, &statbuf) == 0)
if (qflag && stat(path, &statbuf) == 0) {
p->flags |= F_VISIT;
else
} else {
(void)printf("%s missing", path);
rval = MISMATCHEXIT;
}
}
if (p->type != F_DIR && p->type != F_LINK) {
putchar('\n');
@ -226,7 +234,9 @@ miss(NODE *p, char *tail)
for (tp = tail; *tp; ++tp);
*tp = '/';
miss(p->child, tp + 1);
rrval = miss(p->child, tp + 1);
if (rrval != 0)
rval = rrval;
*tp = '\0';
if (!create)
@ -252,4 +262,5 @@ miss(NODE *p, char *tail)
(void)printf("%s: file flags not set: %s\n",
path, strerror(errno));
}
return rval;
}

13
mv/mv.c
View File

@ -67,6 +67,7 @@ __RCSID("$FreeBSD: src/bin/mv/mv.c,v 1.39 2002/07/09 17:45:13 johan Exp $");
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include <locale.h>
#ifdef __APPLE__
#include <copyfile.h>
@ -240,6 +241,7 @@ do_move(char *from, char *to)
struct stat sb;
int ask, ch, first;
char modep[15];
char resp[] = {'\0', '\0'};
/*
* Check access. If interactive and file exists, ask user if it
@ -272,10 +274,17 @@ do_move(char *from, char *to)
ask = 1;
}
if (ask) {
/* Load user specified locale */
setlocale(LC_MESSAGES, "");
first = ch = getchar();
while (ch != '\n' && ch != EOF)
ch = getchar();
if (first != 'y' && first != 'Y') {
/* only care about the first character */
resp[0] = first;
if (rpmatch(resp) != 1) {
(void)fprintf(stderr, "not overwritten\n");
return (0);
}
@ -443,7 +452,7 @@ copy(char *from, char *to)
{
int pid, status;
/* posix_spawn mv from to && rm from */
/* posix_spawn cp from to && rm from */
if ((pid = fork()) == 0) {
execl(_PATH_CP, "mv", vflg ? "-PRpv" : "-PRp", "--", from, to,

View File

@ -147,10 +147,20 @@ ls_list(ARCHD *arcn, time_t now, FILE *fp)
# endif
(unsigned long)MINOR(sbp->st_rdev));
else {
/*
* UNIX compliance fix: printing filename length for soft links
* from arcn->ln_nlen instead of sbp->st_size, which is 0.
*/
off_t nlen;
if (arcn->type == PAX_SLK) {
nlen = arcn->ln_nlen;
} else {
nlen = sbp->st_size;
}
# ifdef LONG_OFF_T
(void)fprintf(fp, "%9lu ", sbp->st_size);
(void)fprintf(fp, "%9lu ", nlen);
# else
(void)fprintf(fp, "%9qu ", sbp->st_size);
(void)fprintf(fp, "%9qu ", nlen);
# endif
}

View File

@ -944,6 +944,10 @@ pax_rd(ARCHD *arcn, char *buf)
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);
/* When we have extended header for size, prefer it over hd->size */
if (size_x_current) {
sscanf(size_x_current, "%lld", &arcn->sb.st_size);
}
#endif
arcn->sb.st_mtime = (time_t)asc_ul(hd->mtime, sizeof(hd->mtime), OCT);
if (arcn->sb.st_atimespec.tv_sec == 0) { // Can be set from header
@ -1315,6 +1319,9 @@ pax_wr(ARCHD *arcn)
mode_t mode12only;
int term_char=3; /* orignal setting */
term_char=1; /* To pass conformance tests 274, 301 */
const char *size_header_name = "size";
char size_value[100];
bzero(size_value, sizeof(size_value));
/*
* check for those file system types pax cannot store
@ -1444,8 +1451,21 @@ pax_wr(ARCHD *arcn)
if (uqd_oct((u_quad_t)arcn->sb.st_size, hd->size,
sizeof(hd->size), term_char)) {
# endif
paxwarn(1,"File is too long for pax %s",arcn->org_name);
return(1);
/*
* Insert an extended header for size=<arcn->sb.st_size> since
* octal range of 12 byte string cannot fit > 8GiB files in header.
* This fixes Conformance test pax.343
*/
int i;
snprintf(size_value, sizeof(size_value), "%lld", arcn->sb.st_size);
for (i = 0; i < sizeof(o_option_table)/sizeof(O_OPTION_TYPE); i++) {
if (strncasecmp(size_header_name, o_option_table[i].name, o_option_table[i].len) == 0) {
size_x = size_value;
ext_header_entry[ext_header_inx++] = i;
}
}
generate_pax_ext_header_and_data(arcn, ext_header_inx, &ext_header_entry[0],
PAXXTYPE, header_name_x, header_name_x_requested);
}
break;
}

48
rm/rm.c
View File

@ -60,12 +60,17 @@ __used static const char rcsid[] =
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include <locale.h>
#ifdef __APPLE__
#include <removefile.h>
#include <pwd.h>
#include <grp.h>
#include "get_compat.h"
#ifndef AT_REMOVEDIR_DATALESS
#define AT_REMOVEDIR_DATALESS 0x0100 /* Remove a dataless directory without materializing first */
#endif
#else
#define COMPAT_MODE(func, mode) 1
#endif
@ -280,7 +285,15 @@ rm_tree(argv)
switch (p->fts_info) {
case FTS_DP:
case FTS_DNR:
#if __APPLE__
if (p->fts_statp != NULL && (p->fts_statp->st_flags & SF_DATALESS) != 0)
rval = unlinkat(AT_FDCWD, p->fts_accpath, AT_REMOVEDIR_DATALESS);
else
rval = rmdir(p->fts_accpath);
#else
rval = rmdir(p->fts_accpath);
#endif
if (rval == 0 || (fflag && errno == ENOENT)) {
if (rval == 0 && vflag)
(void)printf("%s\n",
@ -465,12 +478,21 @@ int
yes_or_no()
{
int ch, first;
char resp[] = {'\0', '\0'};
(void)fflush(stderr);
/* Load user specified locale */
setlocale(LC_MESSAGES, "");
first = ch = getchar();
while (ch != '\n' && ch != EOF)
ch = getchar();
return (first == 'y' || first == 'Y');
/* only care about the first character */
resp[0] = first;
return (rpmatch(resp) == 1);
}
int
@ -530,10 +552,28 @@ checkdot(argv)
complained = 0;
for (t = argv; *t;) {
if ((p = strrchr(*t, '/')) != NULL)
++p;
else
size_t len = strlen(*t);
char truncated[len];
if ((p = strrchr(*t, '/')) != NULL) {
if (p[1] == '\0') { // one or more trailing / -- treat as if not present
for (; (p > *t) && (p[-1] == '/');) {
len--;
p--;
}
strlcpy(truncated, *t, len);
p = strrchr(truncated, '/');
if (p) {
++p;
} else {
p = truncated;
}
} else {
++p;
}
} else {
p = *t;
}
if (ISDOT(p)) {
if (!complained++)
warnx("\".\" and \"..\" may not be removed");

View File

@ -731,7 +731,14 @@ format1(const struct stat *st,
small = (sizeof(st->st_flags) == 4);
data = st->st_flags;
sdata = NULL;
formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX;
formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX |
FMTF_STRING;
if (ofmt == FMTF_STRING) {
small = 0;
data = 0;
snprintf(path, sizeof(path), "%s", fflagstostr(st->st_flags));
sdata = path;
}
if (ofmt == 0)
ofmt = FMTF_UNSIGNED;
break;

26
tests/chgrp.sh Normal file
View File

@ -0,0 +1,26 @@
#!/bin/sh
GROUPID=31337
dscl /Local/Default -read /Groups/$GROUPID > /dev/null 2>&1
if [ $? != "0" ]; then
dscl /Local/Default -create /Groups/$GROUPID
dscl /Local/Default -create /Groups/$GROUPID PrimaryGroupID 9999
fi
mkdir /tmp/$$
chgrp $GROUPID /tmp/$$
gid=`/usr/bin/stat -f '%g' /tmp/$$`
if [ "$gid" != "9999" ]; then
echo "chgrp $GROUPID, expected group 9999, is $gid"
exit 1
fi
chgrp -n $GROUPID /tmp/$$
gid=`/usr/bin/stat -f '%g' /tmp/$$`
if [ "$gid" != "$GROUPID" ]; then
echo "chgrp -n $GROUPID, expected group $GROUPID, is $gid"
exit 1
fi
exit 0

33
tests/file_cmds.plist Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Project</key>
<string>file_cmds</string>
<key>IgnoreOutput</key>
<true/>
<key>Tests</key>
<array>
<dict>
<key>Command</key>
<array>
<string>/bin/sh</string>
<string>chgrp.sh</string>
</array>
<key>AsRoot</key>
<true/>
<key>TestName</key>
<string>chgrp</string>
<key>WhenToRun</key>
<array>
<string>PRESUBMISSION</string>
<string>NIGHTLY</string>
</array>
<key>WorkingDirectory</key>
<string>/AppleInternal/Tests/file_cmds</string>
</dict>
</array>
<key>Timeout</key>
<integer>30</integer>
</dict>
</plist>