1*9781SMoriah.Waterland@Sun.COM /* 2*9781SMoriah.Waterland@Sun.COM * CDDL HEADER START 3*9781SMoriah.Waterland@Sun.COM * 4*9781SMoriah.Waterland@Sun.COM * The contents of this file are subject to the terms of the 5*9781SMoriah.Waterland@Sun.COM * Common Development and Distribution License (the "License"). 6*9781SMoriah.Waterland@Sun.COM * You may not use this file except in compliance with the License. 7*9781SMoriah.Waterland@Sun.COM * 8*9781SMoriah.Waterland@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*9781SMoriah.Waterland@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*9781SMoriah.Waterland@Sun.COM * See the License for the specific language governing permissions 11*9781SMoriah.Waterland@Sun.COM * and limitations under the License. 12*9781SMoriah.Waterland@Sun.COM * 13*9781SMoriah.Waterland@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*9781SMoriah.Waterland@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*9781SMoriah.Waterland@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*9781SMoriah.Waterland@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*9781SMoriah.Waterland@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*9781SMoriah.Waterland@Sun.COM * 19*9781SMoriah.Waterland@Sun.COM * CDDL HEADER END 20*9781SMoriah.Waterland@Sun.COM */ 21*9781SMoriah.Waterland@Sun.COM 22*9781SMoriah.Waterland@Sun.COM /* 23*9781SMoriah.Waterland@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*9781SMoriah.Waterland@Sun.COM * Use is subject to license terms. 25*9781SMoriah.Waterland@Sun.COM */ 26*9781SMoriah.Waterland@Sun.COM 27*9781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*9781SMoriah.Waterland@Sun.COM /* All Rights Reserved */ 29*9781SMoriah.Waterland@Sun.COM 30*9781SMoriah.Waterland@Sun.COM 31*9781SMoriah.Waterland@Sun.COM 32*9781SMoriah.Waterland@Sun.COM #include <stdio.h> 33*9781SMoriah.Waterland@Sun.COM #include <limits.h> 34*9781SMoriah.Waterland@Sun.COM #include <stdlib.h> 35*9781SMoriah.Waterland@Sun.COM #include <unistd.h> 36*9781SMoriah.Waterland@Sun.COM #include <utime.h> 37*9781SMoriah.Waterland@Sun.COM #include <sys/types.h> 38*9781SMoriah.Waterland@Sun.COM #include <sys/param.h> 39*9781SMoriah.Waterland@Sun.COM #include <sys/stat.h> 40*9781SMoriah.Waterland@Sun.COM #include <sys/statvfs.h> 41*9781SMoriah.Waterland@Sun.COM #include <grp.h> 42*9781SMoriah.Waterland@Sun.COM #include <pwd.h> 43*9781SMoriah.Waterland@Sun.COM #include <errno.h> 44*9781SMoriah.Waterland@Sun.COM #include <string.h> 45*9781SMoriah.Waterland@Sun.COM #include <stdarg.h> 46*9781SMoriah.Waterland@Sun.COM #include <fcntl.h> 47*9781SMoriah.Waterland@Sun.COM #include <sys/mkdev.h> 48*9781SMoriah.Waterland@Sun.COM #include "pkgstrct.h" 49*9781SMoriah.Waterland@Sun.COM #include "pkglib.h" 50*9781SMoriah.Waterland@Sun.COM #include "pkglibmsgs.h" 51*9781SMoriah.Waterland@Sun.COM #include "pkglocale.h" 52*9781SMoriah.Waterland@Sun.COM 53*9781SMoriah.Waterland@Sun.COM #define WDMSK 0xFFFF 54*9781SMoriah.Waterland@Sun.COM #define DATEFMT "%D %r" 55*9781SMoriah.Waterland@Sun.COM #define LONG_BOUNDARY ((sizeof (unsigned long))-1) 56*9781SMoriah.Waterland@Sun.COM #define CHUNK 1024*1024 57*9781SMoriah.Waterland@Sun.COM 58*9781SMoriah.Waterland@Sun.COM static char theErrBuf[PATH_MAX+512] = {'\0'}; 59*9781SMoriah.Waterland@Sun.COM static char *theErrStr = NULL; 60*9781SMoriah.Waterland@Sun.COM 61*9781SMoriah.Waterland@Sun.COM /* checksum disable switch */ 62*9781SMoriah.Waterland@Sun.COM static int enable_checksum = 1; 63*9781SMoriah.Waterland@Sun.COM 64*9781SMoriah.Waterland@Sun.COM /* attribute disable flag */ 65*9781SMoriah.Waterland@Sun.COM static int disable_attributes = 0; 66*9781SMoriah.Waterland@Sun.COM 67*9781SMoriah.Waterland@Sun.COM /* non-ABI symlinks supported */ 68*9781SMoriah.Waterland@Sun.COM static int nonabi_symlinks; 69*9781SMoriah.Waterland@Sun.COM 70*9781SMoriah.Waterland@Sun.COM /* 71*9781SMoriah.Waterland@Sun.COM * forward declarations 72*9781SMoriah.Waterland@Sun.COM */ 73*9781SMoriah.Waterland@Sun.COM 74*9781SMoriah.Waterland@Sun.COM static int clear_target(char *path, char *ftype, int is_a_dir); 75*9781SMoriah.Waterland@Sun.COM 76*9781SMoriah.Waterland@Sun.COM unsigned long compute_checksum(int *r_err, char *path); 77*9781SMoriah.Waterland@Sun.COM 78*9781SMoriah.Waterland@Sun.COM /* union used to generate checksum */ 79*9781SMoriah.Waterland@Sun.COM typedef union hilo { 80*9781SMoriah.Waterland@Sun.COM struct part { 81*9781SMoriah.Waterland@Sun.COM uint16_t hi; 82*9781SMoriah.Waterland@Sun.COM uint16_t lo; 83*9781SMoriah.Waterland@Sun.COM } hl; 84*9781SMoriah.Waterland@Sun.COM uint32_t lg; 85*9781SMoriah.Waterland@Sun.COM } CHECKSUM_T; 86*9781SMoriah.Waterland@Sun.COM 87*9781SMoriah.Waterland@Sun.COM /*PRINTFLIKE1*/ 88*9781SMoriah.Waterland@Sun.COM static void 89*9781SMoriah.Waterland@Sun.COM reperr(char *fmt, ...) 90*9781SMoriah.Waterland@Sun.COM { 91*9781SMoriah.Waterland@Sun.COM char *pt; 92*9781SMoriah.Waterland@Sun.COM ssize_t ptln; 93*9781SMoriah.Waterland@Sun.COM va_list ap; 94*9781SMoriah.Waterland@Sun.COM int n; 95*9781SMoriah.Waterland@Sun.COM 96*9781SMoriah.Waterland@Sun.COM if (fmt == (char *)NULL) { 97*9781SMoriah.Waterland@Sun.COM theErrBuf[0] = '\0'; 98*9781SMoriah.Waterland@Sun.COM } else { 99*9781SMoriah.Waterland@Sun.COM if (n = strlen(theErrBuf)) { 100*9781SMoriah.Waterland@Sun.COM pt = theErrBuf + n; 101*9781SMoriah.Waterland@Sun.COM *pt++ = '\n'; 102*9781SMoriah.Waterland@Sun.COM *pt = '\0'; 103*9781SMoriah.Waterland@Sun.COM ptln = sizeof (theErrBuf)-n; 104*9781SMoriah.Waterland@Sun.COM } else { 105*9781SMoriah.Waterland@Sun.COM pt = theErrBuf; 106*9781SMoriah.Waterland@Sun.COM ptln = sizeof (theErrBuf); 107*9781SMoriah.Waterland@Sun.COM } 108*9781SMoriah.Waterland@Sun.COM va_start(ap, fmt); 109*9781SMoriah.Waterland@Sun.COM /* LINTED variable format specifier to vsnprintf() */ 110*9781SMoriah.Waterland@Sun.COM (void) vsnprintf(pt, ptln, fmt, ap); 111*9781SMoriah.Waterland@Sun.COM va_end(ap); 112*9781SMoriah.Waterland@Sun.COM } 113*9781SMoriah.Waterland@Sun.COM } 114*9781SMoriah.Waterland@Sun.COM 115*9781SMoriah.Waterland@Sun.COM /* 116*9781SMoriah.Waterland@Sun.COM * Name: cverify 117*9781SMoriah.Waterland@Sun.COM * Description: This function verifies and (if fix > 0) fixes the contents 118*9781SMoriah.Waterland@Sun.COM * of the file at the path provided 119*9781SMoriah.Waterland@Sun.COM * Arguments: fix - 0 - do not fix entries, 1 - fix entries 120*9781SMoriah.Waterland@Sun.COM * ftype - single character "type" the entry is supposed to be 121*9781SMoriah.Waterland@Sun.COM * path - path to file 122*9781SMoriah.Waterland@Sun.COM * cinfo - content info structure representing the contents 123*9781SMoriah.Waterland@Sun.COM * the entry is supposed to contain 124*9781SMoriah.Waterland@Sun.COM * allow_checksum - determine if checksumming should be disabled: 125*9781SMoriah.Waterland@Sun.COM * == 0 - do not perform checksum ever - override enable_checksum. 126*9781SMoriah.Waterland@Sun.COM * != 0 - use the default checksum flag "enable_checksum" to 127*9781SMoriah.Waterland@Sun.COM * determine if checksumming should be done. 128*9781SMoriah.Waterland@Sun.COM * NOTE: modification and creation times can be repaired; the contents 129*9781SMoriah.Waterland@Sun.COM * of the file cannot be corrected if the checksum indicates that 130*9781SMoriah.Waterland@Sun.COM * the contents are not correct - VE_CONT will be returned in this 131*9781SMoriah.Waterland@Sun.COM * case. 132*9781SMoriah.Waterland@Sun.COM * Possible return values: 133*9781SMoriah.Waterland@Sun.COM * - 0 = successful 134*9781SMoriah.Waterland@Sun.COM * - VE_EXIST = path name does not exist 135*9781SMoriah.Waterland@Sun.COM * - VE_FTYPE = path file type is not recognized, is not supported, 136*9781SMoriah.Waterland@Sun.COM * or is not what was expected 137*9781SMoriah.Waterland@Sun.COM * - VE_ATTR = path mode/group/user is not what was expected 138*9781SMoriah.Waterland@Sun.COM * - VE_CONT = mod time/link target/major/minor/size/file system type/current 139*9781SMoriah.Waterland@Sun.COM * directory is not what was expected 140*9781SMoriah.Waterland@Sun.COM * - VE_FAIL = utime/target directory/link/stat/symlink/mknod/chmod/statvfs/ 141*9781SMoriah.Waterland@Sun.COM * chown failed 142*9781SMoriah.Waterland@Sun.COM */ 143*9781SMoriah.Waterland@Sun.COM 144*9781SMoriah.Waterland@Sun.COM int 145*9781SMoriah.Waterland@Sun.COM cverify(int fix, char *ftype, char *path, struct cinfo *cinfo, 146*9781SMoriah.Waterland@Sun.COM int allow_checksum) 147*9781SMoriah.Waterland@Sun.COM { 148*9781SMoriah.Waterland@Sun.COM struct stat status; /* file status buffer */ 149*9781SMoriah.Waterland@Sun.COM struct utimbuf times; 150*9781SMoriah.Waterland@Sun.COM unsigned long mycksum; 151*9781SMoriah.Waterland@Sun.COM int setval, retcode; 152*9781SMoriah.Waterland@Sun.COM char tbuf1[512]; 153*9781SMoriah.Waterland@Sun.COM char tbuf2[512]; 154*9781SMoriah.Waterland@Sun.COM int cksumerr; 155*9781SMoriah.Waterland@Sun.COM 156*9781SMoriah.Waterland@Sun.COM setval = (*ftype == '?'); 157*9781SMoriah.Waterland@Sun.COM retcode = 0; 158*9781SMoriah.Waterland@Sun.COM reperr(NULL); 159*9781SMoriah.Waterland@Sun.COM 160*9781SMoriah.Waterland@Sun.COM if (stat(path, &status) < 0) { 161*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_EXIST)); 162*9781SMoriah.Waterland@Sun.COM return (VE_EXIST); 163*9781SMoriah.Waterland@Sun.COM } 164*9781SMoriah.Waterland@Sun.COM 165*9781SMoriah.Waterland@Sun.COM /* -1 requires modtimes to be the same */ 166*9781SMoriah.Waterland@Sun.COM /* 0 reports modtime failure */ 167*9781SMoriah.Waterland@Sun.COM /* 1 fixes modtimes */ 168*9781SMoriah.Waterland@Sun.COM 169*9781SMoriah.Waterland@Sun.COM if (setval || (cinfo->modtime == BADCONT)) { 170*9781SMoriah.Waterland@Sun.COM cinfo->modtime = status.st_mtime; 171*9781SMoriah.Waterland@Sun.COM } else if (status.st_mtime != cinfo->modtime) { 172*9781SMoriah.Waterland@Sun.COM if (fix > 0) { 173*9781SMoriah.Waterland@Sun.COM /* reset times on the file */ 174*9781SMoriah.Waterland@Sun.COM times.actime = cinfo->modtime; 175*9781SMoriah.Waterland@Sun.COM times.modtime = cinfo->modtime; 176*9781SMoriah.Waterland@Sun.COM if (utime(path, ×)) { 177*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_MODFAIL)); 178*9781SMoriah.Waterland@Sun.COM retcode = VE_FAIL; 179*9781SMoriah.Waterland@Sun.COM } 180*9781SMoriah.Waterland@Sun.COM } else if (fix < 0) { 181*9781SMoriah.Waterland@Sun.COM /* modtimes must be the same */ 182*9781SMoriah.Waterland@Sun.COM if (strftime(tbuf1, sizeof (tbuf1), DATEFMT, 183*9781SMoriah.Waterland@Sun.COM localtime(&cinfo->modtime)) == 0) { 184*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_MEM)); 185*9781SMoriah.Waterland@Sun.COM } 186*9781SMoriah.Waterland@Sun.COM if (strftime(tbuf2, sizeof (tbuf2), DATEFMT, 187*9781SMoriah.Waterland@Sun.COM localtime(&status.st_mtime)) == 0) { 188*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_MEM)); 189*9781SMoriah.Waterland@Sun.COM } 190*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_MTIME), tbuf1, tbuf2); 191*9781SMoriah.Waterland@Sun.COM retcode = VE_CONT; 192*9781SMoriah.Waterland@Sun.COM } 193*9781SMoriah.Waterland@Sun.COM } 194*9781SMoriah.Waterland@Sun.COM 195*9781SMoriah.Waterland@Sun.COM if (setval || (cinfo->size == (fsblkcnt_t)BADCONT)) { 196*9781SMoriah.Waterland@Sun.COM cinfo->size = status.st_size; 197*9781SMoriah.Waterland@Sun.COM } else if (status.st_size != cinfo->size) { 198*9781SMoriah.Waterland@Sun.COM if (!retcode) { 199*9781SMoriah.Waterland@Sun.COM retcode = VE_CONT; 200*9781SMoriah.Waterland@Sun.COM } 201*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_SIZE), cinfo->size, status.st_size); 202*9781SMoriah.Waterland@Sun.COM } 203*9781SMoriah.Waterland@Sun.COM 204*9781SMoriah.Waterland@Sun.COM cksumerr = 0; 205*9781SMoriah.Waterland@Sun.COM 206*9781SMoriah.Waterland@Sun.COM /* 207*9781SMoriah.Waterland@Sun.COM * see if checksumming should be done: if checksumming is allowed, 208*9781SMoriah.Waterland@Sun.COM * and checksumming is enabled, then checksum the file. 209*9781SMoriah.Waterland@Sun.COM */ 210*9781SMoriah.Waterland@Sun.COM 211*9781SMoriah.Waterland@Sun.COM /* return if no need to compute checksum */ 212*9781SMoriah.Waterland@Sun.COM 213*9781SMoriah.Waterland@Sun.COM if ((allow_checksum == 0) || (enable_checksum == 0)) { 214*9781SMoriah.Waterland@Sun.COM return (retcode); 215*9781SMoriah.Waterland@Sun.COM } 216*9781SMoriah.Waterland@Sun.COM 217*9781SMoriah.Waterland@Sun.COM /* compute checksum */ 218*9781SMoriah.Waterland@Sun.COM 219*9781SMoriah.Waterland@Sun.COM mycksum = compute_checksum(&cksumerr, path); 220*9781SMoriah.Waterland@Sun.COM 221*9781SMoriah.Waterland@Sun.COM /* set value if not set or if checksum cannot be computed */ 222*9781SMoriah.Waterland@Sun.COM 223*9781SMoriah.Waterland@Sun.COM if (setval || (cinfo->cksum == BADCONT)) { 224*9781SMoriah.Waterland@Sun.COM cinfo->cksum = mycksum; 225*9781SMoriah.Waterland@Sun.COM return (retcode); 226*9781SMoriah.Waterland@Sun.COM } 227*9781SMoriah.Waterland@Sun.COM 228*9781SMoriah.Waterland@Sun.COM /* report / return error if checksums mismatch or there is an error */ 229*9781SMoriah.Waterland@Sun.COM 230*9781SMoriah.Waterland@Sun.COM if ((mycksum != cinfo->cksum) || cksumerr) { 231*9781SMoriah.Waterland@Sun.COM if (!retcode) { 232*9781SMoriah.Waterland@Sun.COM retcode = VE_CONT; 233*9781SMoriah.Waterland@Sun.COM } 234*9781SMoriah.Waterland@Sun.COM if (!cksumerr) { 235*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_CKSUM), cinfo->cksum, mycksum); 236*9781SMoriah.Waterland@Sun.COM } 237*9781SMoriah.Waterland@Sun.COM } 238*9781SMoriah.Waterland@Sun.COM 239*9781SMoriah.Waterland@Sun.COM return (retcode); 240*9781SMoriah.Waterland@Sun.COM } 241*9781SMoriah.Waterland@Sun.COM 242*9781SMoriah.Waterland@Sun.COM /* 243*9781SMoriah.Waterland@Sun.COM * Name: compute_checksum 244*9781SMoriah.Waterland@Sun.COM * Description: generate checksum for specified file 245*9781SMoriah.Waterland@Sun.COM * Arguments: r_cksumerr (int *) [RO, *RW] 246*9781SMoriah.Waterland@Sun.COM * - pointer to integer that is set on return to: 247*9781SMoriah.Waterland@Sun.COM * == 0 - no error occurred 248*9781SMoriah.Waterland@Sun.COM * != 0 - error occurred 249*9781SMoriah.Waterland@Sun.COM * a_path (char *) [RO, *RO] 250*9781SMoriah.Waterland@Sun.COM * - pointer to string representing path to file to 251*9781SMoriah.Waterland@Sun.COM * generate checksum of 252*9781SMoriah.Waterland@Sun.COM * Returns: unsigned long - results: 253*9781SMoriah.Waterland@Sun.COM * - If *r_cksumerr == 0, checksum of specified file 254*9781SMoriah.Waterland@Sun.COM * - If *r_cksumerr != 0, undefined 255*9781SMoriah.Waterland@Sun.COM */ 256*9781SMoriah.Waterland@Sun.COM unsigned long 257*9781SMoriah.Waterland@Sun.COM compute_checksum(int *r_cksumerr, char *a_path) 258*9781SMoriah.Waterland@Sun.COM { 259*9781SMoriah.Waterland@Sun.COM CHECKSUM_T suma; /* to split four-bytes into 2 two-byte values */ 260*9781SMoriah.Waterland@Sun.COM CHECKSUM_T tempa; 261*9781SMoriah.Waterland@Sun.COM int fd; 262*9781SMoriah.Waterland@Sun.COM uint32_t lg; /* running checksum value */ 263*9781SMoriah.Waterland@Sun.COM uint32_t buf[CHUNK/4]; /* to read CHUNK bytes */ 264*9781SMoriah.Waterland@Sun.COM uint32_t lsavhi; /* high order two-bytes of four-byte checksum */ 265*9781SMoriah.Waterland@Sun.COM uint32_t lsavlo; /* low order two-bytes of four-byte checksum */ 266*9781SMoriah.Waterland@Sun.COM int leap = sizeof (uint32_t); 267*9781SMoriah.Waterland@Sun.COM int notyet = 0; 268*9781SMoriah.Waterland@Sun.COM int nread; 269*9781SMoriah.Waterland@Sun.COM struct stat64 sbuf; 270*9781SMoriah.Waterland@Sun.COM 271*9781SMoriah.Waterland@Sun.COM /* reset error flag */ 272*9781SMoriah.Waterland@Sun.COM *r_cksumerr = 0; 273*9781SMoriah.Waterland@Sun.COM 274*9781SMoriah.Waterland@Sun.COM /* open file and obtain -> where file is mapped/read */ 275*9781SMoriah.Waterland@Sun.COM if ((fd = open(a_path, O_RDONLY)) < 0) { 276*9781SMoriah.Waterland@Sun.COM *r_cksumerr = 1; 277*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_NO_CKSUM)); 278*9781SMoriah.Waterland@Sun.COM perror(ERR_NO_CKSUM); 279*9781SMoriah.Waterland@Sun.COM return (0); 280*9781SMoriah.Waterland@Sun.COM } 281*9781SMoriah.Waterland@Sun.COM 282*9781SMoriah.Waterland@Sun.COM if (fstat64(fd, &sbuf) != 0) { 283*9781SMoriah.Waterland@Sun.COM *r_cksumerr = 1; 284*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_NO_CKSUM)); 285*9781SMoriah.Waterland@Sun.COM perror(ERR_NO_CKSUM); 286*9781SMoriah.Waterland@Sun.COM return (0); 287*9781SMoriah.Waterland@Sun.COM } 288*9781SMoriah.Waterland@Sun.COM 289*9781SMoriah.Waterland@Sun.COM /* initialize checksum value */ 290*9781SMoriah.Waterland@Sun.COM lg = 0; 291*9781SMoriah.Waterland@Sun.COM 292*9781SMoriah.Waterland@Sun.COM /* 293*9781SMoriah.Waterland@Sun.COM * Read CHUNK bytes off the file at a time; Read size of long bytes 294*9781SMoriah.Waterland@Sun.COM * from memory at a time and process them. 295*9781SMoriah.Waterland@Sun.COM * If last read, then read remnant bytes and process individually. 296*9781SMoriah.Waterland@Sun.COM */ 297*9781SMoriah.Waterland@Sun.COM errno = 0; 298*9781SMoriah.Waterland@Sun.COM while ((nread = read(fd, (void*)buf, 299*9781SMoriah.Waterland@Sun.COM (sbuf.st_size < CHUNK) ? sbuf.st_size : CHUNK)) > 0) { 300*9781SMoriah.Waterland@Sun.COM uchar_t *s; 301*9781SMoriah.Waterland@Sun.COM uint32_t *p = buf; 302*9781SMoriah.Waterland@Sun.COM 303*9781SMoriah.Waterland@Sun.COM notyet = nread % leap; 304*9781SMoriah.Waterland@Sun.COM nread -= notyet; 305*9781SMoriah.Waterland@Sun.COM 306*9781SMoriah.Waterland@Sun.COM for (; nread > 0; nread -= leap) { 307*9781SMoriah.Waterland@Sun.COM lg += ((((*p)>>24)&0xFF) & WDMSK); 308*9781SMoriah.Waterland@Sun.COM lg += ((((*p)>>16)&0xFF) & WDMSK); 309*9781SMoriah.Waterland@Sun.COM lg += ((((*p)>>8)&0xFF) & WDMSK); 310*9781SMoriah.Waterland@Sun.COM lg += (((*p)&0xFF) & WDMSK); 311*9781SMoriah.Waterland@Sun.COM p++; 312*9781SMoriah.Waterland@Sun.COM } 313*9781SMoriah.Waterland@Sun.COM s = (uchar_t *)p; 314*9781SMoriah.Waterland@Sun.COM /* leftover bytes less than four in number */ 315*9781SMoriah.Waterland@Sun.COM while (notyet--) 316*9781SMoriah.Waterland@Sun.COM lg += (((uint32_t)(*s++)) & WDMSK); 317*9781SMoriah.Waterland@Sun.COM } 318*9781SMoriah.Waterland@Sun.COM 319*9781SMoriah.Waterland@Sun.COM /* wind up */ 320*9781SMoriah.Waterland@Sun.COM (void) close(fd); 321*9781SMoriah.Waterland@Sun.COM 322*9781SMoriah.Waterland@Sun.COM /* compute checksum components */ 323*9781SMoriah.Waterland@Sun.COM suma.lg = lg; 324*9781SMoriah.Waterland@Sun.COM tempa.lg = (suma.hl.lo & WDMSK) + (suma.hl.hi & WDMSK); 325*9781SMoriah.Waterland@Sun.COM lsavhi = (uint32_t)tempa.hl.hi; 326*9781SMoriah.Waterland@Sun.COM lsavlo = (uint32_t)tempa.hl.lo; 327*9781SMoriah.Waterland@Sun.COM 328*9781SMoriah.Waterland@Sun.COM /* return final checksum value */ 329*9781SMoriah.Waterland@Sun.COM return (lsavhi+lsavlo); 330*9781SMoriah.Waterland@Sun.COM } 331*9781SMoriah.Waterland@Sun.COM 332*9781SMoriah.Waterland@Sun.COM static struct stat status; /* file status buffer */ 333*9781SMoriah.Waterland@Sun.COM static struct statvfs vfsstatus; /* filesystem status buffer */ 334*9781SMoriah.Waterland@Sun.COM 335*9781SMoriah.Waterland@Sun.COM /* 336*9781SMoriah.Waterland@Sun.COM * Remove the thing that's currently in place so we can put down the package 337*9781SMoriah.Waterland@Sun.COM * object. If we're replacing a directory with a directory, leave it alone. 338*9781SMoriah.Waterland@Sun.COM * Returns 1 if all OK and 0 if failed. 339*9781SMoriah.Waterland@Sun.COM */ 340*9781SMoriah.Waterland@Sun.COM static int 341*9781SMoriah.Waterland@Sun.COM clear_target(char *path, char *ftype, int is_a_dir) 342*9781SMoriah.Waterland@Sun.COM { 343*9781SMoriah.Waterland@Sun.COM int retcode = 1; 344*9781SMoriah.Waterland@Sun.COM 345*9781SMoriah.Waterland@Sun.COM if (is_a_dir) { /* if there's a directory there already ... */ 346*9781SMoriah.Waterland@Sun.COM /* ... and this isn't, ... */ 347*9781SMoriah.Waterland@Sun.COM if ((*ftype != 'd') && (*ftype != 'x')) { 348*9781SMoriah.Waterland@Sun.COM if (rmdir(path)) { /* try to remove it. */ 349*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_RMDIR), path); 350*9781SMoriah.Waterland@Sun.COM retcode = 0; 351*9781SMoriah.Waterland@Sun.COM } 352*9781SMoriah.Waterland@Sun.COM } 353*9781SMoriah.Waterland@Sun.COM } else { 354*9781SMoriah.Waterland@Sun.COM if (remove(path)) { 355*9781SMoriah.Waterland@Sun.COM if (errno != ENOENT) { 356*9781SMoriah.Waterland@Sun.COM retcode = 0; /* It didn't work. */ 357*9781SMoriah.Waterland@Sun.COM } 358*9781SMoriah.Waterland@Sun.COM } 359*9781SMoriah.Waterland@Sun.COM } 360*9781SMoriah.Waterland@Sun.COM 361*9781SMoriah.Waterland@Sun.COM return (retcode); 362*9781SMoriah.Waterland@Sun.COM } 363*9781SMoriah.Waterland@Sun.COM 364*9781SMoriah.Waterland@Sun.COM /* 365*9781SMoriah.Waterland@Sun.COM * Name: averify 366*9781SMoriah.Waterland@Sun.COM * Description: This function verifies and (if fix > 0) fixes the attributes 367*9781SMoriah.Waterland@Sun.COM * of the file at the path provided. 368*9781SMoriah.Waterland@Sun.COM * Arguments: fix - 0 - do not fix entries, 1 - fix entries 369*9781SMoriah.Waterland@Sun.COM * ftype - single character "type" the entry is supposed to be 370*9781SMoriah.Waterland@Sun.COM * path - path to file 371*9781SMoriah.Waterland@Sun.COM * ainfo - attribute info structure representing the attributes 372*9781SMoriah.Waterland@Sun.COM * the entry is supposed to be 373*9781SMoriah.Waterland@Sun.COM * NOTE: attributes are links and permissions 374*9781SMoriah.Waterland@Sun.COM * Possible return values: 375*9781SMoriah.Waterland@Sun.COM * - 0 = successful 376*9781SMoriah.Waterland@Sun.COM * - VE_EXIST = path name does not exist 377*9781SMoriah.Waterland@Sun.COM * - VE_FTYPE = path file type is not recognized, is not supported, 378*9781SMoriah.Waterland@Sun.COM * or is not what was expected 379*9781SMoriah.Waterland@Sun.COM * - VE_ATTR = path mode/group/user is not what was expected 380*9781SMoriah.Waterland@Sun.COM * - VE_CONT = mod time/link target/major/minor/size/file system type/current 381*9781SMoriah.Waterland@Sun.COM * directory is not what was expected 382*9781SMoriah.Waterland@Sun.COM * - VE_FAIL = utime/target directory/link/stat/symlink/mknod/chmod/statvfs/ 383*9781SMoriah.Waterland@Sun.COM * chown failed 384*9781SMoriah.Waterland@Sun.COM */ 385*9781SMoriah.Waterland@Sun.COM int 386*9781SMoriah.Waterland@Sun.COM averify(int fix, char *ftype, char *path, struct ainfo *ainfo) 387*9781SMoriah.Waterland@Sun.COM { 388*9781SMoriah.Waterland@Sun.COM struct group *grp; /* group entry buffer */ 389*9781SMoriah.Waterland@Sun.COM struct passwd *pwd; 390*9781SMoriah.Waterland@Sun.COM int n; 391*9781SMoriah.Waterland@Sun.COM int setval; 392*9781SMoriah.Waterland@Sun.COM int uid, gid; 393*9781SMoriah.Waterland@Sun.COM int dochown; 394*9781SMoriah.Waterland@Sun.COM int retcode; 395*9781SMoriah.Waterland@Sun.COM int statError = 0; 396*9781SMoriah.Waterland@Sun.COM int targ_is_dir = 0; /* replacing a directory */ 397*9781SMoriah.Waterland@Sun.COM char myftype; 398*9781SMoriah.Waterland@Sun.COM char buf[PATH_MAX]; 399*9781SMoriah.Waterland@Sun.COM ino_t my_ino; 400*9781SMoriah.Waterland@Sun.COM dev_t my_dev; 401*9781SMoriah.Waterland@Sun.COM char cwd[MAXPATHLEN]; 402*9781SMoriah.Waterland@Sun.COM char *cd; 403*9781SMoriah.Waterland@Sun.COM char *c; 404*9781SMoriah.Waterland@Sun.COM 405*9781SMoriah.Waterland@Sun.COM setval = (*ftype == '?'); 406*9781SMoriah.Waterland@Sun.COM retcode = 0; 407*9781SMoriah.Waterland@Sun.COM reperr(NULL); 408*9781SMoriah.Waterland@Sun.COM 409*9781SMoriah.Waterland@Sun.COM if (get_disable_attribute_check()) { 410*9781SMoriah.Waterland@Sun.COM return (0); 411*9781SMoriah.Waterland@Sun.COM } 412*9781SMoriah.Waterland@Sun.COM 413*9781SMoriah.Waterland@Sun.COM if (*ftype == 'l') { 414*9781SMoriah.Waterland@Sun.COM if (stat(path, &status) < 0) { 415*9781SMoriah.Waterland@Sun.COM retcode = VE_EXIST; 416*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_EXIST)); 417*9781SMoriah.Waterland@Sun.COM } 418*9781SMoriah.Waterland@Sun.COM 419*9781SMoriah.Waterland@Sun.COM my_ino = status.st_ino; 420*9781SMoriah.Waterland@Sun.COM my_dev = status.st_dev; 421*9781SMoriah.Waterland@Sun.COM 422*9781SMoriah.Waterland@Sun.COM /* Get copy of the current working directory */ 423*9781SMoriah.Waterland@Sun.COM if (getcwd(cwd, MAXPATHLEN) == NULL) { 424*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_GETWD), ainfo->local); 425*9781SMoriah.Waterland@Sun.COM return (VE_FAIL); 426*9781SMoriah.Waterland@Sun.COM } 427*9781SMoriah.Waterland@Sun.COM 428*9781SMoriah.Waterland@Sun.COM /* 429*9781SMoriah.Waterland@Sun.COM * Change to the directory in which the hard 430*9781SMoriah.Waterland@Sun.COM * link is to be created. 431*9781SMoriah.Waterland@Sun.COM */ 432*9781SMoriah.Waterland@Sun.COM cd = strdup(path); 433*9781SMoriah.Waterland@Sun.COM c = strrchr(cd, '/'); 434*9781SMoriah.Waterland@Sun.COM if (c) { 435*9781SMoriah.Waterland@Sun.COM /* bugid 4247895 */ 436*9781SMoriah.Waterland@Sun.COM if (strcmp(cd, c) == 0) 437*9781SMoriah.Waterland@Sun.COM strcpy(cd, "/"); 438*9781SMoriah.Waterland@Sun.COM else 439*9781SMoriah.Waterland@Sun.COM *c = NULL; 440*9781SMoriah.Waterland@Sun.COM 441*9781SMoriah.Waterland@Sun.COM if (chdir(cd) != 0) { 442*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_CHDIR), cd); 443*9781SMoriah.Waterland@Sun.COM return (VE_FAIL); 444*9781SMoriah.Waterland@Sun.COM } 445*9781SMoriah.Waterland@Sun.COM } 446*9781SMoriah.Waterland@Sun.COM free(cd); 447*9781SMoriah.Waterland@Sun.COM 448*9781SMoriah.Waterland@Sun.COM if (retcode || (status.st_nlink < 2) || 449*9781SMoriah.Waterland@Sun.COM (stat(ainfo->local, &status) < 0) || 450*9781SMoriah.Waterland@Sun.COM (my_dev != status.st_dev) || (my_ino != status.st_ino)) { 451*9781SMoriah.Waterland@Sun.COM if (fix) { 452*9781SMoriah.Waterland@Sun.COM /* 453*9781SMoriah.Waterland@Sun.COM * Don't want to do a hard link to a 454*9781SMoriah.Waterland@Sun.COM * directory. 455*9781SMoriah.Waterland@Sun.COM */ 456*9781SMoriah.Waterland@Sun.COM if (!isdir(ainfo->local)) { 457*9781SMoriah.Waterland@Sun.COM chdir(cwd); 458*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_LINKISDIR), 459*9781SMoriah.Waterland@Sun.COM ainfo->local); 460*9781SMoriah.Waterland@Sun.COM return (VE_FAIL); 461*9781SMoriah.Waterland@Sun.COM } 462*9781SMoriah.Waterland@Sun.COM /* Now do the link. */ 463*9781SMoriah.Waterland@Sun.COM if (!clear_target(path, ftype, targ_is_dir)) 464*9781SMoriah.Waterland@Sun.COM return (VE_FAIL); 465*9781SMoriah.Waterland@Sun.COM 466*9781SMoriah.Waterland@Sun.COM if (link(ainfo->local, path)) { 467*9781SMoriah.Waterland@Sun.COM chdir(cwd); 468*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_LINKFAIL), 469*9781SMoriah.Waterland@Sun.COM ainfo->local); 470*9781SMoriah.Waterland@Sun.COM return (VE_FAIL); 471*9781SMoriah.Waterland@Sun.COM } 472*9781SMoriah.Waterland@Sun.COM retcode = 0; 473*9781SMoriah.Waterland@Sun.COM } else { 474*9781SMoriah.Waterland@Sun.COM /* Go back to previous working directory */ 475*9781SMoriah.Waterland@Sun.COM if (chdir(cwd) != 0) 476*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_CHDIR), cwd); 477*9781SMoriah.Waterland@Sun.COM 478*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_LINK), ainfo->local); 479*9781SMoriah.Waterland@Sun.COM return (VE_CONT); 480*9781SMoriah.Waterland@Sun.COM } 481*9781SMoriah.Waterland@Sun.COM } 482*9781SMoriah.Waterland@Sun.COM 483*9781SMoriah.Waterland@Sun.COM /* Go back to previous working directory */ 484*9781SMoriah.Waterland@Sun.COM if (chdir(cwd) != 0) { 485*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_CHDIR), cwd); 486*9781SMoriah.Waterland@Sun.COM return (VE_CONT); 487*9781SMoriah.Waterland@Sun.COM } 488*9781SMoriah.Waterland@Sun.COM 489*9781SMoriah.Waterland@Sun.COM return (retcode); 490*9781SMoriah.Waterland@Sun.COM } 491*9781SMoriah.Waterland@Sun.COM 492*9781SMoriah.Waterland@Sun.COM retcode = 0; 493*9781SMoriah.Waterland@Sun.COM 494*9781SMoriah.Waterland@Sun.COM /* If we are to process symlinks the old way then we follow the link */ 495*9781SMoriah.Waterland@Sun.COM if (nonABI_symlinks()) { 496*9781SMoriah.Waterland@Sun.COM if ((*ftype == 's') ? lstat(path, &status) : 497*9781SMoriah.Waterland@Sun.COM stat(path, &status)) { 498*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_EXIST)); 499*9781SMoriah.Waterland@Sun.COM retcode = VE_EXIST; 500*9781SMoriah.Waterland@Sun.COM myftype = '?'; 501*9781SMoriah.Waterland@Sun.COM statError++; 502*9781SMoriah.Waterland@Sun.COM } 503*9781SMoriah.Waterland@Sun.COM /* If not then we inspect the target of the link */ 504*9781SMoriah.Waterland@Sun.COM } else { 505*9781SMoriah.Waterland@Sun.COM if ((n = lstat(path, &status)) == -1) { 506*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_EXIST)); 507*9781SMoriah.Waterland@Sun.COM retcode = VE_EXIST; 508*9781SMoriah.Waterland@Sun.COM myftype = '?'; 509*9781SMoriah.Waterland@Sun.COM statError++; 510*9781SMoriah.Waterland@Sun.COM } 511*9781SMoriah.Waterland@Sun.COM } 512*9781SMoriah.Waterland@Sun.COM if (!statError) { 513*9781SMoriah.Waterland@Sun.COM /* determining actual type of existing object */ 514*9781SMoriah.Waterland@Sun.COM switch (status.st_mode & S_IFMT) { 515*9781SMoriah.Waterland@Sun.COM case S_IFLNK: 516*9781SMoriah.Waterland@Sun.COM myftype = 's'; 517*9781SMoriah.Waterland@Sun.COM break; 518*9781SMoriah.Waterland@Sun.COM 519*9781SMoriah.Waterland@Sun.COM case S_IFIFO: 520*9781SMoriah.Waterland@Sun.COM myftype = 'p'; 521*9781SMoriah.Waterland@Sun.COM break; 522*9781SMoriah.Waterland@Sun.COM 523*9781SMoriah.Waterland@Sun.COM case S_IFCHR: 524*9781SMoriah.Waterland@Sun.COM myftype = 'c'; 525*9781SMoriah.Waterland@Sun.COM break; 526*9781SMoriah.Waterland@Sun.COM 527*9781SMoriah.Waterland@Sun.COM case S_IFDIR: 528*9781SMoriah.Waterland@Sun.COM myftype = 'd'; 529*9781SMoriah.Waterland@Sun.COM targ_is_dir = 1; 530*9781SMoriah.Waterland@Sun.COM break; 531*9781SMoriah.Waterland@Sun.COM 532*9781SMoriah.Waterland@Sun.COM case S_IFBLK: 533*9781SMoriah.Waterland@Sun.COM myftype = 'b'; 534*9781SMoriah.Waterland@Sun.COM break; 535*9781SMoriah.Waterland@Sun.COM 536*9781SMoriah.Waterland@Sun.COM case S_IFREG: 537*9781SMoriah.Waterland@Sun.COM case 0: 538*9781SMoriah.Waterland@Sun.COM myftype = 'f'; 539*9781SMoriah.Waterland@Sun.COM break; 540*9781SMoriah.Waterland@Sun.COM 541*9781SMoriah.Waterland@Sun.COM case S_IFDOOR: 542*9781SMoriah.Waterland@Sun.COM myftype = 'D'; 543*9781SMoriah.Waterland@Sun.COM break; 544*9781SMoriah.Waterland@Sun.COM 545*9781SMoriah.Waterland@Sun.COM default: 546*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_UNKNOWN)); 547*9781SMoriah.Waterland@Sun.COM return (VE_FTYPE); 548*9781SMoriah.Waterland@Sun.COM } 549*9781SMoriah.Waterland@Sun.COM } 550*9781SMoriah.Waterland@Sun.COM 551*9781SMoriah.Waterland@Sun.COM if (setval) { 552*9781SMoriah.Waterland@Sun.COM /* 553*9781SMoriah.Waterland@Sun.COM * Check to make sure that a package or an installf that uses 554*9781SMoriah.Waterland@Sun.COM * wild cards '?' to assume the ftype of an object on the 555*9781SMoriah.Waterland@Sun.COM * system is not assuming a door ftype. Doors are not supported 556*9781SMoriah.Waterland@Sun.COM * but should be ignored. 557*9781SMoriah.Waterland@Sun.COM */ 558*9781SMoriah.Waterland@Sun.COM if (myftype == 'D') { 559*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_FTYPED), path); 560*9781SMoriah.Waterland@Sun.COM retcode = VE_FTYPE; 561*9781SMoriah.Waterland@Sun.COM return (VE_FTYPE); 562*9781SMoriah.Waterland@Sun.COM } else { 563*9781SMoriah.Waterland@Sun.COM *ftype = myftype; 564*9781SMoriah.Waterland@Sun.COM } 565*9781SMoriah.Waterland@Sun.COM } else if (!retcode && (*ftype != myftype) && 566*9781SMoriah.Waterland@Sun.COM ((myftype != 'f') || !strchr("ilev", *ftype)) && 567*9781SMoriah.Waterland@Sun.COM ((myftype != 'd') || (*ftype != 'x'))) { 568*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_FTYPE), *ftype, myftype); 569*9781SMoriah.Waterland@Sun.COM retcode = VE_FTYPE; 570*9781SMoriah.Waterland@Sun.COM } 571*9781SMoriah.Waterland@Sun.COM 572*9781SMoriah.Waterland@Sun.COM if (!retcode && (*ftype == 's')) { 573*9781SMoriah.Waterland@Sun.COM /* make sure that symbolic link is correct */ 574*9781SMoriah.Waterland@Sun.COM n = readlink(path, buf, PATH_MAX); 575*9781SMoriah.Waterland@Sun.COM if (n < 0) { 576*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_SLINK), ainfo->local); 577*9781SMoriah.Waterland@Sun.COM retcode = VE_CONT; 578*9781SMoriah.Waterland@Sun.COM } else if (ainfo->local != NULL) { 579*9781SMoriah.Waterland@Sun.COM buf[n] = '\0'; 580*9781SMoriah.Waterland@Sun.COM if (strcmp(buf, ainfo->local)) { 581*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_SLINK), ainfo->local); 582*9781SMoriah.Waterland@Sun.COM retcode = VE_CONT; 583*9781SMoriah.Waterland@Sun.COM } 584*9781SMoriah.Waterland@Sun.COM } else if (ainfo->local == NULL) { 585*9781SMoriah.Waterland@Sun.COM /* 586*9781SMoriah.Waterland@Sun.COM * Since a sym link target exists, insert it 587*9781SMoriah.Waterland@Sun.COM * into the ainfo structure 588*9781SMoriah.Waterland@Sun.COM */ 589*9781SMoriah.Waterland@Sun.COM buf[n] = '\0'; 590*9781SMoriah.Waterland@Sun.COM ainfo->local = strdup(buf); 591*9781SMoriah.Waterland@Sun.COM } 592*9781SMoriah.Waterland@Sun.COM } 593*9781SMoriah.Waterland@Sun.COM 594*9781SMoriah.Waterland@Sun.COM if (retcode) { 595*9781SMoriah.Waterland@Sun.COM /* The path doesn't exist or is different than it should be. */ 596*9781SMoriah.Waterland@Sun.COM if (fix) { 597*9781SMoriah.Waterland@Sun.COM /* 598*9781SMoriah.Waterland@Sun.COM * Clear the way for the write. If it won't clear, 599*9781SMoriah.Waterland@Sun.COM * there's nothing we can do. 600*9781SMoriah.Waterland@Sun.COM */ 601*9781SMoriah.Waterland@Sun.COM if (!clear_target(path, ftype, targ_is_dir)) 602*9781SMoriah.Waterland@Sun.COM return (VE_FAIL); 603*9781SMoriah.Waterland@Sun.COM 604*9781SMoriah.Waterland@Sun.COM if ((*ftype == 'd') || (*ftype == 'x')) { 605*9781SMoriah.Waterland@Sun.COM char *pt, *p; 606*9781SMoriah.Waterland@Sun.COM 607*9781SMoriah.Waterland@Sun.COM /* Try to make it the easy way */ 608*9781SMoriah.Waterland@Sun.COM if (mkdir(path, ainfo->mode)) { 609*9781SMoriah.Waterland@Sun.COM /* 610*9781SMoriah.Waterland@Sun.COM * Failing that, walk through the 611*9781SMoriah.Waterland@Sun.COM * parent directories creating 612*9781SMoriah.Waterland@Sun.COM * whatever is needed. 613*9781SMoriah.Waterland@Sun.COM */ 614*9781SMoriah.Waterland@Sun.COM p = strdup(path); 615*9781SMoriah.Waterland@Sun.COM pt = (*p == '/') ? p+1 : p; 616*9781SMoriah.Waterland@Sun.COM do { 617*9781SMoriah.Waterland@Sun.COM if (pt = strchr(pt, '/')) 618*9781SMoriah.Waterland@Sun.COM *pt = '\0'; 619*9781SMoriah.Waterland@Sun.COM if (access(p, 0) && 620*9781SMoriah.Waterland@Sun.COM mkdir(p, ainfo->mode)) 621*9781SMoriah.Waterland@Sun.COM break; 622*9781SMoriah.Waterland@Sun.COM if (pt) 623*9781SMoriah.Waterland@Sun.COM *pt++ = '/'; 624*9781SMoriah.Waterland@Sun.COM } while (pt); 625*9781SMoriah.Waterland@Sun.COM free(p); 626*9781SMoriah.Waterland@Sun.COM } 627*9781SMoriah.Waterland@Sun.COM if (stat(path, &status) < 0) { 628*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_DIRFAIL)); 629*9781SMoriah.Waterland@Sun.COM return (VE_FAIL); 630*9781SMoriah.Waterland@Sun.COM } 631*9781SMoriah.Waterland@Sun.COM } else if (*ftype == 's') { 632*9781SMoriah.Waterland@Sun.COM if (symlink(ainfo->local, path)) { 633*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_SLINKFAIL), 634*9781SMoriah.Waterland@Sun.COM ainfo->local); 635*9781SMoriah.Waterland@Sun.COM return (VE_FAIL); 636*9781SMoriah.Waterland@Sun.COM } 637*9781SMoriah.Waterland@Sun.COM 638*9781SMoriah.Waterland@Sun.COM } else if (*ftype == 'c') { 639*9781SMoriah.Waterland@Sun.COM int wilddevno = 0; 640*9781SMoriah.Waterland@Sun.COM /* 641*9781SMoriah.Waterland@Sun.COM * The next three if's support 2.4 and older 642*9781SMoriah.Waterland@Sun.COM * packages that use "?" as device numbers. 643*9781SMoriah.Waterland@Sun.COM * This should be considered for removal by 644*9781SMoriah.Waterland@Sun.COM * release 2.7 or so. 645*9781SMoriah.Waterland@Sun.COM */ 646*9781SMoriah.Waterland@Sun.COM if (ainfo->major == BADMAJOR) { 647*9781SMoriah.Waterland@Sun.COM ainfo->major = 0; 648*9781SMoriah.Waterland@Sun.COM wilddevno = 1; 649*9781SMoriah.Waterland@Sun.COM } 650*9781SMoriah.Waterland@Sun.COM 651*9781SMoriah.Waterland@Sun.COM if (ainfo->minor == BADMINOR) { 652*9781SMoriah.Waterland@Sun.COM ainfo->minor = 0; 653*9781SMoriah.Waterland@Sun.COM wilddevno = 1; 654*9781SMoriah.Waterland@Sun.COM } 655*9781SMoriah.Waterland@Sun.COM 656*9781SMoriah.Waterland@Sun.COM if (wilddevno) { 657*9781SMoriah.Waterland@Sun.COM wilddevno = 0; 658*9781SMoriah.Waterland@Sun.COM logerr(MSG_WLDDEVNO, path, 659*9781SMoriah.Waterland@Sun.COM ainfo->major, ainfo->minor); 660*9781SMoriah.Waterland@Sun.COM } 661*9781SMoriah.Waterland@Sun.COM 662*9781SMoriah.Waterland@Sun.COM if (mknod(path, ainfo->mode | S_IFCHR, 663*9781SMoriah.Waterland@Sun.COM #ifdef SUNOS41 664*9781SMoriah.Waterland@Sun.COM makedev(ainfo->xmajor, ainfo->xminor)) || 665*9781SMoriah.Waterland@Sun.COM #else 666*9781SMoriah.Waterland@Sun.COM makedev(ainfo->major, ainfo->minor)) || 667*9781SMoriah.Waterland@Sun.COM #endif 668*9781SMoriah.Waterland@Sun.COM (stat(path, &status) < 0)) { 669*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_CDEVFAIL)); 670*9781SMoriah.Waterland@Sun.COM return (VE_FAIL); 671*9781SMoriah.Waterland@Sun.COM } 672*9781SMoriah.Waterland@Sun.COM } else if (*ftype == 'b') { 673*9781SMoriah.Waterland@Sun.COM int wilddevno = 0; 674*9781SMoriah.Waterland@Sun.COM /* 675*9781SMoriah.Waterland@Sun.COM * The next three if's support 2.4 and older 676*9781SMoriah.Waterland@Sun.COM * packages that use "?" as device numbers. 677*9781SMoriah.Waterland@Sun.COM * This should be considered for removal by 678*9781SMoriah.Waterland@Sun.COM * release 2.7 or so. 679*9781SMoriah.Waterland@Sun.COM */ 680*9781SMoriah.Waterland@Sun.COM if (ainfo->major == BADMAJOR) { 681*9781SMoriah.Waterland@Sun.COM ainfo->major = 0; 682*9781SMoriah.Waterland@Sun.COM wilddevno = 1; 683*9781SMoriah.Waterland@Sun.COM } 684*9781SMoriah.Waterland@Sun.COM 685*9781SMoriah.Waterland@Sun.COM if (ainfo->minor == BADMINOR) { 686*9781SMoriah.Waterland@Sun.COM ainfo->minor = 0; 687*9781SMoriah.Waterland@Sun.COM wilddevno = 1; 688*9781SMoriah.Waterland@Sun.COM } 689*9781SMoriah.Waterland@Sun.COM 690*9781SMoriah.Waterland@Sun.COM if (wilddevno) { 691*9781SMoriah.Waterland@Sun.COM wilddevno = 0; 692*9781SMoriah.Waterland@Sun.COM logerr(MSG_WLDDEVNO, path, 693*9781SMoriah.Waterland@Sun.COM ainfo->major, ainfo->minor); 694*9781SMoriah.Waterland@Sun.COM } 695*9781SMoriah.Waterland@Sun.COM 696*9781SMoriah.Waterland@Sun.COM if (mknod(path, ainfo->mode | S_IFBLK, 697*9781SMoriah.Waterland@Sun.COM #ifdef SUNOS41 698*9781SMoriah.Waterland@Sun.COM makedev(ainfo->xmajor, ainfo->xminor)) || 699*9781SMoriah.Waterland@Sun.COM #else 700*9781SMoriah.Waterland@Sun.COM makedev(ainfo->major, ainfo->minor)) || 701*9781SMoriah.Waterland@Sun.COM #endif 702*9781SMoriah.Waterland@Sun.COM (stat(path, &status) < 0)) { 703*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_BDEVFAIL)); 704*9781SMoriah.Waterland@Sun.COM return (VE_FAIL); 705*9781SMoriah.Waterland@Sun.COM } 706*9781SMoriah.Waterland@Sun.COM } else if (*ftype == 'p') { 707*9781SMoriah.Waterland@Sun.COM if (mknod(path, ainfo->mode | S_IFIFO, NULL) || 708*9781SMoriah.Waterland@Sun.COM (stat(path, &status) < 0)) { 709*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_PIPEFAIL)); 710*9781SMoriah.Waterland@Sun.COM return (VE_FAIL); 711*9781SMoriah.Waterland@Sun.COM } 712*9781SMoriah.Waterland@Sun.COM } else 713*9781SMoriah.Waterland@Sun.COM return (retcode); 714*9781SMoriah.Waterland@Sun.COM 715*9781SMoriah.Waterland@Sun.COM } else 716*9781SMoriah.Waterland@Sun.COM return (retcode); 717*9781SMoriah.Waterland@Sun.COM } 718*9781SMoriah.Waterland@Sun.COM 719*9781SMoriah.Waterland@Sun.COM if (*ftype == 's') 720*9781SMoriah.Waterland@Sun.COM return (0); /* don't check anything else */ 721*9781SMoriah.Waterland@Sun.COM if (*ftype == 'i') 722*9781SMoriah.Waterland@Sun.COM return (0); /* don't check anything else */ 723*9781SMoriah.Waterland@Sun.COM 724*9781SMoriah.Waterland@Sun.COM retcode = 0; 725*9781SMoriah.Waterland@Sun.COM if ((myftype == 'c') || (myftype == 'b')) { 726*9781SMoriah.Waterland@Sun.COM #ifdef SUNOS41 727*9781SMoriah.Waterland@Sun.COM if (setval || (ainfo->xmajor < 0)) 728*9781SMoriah.Waterland@Sun.COM ainfo->xmajor = ((status.st_rdev>>8)&0377); 729*9781SMoriah.Waterland@Sun.COM if (setval || (ainfo->xminor < 0)) 730*9781SMoriah.Waterland@Sun.COM ainfo->xminor = (status.st_rdev&0377); 731*9781SMoriah.Waterland@Sun.COM /* check major & minor */ 732*9781SMoriah.Waterland@Sun.COM if (status.st_rdev != makedev(ainfo->xmajor, ainfo->xminor)) { 733*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_MAJMIN), ainfo->xmajor, 734*9781SMoriah.Waterland@Sun.COM ainfo->xminor, 735*9781SMoriah.Waterland@Sun.COM (status.st_rdev>>8)&0377, status.st_rdev&0377); 736*9781SMoriah.Waterland@Sun.COM retcode = VE_CONT; 737*9781SMoriah.Waterland@Sun.COM } 738*9781SMoriah.Waterland@Sun.COM #else 739*9781SMoriah.Waterland@Sun.COM if (setval || (ainfo->major == BADMAJOR)) 740*9781SMoriah.Waterland@Sun.COM ainfo->major = major(status.st_rdev); 741*9781SMoriah.Waterland@Sun.COM if (setval || (ainfo->minor == BADMINOR)) 742*9781SMoriah.Waterland@Sun.COM ainfo->minor = minor(status.st_rdev); 743*9781SMoriah.Waterland@Sun.COM /* check major & minor */ 744*9781SMoriah.Waterland@Sun.COM if (status.st_rdev != makedev(ainfo->major, ainfo->minor)) { 745*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_MAJMIN), ainfo->major, ainfo->minor, 746*9781SMoriah.Waterland@Sun.COM major(status.st_rdev), minor(status.st_rdev)); 747*9781SMoriah.Waterland@Sun.COM retcode = VE_CONT; 748*9781SMoriah.Waterland@Sun.COM } 749*9781SMoriah.Waterland@Sun.COM #endif 750*9781SMoriah.Waterland@Sun.COM } 751*9781SMoriah.Waterland@Sun.COM 752*9781SMoriah.Waterland@Sun.COM /* compare specified mode w/ actual mode excluding sticky bit */ 753*9781SMoriah.Waterland@Sun.COM if (setval || (ainfo->mode == BADMODE) || (ainfo->mode == WILDCARD)) 754*9781SMoriah.Waterland@Sun.COM ainfo->mode = status.st_mode & 07777; 755*9781SMoriah.Waterland@Sun.COM else if ((ainfo->mode & 06777) != (status.st_mode & 06777)) { 756*9781SMoriah.Waterland@Sun.COM if (fix) { 757*9781SMoriah.Waterland@Sun.COM if ((ainfo->mode == BADMODE) || 758*9781SMoriah.Waterland@Sun.COM (chmod(path, ainfo->mode) < 0)) 759*9781SMoriah.Waterland@Sun.COM retcode = VE_FAIL; 760*9781SMoriah.Waterland@Sun.COM } else { 761*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_PERM), ainfo->mode, 762*9781SMoriah.Waterland@Sun.COM status.st_mode & 07777); 763*9781SMoriah.Waterland@Sun.COM if (!retcode) 764*9781SMoriah.Waterland@Sun.COM retcode = VE_ATTR; 765*9781SMoriah.Waterland@Sun.COM } 766*9781SMoriah.Waterland@Sun.COM } 767*9781SMoriah.Waterland@Sun.COM 768*9781SMoriah.Waterland@Sun.COM dochown = 0; 769*9781SMoriah.Waterland@Sun.COM 770*9781SMoriah.Waterland@Sun.COM /* get group entry for specified group */ 771*9781SMoriah.Waterland@Sun.COM if (setval || strcmp(ainfo->group, BADGROUP) == 0) { 772*9781SMoriah.Waterland@Sun.COM grp = cgrgid(status.st_gid); 773*9781SMoriah.Waterland@Sun.COM if (grp) 774*9781SMoriah.Waterland@Sun.COM (void) strcpy(ainfo->group, grp->gr_name); 775*9781SMoriah.Waterland@Sun.COM else { 776*9781SMoriah.Waterland@Sun.COM if (!retcode) 777*9781SMoriah.Waterland@Sun.COM retcode = VE_ATTR; 778*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_BADGRPID), status.st_gid); 779*9781SMoriah.Waterland@Sun.COM } 780*9781SMoriah.Waterland@Sun.COM gid = status.st_gid; 781*9781SMoriah.Waterland@Sun.COM } else if ((grp = cgrnam(ainfo->group)) == NULL) { 782*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_BADGRPNM), ainfo->group); 783*9781SMoriah.Waterland@Sun.COM if (!retcode) 784*9781SMoriah.Waterland@Sun.COM retcode = VE_ATTR; 785*9781SMoriah.Waterland@Sun.COM } else if ((gid = grp->gr_gid) != status.st_gid) { 786*9781SMoriah.Waterland@Sun.COM if (fix) { 787*9781SMoriah.Waterland@Sun.COM /* save specified GID */ 788*9781SMoriah.Waterland@Sun.COM gid = grp->gr_gid; 789*9781SMoriah.Waterland@Sun.COM dochown++; 790*9781SMoriah.Waterland@Sun.COM } else { 791*9781SMoriah.Waterland@Sun.COM if ((grp = cgrgid((int)status.st_gid)) == 792*9781SMoriah.Waterland@Sun.COM (struct group *)NULL) { 793*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_GROUP), ainfo->group, 794*9781SMoriah.Waterland@Sun.COM "(null)"); 795*9781SMoriah.Waterland@Sun.COM } else { 796*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_GROUP), ainfo->group, 797*9781SMoriah.Waterland@Sun.COM grp->gr_name); 798*9781SMoriah.Waterland@Sun.COM } 799*9781SMoriah.Waterland@Sun.COM if (!retcode) 800*9781SMoriah.Waterland@Sun.COM retcode = VE_ATTR; 801*9781SMoriah.Waterland@Sun.COM } 802*9781SMoriah.Waterland@Sun.COM } 803*9781SMoriah.Waterland@Sun.COM 804*9781SMoriah.Waterland@Sun.COM /* get password entry for specified owner */ 805*9781SMoriah.Waterland@Sun.COM if (setval || strcmp(ainfo->owner, BADOWNER) == 0) { 806*9781SMoriah.Waterland@Sun.COM pwd = cpwuid((int)status.st_uid); 807*9781SMoriah.Waterland@Sun.COM if (pwd) 808*9781SMoriah.Waterland@Sun.COM (void) strcpy(ainfo->owner, pwd->pw_name); 809*9781SMoriah.Waterland@Sun.COM else { 810*9781SMoriah.Waterland@Sun.COM if (!retcode) 811*9781SMoriah.Waterland@Sun.COM retcode = VE_ATTR; 812*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_BADUSRID), status.st_uid); 813*9781SMoriah.Waterland@Sun.COM } 814*9781SMoriah.Waterland@Sun.COM uid = status.st_uid; 815*9781SMoriah.Waterland@Sun.COM } else if ((pwd = cpwnam(ainfo->owner)) == NULL) { 816*9781SMoriah.Waterland@Sun.COM /* UID does not exist in password file */ 817*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_BADUSRNM), ainfo->owner); 818*9781SMoriah.Waterland@Sun.COM if (!retcode) 819*9781SMoriah.Waterland@Sun.COM retcode = VE_ATTR; 820*9781SMoriah.Waterland@Sun.COM } else if ((uid = pwd->pw_uid) != status.st_uid) { 821*9781SMoriah.Waterland@Sun.COM /* get owner name for actual UID */ 822*9781SMoriah.Waterland@Sun.COM if (fix) { 823*9781SMoriah.Waterland@Sun.COM uid = pwd->pw_uid; 824*9781SMoriah.Waterland@Sun.COM dochown++; 825*9781SMoriah.Waterland@Sun.COM } else { 826*9781SMoriah.Waterland@Sun.COM pwd = cpwuid((int)status.st_uid); 827*9781SMoriah.Waterland@Sun.COM if (pwd == NULL) 828*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_BADUSRID), 829*9781SMoriah.Waterland@Sun.COM (int)status.st_uid); 830*9781SMoriah.Waterland@Sun.COM else 831*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_OWNER), ainfo->owner, 832*9781SMoriah.Waterland@Sun.COM pwd->pw_name); 833*9781SMoriah.Waterland@Sun.COM 834*9781SMoriah.Waterland@Sun.COM if (!retcode) 835*9781SMoriah.Waterland@Sun.COM retcode = VE_ATTR; 836*9781SMoriah.Waterland@Sun.COM } 837*9781SMoriah.Waterland@Sun.COM } 838*9781SMoriah.Waterland@Sun.COM 839*9781SMoriah.Waterland@Sun.COM if (statvfs(path, &vfsstatus) < 0) { 840*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_EXIST)); 841*9781SMoriah.Waterland@Sun.COM retcode = VE_FAIL; 842*9781SMoriah.Waterland@Sun.COM } else { 843*9781SMoriah.Waterland@Sun.COM if (dochown) { 844*9781SMoriah.Waterland@Sun.COM /* pcfs doesn't support file ownership */ 845*9781SMoriah.Waterland@Sun.COM if (strcmp(vfsstatus.f_basetype, "pcfs") != 0 && 846*9781SMoriah.Waterland@Sun.COM chown(path, uid, gid) < 0) { 847*9781SMoriah.Waterland@Sun.COM retcode = VE_FAIL; /* chown failed */ 848*9781SMoriah.Waterland@Sun.COM } 849*9781SMoriah.Waterland@Sun.COM } 850*9781SMoriah.Waterland@Sun.COM } 851*9781SMoriah.Waterland@Sun.COM 852*9781SMoriah.Waterland@Sun.COM if (retcode == VE_FAIL) 853*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(ERR_ATTRFAIL)); 854*9781SMoriah.Waterland@Sun.COM return (retcode); 855*9781SMoriah.Waterland@Sun.COM } 856*9781SMoriah.Waterland@Sun.COM 857*9781SMoriah.Waterland@Sun.COM /* 858*9781SMoriah.Waterland@Sun.COM * This is a special fast verify which basically checks the attributes 859*9781SMoriah.Waterland@Sun.COM * and then, if all is OK, checks the size and mod time using the same 860*9781SMoriah.Waterland@Sun.COM * stat and statvfs structures. 861*9781SMoriah.Waterland@Sun.COM */ 862*9781SMoriah.Waterland@Sun.COM int 863*9781SMoriah.Waterland@Sun.COM fverify(int fix, char *ftype, char *path, struct ainfo *ainfo, 864*9781SMoriah.Waterland@Sun.COM struct cinfo *cinfo) 865*9781SMoriah.Waterland@Sun.COM { 866*9781SMoriah.Waterland@Sun.COM int retval; 867*9781SMoriah.Waterland@Sun.COM 868*9781SMoriah.Waterland@Sun.COM /* return success if attribute checks are disabled */ 869*9781SMoriah.Waterland@Sun.COM 870*9781SMoriah.Waterland@Sun.COM if (get_disable_attribute_check()) { 871*9781SMoriah.Waterland@Sun.COM return (0); 872*9781SMoriah.Waterland@Sun.COM } 873*9781SMoriah.Waterland@Sun.COM 874*9781SMoriah.Waterland@Sun.COM if ((retval = averify(fix, ftype, path, ainfo)) == 0) { 875*9781SMoriah.Waterland@Sun.COM if (*ftype == 'f' || *ftype == 'i') { 876*9781SMoriah.Waterland@Sun.COM if (cinfo->size != status.st_size) { 877*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(WRN_QV_SIZE), path); 878*9781SMoriah.Waterland@Sun.COM retval = VE_CONT; 879*9781SMoriah.Waterland@Sun.COM } 880*9781SMoriah.Waterland@Sun.COM /* pcfs doesn't support modification times */ 881*9781SMoriah.Waterland@Sun.COM if (strcmp(vfsstatus.f_basetype, "pcfs") != 0) { 882*9781SMoriah.Waterland@Sun.COM if (cinfo->modtime != status.st_mtime) { 883*9781SMoriah.Waterland@Sun.COM reperr(pkg_gt(WRN_QV_MTIME), path); 884*9781SMoriah.Waterland@Sun.COM retval = VE_CONT; 885*9781SMoriah.Waterland@Sun.COM } 886*9781SMoriah.Waterland@Sun.COM } 887*9781SMoriah.Waterland@Sun.COM } 888*9781SMoriah.Waterland@Sun.COM } 889*9781SMoriah.Waterland@Sun.COM 890*9781SMoriah.Waterland@Sun.COM return (retval); 891*9781SMoriah.Waterland@Sun.COM } 892*9781SMoriah.Waterland@Sun.COM 893*9781SMoriah.Waterland@Sun.COM /* 894*9781SMoriah.Waterland@Sun.COM * This function determines whether or not non-ABI symlinks are supported. 895*9781SMoriah.Waterland@Sun.COM */ 896*9781SMoriah.Waterland@Sun.COM 897*9781SMoriah.Waterland@Sun.COM int 898*9781SMoriah.Waterland@Sun.COM nonABI_symlinks(void) 899*9781SMoriah.Waterland@Sun.COM { 900*9781SMoriah.Waterland@Sun.COM return (nonabi_symlinks); 901*9781SMoriah.Waterland@Sun.COM } 902*9781SMoriah.Waterland@Sun.COM 903*9781SMoriah.Waterland@Sun.COM void 904*9781SMoriah.Waterland@Sun.COM set_nonABI_symlinks(void) 905*9781SMoriah.Waterland@Sun.COM { 906*9781SMoriah.Waterland@Sun.COM nonabi_symlinks = 1; 907*9781SMoriah.Waterland@Sun.COM } 908*9781SMoriah.Waterland@Sun.COM 909*9781SMoriah.Waterland@Sun.COM /* 910*9781SMoriah.Waterland@Sun.COM * Disable attribute checking. Only disable attribute checking if files 911*9781SMoriah.Waterland@Sun.COM * are guaranteed to exist in the FS. 912*9781SMoriah.Waterland@Sun.COM */ 913*9781SMoriah.Waterland@Sun.COM void 914*9781SMoriah.Waterland@Sun.COM disable_attribute_check(void) 915*9781SMoriah.Waterland@Sun.COM { 916*9781SMoriah.Waterland@Sun.COM disable_attributes = 1; 917*9781SMoriah.Waterland@Sun.COM } 918*9781SMoriah.Waterland@Sun.COM 919*9781SMoriah.Waterland@Sun.COM /* 920*9781SMoriah.Waterland@Sun.COM * This function determines whether or not to do attribute checking. 921*9781SMoriah.Waterland@Sun.COM * Returns: 0 - Do attribute checking 922*9781SMoriah.Waterland@Sun.COM * !0 - Don't do attribute checking 923*9781SMoriah.Waterland@Sun.COM */ 924*9781SMoriah.Waterland@Sun.COM int 925*9781SMoriah.Waterland@Sun.COM get_disable_attribute_check(void) 926*9781SMoriah.Waterland@Sun.COM { 927*9781SMoriah.Waterland@Sun.COM return (disable_attributes); 928*9781SMoriah.Waterland@Sun.COM } 929*9781SMoriah.Waterland@Sun.COM 930*9781SMoriah.Waterland@Sun.COM /* 931*9781SMoriah.Waterland@Sun.COM * This function returns the address of the "global" error buffer that 932*9781SMoriah.Waterland@Sun.COM * is populated by the various functions in this module. 933*9781SMoriah.Waterland@Sun.COM */ 934*9781SMoriah.Waterland@Sun.COM 935*9781SMoriah.Waterland@Sun.COM char * 936*9781SMoriah.Waterland@Sun.COM getErrbufAddr(void) 937*9781SMoriah.Waterland@Sun.COM { 938*9781SMoriah.Waterland@Sun.COM return (theErrBuf); 939*9781SMoriah.Waterland@Sun.COM } 940*9781SMoriah.Waterland@Sun.COM 941*9781SMoriah.Waterland@Sun.COM /* 942*9781SMoriah.Waterland@Sun.COM * This function returns the size of the buffer returned by getErrbufAddr() 943*9781SMoriah.Waterland@Sun.COM */ 944*9781SMoriah.Waterland@Sun.COM 945*9781SMoriah.Waterland@Sun.COM int 946*9781SMoriah.Waterland@Sun.COM getErrbufSize(void) 947*9781SMoriah.Waterland@Sun.COM { 948*9781SMoriah.Waterland@Sun.COM return (sizeof (theErrBuf)); 949*9781SMoriah.Waterland@Sun.COM } 950*9781SMoriah.Waterland@Sun.COM 951*9781SMoriah.Waterland@Sun.COM /* 952*9781SMoriah.Waterland@Sun.COM * This function returns the current global "error string" 953*9781SMoriah.Waterland@Sun.COM */ 954*9781SMoriah.Waterland@Sun.COM 955*9781SMoriah.Waterland@Sun.COM char * 956*9781SMoriah.Waterland@Sun.COM getErrstr(void) 957*9781SMoriah.Waterland@Sun.COM { 958*9781SMoriah.Waterland@Sun.COM return (theErrStr); 959*9781SMoriah.Waterland@Sun.COM } 960*9781SMoriah.Waterland@Sun.COM 961*9781SMoriah.Waterland@Sun.COM /* 962*9781SMoriah.Waterland@Sun.COM * This function sets the global "error string" 963*9781SMoriah.Waterland@Sun.COM */ 964*9781SMoriah.Waterland@Sun.COM 965*9781SMoriah.Waterland@Sun.COM void 966*9781SMoriah.Waterland@Sun.COM setErrstr(char *a_errstr) 967*9781SMoriah.Waterland@Sun.COM { 968*9781SMoriah.Waterland@Sun.COM theErrStr = a_errstr; 969*9781SMoriah.Waterland@Sun.COM } 970*9781SMoriah.Waterland@Sun.COM 971*9781SMoriah.Waterland@Sun.COM /* 972*9781SMoriah.Waterland@Sun.COM * This function enables checksumming 973*9781SMoriah.Waterland@Sun.COM */ 974*9781SMoriah.Waterland@Sun.COM 975*9781SMoriah.Waterland@Sun.COM void 976*9781SMoriah.Waterland@Sun.COM checksum_on(void) 977*9781SMoriah.Waterland@Sun.COM { 978*9781SMoriah.Waterland@Sun.COM enable_checksum = 1; 979*9781SMoriah.Waterland@Sun.COM } 980*9781SMoriah.Waterland@Sun.COM 981*9781SMoriah.Waterland@Sun.COM /* 982*9781SMoriah.Waterland@Sun.COM * This function disables checksumming 983*9781SMoriah.Waterland@Sun.COM */ 984*9781SMoriah.Waterland@Sun.COM 985*9781SMoriah.Waterland@Sun.COM void 986*9781SMoriah.Waterland@Sun.COM checksum_off(void) 987*9781SMoriah.Waterland@Sun.COM { 988*9781SMoriah.Waterland@Sun.COM enable_checksum = 0; 989*9781SMoriah.Waterland@Sun.COM } 990