From 293419153983bb06b87bfc1fb960e009b0d85f7b Mon Sep 17 00:00:00 2001 From: Apple Date: Thu, 9 Jul 2015 01:14:12 +0000 Subject: [PATCH] file_cmds-251.tar.gz --- chmod/chmod_acl.c | 33 +++++--------- cp/utils.c | 69 ++++++++++++++--------------- dd/dd.entitlements | 9 ++++ dd/install_symlink.sh | 16 +++++++ df/df.c | 18 ++++---- file_cmds.xcodeproj/project.pbxproj | 26 ++++++++++- ipcs/ipcs.c | 35 +++------------ ls/print.c | 63 +++++++++++--------------- pax/pax_format.c | 88 ++++++++++++++++++++++--------------- 9 files changed, 187 insertions(+), 170 deletions(-) create mode 100644 dd/dd.entitlements create mode 100644 dd/install_symlink.sh diff --git a/chmod/chmod_acl.c b/chmod/chmod_acl.c index 2bb8e39..34708fc 100644 --- a/chmod/chmod_acl.c +++ b/chmod/chmod_acl.c @@ -100,31 +100,22 @@ static struct { uuid_t * name_to_uuid(char *tok, int nametype) { - struct passwd *tpass = NULL; - struct group *tgrp = NULL; uuid_t *entryg = NULL; + size_t len = strlen(tok); - if ((entryg = (uuid_t *) calloc(1,sizeof(uuid_t))) == NULL) - err(1, "Unable to allocate a uuid"); - - if (nametype & NAME_USER) - tpass = getpwnam(tok); - - if (NULL == tpass && (nametype & NAME_GROUP)) - tgrp = getgrnam(tok); + if ((entryg = (uuid_t *) calloc(1, sizeof(uuid_t))) == NULL) { + errx(1, "Unable to allocate a uuid"); + } - if (tpass) { - if (0 != mbr_uid_to_uuid(tpass->pw_uid, *entryg)) { - errx(1, "mbr_uid_to_uuid(): Unable to translate uid %d", tpass->pw_uid); - } - } else if (tgrp) { - if (0 != mbr_gid_to_uuid(tgrp->gr_gid, *entryg)) { - errx(1, "mbr_gid_to_uuid(): Unable to translate gid %d", tgrp->gr_gid); - } - } else { - errx(1, "Unable to translate '%s' to a UID/GID", tok); + if ((nametype & NAME_USER) && mbr_identifier_to_uuid(ID_TYPE_USERNAME, tok, len, *entryg) == 0) { + return entryg; + } + + if ((nametype & NAME_GROUP) && mbr_identifier_to_uuid(ID_TYPE_GROUPNAME, tok, len, *entryg) == 0) { + return entryg; } - return entryg; + + errx(1, "Unable to translate '%s' to a UUID", tok); } /* Convert an acl entry in string form to an acl_entry_t */ diff --git a/cp/utils.c b/cp/utils.c index 5995672..a2d031d 100644 --- a/cp/utils.c +++ b/cp/utils.c @@ -358,26 +358,20 @@ setfile(struct stat *fs, int fd) rval = 0; fdval = fd != -1; islink = !fdval && S_ISLNK(fs->st_mode); - fs->st_mode &= S_ISUID | S_ISGID | S_ISVTX | - S_IRWXU | S_IRWXG | S_IRWXO; + fs->st_mode &= S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO; TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec); TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec); -#ifdef __APPLE__ - if (islink ? 0 : utimes(to.p_path, tv)) { -#else - if (islink ? lutimes(to.p_path, tv) : utimes(to.p_path, tv)) { -#endif /* __APPLE__ */ - warn("%sutimes: %s", islink ? "l" : "", to.p_path); + if (fdval ? futimes(fd, tv) : (islink ? lutimes(to.p_path, tv) : utimes(to.p_path, tv))) { + warn("%sutimes: %s", fdval ? "f" : (islink ? "l" : ""), to.p_path); rval = 1; } - if (fdval ? fstat(fd, &ts) : - (islink ? lstat(to.p_path, &ts) : stat(to.p_path, &ts))) + if (fdval ? fstat(fd, &ts) : (islink ? lstat(to.p_path, &ts) : + stat(to.p_path, &ts))) { gotstat = 0; - else { + } else { gotstat = 1; - ts.st_mode &= S_ISUID | S_ISGID | S_ISVTX | - S_IRWXU | S_IRWXG | S_IRWXO; + ts.st_mode &= S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO; } /* * Changing the ownership probably won't succeed, unless we're root @@ -385,34 +379,37 @@ setfile(struct stat *fs, int fd) * the mode; current BSD behavior is to remove all setuid bits on * chown. If chown fails, lose setuid/setgid bits. */ - if (!gotstat || fs->st_uid != ts.st_uid || fs->st_gid != ts.st_gid) - if (fdval ? fchown(fd, fs->st_uid, fs->st_gid) : - (islink ? lchown(to.p_path, fs->st_uid, fs->st_gid) : - chown(to.p_path, fs->st_uid, fs->st_gid))) { - if (errno != EPERM) { - warn("%schown: %s", islink ? "l" : "", to.p_path); - rval = 1; - } - fs->st_mode &= ~(S_ISUID | S_ISGID); - } + if (!gotstat || fs->st_uid != ts.st_uid || fs->st_gid != ts.st_gid) { + if (fdval ? fchown(fd, fs->st_uid, fs->st_gid) : (islink ? + lchown(to.p_path, fs->st_uid, fs->st_gid) : + chown(to.p_path, fs->st_uid, fs->st_gid))) { + if (errno != EPERM) { + warn("%schown: %s", fdval ? "f" : (islink ? "l" : ""), to.p_path); + rval = 1; + } + fs->st_mode &= ~(S_ISUID | S_ISGID); + } + } - if (!gotstat || fs->st_mode != ts.st_mode) - if (fdval ? fchmod(fd, fs->st_mode) : - (islink ? lchmod(to.p_path, fs->st_mode) : - chmod(to.p_path, fs->st_mode))) { - warn("%schmod: %s", islink ? "l" : "", to.p_path); + if (!gotstat || fs->st_mode != ts.st_mode) { + if (fdval ? fchmod(fd, fs->st_mode) : (islink ? + lchmod(to.p_path, fs->st_mode) : + chmod(to.p_path, fs->st_mode))) { + warn("%schmod: %s", fdval ? "f" : (islink ? "l" : ""), to.p_path); rval = 1; } + } - if (!gotstat || fs->st_flags != ts.st_flags) - if (fdval ? - fchflags(fd, fs->st_flags) : - (islink ? lchflags(to.p_path, fs->st_flags) : - chflags(to.p_path, fs->st_flags))) { - warn("%schflags: %s", islink ? "l" : "", to.p_path); - rval = 1; + if (!gotstat || fs->st_flags != ts.st_flags) { + if (fdval ? fchflags(fd, fs->st_flags) : (islink ? + lchflags(to.p_path, fs->st_flags) : + chflags(to.p_path, fs->st_flags))) { + if (errno != EPERM) { + warn("%schflags: %s", fdval ? "f" : (islink ? "l" : ""), to.p_path); + rval = 1; + } } - + } return (rval); } diff --git a/dd/dd.entitlements b/dd/dd.entitlements new file mode 100644 index 0000000..abb8bc5 --- /dev/null +++ b/dd/dd.entitlements @@ -0,0 +1,9 @@ + + + + + com.apple.private.security.disk-device-access + + + + diff --git a/dd/install_symlink.sh b/dd/install_symlink.sh new file mode 100644 index 0000000..4b8cd15 --- /dev/null +++ b/dd/install_symlink.sh @@ -0,0 +1,16 @@ +#!/bin/sh +set -e +set -x + +case "$PLATFORM_NAME" in +iphoneos|appletvos|watchos) + ln -hfs /usr/local/bin/dd "$DSTROOT"/bin/dd + ;; +macosx) + ;; +*) + echo "Unsupported platform: $PLATFORM_NAME" + exit 1 + ;; +esac + diff --git a/df/df.c b/df/df.c index 142bbf1..7e576d7 100644 --- a/df/df.c +++ b/df/df.c @@ -121,7 +121,7 @@ unit_t unitp [] = { NONE, KILO, MEGA, GIGA, TERA, PETA }; int bread(off_t, void *, int); int checkvfsname(const char *, char **); char *getmntpt(char *); -int longwidth(long long); +int int64width(int64_t); char *makenetvfslist(void); char **makevfslist(const char *); void prthuman(struct statfs *, uint64_t); @@ -500,8 +500,8 @@ prtstat(struct statfs *sfsp, struct maxwidths *mwp) if (iflag) { inodes = sfsp->f_files; used = inodes - sfsp->f_ffree; - (void)printf(" %*llu %*lu %4.0f%% ", mwp->iused, used, - mwp->ifree, (unsigned long)sfsp->f_ffree, inodes == 0 ? 100.0 : + (void)printf(" %*llu %*llu %4.0f%% ", mwp->iused, used, + mwp->ifree, sfsp->f_ffree, inodes == 0 ? 100.0 : (double)used / (double)inodes * 100.0); } else (void)printf(" "); @@ -522,20 +522,20 @@ update_maxwidths(struct maxwidths *mwp, struct statfs *sfsp) getbsize(&dummy, &blocksize); mwp->mntfrom = imax(mwp->mntfrom, (int)strlen(sfsp->f_mntfromname)); - mwp->total = imax(mwp->total, longwidth(fsbtoblk(sfsp->f_blocks, + mwp->total = imax(mwp->total, int64width(fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize, sfsp->f_mntonname))); if (sfsp->f_blocks >= sfsp->f_bfree) - mwp->used = imax(mwp->used, longwidth(fsbtoblk(sfsp->f_blocks - + mwp->used = imax(mwp->used, int64width(fsbtoblk(sfsp->f_blocks - sfsp->f_bfree, sfsp->f_bsize, blocksize, sfsp->f_mntonname))); - mwp->avail = imax(mwp->avail, longwidth(fsbtoblk(sfsp->f_bavail, + mwp->avail = imax(mwp->avail, int64width(fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize, sfsp->f_mntonname))); - mwp->iused = imax(mwp->iused, longwidth((unsigned)(sfsp->f_files - sfsp->f_ffree))); - mwp->ifree = imax(mwp->ifree, longwidth((unsigned)(sfsp->f_ffree))); + mwp->iused = imax(mwp->iused, int64width(sfsp->f_files - sfsp->f_ffree)); + mwp->ifree = imax(mwp->ifree, int64width(sfsp->f_ffree)); } /* Return the width in characters of the specified long. */ int -longwidth(long long val) +int64width(int64_t val) { int len; diff --git a/file_cmds.xcodeproj/project.pbxproj b/file_cmds.xcodeproj/project.pbxproj index e115549..eddbd0a 100644 --- a/file_cmds.xcodeproj/project.pbxproj +++ b/file_cmds.xcodeproj/project.pbxproj @@ -1143,6 +1143,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 0773099A1A3A4DFE00E9B4EA /* dd.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = dd.entitlements; sourceTree = ""; }; 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; }; @@ -1691,6 +1692,7 @@ FCB1BDF814B6460C0070FACB /* dd */ = { isa = PBXGroup; children = ( + 0773099A1A3A4DFE00E9B4EA /* dd.entitlements */, FCB1BDF914B6460C0070FACB /* args.c */, FCB1BDFA14B6460C0070FACB /* conv.c */, FCB1BDFB14B6460C0070FACB /* conv_tab.c */, @@ -2081,6 +2083,7 @@ FC8A8B3514B648EA001B97AD /* Sources */, FC8A8B3614B648EA001B97AD /* Frameworks */, FC8A8B3714B648EA001B97AD /* CopyFiles */, + 72E62BA81A3A62960015FC8E /* ShellScript */, ); buildRules = ( ); @@ -2440,7 +2443,7 @@ FCB1BDAF14B645D00070FACB /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0600; + LastUpgradeCheck = 0610; ORGANIZATIONNAME = "Apple Inc."; }; buildConfigurationList = FCB1BDB214B645D00070FACB /* Build configuration list for PBXProject "file_cmds" */; @@ -2509,6 +2512,20 @@ shellScript = "install -d -g ${GROUP} -o ${USER} -m 0755 ${INSTALL_DIR}\ninstall -d -g ${GROUP} -o ${USER} -m 0755 ${DSTROOT}/usr/share\ninstall -d -g ${GROUP} -o ${USER} -m 0755 ${DSTROOT}/usr/share/man\ninstall -d -g ${GROUP} -o ${USER} -m 0755 ${DSTROOT}/usr/share/man/man{1,7,8}"; showEnvVarsInLog = 0; }; + 72E62BA81A3A62960015FC8E /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = ". ${SRCROOT}/dd/install_symlink.sh"; + showEnvVarsInLog = 0; + }; FC8A8C4C14B64DF9001B97AD /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 8; @@ -3284,7 +3301,12 @@ FC8A8B3914B648EA001B97AD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_ENTITLEMENTS = dd/dd.entitlements; + "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = ""; + CODE_SIGN_IDENTITY = "-"; INSTALL_PATH = /bin; + "INSTALL_PATH[sdk=appletvos]" = /usr/local/bin; + "INSTALL_PATH[sdk=iphoneos*]" = /usr/local/bin; }; name = Release; }; @@ -3318,7 +3340,6 @@ FC8A8B6114B648EC001B97AD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - INSTALL_MODE_FLAG = "u+s,u+rw,go-rw,a+X"; OTHER_CFLAGS = ( "-iquote", "$(SDKROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders", @@ -3505,6 +3526,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; INSTALL_PATH = /usr/bin; PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx.internal; VERSIONING_SYSTEM = "apple-generic"; WARNING_CFLAGS = ( "-Wall", diff --git a/ipcs/ipcs.c b/ipcs/ipcs.c index b5f6e75..986b229 100644 --- a/ipcs/ipcs.c +++ b/ipcs/ipcs.c @@ -117,26 +117,6 @@ usage(void) errx(EX_USAGE, "%s","usage: ipcs [-abcmopqstMQST]\n"); } -static int -safe_sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen) -{ - int rv, sv_errno=0; - - if (seteuid(0)) /* iterator needs root write access to sysctl */ - err(1, "seteuid(0) failed"); - - rv = sysctlbyname(name, oldp, oldlenp, newp, newlen); - if (rv < 0) - sv_errno = errno; - - if (seteuid(getuid())) - err(1, "seteuid(%d) failed", getuid()); - - if (rv < 0) - errno = sv_errno; - return rv; -} - int main(argc, argv) int argc; @@ -149,9 +129,6 @@ main(argc, argv) char datestring[100]; int i; - if (seteuid(getuid())) /* run as user */ - err(1, "seteuid(%d) failed", getuid()); - while ((i = getopt(argc, argv, "MmQqSsabcoptT")) != -1) switch (i) { case 'M': @@ -219,7 +196,7 @@ main(argc, argv) ic.ipcs_data = &msginfo; ic.ipcs_datalen = sizeof(msginfo); - if (safe_sysctlbyname(IPCS_MSG_SYSCTL, &ic, &ic_size, &ic, ic_size)) { + if (sysctlbyname(IPCS_MSG_SYSCTL, &ic, &ic_size, &ic, ic_size)) { if (errno != EPERM) { char buffer[1024]; snprintf(buffer, 1024, "sysctlbyname(IPCS_MSG_SYSCTL, op=CONF, &ic, &%ld) datalen=%d", @@ -270,7 +247,7 @@ main(argc, argv) memset(msqptr, 0, sizeof(*msqptr)); - while(!(safe_sysctlbyname(IPCS_MSG_SYSCTL, &ic, &ic_size, &ic, ic_size))) { + while(!(sysctlbyname(IPCS_MSG_SYSCTL, &ic, &ic_size, &ic, ic_size))) { ic.ipcs_data = msqptr; if (msqptr->msg_qbytes != 0) { @@ -345,7 +322,7 @@ main(argc, argv) ic.ipcs_data = &shminfo; ic.ipcs_datalen = sizeof(shminfo); - if (safe_sysctlbyname(IPCS_SHM_SYSCTL, &ic, &ic_size, &ic, ic_size)) { + if (sysctlbyname(IPCS_SHM_SYSCTL, &ic, &ic_size, &ic, ic_size)) { if (errno != EPERM) { errx(1, "sysctlbyname(IPCS_SHM_SYSCTL, op=CONF, &ic, &%ld) datalen=%d failed: %s\n", sizeof(ic), ic.ipcs_datalen, strerror(errno)); @@ -391,7 +368,7 @@ main(argc, argv) ic.ipcs_data = shmptr; memset(shmptr, 0, sizeof(*shmptr)); - while(!(safe_sysctlbyname(IPCS_SHM_SYSCTL, &ic, &ic_size, &ic, ic_size))) { + while(!(sysctlbyname(IPCS_SHM_SYSCTL, &ic, &ic_size, &ic, ic_size))) { ic.ipcs_data = shmptr; /* xnu workaround */ if (shmptr->shm_perm.mode & 0x0800) { @@ -467,7 +444,7 @@ else ic.ipcs_data = &seminfo; ic.ipcs_datalen = sizeof(seminfo); - if (safe_sysctlbyname(IPCS_SEM_SYSCTL, &ic, &ic_size, &ic, ic_size)) { + if (sysctlbyname(IPCS_SEM_SYSCTL, &ic, &ic_size, &ic, ic_size)) { if (errno != EPERM) { char buffer[1024]; snprintf(buffer, 1024, "sysctlbyname(IPCS_SEM_SYSCTL, op=CONF, &ic, &%ld) datalen=%d", @@ -522,7 +499,7 @@ else memset(semaptr, 0, sizeof(*semaptr)); - while(!(safe_sysctlbyname(IPCS_SEM_SYSCTL, &ic, &ic_size, &ic, ic_size))) { + while(!(sysctlbyname(IPCS_SEM_SYSCTL, &ic, &ic_size, &ic, ic_size))) { ic.ipcs_data = semaptr; /* xnu workaround */ if ((semaptr->sem_perm.mode & SEM_ALLOC) != 0) { diff --git a/ls/print.c b/ls/print.c index d137156..b43f6b7 100644 --- a/ls/print.c +++ b/ls/print.c @@ -204,48 +204,35 @@ static char * uuid_to_name(uuid_t *uu) { #if TARGET_OS_EMBEDDED - return strdup(""); + return strdup(""); #else /* !TARGET_OS_EMBEDDED */ - int is_gid = -1; - struct group *tgrp = NULL; - struct passwd *tpass = NULL; - char *name = NULL; - uid_t id; - - + int type; + char *name = NULL; + char *recname = NULL; + #define MAXNAMETAG (MAXLOGNAME + 6) /* + strlen("group:") */ - name = (char *) malloc(MAXNAMETAG); - - if (NULL == name) - err(1, "malloc"); - - if (!f_numericonly) { - if (0 != mbr_uuid_to_id(*uu, &id, &is_gid)) - goto errout; + name = (char *) malloc(MAXNAMETAG); + + if (NULL == name) { + err(1, "malloc"); + } + + if (f_numericonly) { + goto errout; } - - switch (is_gid) { - case ID_TYPE_UID: - tpass = getpwuid(id); - if (!tpass) { - goto errout; - } - snprintf(name, MAXNAMETAG, "%s:%s", "user", tpass->pw_name); - break; - case ID_TYPE_GID: - tgrp = getgrgid((gid_t) id); - if (!tgrp) { - goto errout; - } - snprintf(name, MAXNAMETAG, "%s:%s", "group", tgrp->gr_name); - break; - default: + + if (mbr_identifier_translate(ID_TYPE_UUID, *uu, sizeof(*uu), ID_TYPE_NAME, (void **) &recname, &type)) { goto errout; - } - return name; - errout: - uuid_unparse_upper(*uu, name); - return name; + } + + snprintf(name, MAXNAMETAG, "%s:%s", (type == MBR_REC_TYPE_USER ? "user" : "group"), recname); + free(recname); + + return name; +errout: + uuid_unparse_upper(*uu, name); + + return name; #endif /* !TARGET_OS_EMBEDDED */ } diff --git a/pax/pax_format.c b/pax/pax_format.c index 3b34ca8..3ac97ed 100644 --- a/pax/pax_format.c +++ b/pax/pax_format.c @@ -117,6 +117,7 @@ char *pax_list_opt_format; #define KW_PATH_CASE 0 #define KW_SKIP_CASE -1 +#define KW_ATIME_CASE -2 typedef struct { char * name; @@ -136,7 +137,7 @@ typedef struct { O_OPTION_TYPE o_option_table[] = { { "atime", 5, 1, O_OPTION_ACTION_STORE_HEADER, O_OPTION_ACTION_STORE_HEADER, - &atime_g, &atime_x, &atime_g_current, &atime_x_current, 0, KW_SKIP_CASE }, + &atime_g, &atime_x, &atime_g_current, &atime_x_current, 0, KW_ATIME_CASE }, { "charset", 7, 1, O_OPTION_ACTION_STORE_HEADER, O_OPTION_ACTION_IGNORE, &charset_g, &charset_x, &charset_g_current, &charset_x_current, 0, KW_SKIP_CASE }, { "comment", 7, 1, O_OPTION_ACTION_STORE_HEADER, O_OPTION_ACTION_IGNORE, @@ -757,53 +758,67 @@ expand_extended_headers(ARCHD *arcn, HD_USTAR *hd) /* Acceleration: check during command option processing. If there are no -o options, and no changes from any header, do not need to run through this loop. */ - current_value = NULL; for (i = 0; i < sizeof(o_option_table)/sizeof(O_OPTION_TYPE); i++) { int header_len, free_it; - if (!o_option_table[i].active) continue; /* deleted keywords */ + if (!o_option_table[i].active) { + continue; /* deleted keywords */ + } header_len = o_option_table[i].header_len; + if (header_len == KW_SKIP_CASE) { + continue; + } free_it = 0; - if (header_len >= 0) { /* Normal keywords */ + /* Calculate values for all non-skip keywords */ + current_value = NULL; + if (o_option_table[i].x_value) { current_value = *o_option_table[i].x_value; - if (!current_value) { /* No -o := */ + } + if (!current_value) { /* No -o := */ + if (o_option_table[i].x_value_current) { current_value = *o_option_table[i].x_value_current; - if (current_value) { - /* Must remove it: x header values not valid beyond this header */ - *o_option_table[i].x_value_current = NULL; - free_it = 1; - } else { /* No x values, try globals */ - current_value = *o_option_table[i].g_value; - if (!current_value) - current_value = *o_option_table[i].g_value_current; - } } if (current_value) { - /* Update current header with this value */ - /* + /* Must remove it: x header values not valid beyond this header */ + *o_option_table[i].x_value_current = NULL; + free_it = 1; + } else { /* No x values, try globals */ + current_value = *o_option_table[i].g_value; + if (!current_value) { + current_value = *o_option_table[i].g_value_current; + } + } + } + if (current_value) { + /* Update current header with this value */ + /* printf ("Found current_value:%s for %s, pids=%d\n", - current_value, o_option_table[i].name, pids); + current_value, o_option_table[i].name, pids); */ - len = strlen(current_value); - if (header_len == KW_PATH_CASE) { /* Special case for path keyword */ - path_replaced = 1; - arcn->nlen = len; - strlcpy(arcn->name,current_value,sizeof(arcn->name)); + len = strlen(current_value); + if (header_len == KW_ATIME_CASE) { + time_t asecs = strtoul(current_value, NULL, 10); + arcn->sb.st_atimespec.tv_sec = asecs; + } else if (header_len == KW_PATH_CASE) { /* Special case for path keyword */ + path_replaced = 1; + arcn->nlen = len; + strlcpy(arcn->name,current_value,sizeof(arcn->name)); + } else if (header_len >= 0) { // Skip negative values + if (len > header_len) { + paxwarn(1," length of string from extended header bigger than header field:" + " THAT won't work!\n"); } else { - if (len > header_len) { - paxwarn(1," length of string from extended header bigger than header field:" - " THAT won't work!\n"); - } else { - char * p = (char *) myhd; - memcpy(&p[o_option_table[i].header_inx], - current_value, len); - if (len != header_len) { - /* pad with ? */ - p[o_option_table[i].header_inx+len] = '\0'; - } + char * p = (char *) myhd; + memcpy(&p[o_option_table[i].header_inx], + current_value, len); + if (len != header_len) { + /* pad with ? */ + p[o_option_table[i].header_inx+len] = '\0'; } } } - if (free_it) free(current_value); + if (free_it) { + free(current_value); + } } } @@ -931,7 +946,10 @@ pax_rd(ARCHD *arcn, char *buf) 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; + if (arcn->sb.st_atimespec.tv_sec == 0) { // Can be set from header + arcn->sb.st_atime = arcn->sb.st_mtime; + } + arcn->sb.st_ctime = arcn->sb.st_mtime; /* * If we can find the ascii names for gname and uname in the password -- 2.7.4