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