15c51f124SMoriah Waterland /* 25c51f124SMoriah Waterland * CDDL HEADER START 35c51f124SMoriah Waterland * 45c51f124SMoriah Waterland * The contents of this file are subject to the terms of the 55c51f124SMoriah Waterland * Common Development and Distribution License (the "License"). 65c51f124SMoriah Waterland * You may not use this file except in compliance with the License. 75c51f124SMoriah Waterland * 85c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing. 105c51f124SMoriah Waterland * See the License for the specific language governing permissions 115c51f124SMoriah Waterland * and limitations under the License. 125c51f124SMoriah Waterland * 135c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each 145c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the 165c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying 175c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner] 185c51f124SMoriah Waterland * 195c51f124SMoriah Waterland * CDDL HEADER END 205c51f124SMoriah Waterland */ 215c51f124SMoriah Waterland 225c51f124SMoriah Waterland /* 235c51f124SMoriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 245c51f124SMoriah Waterland * Use is subject to license terms. 255c51f124SMoriah Waterland */ 265c51f124SMoriah Waterland 275c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 285c51f124SMoriah Waterland /* All Rights Reserved */ 295c51f124SMoriah Waterland 305c51f124SMoriah Waterland 315c51f124SMoriah Waterland 325c51f124SMoriah Waterland #include <stdio.h> 335c51f124SMoriah Waterland #include <limits.h> 345c51f124SMoriah Waterland #include <stdlib.h> 355c51f124SMoriah Waterland #include <unistd.h> 365c51f124SMoriah Waterland #include <utime.h> 375c51f124SMoriah Waterland #include <sys/types.h> 385c51f124SMoriah Waterland #include <sys/param.h> 395c51f124SMoriah Waterland #include <sys/stat.h> 405c51f124SMoriah Waterland #include <sys/statvfs.h> 415c51f124SMoriah Waterland #include <grp.h> 425c51f124SMoriah Waterland #include <pwd.h> 435c51f124SMoriah Waterland #include <errno.h> 445c51f124SMoriah Waterland #include <string.h> 455c51f124SMoriah Waterland #include <stdarg.h> 465c51f124SMoriah Waterland #include <fcntl.h> 475c51f124SMoriah Waterland #include <sys/mkdev.h> 485c51f124SMoriah Waterland #include "pkgstrct.h" 495c51f124SMoriah Waterland #include "pkglib.h" 505c51f124SMoriah Waterland #include "pkglibmsgs.h" 515c51f124SMoriah Waterland #include "pkglocale.h" 525c51f124SMoriah Waterland 535c51f124SMoriah Waterland #define WDMSK 0xFFFF 545c51f124SMoriah Waterland #define DATEFMT "%D %r" 555c51f124SMoriah Waterland #define LONG_BOUNDARY ((sizeof (unsigned long))-1) 565c51f124SMoriah Waterland #define CHUNK 1024*1024 575c51f124SMoriah Waterland 585c51f124SMoriah Waterland static char theErrBuf[PATH_MAX+512] = {'\0'}; 595c51f124SMoriah Waterland static char *theErrStr = NULL; 605c51f124SMoriah Waterland 615c51f124SMoriah Waterland /* checksum disable switch */ 625c51f124SMoriah Waterland static int enable_checksum = 1; 635c51f124SMoriah Waterland 645c51f124SMoriah Waterland /* attribute disable flag */ 655c51f124SMoriah Waterland static int disable_attributes = 0; 665c51f124SMoriah Waterland 675c51f124SMoriah Waterland /* non-ABI symlinks supported */ 685c51f124SMoriah Waterland static int nonabi_symlinks; 695c51f124SMoriah Waterland 705c51f124SMoriah Waterland /* 715c51f124SMoriah Waterland * forward declarations 725c51f124SMoriah Waterland */ 735c51f124SMoriah Waterland 745c51f124SMoriah Waterland static int clear_target(char *path, char *ftype, int is_a_dir); 755c51f124SMoriah Waterland 765c51f124SMoriah Waterland unsigned long compute_checksum(int *r_err, char *path); 775c51f124SMoriah Waterland 785c51f124SMoriah Waterland /* union used to generate checksum */ 795c51f124SMoriah Waterland typedef union hilo { 805c51f124SMoriah Waterland struct part { 815c51f124SMoriah Waterland uint16_t hi; 825c51f124SMoriah Waterland uint16_t lo; 835c51f124SMoriah Waterland } hl; 845c51f124SMoriah Waterland uint32_t lg; 855c51f124SMoriah Waterland } CHECKSUM_T; 865c51f124SMoriah Waterland 875c51f124SMoriah Waterland /*PRINTFLIKE1*/ 88*b46ec01aSok199659 static void 895c51f124SMoriah Waterland reperr(char *fmt, ...) 905c51f124SMoriah Waterland { 915c51f124SMoriah Waterland char *pt; 925c51f124SMoriah Waterland ssize_t ptln; 935c51f124SMoriah Waterland va_list ap; 945c51f124SMoriah Waterland int n; 955c51f124SMoriah Waterland 965c51f124SMoriah Waterland if (fmt == (char *)NULL) { 975c51f124SMoriah Waterland theErrBuf[0] = '\0'; 985c51f124SMoriah Waterland } else { 995c51f124SMoriah Waterland if (n = strlen(theErrBuf)) { 1005c51f124SMoriah Waterland pt = theErrBuf + n; 1015c51f124SMoriah Waterland *pt++ = '\n'; 1025c51f124SMoriah Waterland *pt = '\0'; 1035c51f124SMoriah Waterland ptln = sizeof (theErrBuf)-n; 1045c51f124SMoriah Waterland } else { 1055c51f124SMoriah Waterland pt = theErrBuf; 1065c51f124SMoriah Waterland ptln = sizeof (theErrBuf); 1075c51f124SMoriah Waterland } 1085c51f124SMoriah Waterland va_start(ap, fmt); 1095c51f124SMoriah Waterland /* LINTED variable format specifier to vsnprintf() */ 1105c51f124SMoriah Waterland (void) vsnprintf(pt, ptln, fmt, ap); 1115c51f124SMoriah Waterland va_end(ap); 1125c51f124SMoriah Waterland } 1135c51f124SMoriah Waterland } 1145c51f124SMoriah Waterland 1155c51f124SMoriah Waterland /* 1165c51f124SMoriah Waterland * Name: cverify 1175c51f124SMoriah Waterland * Description: This function verifies and (if fix > 0) fixes the contents 1185c51f124SMoriah Waterland * of the file at the path provided 1195c51f124SMoriah Waterland * Arguments: fix - 0 - do not fix entries, 1 - fix entries 1205c51f124SMoriah Waterland * ftype - single character "type" the entry is supposed to be 1215c51f124SMoriah Waterland * path - path to file 1225c51f124SMoriah Waterland * cinfo - content info structure representing the contents 1235c51f124SMoriah Waterland * the entry is supposed to contain 1245c51f124SMoriah Waterland * allow_checksum - determine if checksumming should be disabled: 1255c51f124SMoriah Waterland * == 0 - do not perform checksum ever - override enable_checksum. 1265c51f124SMoriah Waterland * != 0 - use the default checksum flag "enable_checksum" to 1275c51f124SMoriah Waterland * determine if checksumming should be done. 1285c51f124SMoriah Waterland * NOTE: modification and creation times can be repaired; the contents 1295c51f124SMoriah Waterland * of the file cannot be corrected if the checksum indicates that 1305c51f124SMoriah Waterland * the contents are not correct - VE_CONT will be returned in this 1315c51f124SMoriah Waterland * case. 1325c51f124SMoriah Waterland * Possible return values: 1335c51f124SMoriah Waterland * - 0 = successful 1345c51f124SMoriah Waterland * - VE_EXIST = path name does not exist 1355c51f124SMoriah Waterland * - VE_FTYPE = path file type is not recognized, is not supported, 1365c51f124SMoriah Waterland * or is not what was expected 1375c51f124SMoriah Waterland * - VE_ATTR = path mode/group/user is not what was expected 1385c51f124SMoriah Waterland * - VE_CONT = mod time/link target/major/minor/size/file system type/current 1395c51f124SMoriah Waterland * directory is not what was expected 1405c51f124SMoriah Waterland * - VE_FAIL = utime/target directory/link/stat/symlink/mknod/chmod/statvfs/ 1415c51f124SMoriah Waterland * chown failed 1425c51f124SMoriah Waterland */ 1435c51f124SMoriah Waterland 1445c51f124SMoriah Waterland int 1455c51f124SMoriah Waterland cverify(int fix, char *ftype, char *path, struct cinfo *cinfo, 1465c51f124SMoriah Waterland int allow_checksum) 1475c51f124SMoriah Waterland { 1485c51f124SMoriah Waterland struct stat status; /* file status buffer */ 1495c51f124SMoriah Waterland struct utimbuf times; 1505c51f124SMoriah Waterland unsigned long mycksum; 1515c51f124SMoriah Waterland int setval, retcode; 1525c51f124SMoriah Waterland char tbuf1[512]; 1535c51f124SMoriah Waterland char tbuf2[512]; 1545c51f124SMoriah Waterland int cksumerr; 1555c51f124SMoriah Waterland 1565c51f124SMoriah Waterland setval = (*ftype == '?'); 1575c51f124SMoriah Waterland retcode = 0; 1585c51f124SMoriah Waterland reperr(NULL); 1595c51f124SMoriah Waterland 1605c51f124SMoriah Waterland if (stat(path, &status) < 0) { 1615c51f124SMoriah Waterland reperr(pkg_gt(ERR_EXIST)); 1625c51f124SMoriah Waterland return (VE_EXIST); 1635c51f124SMoriah Waterland } 1645c51f124SMoriah Waterland 1655c51f124SMoriah Waterland /* -1 requires modtimes to be the same */ 1665c51f124SMoriah Waterland /* 0 reports modtime failure */ 1675c51f124SMoriah Waterland /* 1 fixes modtimes */ 1685c51f124SMoriah Waterland 1695c51f124SMoriah Waterland if (setval || (cinfo->modtime == BADCONT)) { 1705c51f124SMoriah Waterland cinfo->modtime = status.st_mtime; 1715c51f124SMoriah Waterland } else if (status.st_mtime != cinfo->modtime) { 1725c51f124SMoriah Waterland if (fix > 0) { 1735c51f124SMoriah Waterland /* reset times on the file */ 1745c51f124SMoriah Waterland times.actime = cinfo->modtime; 1755c51f124SMoriah Waterland times.modtime = cinfo->modtime; 1765c51f124SMoriah Waterland if (utime(path, ×)) { 1775c51f124SMoriah Waterland reperr(pkg_gt(ERR_MODFAIL)); 1785c51f124SMoriah Waterland retcode = VE_FAIL; 1795c51f124SMoriah Waterland } 1805c51f124SMoriah Waterland } else if (fix < 0) { 1815c51f124SMoriah Waterland /* modtimes must be the same */ 1825c51f124SMoriah Waterland if (strftime(tbuf1, sizeof (tbuf1), DATEFMT, 1835c51f124SMoriah Waterland localtime(&cinfo->modtime)) == 0) { 1845c51f124SMoriah Waterland reperr(pkg_gt(ERR_MEM)); 1855c51f124SMoriah Waterland } 1865c51f124SMoriah Waterland if (strftime(tbuf2, sizeof (tbuf2), DATEFMT, 1875c51f124SMoriah Waterland localtime(&status.st_mtime)) == 0) { 1885c51f124SMoriah Waterland reperr(pkg_gt(ERR_MEM)); 1895c51f124SMoriah Waterland } 1905c51f124SMoriah Waterland reperr(pkg_gt(ERR_MTIME), tbuf1, tbuf2); 1915c51f124SMoriah Waterland retcode = VE_CONT; 1925c51f124SMoriah Waterland } 1935c51f124SMoriah Waterland } 1945c51f124SMoriah Waterland 1955c51f124SMoriah Waterland if (setval || (cinfo->size == (fsblkcnt_t)BADCONT)) { 1965c51f124SMoriah Waterland cinfo->size = status.st_size; 1975c51f124SMoriah Waterland } else if (status.st_size != cinfo->size) { 1985c51f124SMoriah Waterland if (!retcode) { 1995c51f124SMoriah Waterland retcode = VE_CONT; 2005c51f124SMoriah Waterland } 2015c51f124SMoriah Waterland reperr(pkg_gt(ERR_SIZE), cinfo->size, status.st_size); 2025c51f124SMoriah Waterland } 2035c51f124SMoriah Waterland 2045c51f124SMoriah Waterland cksumerr = 0; 2055c51f124SMoriah Waterland 2065c51f124SMoriah Waterland /* 2075c51f124SMoriah Waterland * see if checksumming should be done: if checksumming is allowed, 2085c51f124SMoriah Waterland * and checksumming is enabled, then checksum the file. 2095c51f124SMoriah Waterland */ 2105c51f124SMoriah Waterland 2115c51f124SMoriah Waterland /* return if no need to compute checksum */ 2125c51f124SMoriah Waterland 2135c51f124SMoriah Waterland if ((allow_checksum == 0) || (enable_checksum == 0)) { 2145c51f124SMoriah Waterland return (retcode); 2155c51f124SMoriah Waterland } 2165c51f124SMoriah Waterland 2175c51f124SMoriah Waterland /* compute checksum */ 2185c51f124SMoriah Waterland 2195c51f124SMoriah Waterland mycksum = compute_checksum(&cksumerr, path); 2205c51f124SMoriah Waterland 2215c51f124SMoriah Waterland /* set value if not set or if checksum cannot be computed */ 2225c51f124SMoriah Waterland 2235c51f124SMoriah Waterland if (setval || (cinfo->cksum == BADCONT)) { 2245c51f124SMoriah Waterland cinfo->cksum = mycksum; 2255c51f124SMoriah Waterland return (retcode); 2265c51f124SMoriah Waterland } 2275c51f124SMoriah Waterland 2285c51f124SMoriah Waterland /* report / return error if checksums mismatch or there is an error */ 2295c51f124SMoriah Waterland 2305c51f124SMoriah Waterland if ((mycksum != cinfo->cksum) || cksumerr) { 2315c51f124SMoriah Waterland if (!retcode) { 2325c51f124SMoriah Waterland retcode = VE_CONT; 2335c51f124SMoriah Waterland } 2345c51f124SMoriah Waterland if (!cksumerr) { 2355c51f124SMoriah Waterland reperr(pkg_gt(ERR_CKSUM), cinfo->cksum, mycksum); 2365c51f124SMoriah Waterland } 2375c51f124SMoriah Waterland } 2385c51f124SMoriah Waterland 2395c51f124SMoriah Waterland return (retcode); 2405c51f124SMoriah Waterland } 2415c51f124SMoriah Waterland 2425c51f124SMoriah Waterland /* 2435c51f124SMoriah Waterland * Name: compute_checksum 2445c51f124SMoriah Waterland * Description: generate checksum for specified file 2455c51f124SMoriah Waterland * Arguments: r_cksumerr (int *) [RO, *RW] 2465c51f124SMoriah Waterland * - pointer to integer that is set on return to: 2475c51f124SMoriah Waterland * == 0 - no error occurred 2485c51f124SMoriah Waterland * != 0 - error occurred 2495c51f124SMoriah Waterland * a_path (char *) [RO, *RO] 2505c51f124SMoriah Waterland * - pointer to string representing path to file to 2515c51f124SMoriah Waterland * generate checksum of 2525c51f124SMoriah Waterland * Returns: unsigned long - results: 2535c51f124SMoriah Waterland * - If *r_cksumerr == 0, checksum of specified file 2545c51f124SMoriah Waterland * - If *r_cksumerr != 0, undefined 2555c51f124SMoriah Waterland */ 2565c51f124SMoriah Waterland unsigned long 2575c51f124SMoriah Waterland compute_checksum(int *r_cksumerr, char *a_path) 2585c51f124SMoriah Waterland { 2595c51f124SMoriah Waterland CHECKSUM_T suma; /* to split four-bytes into 2 two-byte values */ 2605c51f124SMoriah Waterland CHECKSUM_T tempa; 2615c51f124SMoriah Waterland int fd; 2625c51f124SMoriah Waterland uint32_t lg; /* running checksum value */ 2635c51f124SMoriah Waterland uint32_t buf[CHUNK/4]; /* to read CHUNK bytes */ 2645c51f124SMoriah Waterland uint32_t lsavhi; /* high order two-bytes of four-byte checksum */ 2655c51f124SMoriah Waterland uint32_t lsavlo; /* low order two-bytes of four-byte checksum */ 2665c51f124SMoriah Waterland int leap = sizeof (uint32_t); 2675c51f124SMoriah Waterland int notyet = 0; 2685c51f124SMoriah Waterland int nread; 2695c51f124SMoriah Waterland struct stat64 sbuf; 2705c51f124SMoriah Waterland 2715c51f124SMoriah Waterland /* reset error flag */ 2725c51f124SMoriah Waterland *r_cksumerr = 0; 2735c51f124SMoriah Waterland 2745c51f124SMoriah Waterland /* open file and obtain -> where file is mapped/read */ 2755c51f124SMoriah Waterland if ((fd = open(a_path, O_RDONLY)) < 0) { 2765c51f124SMoriah Waterland *r_cksumerr = 1; 2775c51f124SMoriah Waterland reperr(pkg_gt(ERR_NO_CKSUM)); 2785c51f124SMoriah Waterland perror(ERR_NO_CKSUM); 2795c51f124SMoriah Waterland return (0); 2805c51f124SMoriah Waterland } 2815c51f124SMoriah Waterland 2825c51f124SMoriah Waterland if (fstat64(fd, &sbuf) != 0) { 2835c51f124SMoriah Waterland *r_cksumerr = 1; 2845c51f124SMoriah Waterland reperr(pkg_gt(ERR_NO_CKSUM)); 2855c51f124SMoriah Waterland perror(ERR_NO_CKSUM); 2865c51f124SMoriah Waterland return (0); 2875c51f124SMoriah Waterland } 2885c51f124SMoriah Waterland 2895c51f124SMoriah Waterland /* initialize checksum value */ 2905c51f124SMoriah Waterland lg = 0; 2915c51f124SMoriah Waterland 2925c51f124SMoriah Waterland /* 2935c51f124SMoriah Waterland * Read CHUNK bytes off the file at a time; Read size of long bytes 2945c51f124SMoriah Waterland * from memory at a time and process them. 2955c51f124SMoriah Waterland * If last read, then read remnant bytes and process individually. 2965c51f124SMoriah Waterland */ 2975c51f124SMoriah Waterland errno = 0; 2985c51f124SMoriah Waterland while ((nread = read(fd, (void*)buf, 2995c51f124SMoriah Waterland (sbuf.st_size < CHUNK) ? sbuf.st_size : CHUNK)) > 0) { 3005c51f124SMoriah Waterland uchar_t *s; 3015c51f124SMoriah Waterland uint32_t *p = buf; 3025c51f124SMoriah Waterland 3035c51f124SMoriah Waterland notyet = nread % leap; 3045c51f124SMoriah Waterland nread -= notyet; 3055c51f124SMoriah Waterland 3065c51f124SMoriah Waterland for (; nread > 0; nread -= leap) { 3075c51f124SMoriah Waterland lg += ((((*p)>>24)&0xFF) & WDMSK); 3085c51f124SMoriah Waterland lg += ((((*p)>>16)&0xFF) & WDMSK); 3095c51f124SMoriah Waterland lg += ((((*p)>>8)&0xFF) & WDMSK); 3105c51f124SMoriah Waterland lg += (((*p)&0xFF) & WDMSK); 3115c51f124SMoriah Waterland p++; 3125c51f124SMoriah Waterland } 3135c51f124SMoriah Waterland s = (uchar_t *)p; 3145c51f124SMoriah Waterland /* leftover bytes less than four in number */ 3155c51f124SMoriah Waterland while (notyet--) 3165c51f124SMoriah Waterland lg += (((uint32_t)(*s++)) & WDMSK); 3175c51f124SMoriah Waterland } 3185c51f124SMoriah Waterland 3195c51f124SMoriah Waterland /* wind up */ 3205c51f124SMoriah Waterland (void) close(fd); 3215c51f124SMoriah Waterland 3225c51f124SMoriah Waterland /* compute checksum components */ 3235c51f124SMoriah Waterland suma.lg = lg; 3245c51f124SMoriah Waterland tempa.lg = (suma.hl.lo & WDMSK) + (suma.hl.hi & WDMSK); 3255c51f124SMoriah Waterland lsavhi = (uint32_t)tempa.hl.hi; 3265c51f124SMoriah Waterland lsavlo = (uint32_t)tempa.hl.lo; 3275c51f124SMoriah Waterland 3285c51f124SMoriah Waterland /* return final checksum value */ 3295c51f124SMoriah Waterland return (lsavhi+lsavlo); 3305c51f124SMoriah Waterland } 3315c51f124SMoriah Waterland 3325c51f124SMoriah Waterland static struct stat status; /* file status buffer */ 3335c51f124SMoriah Waterland static struct statvfs vfsstatus; /* filesystem status buffer */ 3345c51f124SMoriah Waterland 3355c51f124SMoriah Waterland /* 3365c51f124SMoriah Waterland * Remove the thing that's currently in place so we can put down the package 3375c51f124SMoriah Waterland * object. If we're replacing a directory with a directory, leave it alone. 3385c51f124SMoriah Waterland * Returns 1 if all OK and 0 if failed. 3395c51f124SMoriah Waterland */ 3405c51f124SMoriah Waterland static int 3415c51f124SMoriah Waterland clear_target(char *path, char *ftype, int is_a_dir) 3425c51f124SMoriah Waterland { 3435c51f124SMoriah Waterland int retcode = 1; 3445c51f124SMoriah Waterland 3455c51f124SMoriah Waterland if (is_a_dir) { /* if there's a directory there already ... */ 3465c51f124SMoriah Waterland /* ... and this isn't, ... */ 3475c51f124SMoriah Waterland if ((*ftype != 'd') && (*ftype != 'x')) { 3485c51f124SMoriah Waterland if (rmdir(path)) { /* try to remove it. */ 3495c51f124SMoriah Waterland reperr(pkg_gt(ERR_RMDIR), path); 3505c51f124SMoriah Waterland retcode = 0; 3515c51f124SMoriah Waterland } 3525c51f124SMoriah Waterland } 3535c51f124SMoriah Waterland } else { 3545c51f124SMoriah Waterland if (remove(path)) { 3555c51f124SMoriah Waterland if (errno != ENOENT) { 3565c51f124SMoriah Waterland retcode = 0; /* It didn't work. */ 3575c51f124SMoriah Waterland } 3585c51f124SMoriah Waterland } 3595c51f124SMoriah Waterland } 3605c51f124SMoriah Waterland 3615c51f124SMoriah Waterland return (retcode); 3625c51f124SMoriah Waterland } 3635c51f124SMoriah Waterland 3645c51f124SMoriah Waterland /* 3655c51f124SMoriah Waterland * Name: averify 3665c51f124SMoriah Waterland * Description: This function verifies and (if fix > 0) fixes the attributes 3675c51f124SMoriah Waterland * of the file at the path provided. 3685c51f124SMoriah Waterland * Arguments: fix - 0 - do not fix entries, 1 - fix entries 3695c51f124SMoriah Waterland * ftype - single character "type" the entry is supposed to be 3705c51f124SMoriah Waterland * path - path to file 3715c51f124SMoriah Waterland * ainfo - attribute info structure representing the attributes 3725c51f124SMoriah Waterland * the entry is supposed to be 3735c51f124SMoriah Waterland * NOTE: attributes are links and permissions 3745c51f124SMoriah Waterland * Possible return values: 3755c51f124SMoriah Waterland * - 0 = successful 3765c51f124SMoriah Waterland * - VE_EXIST = path name does not exist 3775c51f124SMoriah Waterland * - VE_FTYPE = path file type is not recognized, is not supported, 3785c51f124SMoriah Waterland * or is not what was expected 3795c51f124SMoriah Waterland * - VE_ATTR = path mode/group/user is not what was expected 3805c51f124SMoriah Waterland * - VE_CONT = mod time/link target/major/minor/size/file system type/current 3815c51f124SMoriah Waterland * directory is not what was expected 3825c51f124SMoriah Waterland * - VE_FAIL = utime/target directory/link/stat/symlink/mknod/chmod/statvfs/ 3835c51f124SMoriah Waterland * chown failed 3845c51f124SMoriah Waterland */ 3855c51f124SMoriah Waterland int 3865c51f124SMoriah Waterland averify(int fix, char *ftype, char *path, struct ainfo *ainfo) 3875c51f124SMoriah Waterland { 3885c51f124SMoriah Waterland struct group *grp; /* group entry buffer */ 3895c51f124SMoriah Waterland struct passwd *pwd; 3905c51f124SMoriah Waterland int n; 3915c51f124SMoriah Waterland int setval; 3925c51f124SMoriah Waterland int uid, gid; 3935c51f124SMoriah Waterland int dochown; 3945c51f124SMoriah Waterland int retcode; 395*b46ec01aSok199659 int statError = 0; 3965c51f124SMoriah Waterland int targ_is_dir = 0; /* replacing a directory */ 3975c51f124SMoriah Waterland char myftype; 3985c51f124SMoriah Waterland char buf[PATH_MAX]; 3995c51f124SMoriah Waterland ino_t my_ino; 4005c51f124SMoriah Waterland dev_t my_dev; 4015c51f124SMoriah Waterland char cwd[MAXPATHLEN]; 4025c51f124SMoriah Waterland char *cd; 4035c51f124SMoriah Waterland char *c; 4045c51f124SMoriah Waterland 4055c51f124SMoriah Waterland setval = (*ftype == '?'); 4065c51f124SMoriah Waterland retcode = 0; 4075c51f124SMoriah Waterland reperr(NULL); 4085c51f124SMoriah Waterland 4095c51f124SMoriah Waterland if (get_disable_attribute_check()) { 4105c51f124SMoriah Waterland return (0); 4115c51f124SMoriah Waterland } 4125c51f124SMoriah Waterland 4135c51f124SMoriah Waterland if (*ftype == 'l') { 4145c51f124SMoriah Waterland if (stat(path, &status) < 0) { 4155c51f124SMoriah Waterland retcode = VE_EXIST; 4165c51f124SMoriah Waterland reperr(pkg_gt(ERR_EXIST)); 4175c51f124SMoriah Waterland } 4185c51f124SMoriah Waterland 4195c51f124SMoriah Waterland my_ino = status.st_ino; 4205c51f124SMoriah Waterland my_dev = status.st_dev; 4215c51f124SMoriah Waterland 4225c51f124SMoriah Waterland /* Get copy of the current working directory */ 4235c51f124SMoriah Waterland if (getcwd(cwd, MAXPATHLEN) == NULL) { 4245c51f124SMoriah Waterland reperr(pkg_gt(ERR_GETWD), ainfo->local); 4255c51f124SMoriah Waterland return (VE_FAIL); 4265c51f124SMoriah Waterland } 4275c51f124SMoriah Waterland 4285c51f124SMoriah Waterland /* 4295c51f124SMoriah Waterland * Change to the directory in which the hard 4305c51f124SMoriah Waterland * link is to be created. 4315c51f124SMoriah Waterland */ 4325c51f124SMoriah Waterland cd = strdup(path); 4335c51f124SMoriah Waterland c = strrchr(cd, '/'); 4345c51f124SMoriah Waterland if (c) { 4355c51f124SMoriah Waterland /* bugid 4247895 */ 4365c51f124SMoriah Waterland if (strcmp(cd, c) == 0) 4375c51f124SMoriah Waterland strcpy(cd, "/"); 4385c51f124SMoriah Waterland else 4395c51f124SMoriah Waterland *c = NULL; 4405c51f124SMoriah Waterland 4415c51f124SMoriah Waterland if (chdir(cd) != 0) { 4425c51f124SMoriah Waterland reperr(pkg_gt(ERR_CHDIR), cd); 4435c51f124SMoriah Waterland return (VE_FAIL); 4445c51f124SMoriah Waterland } 4455c51f124SMoriah Waterland } 4465c51f124SMoriah Waterland free(cd); 4475c51f124SMoriah Waterland 4485c51f124SMoriah Waterland if (retcode || (status.st_nlink < 2) || 4495c51f124SMoriah Waterland (stat(ainfo->local, &status) < 0) || 4505c51f124SMoriah Waterland (my_dev != status.st_dev) || (my_ino != status.st_ino)) { 4515c51f124SMoriah Waterland if (fix) { 4525c51f124SMoriah Waterland /* 4535c51f124SMoriah Waterland * Don't want to do a hard link to a 4545c51f124SMoriah Waterland * directory. 4555c51f124SMoriah Waterland */ 4565c51f124SMoriah Waterland if (!isdir(ainfo->local)) { 4575c51f124SMoriah Waterland chdir(cwd); 4585c51f124SMoriah Waterland reperr(pkg_gt(ERR_LINKISDIR), 4595c51f124SMoriah Waterland ainfo->local); 4605c51f124SMoriah Waterland return (VE_FAIL); 4615c51f124SMoriah Waterland } 4625c51f124SMoriah Waterland /* Now do the link. */ 4635c51f124SMoriah Waterland if (!clear_target(path, ftype, targ_is_dir)) 4645c51f124SMoriah Waterland return (VE_FAIL); 4655c51f124SMoriah Waterland 4665c51f124SMoriah Waterland if (link(ainfo->local, path)) { 4675c51f124SMoriah Waterland chdir(cwd); 4685c51f124SMoriah Waterland reperr(pkg_gt(ERR_LINKFAIL), 4695c51f124SMoriah Waterland ainfo->local); 4705c51f124SMoriah Waterland return (VE_FAIL); 4715c51f124SMoriah Waterland } 4725c51f124SMoriah Waterland retcode = 0; 4735c51f124SMoriah Waterland } else { 4745c51f124SMoriah Waterland /* Go back to previous working directory */ 4755c51f124SMoriah Waterland if (chdir(cwd) != 0) 4765c51f124SMoriah Waterland reperr(pkg_gt(ERR_CHDIR), cwd); 4775c51f124SMoriah Waterland 4785c51f124SMoriah Waterland reperr(pkg_gt(ERR_LINK), ainfo->local); 4795c51f124SMoriah Waterland return (VE_CONT); 4805c51f124SMoriah Waterland } 4815c51f124SMoriah Waterland } 4825c51f124SMoriah Waterland 4835c51f124SMoriah Waterland /* Go back to previous working directory */ 4845c51f124SMoriah Waterland if (chdir(cwd) != 0) { 4855c51f124SMoriah Waterland reperr(pkg_gt(ERR_CHDIR), cwd); 4865c51f124SMoriah Waterland return (VE_CONT); 4875c51f124SMoriah Waterland } 4885c51f124SMoriah Waterland 4895c51f124SMoriah Waterland return (retcode); 4905c51f124SMoriah Waterland } 4915c51f124SMoriah Waterland 4925c51f124SMoriah Waterland retcode = 0; 4935c51f124SMoriah Waterland 494*b46ec01aSok199659 /* If we are to process symlinks the old way then we follow the link */ 495*b46ec01aSok199659 if (nonABI_symlinks()) { 496*b46ec01aSok199659 if ((*ftype == 's') ? lstat(path, &status) : 497*b46ec01aSok199659 stat(path, &status)) { 498*b46ec01aSok199659 reperr(pkg_gt(ERR_EXIST)); 499*b46ec01aSok199659 retcode = VE_EXIST; 500*b46ec01aSok199659 myftype = '?'; 501*b46ec01aSok199659 statError++; 502*b46ec01aSok199659 } 503*b46ec01aSok199659 /* If not then we inspect the target of the link */ 504*b46ec01aSok199659 } else { 505*b46ec01aSok199659 if ((n = lstat(path, &status)) == -1) { 506*b46ec01aSok199659 reperr(pkg_gt(ERR_EXIST)); 507*b46ec01aSok199659 retcode = VE_EXIST; 508*b46ec01aSok199659 myftype = '?'; 509*b46ec01aSok199659 statError++; 510*b46ec01aSok199659 } 511*b46ec01aSok199659 } 512*b46ec01aSok199659 if (!statError) { 513*b46ec01aSok199659 /* determining actual type of existing object */ 514*b46ec01aSok199659 switch (status.st_mode & S_IFMT) { 515*b46ec01aSok199659 case S_IFLNK: 516*b46ec01aSok199659 myftype = 's'; 517*b46ec01aSok199659 break; 5185c51f124SMoriah Waterland 519*b46ec01aSok199659 case S_IFIFO: 520*b46ec01aSok199659 myftype = 'p'; 521*b46ec01aSok199659 break; 5225c51f124SMoriah Waterland 523*b46ec01aSok199659 case S_IFCHR: 524*b46ec01aSok199659 myftype = 'c'; 525*b46ec01aSok199659 break; 526*b46ec01aSok199659 527*b46ec01aSok199659 case S_IFDIR: 528*b46ec01aSok199659 myftype = 'd'; 5295c51f124SMoriah Waterland targ_is_dir = 1; 530*b46ec01aSok199659 break; 531*b46ec01aSok199659 532*b46ec01aSok199659 case S_IFBLK: 533*b46ec01aSok199659 myftype = 'b'; 534*b46ec01aSok199659 break; 535*b46ec01aSok199659 536*b46ec01aSok199659 case S_IFREG: 537*b46ec01aSok199659 case 0: 538*b46ec01aSok199659 myftype = 'f'; 539*b46ec01aSok199659 break; 540*b46ec01aSok199659 541*b46ec01aSok199659 case S_IFDOOR: 542*b46ec01aSok199659 myftype = 'D'; 543*b46ec01aSok199659 break; 544*b46ec01aSok199659 545*b46ec01aSok199659 default: 546*b46ec01aSok199659 reperr(pkg_gt(ERR_UNKNOWN)); 547*b46ec01aSok199659 return (VE_FTYPE); 548*b46ec01aSok199659 } 549*b46ec01aSok199659 } 5505c51f124SMoriah Waterland 5515c51f124SMoriah Waterland if (setval) { 5525c51f124SMoriah Waterland /* 5535c51f124SMoriah Waterland * Check to make sure that a package or an installf that uses 5545c51f124SMoriah Waterland * wild cards '?' to assume the ftype of an object on the 5555c51f124SMoriah Waterland * system is not assuming a door ftype. Doors are not supported 5565c51f124SMoriah Waterland * but should be ignored. 5575c51f124SMoriah Waterland */ 5585c51f124SMoriah Waterland if (myftype == 'D') { 5595c51f124SMoriah Waterland reperr(pkg_gt(ERR_FTYPED), path); 5605c51f124SMoriah Waterland retcode = VE_FTYPE; 5615c51f124SMoriah Waterland return (VE_FTYPE); 5625c51f124SMoriah Waterland } else { 5635c51f124SMoriah Waterland *ftype = myftype; 5645c51f124SMoriah Waterland } 5655c51f124SMoriah Waterland } else if (!retcode && (*ftype != myftype) && 5665c51f124SMoriah Waterland ((myftype != 'f') || !strchr("ilev", *ftype)) && 5675c51f124SMoriah Waterland ((myftype != 'd') || (*ftype != 'x'))) { 5685c51f124SMoriah Waterland reperr(pkg_gt(ERR_FTYPE), *ftype, myftype); 5695c51f124SMoriah Waterland retcode = VE_FTYPE; 5705c51f124SMoriah Waterland } 5715c51f124SMoriah Waterland 5725c51f124SMoriah Waterland if (!retcode && (*ftype == 's')) { 5735c51f124SMoriah Waterland /* make sure that symbolic link is correct */ 5745c51f124SMoriah Waterland n = readlink(path, buf, PATH_MAX); 5755c51f124SMoriah Waterland if (n < 0) { 5765c51f124SMoriah Waterland reperr(pkg_gt(ERR_SLINK), ainfo->local); 5775c51f124SMoriah Waterland retcode = VE_CONT; 5785c51f124SMoriah Waterland } else if (ainfo->local != NULL) { 5795c51f124SMoriah Waterland buf[n] = '\0'; 5805c51f124SMoriah Waterland if (strcmp(buf, ainfo->local)) { 5815c51f124SMoriah Waterland reperr(pkg_gt(ERR_SLINK), ainfo->local); 5825c51f124SMoriah Waterland retcode = VE_CONT; 5835c51f124SMoriah Waterland } 5845c51f124SMoriah Waterland } else if (ainfo->local == NULL) { 5855c51f124SMoriah Waterland /* 5865c51f124SMoriah Waterland * Since a sym link target exists, insert it 5875c51f124SMoriah Waterland * into the ainfo structure 5885c51f124SMoriah Waterland */ 5895c51f124SMoriah Waterland buf[n] = '\0'; 5905c51f124SMoriah Waterland ainfo->local = strdup(buf); 5915c51f124SMoriah Waterland } 5925c51f124SMoriah Waterland } 5935c51f124SMoriah Waterland 5945c51f124SMoriah Waterland if (retcode) { 5955c51f124SMoriah Waterland /* The path doesn't exist or is different than it should be. */ 5965c51f124SMoriah Waterland if (fix) { 5975c51f124SMoriah Waterland /* 5985c51f124SMoriah Waterland * Clear the way for the write. If it won't clear, 5995c51f124SMoriah Waterland * there's nothing we can do. 6005c51f124SMoriah Waterland */ 6015c51f124SMoriah Waterland if (!clear_target(path, ftype, targ_is_dir)) 6025c51f124SMoriah Waterland return (VE_FAIL); 6035c51f124SMoriah Waterland 6045c51f124SMoriah Waterland if ((*ftype == 'd') || (*ftype == 'x')) { 6055c51f124SMoriah Waterland char *pt, *p; 6065c51f124SMoriah Waterland 6075c51f124SMoriah Waterland /* Try to make it the easy way */ 6085c51f124SMoriah Waterland if (mkdir(path, ainfo->mode)) { 6095c51f124SMoriah Waterland /* 6105c51f124SMoriah Waterland * Failing that, walk through the 6115c51f124SMoriah Waterland * parent directories creating 6125c51f124SMoriah Waterland * whatever is needed. 6135c51f124SMoriah Waterland */ 6145c51f124SMoriah Waterland p = strdup(path); 6155c51f124SMoriah Waterland pt = (*p == '/') ? p+1 : p; 6165c51f124SMoriah Waterland do { 6175c51f124SMoriah Waterland if (pt = strchr(pt, '/')) 6185c51f124SMoriah Waterland *pt = '\0'; 6195c51f124SMoriah Waterland if (access(p, 0) && 6205c51f124SMoriah Waterland mkdir(p, ainfo->mode)) 6215c51f124SMoriah Waterland break; 6225c51f124SMoriah Waterland if (pt) 6235c51f124SMoriah Waterland *pt++ = '/'; 6245c51f124SMoriah Waterland } while (pt); 6255c51f124SMoriah Waterland free(p); 6265c51f124SMoriah Waterland } 6275c51f124SMoriah Waterland if (stat(path, &status) < 0) { 6285c51f124SMoriah Waterland reperr(pkg_gt(ERR_DIRFAIL)); 6295c51f124SMoriah Waterland return (VE_FAIL); 6305c51f124SMoriah Waterland } 6315c51f124SMoriah Waterland } else if (*ftype == 's') { 6325c51f124SMoriah Waterland if (symlink(ainfo->local, path)) { 6335c51f124SMoriah Waterland reperr(pkg_gt(ERR_SLINKFAIL), 6345c51f124SMoriah Waterland ainfo->local); 6355c51f124SMoriah Waterland return (VE_FAIL); 6365c51f124SMoriah Waterland } 6375c51f124SMoriah Waterland 6385c51f124SMoriah Waterland } else if (*ftype == 'c') { 6395c51f124SMoriah Waterland int wilddevno = 0; 6405c51f124SMoriah Waterland /* 6415c51f124SMoriah Waterland * The next three if's support 2.4 and older 6425c51f124SMoriah Waterland * packages that use "?" as device numbers. 6435c51f124SMoriah Waterland * This should be considered for removal by 6445c51f124SMoriah Waterland * release 2.7 or so. 6455c51f124SMoriah Waterland */ 6465c51f124SMoriah Waterland if (ainfo->major == BADMAJOR) { 6475c51f124SMoriah Waterland ainfo->major = 0; 6485c51f124SMoriah Waterland wilddevno = 1; 6495c51f124SMoriah Waterland } 6505c51f124SMoriah Waterland 6515c51f124SMoriah Waterland if (ainfo->minor == BADMINOR) { 6525c51f124SMoriah Waterland ainfo->minor = 0; 6535c51f124SMoriah Waterland wilddevno = 1; 6545c51f124SMoriah Waterland } 6555c51f124SMoriah Waterland 6565c51f124SMoriah Waterland if (wilddevno) { 6575c51f124SMoriah Waterland wilddevno = 0; 6585c51f124SMoriah Waterland logerr(MSG_WLDDEVNO, path, 6595c51f124SMoriah Waterland ainfo->major, ainfo->minor); 6605c51f124SMoriah Waterland } 6615c51f124SMoriah Waterland 6625c51f124SMoriah Waterland if (mknod(path, ainfo->mode | S_IFCHR, 6635c51f124SMoriah Waterland #ifdef SUNOS41 6645c51f124SMoriah Waterland makedev(ainfo->xmajor, ainfo->xminor)) || 6655c51f124SMoriah Waterland #else 6665c51f124SMoriah Waterland makedev(ainfo->major, ainfo->minor)) || 6675c51f124SMoriah Waterland #endif 6685c51f124SMoriah Waterland (stat(path, &status) < 0)) { 6695c51f124SMoriah Waterland reperr(pkg_gt(ERR_CDEVFAIL)); 6705c51f124SMoriah Waterland return (VE_FAIL); 6715c51f124SMoriah Waterland } 6725c51f124SMoriah Waterland } else if (*ftype == 'b') { 6735c51f124SMoriah Waterland int wilddevno = 0; 6745c51f124SMoriah Waterland /* 6755c51f124SMoriah Waterland * The next three if's support 2.4 and older 6765c51f124SMoriah Waterland * packages that use "?" as device numbers. 6775c51f124SMoriah Waterland * This should be considered for removal by 6785c51f124SMoriah Waterland * release 2.7 or so. 6795c51f124SMoriah Waterland */ 6805c51f124SMoriah Waterland if (ainfo->major == BADMAJOR) { 6815c51f124SMoriah Waterland ainfo->major = 0; 6825c51f124SMoriah Waterland wilddevno = 1; 6835c51f124SMoriah Waterland } 6845c51f124SMoriah Waterland 6855c51f124SMoriah Waterland if (ainfo->minor == BADMINOR) { 6865c51f124SMoriah Waterland ainfo->minor = 0; 6875c51f124SMoriah Waterland wilddevno = 1; 6885c51f124SMoriah Waterland } 6895c51f124SMoriah Waterland 6905c51f124SMoriah Waterland if (wilddevno) { 6915c51f124SMoriah Waterland wilddevno = 0; 6925c51f124SMoriah Waterland logerr(MSG_WLDDEVNO, path, 6935c51f124SMoriah Waterland ainfo->major, ainfo->minor); 6945c51f124SMoriah Waterland } 6955c51f124SMoriah Waterland 6965c51f124SMoriah Waterland if (mknod(path, ainfo->mode | S_IFBLK, 6975c51f124SMoriah Waterland #ifdef SUNOS41 6985c51f124SMoriah Waterland makedev(ainfo->xmajor, ainfo->xminor)) || 6995c51f124SMoriah Waterland #else 7005c51f124SMoriah Waterland makedev(ainfo->major, ainfo->minor)) || 7015c51f124SMoriah Waterland #endif 7025c51f124SMoriah Waterland (stat(path, &status) < 0)) { 7035c51f124SMoriah Waterland reperr(pkg_gt(ERR_BDEVFAIL)); 7045c51f124SMoriah Waterland return (VE_FAIL); 7055c51f124SMoriah Waterland } 7065c51f124SMoriah Waterland } else if (*ftype == 'p') { 7075c51f124SMoriah Waterland if (mknod(path, ainfo->mode | S_IFIFO, NULL) || 7085c51f124SMoriah Waterland (stat(path, &status) < 0)) { 7095c51f124SMoriah Waterland reperr(pkg_gt(ERR_PIPEFAIL)); 7105c51f124SMoriah Waterland return (VE_FAIL); 7115c51f124SMoriah Waterland } 7125c51f124SMoriah Waterland } else 7135c51f124SMoriah Waterland return (retcode); 7145c51f124SMoriah Waterland 7155c51f124SMoriah Waterland } else 7165c51f124SMoriah Waterland return (retcode); 7175c51f124SMoriah Waterland } 7185c51f124SMoriah Waterland 7195c51f124SMoriah Waterland if (*ftype == 's') 7205c51f124SMoriah Waterland return (0); /* don't check anything else */ 7215c51f124SMoriah Waterland if (*ftype == 'i') 7225c51f124SMoriah Waterland return (0); /* don't check anything else */ 7235c51f124SMoriah Waterland 7245c51f124SMoriah Waterland retcode = 0; 7255c51f124SMoriah Waterland if ((myftype == 'c') || (myftype == 'b')) { 7265c51f124SMoriah Waterland #ifdef SUNOS41 7275c51f124SMoriah Waterland if (setval || (ainfo->xmajor < 0)) 7285c51f124SMoriah Waterland ainfo->xmajor = ((status.st_rdev>>8)&0377); 7295c51f124SMoriah Waterland if (setval || (ainfo->xminor < 0)) 7305c51f124SMoriah Waterland ainfo->xminor = (status.st_rdev&0377); 7315c51f124SMoriah Waterland /* check major & minor */ 7325c51f124SMoriah Waterland if (status.st_rdev != makedev(ainfo->xmajor, ainfo->xminor)) { 7335c51f124SMoriah Waterland reperr(pkg_gt(ERR_MAJMIN), ainfo->xmajor, 7345c51f124SMoriah Waterland ainfo->xminor, 7355c51f124SMoriah Waterland (status.st_rdev>>8)&0377, status.st_rdev&0377); 7365c51f124SMoriah Waterland retcode = VE_CONT; 7375c51f124SMoriah Waterland } 7385c51f124SMoriah Waterland #else 7395c51f124SMoriah Waterland if (setval || (ainfo->major == BADMAJOR)) 7405c51f124SMoriah Waterland ainfo->major = major(status.st_rdev); 7415c51f124SMoriah Waterland if (setval || (ainfo->minor == BADMINOR)) 7425c51f124SMoriah Waterland ainfo->minor = minor(status.st_rdev); 7435c51f124SMoriah Waterland /* check major & minor */ 7445c51f124SMoriah Waterland if (status.st_rdev != makedev(ainfo->major, ainfo->minor)) { 7455c51f124SMoriah Waterland reperr(pkg_gt(ERR_MAJMIN), ainfo->major, ainfo->minor, 7465c51f124SMoriah Waterland major(status.st_rdev), minor(status.st_rdev)); 7475c51f124SMoriah Waterland retcode = VE_CONT; 7485c51f124SMoriah Waterland } 7495c51f124SMoriah Waterland #endif 7505c51f124SMoriah Waterland } 7515c51f124SMoriah Waterland 7525c51f124SMoriah Waterland /* compare specified mode w/ actual mode excluding sticky bit */ 7535c51f124SMoriah Waterland if (setval || (ainfo->mode == BADMODE) || (ainfo->mode == WILDCARD)) 7545c51f124SMoriah Waterland ainfo->mode = status.st_mode & 07777; 7555c51f124SMoriah Waterland else if ((ainfo->mode & 06777) != (status.st_mode & 06777)) { 7565c51f124SMoriah Waterland if (fix) { 7575c51f124SMoriah Waterland if ((ainfo->mode == BADMODE) || 7585c51f124SMoriah Waterland (chmod(path, ainfo->mode) < 0)) 7595c51f124SMoriah Waterland retcode = VE_FAIL; 7605c51f124SMoriah Waterland } else { 7615c51f124SMoriah Waterland reperr(pkg_gt(ERR_PERM), ainfo->mode, 7625c51f124SMoriah Waterland status.st_mode & 07777); 7635c51f124SMoriah Waterland if (!retcode) 7645c51f124SMoriah Waterland retcode = VE_ATTR; 7655c51f124SMoriah Waterland } 7665c51f124SMoriah Waterland } 7675c51f124SMoriah Waterland 7685c51f124SMoriah Waterland dochown = 0; 7695c51f124SMoriah Waterland 7705c51f124SMoriah Waterland /* get group entry for specified group */ 7715c51f124SMoriah Waterland if (setval || strcmp(ainfo->group, BADGROUP) == 0) { 7725c51f124SMoriah Waterland grp = cgrgid(status.st_gid); 7735c51f124SMoriah Waterland if (grp) 7745c51f124SMoriah Waterland (void) strcpy(ainfo->group, grp->gr_name); 7755c51f124SMoriah Waterland else { 7765c51f124SMoriah Waterland if (!retcode) 7775c51f124SMoriah Waterland retcode = VE_ATTR; 7785c51f124SMoriah Waterland reperr(pkg_gt(ERR_BADGRPID), status.st_gid); 7795c51f124SMoriah Waterland } 7805c51f124SMoriah Waterland gid = status.st_gid; 7815c51f124SMoriah Waterland } else if ((grp = cgrnam(ainfo->group)) == NULL) { 7825c51f124SMoriah Waterland reperr(pkg_gt(ERR_BADGRPNM), ainfo->group); 7835c51f124SMoriah Waterland if (!retcode) 7845c51f124SMoriah Waterland retcode = VE_ATTR; 7855c51f124SMoriah Waterland } else if ((gid = grp->gr_gid) != status.st_gid) { 7865c51f124SMoriah Waterland if (fix) { 7875c51f124SMoriah Waterland /* save specified GID */ 7885c51f124SMoriah Waterland gid = grp->gr_gid; 7895c51f124SMoriah Waterland dochown++; 7905c51f124SMoriah Waterland } else { 7915c51f124SMoriah Waterland if ((grp = cgrgid((int)status.st_gid)) == 7925c51f124SMoriah Waterland (struct group *)NULL) { 7935c51f124SMoriah Waterland reperr(pkg_gt(ERR_GROUP), ainfo->group, 7945c51f124SMoriah Waterland "(null)"); 7955c51f124SMoriah Waterland } else { 7965c51f124SMoriah Waterland reperr(pkg_gt(ERR_GROUP), ainfo->group, 7975c51f124SMoriah Waterland grp->gr_name); 7985c51f124SMoriah Waterland } 7995c51f124SMoriah Waterland if (!retcode) 8005c51f124SMoriah Waterland retcode = VE_ATTR; 8015c51f124SMoriah Waterland } 8025c51f124SMoriah Waterland } 8035c51f124SMoriah Waterland 8045c51f124SMoriah Waterland /* get password entry for specified owner */ 8055c51f124SMoriah Waterland if (setval || strcmp(ainfo->owner, BADOWNER) == 0) { 8065c51f124SMoriah Waterland pwd = cpwuid((int)status.st_uid); 8075c51f124SMoriah Waterland if (pwd) 8085c51f124SMoriah Waterland (void) strcpy(ainfo->owner, pwd->pw_name); 8095c51f124SMoriah Waterland else { 8105c51f124SMoriah Waterland if (!retcode) 8115c51f124SMoriah Waterland retcode = VE_ATTR; 8125c51f124SMoriah Waterland reperr(pkg_gt(ERR_BADUSRID), status.st_uid); 8135c51f124SMoriah Waterland } 8145c51f124SMoriah Waterland uid = status.st_uid; 8155c51f124SMoriah Waterland } else if ((pwd = cpwnam(ainfo->owner)) == NULL) { 8165c51f124SMoriah Waterland /* UID does not exist in password file */ 8175c51f124SMoriah Waterland reperr(pkg_gt(ERR_BADUSRNM), ainfo->owner); 8185c51f124SMoriah Waterland if (!retcode) 8195c51f124SMoriah Waterland retcode = VE_ATTR; 8205c51f124SMoriah Waterland } else if ((uid = pwd->pw_uid) != status.st_uid) { 8215c51f124SMoriah Waterland /* get owner name for actual UID */ 8225c51f124SMoriah Waterland if (fix) { 8235c51f124SMoriah Waterland uid = pwd->pw_uid; 8245c51f124SMoriah Waterland dochown++; 8255c51f124SMoriah Waterland } else { 8265c51f124SMoriah Waterland pwd = cpwuid((int)status.st_uid); 8275c51f124SMoriah Waterland if (pwd == NULL) 8285c51f124SMoriah Waterland reperr(pkg_gt(ERR_BADUSRID), 8295c51f124SMoriah Waterland (int)status.st_uid); 8305c51f124SMoriah Waterland else 8315c51f124SMoriah Waterland reperr(pkg_gt(ERR_OWNER), ainfo->owner, 8325c51f124SMoriah Waterland pwd->pw_name); 8335c51f124SMoriah Waterland 8345c51f124SMoriah Waterland if (!retcode) 8355c51f124SMoriah Waterland retcode = VE_ATTR; 8365c51f124SMoriah Waterland } 8375c51f124SMoriah Waterland } 8385c51f124SMoriah Waterland 8395c51f124SMoriah Waterland if (statvfs(path, &vfsstatus) < 0) { 8405c51f124SMoriah Waterland reperr(pkg_gt(ERR_EXIST)); 8415c51f124SMoriah Waterland retcode = VE_FAIL; 8425c51f124SMoriah Waterland } else { 8435c51f124SMoriah Waterland if (dochown) { 8445c51f124SMoriah Waterland /* pcfs doesn't support file ownership */ 8455c51f124SMoriah Waterland if (strcmp(vfsstatus.f_basetype, "pcfs") != 0 && 8465c51f124SMoriah Waterland chown(path, uid, gid) < 0) { 8475c51f124SMoriah Waterland retcode = VE_FAIL; /* chown failed */ 8485c51f124SMoriah Waterland } 8495c51f124SMoriah Waterland } 8505c51f124SMoriah Waterland } 8515c51f124SMoriah Waterland 8525c51f124SMoriah Waterland if (retcode == VE_FAIL) 8535c51f124SMoriah Waterland reperr(pkg_gt(ERR_ATTRFAIL)); 8545c51f124SMoriah Waterland return (retcode); 8555c51f124SMoriah Waterland } 8565c51f124SMoriah Waterland 8575c51f124SMoriah Waterland /* 8585c51f124SMoriah Waterland * This is a special fast verify which basically checks the attributes 8595c51f124SMoriah Waterland * and then, if all is OK, checks the size and mod time using the same 8605c51f124SMoriah Waterland * stat and statvfs structures. 8615c51f124SMoriah Waterland */ 8625c51f124SMoriah Waterland int 8635c51f124SMoriah Waterland fverify(int fix, char *ftype, char *path, struct ainfo *ainfo, 8645c51f124SMoriah Waterland struct cinfo *cinfo) 8655c51f124SMoriah Waterland { 8665c51f124SMoriah Waterland int retval; 8675c51f124SMoriah Waterland 8685c51f124SMoriah Waterland /* return success if attribute checks are disabled */ 8695c51f124SMoriah Waterland 8705c51f124SMoriah Waterland if (get_disable_attribute_check()) { 8715c51f124SMoriah Waterland return (0); 8725c51f124SMoriah Waterland } 8735c51f124SMoriah Waterland 8745c51f124SMoriah Waterland if ((retval = averify(fix, ftype, path, ainfo)) == 0) { 8755c51f124SMoriah Waterland if (*ftype == 'f' || *ftype == 'i') { 8765c51f124SMoriah Waterland if (cinfo->size != status.st_size) { 8775c51f124SMoriah Waterland reperr(pkg_gt(WRN_QV_SIZE), path); 8785c51f124SMoriah Waterland retval = VE_CONT; 8795c51f124SMoriah Waterland } 8805c51f124SMoriah Waterland /* pcfs doesn't support modification times */ 8815c51f124SMoriah Waterland if (strcmp(vfsstatus.f_basetype, "pcfs") != 0) { 8825c51f124SMoriah Waterland if (cinfo->modtime != status.st_mtime) { 8835c51f124SMoriah Waterland reperr(pkg_gt(WRN_QV_MTIME), path); 8845c51f124SMoriah Waterland retval = VE_CONT; 8855c51f124SMoriah Waterland } 8865c51f124SMoriah Waterland } 8875c51f124SMoriah Waterland } 8885c51f124SMoriah Waterland } 8895c51f124SMoriah Waterland 8905c51f124SMoriah Waterland return (retval); 8915c51f124SMoriah Waterland } 8925c51f124SMoriah Waterland 8935c51f124SMoriah Waterland /* 8945c51f124SMoriah Waterland * This function determines whether or not non-ABI symlinks are supported. 8955c51f124SMoriah Waterland */ 8965c51f124SMoriah Waterland 8975c51f124SMoriah Waterland int 8985c51f124SMoriah Waterland nonABI_symlinks(void) 8995c51f124SMoriah Waterland { 9005c51f124SMoriah Waterland return (nonabi_symlinks); 9015c51f124SMoriah Waterland } 9025c51f124SMoriah Waterland 9035c51f124SMoriah Waterland void 9045c51f124SMoriah Waterland set_nonABI_symlinks(void) 9055c51f124SMoriah Waterland { 9065c51f124SMoriah Waterland nonabi_symlinks = 1; 9075c51f124SMoriah Waterland } 9085c51f124SMoriah Waterland 9095c51f124SMoriah Waterland /* 9105c51f124SMoriah Waterland * Disable attribute checking. Only disable attribute checking if files 9115c51f124SMoriah Waterland * are guaranteed to exist in the FS. 9125c51f124SMoriah Waterland */ 9135c51f124SMoriah Waterland void 9145c51f124SMoriah Waterland disable_attribute_check(void) 9155c51f124SMoriah Waterland { 9165c51f124SMoriah Waterland disable_attributes = 1; 9175c51f124SMoriah Waterland } 9185c51f124SMoriah Waterland 9195c51f124SMoriah Waterland /* 9205c51f124SMoriah Waterland * This function determines whether or not to do attribute checking. 9215c51f124SMoriah Waterland * Returns: 0 - Do attribute checking 9225c51f124SMoriah Waterland * !0 - Don't do attribute checking 9235c51f124SMoriah Waterland */ 9245c51f124SMoriah Waterland int 9255c51f124SMoriah Waterland get_disable_attribute_check(void) 9265c51f124SMoriah Waterland { 9275c51f124SMoriah Waterland return (disable_attributes); 9285c51f124SMoriah Waterland } 9295c51f124SMoriah Waterland 9305c51f124SMoriah Waterland /* 9315c51f124SMoriah Waterland * This function returns the address of the "global" error buffer that 9325c51f124SMoriah Waterland * is populated by the various functions in this module. 9335c51f124SMoriah Waterland */ 9345c51f124SMoriah Waterland 9355c51f124SMoriah Waterland char * 9365c51f124SMoriah Waterland getErrbufAddr(void) 9375c51f124SMoriah Waterland { 9385c51f124SMoriah Waterland return (theErrBuf); 9395c51f124SMoriah Waterland } 9405c51f124SMoriah Waterland 9415c51f124SMoriah Waterland /* 9425c51f124SMoriah Waterland * This function returns the size of the buffer returned by getErrbufAddr() 9435c51f124SMoriah Waterland */ 9445c51f124SMoriah Waterland 9455c51f124SMoriah Waterland int 9465c51f124SMoriah Waterland getErrbufSize(void) 9475c51f124SMoriah Waterland { 9485c51f124SMoriah Waterland return (sizeof (theErrBuf)); 9495c51f124SMoriah Waterland } 9505c51f124SMoriah Waterland 9515c51f124SMoriah Waterland /* 9525c51f124SMoriah Waterland * This function returns the current global "error string" 9535c51f124SMoriah Waterland */ 9545c51f124SMoriah Waterland 9555c51f124SMoriah Waterland char * 9565c51f124SMoriah Waterland getErrstr(void) 9575c51f124SMoriah Waterland { 9585c51f124SMoriah Waterland return (theErrStr); 9595c51f124SMoriah Waterland } 9605c51f124SMoriah Waterland 9615c51f124SMoriah Waterland /* 9625c51f124SMoriah Waterland * This function sets the global "error string" 9635c51f124SMoriah Waterland */ 9645c51f124SMoriah Waterland 9655c51f124SMoriah Waterland void 9665c51f124SMoriah Waterland setErrstr(char *a_errstr) 9675c51f124SMoriah Waterland { 9685c51f124SMoriah Waterland theErrStr = a_errstr; 9695c51f124SMoriah Waterland } 9705c51f124SMoriah Waterland 9715c51f124SMoriah Waterland /* 9725c51f124SMoriah Waterland * This function enables checksumming 9735c51f124SMoriah Waterland */ 9745c51f124SMoriah Waterland 9755c51f124SMoriah Waterland void 9765c51f124SMoriah Waterland checksum_on(void) 9775c51f124SMoriah Waterland { 9785c51f124SMoriah Waterland enable_checksum = 1; 9795c51f124SMoriah Waterland } 9805c51f124SMoriah Waterland 9815c51f124SMoriah Waterland /* 9825c51f124SMoriah Waterland * This function disables checksumming 9835c51f124SMoriah Waterland */ 9845c51f124SMoriah Waterland 9855c51f124SMoriah Waterland void 9865c51f124SMoriah Waterland checksum_off(void) 9875c51f124SMoriah Waterland { 9885c51f124SMoriah Waterland enable_checksum = 0; 9895c51f124SMoriah Waterland } 990