diff options
author | amw <none@none> | 2007-10-25 16:34:29 -0700 |
---|---|---|
committer | amw <none@none> | 2007-10-25 16:34:29 -0700 |
commit | da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0 (patch) | |
tree | 65be91fb78a6a66183197595333f2e8aafb4640a /usr/src/cmd/pack/pack.c | |
parent | e845e33dd0d1aea22db7edaa8c7d43955d24609b (diff) | |
download | illumos-joyent-da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0.tar.gz |
PSARC/2007/218 caller_context_t in all VOPs
PSARC/2007/227 VFS Feature Registration and ACL on Create
PSARC/2007/244 ZFS Case-insensitive support
PSARC/2007/315 Extensible Attribute Interfaces
PSARC/2007/394 ls(1) new command line options '-/' and '-%': CIFS system attributes support
PSARC/2007/403 Modified Access Checks for CIFS
PSARC/2007/410 Add system attribute support to chmod(1)
PSARC/2007/432 CIFS system attributes support for cp(1), pack(1), unpack(1), compress(1) and uncompress(1)
PSARC/2007/444 Rescind SETTABLE Attribute
PSARC/2007/459 CIFS system attributes support for cpio(1), pax(1), tar(1)
PSARC/2007/546 Update utilities to match CIFS system attributes changes.
PSARC/2007/560 ZFS sharesmb property
4890717 want append-only files
6417428 Case-insensitive file system name lookup to support CIFS
6417435 DOS attributes and additional timestamps to support for CIFS
6417442 File system quarantined and modified attributes to support an integrated Anti-Virus service
6417453 FS boolean property for rejecting/allowing invalid UTF-8 sequences in file names
6473733 RFE: Need support for open-deny modes
6473755 RFE: Need ability to reconcile oplock and delegation conflicts
6494624 sharemgr needs to support CIFS shares better
6546705 All vnode operations need to pass caller_context_t
6546706 Need VOP_SETATTR/VOP_GETATTR to support new, optional attributes
6546893 Solaris system attribute support
6550962 ZFS ACL inheritance needs to be enhanced to support Automatic Inheritance
6553589 RFE: VFS Feature Registration facility
6553770 RFE: ZFS support for ACL-on-CREATE (PSARC 2007/227)
6565581 ls(1) should support file system attributes proposed in PSARC/2007/315
6566784 NTFS streams are not copied along with the files.
6576205 cp(1), pack(1) and compress(1) should support file system attributes proposed in PSARC/2007/315
6578875 RFE: kernel interfaces for nbmand need improvement
6578883 RFE: VOP_SHRLOCK needs additional access types
6578885 chmod(1) should support file system attributes proposed in PSARC/2007/315
6578886 RFE: disallow nbmand state to change on remount
6583349 ACL parser needs to support audit/alarm ACE types
6590347 tar(1) should support filesystem attributes proposed in PSARC/2007/315
6597357 *tar* xv@ doesn't show the hidden directory even though it is restored
6597360 *tar* should re-init xattr info if openat() fails during extraction of and extended attribute
6597368 *tar* cannot restore hard linked extended attributes
6597374 *tar* doesn't display "x " when hard linked attributes are restored
6597375 *tar* extended attribute header off by one
6614861 *cpio* incorrectly archives extended system attributes with -@
6614896 *pax* incorrectly archives extended system attributes with -@
6615225 *tar* incorrectly archives extended system attributes with -@
6617183 CIFS Service - PSARC 2006/715
Diffstat (limited to 'usr/src/cmd/pack/pack.c')
-rw-r--r-- | usr/src/cmd/pack/pack.c | 326 |
1 files changed, 151 insertions, 175 deletions
diff --git a/usr/src/cmd/pack/pack.c b/usr/src/cmd/pack/pack.c index 181e6a61db..67e4814986 100644 --- a/usr/src/cmd/pack/pack.c +++ b/usr/src/cmd/pack/pack.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,28 +30,18 @@ /* * Huffman encoding program - * Usage: pack [[ -f ] [ - ] filename ... ] filename ... + * Usage: pack [[ -f ] [ - ] [-/] filename ... ] filename ... * - option: enable/disable listing of statistics */ -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> #include <locale.h> #include <stdarg.h> -#include <errno.h> #include <sys/isa_defs.h> -#include <stdlib.h> -#include <limits.h> #include <sys/param.h> -#include <fcntl.h> #include <utime.h> -#include <string.h> -#include <dirent.h> -#include <unistd.h> #include <sys/acl.h> #include <aclutils.h> +#include <libcmdutils.h> #undef lint @@ -82,7 +72,6 @@ int force = 0; /* allow forced packing for consistency in directory */ static char filename [MAXPATHLEN]; static int max_name; -static int max_path = MAXPATHLEN; int infile; /* unpacked file */ int outfile; /* packed file */ @@ -123,7 +112,11 @@ struct heap { #define hmove(a, b) {(b).count = (a).count; (b).node = (a).node; } static void heapify(int i); -static int mv_xattrs(int, int, char *, int); + +/* Extended system attribute support */ + +static int saflg = 0; + /* gather character frequency statistics */ /* return 1 if successful, 0 otherwise */ @@ -138,8 +131,8 @@ input(char *source) count[inbuff[--i]&0377] += 2; if (i == 0) return (1); - fprintf(stderr, gettext( - "pack: %s: read error - file unchanged: "), source); + (void) fprintf(stderr, gettext( + "pack: %s: read error - file unchanged: "), source); perror(""); return (0); } @@ -176,7 +169,7 @@ output(char *source) dictsize = outp-&outbuff[0]; /* output the text */ - lseek(infile, 0L, 0); + (void) lseek(infile, 0L, 0); outsize = 0; bitsleft = 8; inleft = 0; @@ -184,9 +177,9 @@ output(char *source) if (inleft <= 0) { inleft = read(infile, inp = &inbuff[0], BUFSIZ); if (inleft < 0) { - fprintf(stderr, gettext( + (void) fprintf(stderr, gettext( "pack: %s: read error - file unchanged: "), - source); + source); perror(""); return (0); } @@ -205,14 +198,14 @@ output(char *source) } if (outp >= &outbuff[BUFSIZ]) { if (write(outfile, outbuff, BUFSIZ) != BUFSIZ) { -wrerr: fprintf(stderr, gettext( - "pack: %s.z: write error - file unchanged: "), - source); +wrerr: (void) fprintf(stderr, gettext( + "pack: %s.z: write error - " + "file unchanged: "), source); perror(""); return (0); } ((union FOUR *)outbuff)->lint.lng = - ((union FOUR *)&outbuff[BUFSIZ])->lint.lng; + ((union FOUR *)&outbuff[BUFSIZ])->lint.lng; outp -= BUFSIZ; outsize += BUFSIZ; } @@ -272,8 +265,8 @@ packfile(char *source) } } if (diffbytes == 1) { - fprintf(stderr, gettext( - "pack: %s: trivial file - file unchanged\n"), source); + (void) fprintf(stderr, gettext( + "pack: %s: trivial file - file unchanged\n"), source); return (0); } insize.lint.lng >>= 1; @@ -311,18 +304,18 @@ packfile(char *source) } if (maxlev > 24) { /* can't occur unless insize.lint.lng >= 2**24 */ - fprintf(stderr, gettext( - "pack: %s: Huffman tree has too many levels - file unchanged\n"), - source); + (void) fprintf(stderr, gettext( + "pack: %s: Huffman tree has too many levels - " + "file unchanged\n"), source); return (0); } /* don't bother if no compression results */ outsize = ((bitsout+7)>>3)+6+maxlev+diffbytes; if ((insize.lint.lng+BUFSIZ-1)/BUFSIZ <= - (outsize+BUFSIZ-1)/BUFSIZ && !force) { - printf(gettext( - "pack: %s: no saving - file unchanged\n"), source); + (outsize+BUFSIZ-1)/BUFSIZ && !force) { + (void) printf(gettext( + "pack: %s: no saving - file unchanged\n"), source); return (0); } @@ -354,6 +347,9 @@ main(int argc, char *argv[]) int error; int fcount = 0; /* count failures */ acl_t *aclp = NULL; + char *progname; + int sattr_exist = 0; + int xattr_exist = 0; (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ @@ -361,9 +357,16 @@ main(int argc, char *argv[]) #endif (void) textdomain(TEXT_DOMAIN); - while ((c = getopt(argc, argv, "f-")) != EOF) { + if (progname = strrchr(argv[0], '/')) + ++progname; + else + progname = argv[0]; + + while ((c = getopt(argc, argv, "f-/")) != EOF) { if (c == 'f') force++; + else if (c == '/') + saflg++; else ++errflg; } @@ -374,18 +377,20 @@ main(int argc, char *argv[]) argc -= optind; argv = &argv[optind]; if (errflg || argc < 1 || - (argc == 1 && argv[0][0] == '-' && argv[0][1] == '\0')) { - fprintf(stderr, gettext( - "usage: pack [-f] [-] file...\n")); + (argc == 1 && (argv[0][0] == '-' || argv[0][0] == '/' && + argv[0][1] == '\0'))) { + (void) fprintf(stderr, gettext( + "usage: pack [-f] [-] [-/] file...\n")); if (argc < 1 || - (argc == 1 && argv[0][0] == '-' && - argv[0][1] == '\0')) { + (argc == 1 && (argv[0][0] == '-' || argv[0][0] == '/') && + argv[0][1] == '\0')) { /* * return 1 for usage error when no file was specified */ return (1); } } + /* loop through the file names */ for (k = 0; k < argc; k++) { if (argv[k][0] == '-' && argv[k][1] == '\0') { @@ -416,45 +421,45 @@ main(int argc, char *argv[]) for (i = 0; i < (MAXPATHLEN-3) && (*cp = argv[k][i]); i++) if (*cp++ == '/') sep = i; if ((infile = open(filename, 0)) < 0) { - fprintf(stderr, gettext( - "pack: %s: cannot open: "), filename); + (void) fprintf(stderr, gettext( + "pack: %s: cannot open: "), filename); perror(""); continue; } if (i >= (MAXPATHLEN-3) || (i-sep) > (max_name - 1)) { - fprintf(stderr, gettext( - "pack: %s: file name too long\n"), argv[k]); + (void) fprintf(stderr, gettext( + "pack: %s: file name too long\n"), argv[k]); continue; } - fstat(infile, &status); + (void) fstat(infile, &status); if (S_ISDIR(status.st_mode)) { - fprintf(stderr, gettext( - "pack: %s: cannot pack a directory\n"), - argv[k]); + (void) fprintf(stderr, gettext( + "pack: %s: cannot pack a directory\n"), + argv[k]); goto closein; } if (status.st_size == 0) { - fprintf(stderr, gettext( - "pack: %s: cannot pack a zero length file\n"), - argv[k]); + (void) fprintf(stderr, gettext( + "pack: %s: cannot pack a zero length file\n"), + argv[k]); goto closein; } if (status.st_nlink != 1) { - fprintf(stderr, gettext( - "pack: %s: has links\n"), - argv[k]); + (void) fprintf(stderr, gettext( + "pack: %s: has links\n"), + argv[k]); goto closein; } *cp++ = SUF0; *cp++ = SUF1; *cp = '\0'; if (stat(filename, &ostatus) != -1) { - fprintf(stderr, gettext( - "pack: %s: already exists\n"), filename); + (void) fprintf(stderr, gettext( + "pack: %s: already exists\n"), filename); goto closein; } - - if ((outfile = creat(filename, status.st_mode)) < 0) { - fprintf(stderr, gettext( - "pack: %s: cannot create: "), filename); + if ((outfile = creat(filename, status.st_mode | O_RDONLY)) + < 0) { + (void) fprintf(stderr, gettext( + "pack: %s: cannot create: "), filename); perror(""); goto closein; } @@ -462,155 +467,126 @@ main(int argc, char *argv[]) error = facl_get(infile, ACL_NO_TRIVIAL, &aclp); if (error != 0) { - fprintf(stderr, gettext( + (void) fprintf(stderr, gettext( "pack: %s: cannot retrieve ACL: %s\n"), argv[k], acl_strerror(error)); } - if (packfile(argv[k]) && - ((pathconf(argv[k], _PC_XATTR_EXISTS) != 1) || - (mv_xattrs(infile, outfile, - argv[k], 0) == 0))) { - if (unlink(argv[k]) != 0) { - fprintf(stderr, gettext( - "pack: %s: cannot unlink: "), - argv[k]); - perror(""); + + if (packfile(argv[k])) { + if (pathconf(argv[k], _PC_XATTR_EXISTS) == 1) + xattr_exist = 1; + if (saflg && sysattr_support(argv[k], + _PC_SATTR_EXISTS) == 1) + sattr_exist = 1; + if (sattr_exist || xattr_exist) { + if (mv_xattrs(progname, argv[k], filename, + sattr_exist, 0) != 0) { + /* Move attributes back ... */ + xattr_exist = 0; + sattr_exist = 0; + if (pathconf(filename, + _PC_XATTR_EXISTS) == 1) + xattr_exist = 1; + if (saflg && sysattr_support(filename, + _PC_SATTR_EXISTS) == 1) + sattr_exist = 1; + if (xattr_exist || sattr_exist) { + (void) mv_xattrs(progname, + filename, argv[k], + sattr_exist, 1); + (void) unlink(filename); + goto out; + } + } else { + errno = 0; + if (unlink(argv[k]) != 0) { + (void) fprintf(stderr, gettext( + "pack: %s :cannot unlink:"), + argv[k]); + if (errno == EPERM) + perror("No permission"); + else + perror(""); + } + } + } else { + errno = 0; + if (unlink(argv[k]) != 0) { + (void) fprintf(stderr, gettext( + "pack: %s :cannot unlink"), + argv[k]); + if (errno == EPERM) + perror("No permission"); + else + perror(""); + } } - printf(gettext( - "pack: %s: %.1f%% Compression\n"), - argv[k], - ((double)(-outsize+(insize.lint.lng))/(double)insize.lint.lng)*100); + (void) printf(gettext( + "pack: %s: %.1f%% Compression\n"), + argv[k], + ((double)(-outsize+(insize.lint.lng))/ + (double)insize.lint.lng)*100); /* output statistics */ if (vflag) { - printf(gettext("\tfrom %ld to %ld bytes\n"), - insize.lint.lng, outsize); - printf(gettext( - "\tHuffman tree has %d levels below root\n"), - maxlev); - printf(gettext( - "\t%d distinct bytes in input\n"), - diffbytes); - printf(gettext( - "\tdictionary overhead = %ld bytes\n"), - dictsize); - printf(gettext( + (void) printf(gettext( + "\tfrom %ld to %ld bytes\n"), + insize.lint.lng, outsize); + (void) printf(gettext( + "\tHuffman tree has %d levels below " + "root\n"), maxlev); + (void) printf(gettext( + "\t%d distinct bytes in input\n"), + diffbytes); + (void) printf(gettext( + "\tdictionary overhead = %ld bytes\n"), + dictsize); + (void) printf(gettext( "\teffective entropy = %.2f bits/byte\n"), - ((double)outsize / (double)insize.lint.lng) * 8); - printf(gettext( + ((double)outsize / (double)insize.lint.lng) + * 8); + (void) printf(gettext( "\tasymptotic entropy = %.2f bits/byte\n"), - ((double)(outsize-dictsize) / - (double)insize.lint.lng) * 8); + ((double)(outsize-dictsize) / + (double)insize.lint.lng) * 8); } + u_times.actime = status.st_atime; u_times.modtime = status.st_mtime; if (utime(filename, &u_times) != 0) { errflg++; - fprintf(stderr, - gettext( - "pack: cannot change times on %s: "), - filename); + (void) fprintf(stderr, + gettext( + "pack: cannot change times on %s: "), + filename); perror(""); } if (chmod(filename, status.st_mode) != 0) { errflg++; - fprintf(stderr, - gettext( - "pack: can't change mode to %o on %s: "), - status.st_mode, filename); + (void) fprintf(stderr, + gettext( + "pack: can't change mode to %o on %s: "), + status.st_mode, filename); perror(""); } - chown(filename, status.st_uid, status.st_gid); + (void) chown(filename, status.st_uid, status.st_gid); if (aclp && (facl_set(outfile, aclp) < 0)) { - fprintf(stderr, gettext( + (void) fprintf(stderr, gettext( "pack: %s: failed to set acl entries\n"), filename); perror(""); } if (!errflg) fcount--; /* success after all */ - } else { - if (pathconf(filename, _PC_XATTR_EXISTS) == 1) { - (void) mv_xattrs(outfile, infile, filename, 1); - } - unlink(filename); - } + } +out: if (aclp) { acl_free(aclp); aclp = NULL; } -closein: close(outfile); - close(infile); +closein: (void) close(outfile); + (void) close(infile); } return (fcount); } - -/* - * mv_xattrs - move (via renameat) all of the extended attributes - * associated with the file referenced by infd to the file - * referenced by outfd. The infile and silent arguments are - * provided for error message processing. This function - * returns 0 on success and -1 on error. - */ -static int -mv_xattrs(int infd, int outfd, char *infile, int silent) -{ - int indfd, outdfd, tmpfd; - DIR *dirp = NULL; - struct dirent *dp = NULL; - int error = 0; - char *etext; - - indfd = outdfd = tmpfd = -1; - - if ((indfd = openat(infd, ".", O_RDONLY|O_XATTR)) == -1) { - etext = gettext("cannot open source"); - error = -1; - goto out; - } - - if ((outdfd = openat(outfd, ".", O_RDONLY|O_XATTR)) == -1) { - etext = gettext("cannot open target"); - error = -1; - goto out; - } - - if ((tmpfd = dup(indfd)) == -1) { - etext = gettext("cannot dup descriptor"); - error = -1; - goto out; - - } - if ((dirp = fdopendir(tmpfd)) == NULL) { - etext = gettext("cannot access source"); - error = -1; - goto out; - } - - while (dp = readdir(dirp)) { - if ((dp->d_name[0] == '.' && dp->d_name[1] == '\0') || - (dp->d_name[0] == '.' && dp->d_name[1] == '.' && - dp->d_name[2] == '\0')) - continue; - if ((renameat(indfd, dp->d_name, outdfd, dp->d_name)) == -1) { - etext = dp->d_name; - error = -1; - goto out; - } - } -out: - if (error == -1 && silent == 0) { - fprintf(stderr, gettext( - "pack: %s: cannot move extended attributes, "), - infile); - perror(etext); - } - if (dirp) - closedir(dirp); - if (indfd != -1) - close(indfd); - if (outdfd != -1) - close(outdfd); - return (error); -} |