17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5f0a2d94fSmarks * Common Development and Distribution License (the "License"). 6f0a2d94fSmarks * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 227c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 237c478bd9Sstevel@tonic-gate 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate /* 26*da6c28aaSamw * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 277c478bd9Sstevel@tonic-gate * Use is subject to license terms. 287c478bd9Sstevel@tonic-gate */ 297c478bd9Sstevel@tonic-gate 30*da6c28aaSamw #pragma ident "%Z%%M% %I% %E% SMI" 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate /* 337c478bd9Sstevel@tonic-gate * Huffman decompressor 347c478bd9Sstevel@tonic-gate * Usage: pcat filename... 357c478bd9Sstevel@tonic-gate * or unpack filename... 367c478bd9Sstevel@tonic-gate */ 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #include <setjmp.h> 397c478bd9Sstevel@tonic-gate #include <signal.h> 407c478bd9Sstevel@tonic-gate #include <locale.h> 417c478bd9Sstevel@tonic-gate #include <utime.h> 427c478bd9Sstevel@tonic-gate #include <sys/param.h> 43fa9e4066Sahrens #include <sys/acl.h> 44fa9e4066Sahrens #include <aclutils.h> 45*da6c28aaSamw #include <libcmdutils.h> 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate static struct utimbuf u_times; 487c478bd9Sstevel@tonic-gate static jmp_buf env; 497c478bd9Sstevel@tonic-gate static struct stat status; 507c478bd9Sstevel@tonic-gate static char *argv0, *argvk; 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate /* rmflg, when set it's ok to rm arvk file on caught signals */ 537c478bd9Sstevel@tonic-gate static int rmflg = 0; 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate #define SUF0 '.' 567c478bd9Sstevel@tonic-gate #define SUF1 'z' 577c478bd9Sstevel@tonic-gate #define US 037 587c478bd9Sstevel@tonic-gate #define RS 036 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate /* variables associated with i/o */ 617c478bd9Sstevel@tonic-gate static char filename[MAXPATHLEN]; 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate static short infile; 647c478bd9Sstevel@tonic-gate static short outfile; 657c478bd9Sstevel@tonic-gate static short inleft; 667c478bd9Sstevel@tonic-gate static short is_eof = 0; 677c478bd9Sstevel@tonic-gate static char *inp; 687c478bd9Sstevel@tonic-gate static char *outp; 697c478bd9Sstevel@tonic-gate static char inbuff[BUFSIZ]; 707c478bd9Sstevel@tonic-gate static char outbuff[BUFSIZ]; 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate /* the dictionary */ 737c478bd9Sstevel@tonic-gate static long origsize; 747c478bd9Sstevel@tonic-gate static short maxlev; 757c478bd9Sstevel@tonic-gate static short intnodes[25]; 767c478bd9Sstevel@tonic-gate static char *tree[25]; 777c478bd9Sstevel@tonic-gate static char characters[256]; 787c478bd9Sstevel@tonic-gate static char *eof; 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate static void putch(char c); 817c478bd9Sstevel@tonic-gate static int expand(); 827c478bd9Sstevel@tonic-gate static int decode(); 837c478bd9Sstevel@tonic-gate static int getwdsize(); 847c478bd9Sstevel@tonic-gate static int getch(); 857c478bd9Sstevel@tonic-gate static int getdict(); 86*da6c28aaSamw 87*da6c28aaSamw /* Extended system attribute support */ 88*da6c28aaSamw 89*da6c28aaSamw static int saflg = 0; 90*da6c28aaSamw 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate /* read in the dictionary portion and build decoding structures */ 937c478bd9Sstevel@tonic-gate /* return 1 if successful, 0 otherwise */ 947c478bd9Sstevel@tonic-gate int 957c478bd9Sstevel@tonic-gate getdict() 967c478bd9Sstevel@tonic-gate { 977c478bd9Sstevel@tonic-gate register int c, i, nchildren; 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate /* 1007c478bd9Sstevel@tonic-gate * check two-byte header 1017c478bd9Sstevel@tonic-gate * get size of original file, 1027c478bd9Sstevel@tonic-gate * get number of levels in maxlev, 1037c478bd9Sstevel@tonic-gate * get number of leaves on level i in intnodes[i], 1047c478bd9Sstevel@tonic-gate * set tree[i] to point to leaves for level i 1057c478bd9Sstevel@tonic-gate */ 1067c478bd9Sstevel@tonic-gate eof = &characters[0]; 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate inbuff[6] = 25; 1097c478bd9Sstevel@tonic-gate inleft = read(infile, &inbuff[0], BUFSIZ); 1107c478bd9Sstevel@tonic-gate if (inleft < 0) { 1117c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1127c478bd9Sstevel@tonic-gate "%s: %s: read error: "), argv0, filename); 1137c478bd9Sstevel@tonic-gate perror(""); 1147c478bd9Sstevel@tonic-gate return (0); 1157c478bd9Sstevel@tonic-gate } 1167c478bd9Sstevel@tonic-gate if (inbuff[0] != US) 1177c478bd9Sstevel@tonic-gate goto goof; 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate if (inbuff[1] == US) { /* oldstyle packing */ 1207c478bd9Sstevel@tonic-gate if (setjmp(env)) 1217c478bd9Sstevel@tonic-gate return (0); 1227c478bd9Sstevel@tonic-gate return (expand()); 1237c478bd9Sstevel@tonic-gate } 1247c478bd9Sstevel@tonic-gate if (inbuff[1] != RS) 1257c478bd9Sstevel@tonic-gate goto goof; 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate inp = &inbuff[2]; 1287c478bd9Sstevel@tonic-gate origsize = 0; 1297c478bd9Sstevel@tonic-gate for (i = 0; i < 4; i++) 1307c478bd9Sstevel@tonic-gate origsize = origsize*256 + ((*inp++) & 0377); 1317c478bd9Sstevel@tonic-gate maxlev = *inp++ & 0377; 1327c478bd9Sstevel@tonic-gate if (maxlev > 24) { 1337c478bd9Sstevel@tonic-gate goof: (void) fprintf(stderr, gettext( 1347c478bd9Sstevel@tonic-gate "%s: %s: not in packed format\n"), argv0, filename); 1357c478bd9Sstevel@tonic-gate return (0); 1367c478bd9Sstevel@tonic-gate } 1377c478bd9Sstevel@tonic-gate for (i = 1; i <= maxlev; i++) 1387c478bd9Sstevel@tonic-gate intnodes[i] = *inp++ & 0377; 1397c478bd9Sstevel@tonic-gate for (i = 1; i <= maxlev; i++) { 1407c478bd9Sstevel@tonic-gate tree[i] = eof; 1417c478bd9Sstevel@tonic-gate for (c = intnodes[i]; c > 0; c--) { 1427c478bd9Sstevel@tonic-gate if (eof >= &characters[255]) 1437c478bd9Sstevel@tonic-gate goto goof; 1447c478bd9Sstevel@tonic-gate *eof++ = *inp++; 1457c478bd9Sstevel@tonic-gate } 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate *eof++ = *inp++; 1487c478bd9Sstevel@tonic-gate intnodes[maxlev] += 2; 1497c478bd9Sstevel@tonic-gate inleft -= inp - &inbuff[0]; 1507c478bd9Sstevel@tonic-gate if (inleft < 0) 1517c478bd9Sstevel@tonic-gate goto goof; 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate /* 1547c478bd9Sstevel@tonic-gate * convert intnodes[i] to be number of 1557c478bd9Sstevel@tonic-gate * internal nodes possessed by level i 1567c478bd9Sstevel@tonic-gate */ 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate nchildren = 0; 1597c478bd9Sstevel@tonic-gate for (i = maxlev; i >= 1; i--) { 1607c478bd9Sstevel@tonic-gate c = intnodes[i]; 1617c478bd9Sstevel@tonic-gate intnodes[i] = nchildren /= 2; 1627c478bd9Sstevel@tonic-gate nchildren += c; 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate return (decode()); 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate /* unpack the file */ 1687c478bd9Sstevel@tonic-gate /* return 1 if successful, 0 otherwise */ 1697c478bd9Sstevel@tonic-gate int 1707c478bd9Sstevel@tonic-gate decode() 1717c478bd9Sstevel@tonic-gate { 1727c478bd9Sstevel@tonic-gate register int bitsleft, c, i; 1737c478bd9Sstevel@tonic-gate int j, lev, cont = 1; 1747c478bd9Sstevel@tonic-gate char *p; 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate outp = &outbuff[0]; 1777c478bd9Sstevel@tonic-gate lev = 1; 1787c478bd9Sstevel@tonic-gate i = 0; 1797c478bd9Sstevel@tonic-gate while (cont) { 1807c478bd9Sstevel@tonic-gate if (inleft <= 0) { 1817c478bd9Sstevel@tonic-gate inleft = read(infile, inp = &inbuff[0], BUFSIZ); 1827c478bd9Sstevel@tonic-gate if (inleft < 0) { 1837c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 1847c478bd9Sstevel@tonic-gate "%s: %s: read error: "), 1857c478bd9Sstevel@tonic-gate argv0, filename); 1867c478bd9Sstevel@tonic-gate perror(""); 1877c478bd9Sstevel@tonic-gate return (0); 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate if (--inleft < 0) { 1917c478bd9Sstevel@tonic-gate uggh: (void) fprintf(stderr, gettext( 1927c478bd9Sstevel@tonic-gate "%s: %s: unpacking error\n"), 1937c478bd9Sstevel@tonic-gate argv0, filename); 1947c478bd9Sstevel@tonic-gate return (0); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate c = *inp++; 1977c478bd9Sstevel@tonic-gate bitsleft = 8; 1987c478bd9Sstevel@tonic-gate while (--bitsleft >= 0) { 1997c478bd9Sstevel@tonic-gate i *= 2; 2007c478bd9Sstevel@tonic-gate if (c & 0200) 2017c478bd9Sstevel@tonic-gate i++; 2027c478bd9Sstevel@tonic-gate c <<= 1; 2037c478bd9Sstevel@tonic-gate if ((j = i - intnodes[lev]) >= 0) { 2047c478bd9Sstevel@tonic-gate p = &tree[lev][j]; 2057c478bd9Sstevel@tonic-gate if (p == eof) { 2067c478bd9Sstevel@tonic-gate c = outp - &outbuff[0]; 207*da6c28aaSamw if (write(outfile, &outbuff[0], c) 208*da6c28aaSamw != c) { 209*da6c28aaSamw wrerr: (void) fprintf(stderr, 210*da6c28aaSamw gettext( 2117c478bd9Sstevel@tonic-gate "%s: %s: write error: "), 2127c478bd9Sstevel@tonic-gate argv0, argvk); 2137c478bd9Sstevel@tonic-gate perror(""); 2147c478bd9Sstevel@tonic-gate return (0); 2157c478bd9Sstevel@tonic-gate } 2167c478bd9Sstevel@tonic-gate origsize -= c; 2177c478bd9Sstevel@tonic-gate if (origsize != 0) 2187c478bd9Sstevel@tonic-gate goto uggh; 2197c478bd9Sstevel@tonic-gate return (1); 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate *outp++ = *p; 2227c478bd9Sstevel@tonic-gate if (outp == &outbuff[BUFSIZ]) { 2237c478bd9Sstevel@tonic-gate if (write(outfile, outp = &outbuff[0], 2247c478bd9Sstevel@tonic-gate BUFSIZ) != BUFSIZ) 2257c478bd9Sstevel@tonic-gate goto wrerr; 2267c478bd9Sstevel@tonic-gate origsize -= BUFSIZ; 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate lev = 1; 2297c478bd9Sstevel@tonic-gate i = 0; 2307c478bd9Sstevel@tonic-gate } else 2317c478bd9Sstevel@tonic-gate lev++; 2327c478bd9Sstevel@tonic-gate } 2337c478bd9Sstevel@tonic-gate } 2347c478bd9Sstevel@tonic-gate return (1); /* we won't get here , but lint is pleased */ 2357c478bd9Sstevel@tonic-gate } 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate int 2387c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 2397c478bd9Sstevel@tonic-gate { 2407c478bd9Sstevel@tonic-gate extern int optind; 2417c478bd9Sstevel@tonic-gate int i, k; 242fa9e4066Sahrens int error; 2437c478bd9Sstevel@tonic-gate int sep, errflg = 0, pcat = 0; 2447c478bd9Sstevel@tonic-gate register char *p1, *cp; 2457c478bd9Sstevel@tonic-gate int fcount = 0; /* failure count */ 2467c478bd9Sstevel@tonic-gate int max_name; 2477c478bd9Sstevel@tonic-gate void onsig(int); 248f0a2d94fSmarks acl_t *aclp = NULL; 249*da6c28aaSamw int c; 250*da6c28aaSamw char *progname; 251*da6c28aaSamw int sattr_exist = 0; 252*da6c28aaSamw int xattr_exist = 0; 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate if (signal(SIGHUP, SIG_IGN) != SIG_IGN) 2557c478bd9Sstevel@tonic-gate #ifdef __STDC__ 256*da6c28aaSamw (void) signal((int)SIGHUP, onsig); 2577c478bd9Sstevel@tonic-gate #else 258*da6c28aaSamw (void) signal((int)SIGHUP, onsig); 2597c478bd9Sstevel@tonic-gate #endif 2607c478bd9Sstevel@tonic-gate if (signal(SIGINT, SIG_IGN) != SIG_IGN) 2617c478bd9Sstevel@tonic-gate #ifdef __STDC__ 262*da6c28aaSamw (void) signal((int)SIGINT, onsig); 2637c478bd9Sstevel@tonic-gate #else 264*da6c28aaSamw (void) signal((int)SIGINT, onsig); 2657c478bd9Sstevel@tonic-gate #endif 2667c478bd9Sstevel@tonic-gate if (signal(SIGTERM, SIG_IGN) != SIG_IGN) 2677c478bd9Sstevel@tonic-gate #ifdef __STDC__ 268*da6c28aaSamw (void) signal((int)SIGTERM, onsig); 2697c478bd9Sstevel@tonic-gate #else 270*da6c28aaSamw (void) signal(SIGTERM, onsig); 2717c478bd9Sstevel@tonic-gate #endif 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 2747c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 2757c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 2767c478bd9Sstevel@tonic-gate #endif 2777c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 2787c478bd9Sstevel@tonic-gate 279*da6c28aaSamw if (progname = strrchr(argv[0], '/')) 280*da6c28aaSamw ++progname; 281*da6c28aaSamw else 282*da6c28aaSamw progname = argv[0]; 283*da6c28aaSamw 2847c478bd9Sstevel@tonic-gate p1 = *argv; 285*da6c28aaSamw while (*p1++) { }; /* Point p1 to end of argv[0] string */ 2867c478bd9Sstevel@tonic-gate while (--p1 >= *argv) 2877c478bd9Sstevel@tonic-gate if (*p1 == '/')break; 2887c478bd9Sstevel@tonic-gate *argv = p1 + 1; 2897c478bd9Sstevel@tonic-gate argv0 = argv[0]; 2907c478bd9Sstevel@tonic-gate if (**argv == 'p')pcat++; /* User entered pcat (or /xx/xx/pcat) */ 2917c478bd9Sstevel@tonic-gate 292*da6c28aaSamw while ((c = getopt(argc, argv, "/")) != EOF) { 293*da6c28aaSamw if (c == '/') { 294*da6c28aaSamw if (pcat) 2957c478bd9Sstevel@tonic-gate ++errflg; 296*da6c28aaSamw else 297*da6c28aaSamw saflg++; 298*da6c28aaSamw } else 299*da6c28aaSamw ++errflg; 300*da6c28aaSamw } 3017c478bd9Sstevel@tonic-gate /* 3027c478bd9Sstevel@tonic-gate * Check for invalid option. Also check for missing 3037c478bd9Sstevel@tonic-gate * file operand, ie: "unpack" or "pcat". 3047c478bd9Sstevel@tonic-gate */ 3057c478bd9Sstevel@tonic-gate argc -= optind; 3067c478bd9Sstevel@tonic-gate argv = &argv[optind]; 3077c478bd9Sstevel@tonic-gate if (errflg || argc < 1) { 308*da6c28aaSamw if (!pcat) 309*da6c28aaSamw (void) fprintf(stderr, 310*da6c28aaSamw gettext("usage: %s [-/] file...\n"), argv0); 311*da6c28aaSamw else 312*da6c28aaSamw (void) fprintf(stderr, gettext("usage: %s file...\n"), 313*da6c28aaSamw argv0); 314*da6c28aaSamw 3157c478bd9Sstevel@tonic-gate if (argc < 1) { 3167c478bd9Sstevel@tonic-gate /* 3177c478bd9Sstevel@tonic-gate * return 1 for usage error when no file was specified 3187c478bd9Sstevel@tonic-gate */ 3197c478bd9Sstevel@tonic-gate return (1); 3207c478bd9Sstevel@tonic-gate } 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate /* loop through the file names */ 3237c478bd9Sstevel@tonic-gate for (k = 0; k < argc; k++) { 3247c478bd9Sstevel@tonic-gate fcount++; /* expect the worst */ 3257c478bd9Sstevel@tonic-gate if (errflg) { 3267c478bd9Sstevel@tonic-gate /* 3277c478bd9Sstevel@tonic-gate * invalid option; just count the number of files not 3287c478bd9Sstevel@tonic-gate * unpacked 3297c478bd9Sstevel@tonic-gate */ 3307c478bd9Sstevel@tonic-gate continue; 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate /* remove any .z suffix the user may have added */ 3337c478bd9Sstevel@tonic-gate for (cp = argv[k]; *cp != '\0'; ++cp) 3347c478bd9Sstevel@tonic-gate ; 3357c478bd9Sstevel@tonic-gate if (cp[-1] == SUF1 && cp[-2] == SUF0) { 3367c478bd9Sstevel@tonic-gate *cp-- = '\0'; *cp-- = '\0'; *cp = '\0'; 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate sep = -1; 3397c478bd9Sstevel@tonic-gate cp = filename; 3407c478bd9Sstevel@tonic-gate argvk = argv[k]; 3417c478bd9Sstevel@tonic-gate /* copy argv[k] to filename and count chars in base name */ 3427c478bd9Sstevel@tonic-gate for (i = 0; i < (MAXPATHLEN-3) && (*cp = argvk[i]); i++) 3437c478bd9Sstevel@tonic-gate if (*cp++ == '/') 3447c478bd9Sstevel@tonic-gate sep = i; 3457c478bd9Sstevel@tonic-gate /* add .z suffix to filename */ 3467c478bd9Sstevel@tonic-gate *cp++ = SUF0; 3477c478bd9Sstevel@tonic-gate *cp++ = SUF1; 3487c478bd9Sstevel@tonic-gate *cp = '\0'; 3497c478bd9Sstevel@tonic-gate if ((infile = open(filename, O_RDONLY)) == -1) { 3507c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 3517c478bd9Sstevel@tonic-gate "%s: %s: cannot open: "), 3527c478bd9Sstevel@tonic-gate argv0, filename); 3537c478bd9Sstevel@tonic-gate perror(""); 3547c478bd9Sstevel@tonic-gate goto done; 3557c478bd9Sstevel@tonic-gate } 3567c478bd9Sstevel@tonic-gate if (pcat) 3577c478bd9Sstevel@tonic-gate outfile = 1; /* standard output */ 3587c478bd9Sstevel@tonic-gate else { 359fa9e4066Sahrens 360fa9e4066Sahrens error = facl_get(infile, ACL_NO_TRIVIAL, &aclp); 361fa9e4066Sahrens if (error != 0) { 362fa9e4066Sahrens (void) printf(gettext( 363fa9e4066Sahrens "%s: %s: cannot retrieve ACL : %s\n"), 364fa9e4066Sahrens argv0, filename, acl_strerror(error)); 365fa9e4066Sahrens } 366fa9e4066Sahrens 3677c478bd9Sstevel@tonic-gate max_name = pathconf(filename, _PC_NAME_MAX); 3687c478bd9Sstevel@tonic-gate if (max_name == -1) { 3697c478bd9Sstevel@tonic-gate /* no limit on length of filename */ 3707c478bd9Sstevel@tonic-gate max_name = _POSIX_NAME_MAX; 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate if (i >= (MAXPATHLEN-1) || (i - sep - 1) > max_name) { 3737c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 3747c478bd9Sstevel@tonic-gate "%s: %s: file name too long\n"), 3757c478bd9Sstevel@tonic-gate argv0, argvk); 3767c478bd9Sstevel@tonic-gate goto done; 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate if (stat(argvk, &status) != -1) { 3797c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 3807c478bd9Sstevel@tonic-gate "%s: %s: already exists\n"), 3817c478bd9Sstevel@tonic-gate argv0, argvk); 3827c478bd9Sstevel@tonic-gate goto done; 3837c478bd9Sstevel@tonic-gate } 3847c478bd9Sstevel@tonic-gate (void) fstat(infile, &status); 3857c478bd9Sstevel@tonic-gate if (status.st_nlink != 1) { 3867c478bd9Sstevel@tonic-gate (void) printf(gettext( 3877c478bd9Sstevel@tonic-gate "%s: %s: Warning: file has links\n"), 3887c478bd9Sstevel@tonic-gate argv0, filename); 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate if ((outfile = creat(argvk, status.st_mode)) == -1) { 3917c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 3927c478bd9Sstevel@tonic-gate "%s: %s: cannot create: "), 3937c478bd9Sstevel@tonic-gate argv0, argvk); 3947c478bd9Sstevel@tonic-gate perror(""); 3957c478bd9Sstevel@tonic-gate goto done; 3967c478bd9Sstevel@tonic-gate } 3977c478bd9Sstevel@tonic-gate rmflg = 1; 3987c478bd9Sstevel@tonic-gate } 3997c478bd9Sstevel@tonic-gate 400*da6c28aaSamw if (getdict()) { /* unpack */ 401*da6c28aaSamw if (pathconf(filename, _PC_XATTR_EXISTS) == 1) 402*da6c28aaSamw xattr_exist = 1; 403*da6c28aaSamw if (saflg && sysattr_support(filename, 404*da6c28aaSamw _PC_SATTR_EXISTS) == 1) 405*da6c28aaSamw sattr_exist = 1; 406*da6c28aaSamw if (pcat || xattr_exist || sattr_exist) { 407*da6c28aaSamw if (mv_xattrs(progname, filename, argv[k], 408*da6c28aaSamw sattr_exist, 0) 409*da6c28aaSamw != 0) { 410*da6c28aaSamw /* Move attributes back ... */ 411*da6c28aaSamw xattr_exist = 0; 412*da6c28aaSamw sattr_exist = 0; 413*da6c28aaSamw if (pathconf(argvk, _PC_XATTR_EXISTS) 414*da6c28aaSamw == 1) 415*da6c28aaSamw xattr_exist = 1; 416*da6c28aaSamw if (saflg && sysattr_support(argvk, 417*da6c28aaSamw _PC_SATTR_EXISTS) == 1) 418*da6c28aaSamw sattr_exist = 1; 419*da6c28aaSamw if (!pcat && (xattr_exist || 420*da6c28aaSamw sattr_exist)) { 421*da6c28aaSamw (void) mv_xattrs(progname, 422*da6c28aaSamw argv[k], filename, 423*da6c28aaSamw sattr_exist, 1); 424*da6c28aaSamw (void) unlink(argvk); 425*da6c28aaSamw goto done; 426*da6c28aaSamw } 427*da6c28aaSamw } else { 428*da6c28aaSamw if (!pcat) 429*da6c28aaSamw (void) unlink(filename); 430*da6c28aaSamw } 431*da6c28aaSamw } else if (!pcat) 432*da6c28aaSamw (void) unlink(filename); 433*da6c28aaSamw 4347c478bd9Sstevel@tonic-gate if (!pcat) { 435*da6c28aaSamw (void) printf(gettext("%s: %s: unpacked\n"), 436*da6c28aaSamw argv0, argvk); 4377c478bd9Sstevel@tonic-gate /* 4387c478bd9Sstevel@tonic-gate * preserve acc & mod dates 4397c478bd9Sstevel@tonic-gate */ 4407c478bd9Sstevel@tonic-gate u_times.actime = status.st_atime; 4417c478bd9Sstevel@tonic-gate u_times.modtime = status.st_mtime; 4427c478bd9Sstevel@tonic-gate if (utime(argvk, &u_times) != 0) { 4437c478bd9Sstevel@tonic-gate errflg++; 4447c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 4457c478bd9Sstevel@tonic-gate "%s: cannot change times on %s: "), 4467c478bd9Sstevel@tonic-gate argv0, argvk); 4477c478bd9Sstevel@tonic-gate perror(""); 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate if (chmod(argvk, status.st_mode) != 0) { 4507c478bd9Sstevel@tonic-gate errflg++; 4517c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 4527c478bd9Sstevel@tonic-gate "%s: cannot change mode to %o on %s: "), 4537c478bd9Sstevel@tonic-gate argv0, (uint_t)status.st_mode, 4547c478bd9Sstevel@tonic-gate argvk); 4557c478bd9Sstevel@tonic-gate perror(""); 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate (void) chown(argvk, 4587c478bd9Sstevel@tonic-gate status.st_uid, status.st_gid); 459fa9e4066Sahrens if (aclp && (facl_set(outfile, aclp) < 0)) { 460fa9e4066Sahrens (void) printf(gettext("%s: cannot " 461fa9e4066Sahrens "set ACL on %s: "), argv0, argvk); 462fa9e4066Sahrens perror(""); 463fa9e4066Sahrens } 464fa9e4066Sahrens 4657c478bd9Sstevel@tonic-gate rmflg = 0; 4667c478bd9Sstevel@tonic-gate } 4677c478bd9Sstevel@tonic-gate if (!errflg) 4687c478bd9Sstevel@tonic-gate fcount--; /* success after all */ 4697c478bd9Sstevel@tonic-gate } 4707c478bd9Sstevel@tonic-gate done: (void) close(infile); 4717c478bd9Sstevel@tonic-gate if (!pcat) 4727c478bd9Sstevel@tonic-gate (void) close(outfile); 473fa9e4066Sahrens 474f0a2d94fSmarks if (aclp) { 475fa9e4066Sahrens acl_free(aclp); 476f0a2d94fSmarks aclp = NULL; 477f0a2d94fSmarks } 4787c478bd9Sstevel@tonic-gate } 4797c478bd9Sstevel@tonic-gate return (fcount); 4807c478bd9Sstevel@tonic-gate } 4817c478bd9Sstevel@tonic-gate 4827c478bd9Sstevel@tonic-gate /* 4837c478bd9Sstevel@tonic-gate * This code is for unpacking files that 4847c478bd9Sstevel@tonic-gate * were packed using the previous algorithm. 4857c478bd9Sstevel@tonic-gate */ 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate static int Tree[1024]; 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate /* return 1 if successful, 0 otherwise */ 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate int 4927c478bd9Sstevel@tonic-gate expand() 4937c478bd9Sstevel@tonic-gate { 4947c478bd9Sstevel@tonic-gate int tp, bit; 4957c478bd9Sstevel@tonic-gate short word; 4967c478bd9Sstevel@tonic-gate int keysize, i, *t; 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate outp = outbuff; 4997c478bd9Sstevel@tonic-gate inp = &inbuff[2]; 5007c478bd9Sstevel@tonic-gate inleft -= 2; 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate origsize = ((long)(unsigned)getwdsize())*256*256; 5037c478bd9Sstevel@tonic-gate origsize += (unsigned)getwdsize(); 5047c478bd9Sstevel@tonic-gate if (origsize == 0 || is_eof) { 5057c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 5067c478bd9Sstevel@tonic-gate "%s: %s: not in packed format\n"), 5077c478bd9Sstevel@tonic-gate argv0, filename); 5087c478bd9Sstevel@tonic-gate return (0); 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate t = Tree; 5117c478bd9Sstevel@tonic-gate for (keysize = getwdsize(); keysize--; ) { 5127c478bd9Sstevel@tonic-gate if ((i = getch()) == 0377) 5137c478bd9Sstevel@tonic-gate *t++ = getwdsize(); 5147c478bd9Sstevel@tonic-gate else { 5157c478bd9Sstevel@tonic-gate /* 5167c478bd9Sstevel@tonic-gate * reached EOF unexpectedly 5177c478bd9Sstevel@tonic-gate */ 5187c478bd9Sstevel@tonic-gate if (is_eof) { 5197c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 5207c478bd9Sstevel@tonic-gate "%s: %s: not in packed format\n"), 5217c478bd9Sstevel@tonic-gate argv0, filename); 5227c478bd9Sstevel@tonic-gate return (0); 5237c478bd9Sstevel@tonic-gate } 5247c478bd9Sstevel@tonic-gate *t++ = i & 0377; 5257c478bd9Sstevel@tonic-gate } 5267c478bd9Sstevel@tonic-gate } 5277c478bd9Sstevel@tonic-gate /* 5287c478bd9Sstevel@tonic-gate * reached EOF unexpectedly 5297c478bd9Sstevel@tonic-gate */ 5307c478bd9Sstevel@tonic-gate if (is_eof) { 5317c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 5327c478bd9Sstevel@tonic-gate "%s: %s: not in packed format\n"), 5337c478bd9Sstevel@tonic-gate argv0, filename); 5347c478bd9Sstevel@tonic-gate return (0); 5357c478bd9Sstevel@tonic-gate } 5367c478bd9Sstevel@tonic-gate 5377c478bd9Sstevel@tonic-gate 5387c478bd9Sstevel@tonic-gate bit = tp = 0; 5397c478bd9Sstevel@tonic-gate for (;;) { 5407c478bd9Sstevel@tonic-gate if (bit <= 0) { 5417c478bd9Sstevel@tonic-gate word = getwdsize(); 5427c478bd9Sstevel@tonic-gate /* 5437c478bd9Sstevel@tonic-gate * reached EOF unexpectedly 5447c478bd9Sstevel@tonic-gate */ 5457c478bd9Sstevel@tonic-gate if (word == 0 && is_eof && origsize > 0) { 5467c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 5477c478bd9Sstevel@tonic-gate "%s: %s: not in packed format\n"), 5487c478bd9Sstevel@tonic-gate argv0, filename); 5497c478bd9Sstevel@tonic-gate return (0); 5507c478bd9Sstevel@tonic-gate } 5517c478bd9Sstevel@tonic-gate bit = 16; 5527c478bd9Sstevel@tonic-gate } 5537c478bd9Sstevel@tonic-gate tp += Tree[tp + (word < 0)]; 5547c478bd9Sstevel@tonic-gate word <<= 1; 5557c478bd9Sstevel@tonic-gate bit--; 5567c478bd9Sstevel@tonic-gate if (Tree[tp] == 0) { 5577c478bd9Sstevel@tonic-gate putch(Tree[tp+1]); 5587c478bd9Sstevel@tonic-gate tp = 0; 5597c478bd9Sstevel@tonic-gate if ((origsize -= 1) == 0) { 5607c478bd9Sstevel@tonic-gate (void) write(outfile, outbuff, outp - outbuff); 5617c478bd9Sstevel@tonic-gate return (1); 5627c478bd9Sstevel@tonic-gate } 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate } 5657c478bd9Sstevel@tonic-gate } 5667c478bd9Sstevel@tonic-gate 5677c478bd9Sstevel@tonic-gate int 5687c478bd9Sstevel@tonic-gate getch() 5697c478bd9Sstevel@tonic-gate { 5707c478bd9Sstevel@tonic-gate if (inleft <= 0) { 5717c478bd9Sstevel@tonic-gate inleft = read(infile, inp = inbuff, BUFSIZ); 5727c478bd9Sstevel@tonic-gate if (inleft < 0) { 5737c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 5747c478bd9Sstevel@tonic-gate "%s: %s: read error: "), 5757c478bd9Sstevel@tonic-gate argv0, filename); 5767c478bd9Sstevel@tonic-gate perror(""); 5777c478bd9Sstevel@tonic-gate longjmp(env, 1); 5787c478bd9Sstevel@tonic-gate } else { /* reached EOF, report it */ 5797c478bd9Sstevel@tonic-gate if (inleft == 0) { 5807c478bd9Sstevel@tonic-gate is_eof = 1; 5817c478bd9Sstevel@tonic-gate return (EOF); 5827c478bd9Sstevel@tonic-gate } 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate inleft--; 5867c478bd9Sstevel@tonic-gate return (*inp++ & 0377); 5877c478bd9Sstevel@tonic-gate } 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate int 5907c478bd9Sstevel@tonic-gate getwdsize() 5917c478bd9Sstevel@tonic-gate { 5927c478bd9Sstevel@tonic-gate char c; 5937c478bd9Sstevel@tonic-gate int d; 5947c478bd9Sstevel@tonic-gate 5957c478bd9Sstevel@tonic-gate c = getch(); 5967c478bd9Sstevel@tonic-gate d = getch(); 5977c478bd9Sstevel@tonic-gate if (is_eof) 5987c478bd9Sstevel@tonic-gate return (0); 5997c478bd9Sstevel@tonic-gate d <<= 8; 6007c478bd9Sstevel@tonic-gate d |= c & 0377; 6017c478bd9Sstevel@tonic-gate return (d); 6027c478bd9Sstevel@tonic-gate } 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate void 6057c478bd9Sstevel@tonic-gate onsig(int sig) 6067c478bd9Sstevel@tonic-gate { 6077c478bd9Sstevel@tonic-gate /* could be running as unpack or pcat */ 6087c478bd9Sstevel@tonic-gate /* but rmflg is set only when running */ 6097c478bd9Sstevel@tonic-gate /* as unpack and only when file is */ 6107c478bd9Sstevel@tonic-gate /* created by unpack and not yet done */ 6117c478bd9Sstevel@tonic-gate if (rmflg == 1) 6127c478bd9Sstevel@tonic-gate (void) unlink(argvk); 613*da6c28aaSamw /* To quiet lint noise */ 614*da6c28aaSamw if (sig == SIGTERM || sig == SIGHUP || sig == SIGINT) 6157c478bd9Sstevel@tonic-gate exit(1); 6167c478bd9Sstevel@tonic-gate } 6177c478bd9Sstevel@tonic-gate 6187c478bd9Sstevel@tonic-gate void 6197c478bd9Sstevel@tonic-gate putch(char c) 6207c478bd9Sstevel@tonic-gate { 6217c478bd9Sstevel@tonic-gate int n; 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate *outp++ = c; 6247c478bd9Sstevel@tonic-gate if (outp == &outbuff[BUFSIZ]) { 6257c478bd9Sstevel@tonic-gate n = write(outfile, outp = outbuff, BUFSIZ); 6267c478bd9Sstevel@tonic-gate if (n < BUFSIZ) { 6277c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 6287c478bd9Sstevel@tonic-gate "%s: %s: write error: "), 6297c478bd9Sstevel@tonic-gate argv0, argvk); 6307c478bd9Sstevel@tonic-gate perror(""); 6317c478bd9Sstevel@tonic-gate longjmp(env, 2); 6327c478bd9Sstevel@tonic-gate } 6337c478bd9Sstevel@tonic-gate } 6347c478bd9Sstevel@tonic-gate } 635