summaryrefslogtreecommitdiff
path: root/usr/src/cmd/pack/pack.c
diff options
context:
space:
mode:
authoramw <none@none>2007-10-25 16:34:29 -0700
committeramw <none@none>2007-10-25 16:34:29 -0700
commitda6c28aaf62fa55f0fdb8004aa40f88f23bf53f0 (patch)
tree65be91fb78a6a66183197595333f2e8aafb4640a /usr/src/cmd/pack/pack.c
parente845e33dd0d1aea22db7edaa8c7d43955d24609b (diff)
downloadillumos-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.c326
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);
-}