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
reperr(char * fmt,...)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
cverify(int fix,char * ftype,char * path,struct cinfo * cinfo,int allow_checksum)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
compute_checksum(int * r_cksumerr,char * a_path)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
clear_target(char * path,char * ftype,int is_a_dir)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
averify(int fix,char * ftype,char * path,struct ainfo * ainfo)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
fverify(int fix,char * ftype,char * path,struct ainfo * ainfo,struct cinfo * cinfo)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
nonABI_symlinks(void)8755c51f124SMoriah Waterland nonABI_symlinks(void)
8765c51f124SMoriah Waterland {
8775c51f124SMoriah Waterland return (nonabi_symlinks);
8785c51f124SMoriah Waterland }
8795c51f124SMoriah Waterland
8805c51f124SMoriah Waterland void
set_nonABI_symlinks(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
disable_attribute_check(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
get_disable_attribute_check(void)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 *
getErrbufAddr(void)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
getErrbufSize(void)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 *
getErrstr(void)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
setErrstr(char * a_errstr)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
checksum_on(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
checksum_off(void)9635c51f124SMoriah Waterland checksum_off(void)
9645c51f124SMoriah Waterland {
9655c51f124SMoriah Waterland enable_checksum = 0;
9665c51f124SMoriah Waterland }
967