17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 237c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 277c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 287c478bd9Sstevel@tonic-gate * Use is subject to license terms. 297c478bd9Sstevel@tonic-gate */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/ 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate /* 5-20-92 added newroot functions */ 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #include <stdio.h> 367c478bd9Sstevel@tonic-gate #include <limits.h> 377c478bd9Sstevel@tonic-gate #include <stdarg.h> 387c478bd9Sstevel@tonic-gate #include <unistd.h> 397c478bd9Sstevel@tonic-gate #include <stdlib.h> 407c478bd9Sstevel@tonic-gate #include <ctype.h> 417c478bd9Sstevel@tonic-gate #include <string.h> 427c478bd9Sstevel@tonic-gate #include <sys/types.h> 437c478bd9Sstevel@tonic-gate #include <sys/stat.h> 447c478bd9Sstevel@tonic-gate #include <dirent.h> 457c478bd9Sstevel@tonic-gate #include <pkginfo.h> 467c478bd9Sstevel@tonic-gate #include <pkgstrct.h> 477c478bd9Sstevel@tonic-gate #include <pkglocs.h> 487c478bd9Sstevel@tonic-gate #include <errno.h> 497c478bd9Sstevel@tonic-gate #include "libadm.h" 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate static void initpkg(struct pkginfo *); 527c478bd9Sstevel@tonic-gate static int rdconfig(struct pkginfo *, char *, char *); 537c478bd9Sstevel@tonic-gate static int ckinfo(char *, char *, char *); 547c478bd9Sstevel@tonic-gate static int ckinst(char *, char *, char *, char *, char *); 557c478bd9Sstevel@tonic-gate static int verscmp(char *, char *); 567c478bd9Sstevel@tonic-gate static int archcmp(char *, char *); 577c478bd9Sstevel@tonic-gate static int compver(char *, char *); 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate /* 607c478bd9Sstevel@tonic-gate * Globals: 617c478bd9Sstevel@tonic-gate * pkgdir - specifies the directory where information about packages 627c478bd9Sstevel@tonic-gate * resides, i.e. the pkginfo file is located in a subdirectory 637c478bd9Sstevel@tonic-gate * 647c478bd9Sstevel@tonic-gate * Caveats: 657c478bd9Sstevel@tonic-gate * The structure provided via "info" will contain malloc'd information; 667c478bd9Sstevel@tonic-gate * this will be free'd upon the next call to pkginfo with this 677c478bd9Sstevel@tonic-gate * same structure. Application calls must make sure this structure 687c478bd9Sstevel@tonic-gate * is null on the first call, or else we'll free static memory areas 697c478bd9Sstevel@tonic-gate * If the "pkg" argument is a wildcard specification, the next found 707c478bd9Sstevel@tonic-gate * instance available which matches the request will be returned 717c478bd9Sstevel@tonic-gate * If the "pkg" argument is a NULL pointer, the structure pointed to 727c478bd9Sstevel@tonic-gate * via "info" will have its elements deallocated and all files 737c478bd9Sstevel@tonic-gate * associated with this routine will be closed 747c478bd9Sstevel@tonic-gate * 757c478bd9Sstevel@tonic-gate * Return codes: 767c478bd9Sstevel@tonic-gate * A non-zero exit code indicates error with "errno" appropriately set: 777c478bd9Sstevel@tonic-gate * EINVAL - invalid argument 787c478bd9Sstevel@tonic-gate * ESRCH - there are no more instances of this package around 797c478bd9Sstevel@tonic-gate * EACCESS - unable to access files which should have been there 807c478bd9Sstevel@tonic-gate */ 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate /*VARARGS*/ 837c478bd9Sstevel@tonic-gate int 847c478bd9Sstevel@tonic-gate pkginfo(struct pkginfo *info, char *pkginst, ...) 857c478bd9Sstevel@tonic-gate { 867c478bd9Sstevel@tonic-gate char *ckarch, *ckvers; 877c478bd9Sstevel@tonic-gate int check; 887c478bd9Sstevel@tonic-gate va_list ap; 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate va_start(ap, pkginst); 917c478bd9Sstevel@tonic-gate if (info == NULL) { 927c478bd9Sstevel@tonic-gate errno = EINVAL; 937c478bd9Sstevel@tonic-gate return (-1); 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate if (pkginst == NULL) { 967c478bd9Sstevel@tonic-gate info->pkginst = NULL; 977c478bd9Sstevel@tonic-gate (void) fpkginfo(info, NULL); 987c478bd9Sstevel@tonic-gate (void) fpkginst(NULL); 997c478bd9Sstevel@tonic-gate return (0); 1007c478bd9Sstevel@tonic-gate } 1017c478bd9Sstevel@tonic-gate ckarch = va_arg(ap, char *); 1027c478bd9Sstevel@tonic-gate ckvers = va_arg(ap, char *); 1037c478bd9Sstevel@tonic-gate va_end(ap); 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate check = 0; 1067c478bd9Sstevel@tonic-gate if (pkgnmchk(pkginst, "all", 1)) { 1077c478bd9Sstevel@tonic-gate /* wild card specification */ 1087c478bd9Sstevel@tonic-gate pkginst = fpkginst(pkginst, ckarch, ckvers); 1097c478bd9Sstevel@tonic-gate if (pkginst == NULL) 1107c478bd9Sstevel@tonic-gate return (-1); 1117c478bd9Sstevel@tonic-gate } else { 1127c478bd9Sstevel@tonic-gate /* request to check indicated instance */ 1137c478bd9Sstevel@tonic-gate if (ckarch || ckvers) 1147c478bd9Sstevel@tonic-gate check++; 1157c478bd9Sstevel@tonic-gate } 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate info->pkginst = NULL; 1187c478bd9Sstevel@tonic-gate if (fpkginfo(info, pkginst)) 1197c478bd9Sstevel@tonic-gate return (-1); 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate if (check) { 1227c478bd9Sstevel@tonic-gate /* 1237c478bd9Sstevel@tonic-gate * verify that the provided instance matches 1247c478bd9Sstevel@tonic-gate * any arch & vers specs that were provided 1257c478bd9Sstevel@tonic-gate */ 1267c478bd9Sstevel@tonic-gate if (ckinst(pkginst, info->arch, info->version, ckarch, 1277c478bd9Sstevel@tonic-gate ckvers)) { 1287c478bd9Sstevel@tonic-gate errno = ESRCH; 1297c478bd9Sstevel@tonic-gate return (-1); 1307c478bd9Sstevel@tonic-gate } 1317c478bd9Sstevel@tonic-gate } 1327c478bd9Sstevel@tonic-gate return (0); 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate int 1377c478bd9Sstevel@tonic-gate fpkginfo(struct pkginfo *info, char *pkginst) 1387c478bd9Sstevel@tonic-gate { 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate if (info == NULL) { 1417c478bd9Sstevel@tonic-gate errno = EINVAL; 1427c478bd9Sstevel@tonic-gate return (-1); 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate initpkg(info); 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate if (pkginst == NULL) 1487c478bd9Sstevel@tonic-gate return (0); 1497c478bd9Sstevel@tonic-gate else if (pkgnmchk(pkginst, "all", 1)) { 1507c478bd9Sstevel@tonic-gate errno = EINVAL; /* not an instance identifier */ 1517c478bd9Sstevel@tonic-gate return (-1); 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate if (pkgdir == NULL) 1547c478bd9Sstevel@tonic-gate pkgdir = get_PKGLOC(); 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate if (rdconfig(info, pkginst, NULL)) { 1577c478bd9Sstevel@tonic-gate initpkg(info); 1587c478bd9Sstevel@tonic-gate return (-1); 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate return (0); 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate static void 1647c478bd9Sstevel@tonic-gate initpkg(struct pkginfo *info) 1657c478bd9Sstevel@tonic-gate { 1667c478bd9Sstevel@tonic-gate /* free previously allocated space */ 1677c478bd9Sstevel@tonic-gate if (info->pkginst) { 1687c478bd9Sstevel@tonic-gate free(info->pkginst); 1697c478bd9Sstevel@tonic-gate if (info->arch) 1707c478bd9Sstevel@tonic-gate free(info->arch); 1717c478bd9Sstevel@tonic-gate if (info->version) 1727c478bd9Sstevel@tonic-gate free(info->version); 1737c478bd9Sstevel@tonic-gate if (info->basedir) 1747c478bd9Sstevel@tonic-gate free(info->basedir); 1757c478bd9Sstevel@tonic-gate if (info->name) 1767c478bd9Sstevel@tonic-gate free(info->name); 1777c478bd9Sstevel@tonic-gate if (info->vendor) 1787c478bd9Sstevel@tonic-gate free(info->vendor); 1797c478bd9Sstevel@tonic-gate if (info->catg) 1807c478bd9Sstevel@tonic-gate free(info->catg); 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate info->pkginst = NULL; 1847c478bd9Sstevel@tonic-gate info->arch = info->version = NULL; 1857c478bd9Sstevel@tonic-gate info->basedir = info->name = NULL; 1867c478bd9Sstevel@tonic-gate info->vendor = info->catg = NULL; 1877c478bd9Sstevel@tonic-gate info->status = PI_UNKNOWN; 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate static int 1917c478bd9Sstevel@tonic-gate rdconfig(struct pkginfo *info, char *pkginst, char *ckvers) 1927c478bd9Sstevel@tonic-gate { 1937c478bd9Sstevel@tonic-gate FILE *fp; 1947c478bd9Sstevel@tonic-gate char temp[256]; 1957c478bd9Sstevel@tonic-gate char *value, *pt, *copy, **memloc; 1967c478bd9Sstevel@tonic-gate int count; 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate if ((fp = pkginfopen(pkgdir, pkginst)) == NULL) { 1997c478bd9Sstevel@tonic-gate errno = EACCES; 2007c478bd9Sstevel@tonic-gate return (-1); 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate *temp = '\0'; 2047c478bd9Sstevel@tonic-gate count = 0; 2057c478bd9Sstevel@tonic-gate while (value = fpkgparam(fp, temp)) { 2067c478bd9Sstevel@tonic-gate if (strcmp(temp, "ARCH") == 0 || 2077c478bd9Sstevel@tonic-gate strcmp(temp, "CATEGORY") == 0) { 2087c478bd9Sstevel@tonic-gate /* remove all whitespace from value */ 2097c478bd9Sstevel@tonic-gate pt = copy = value; 2107c478bd9Sstevel@tonic-gate while (*pt) { 2117c478bd9Sstevel@tonic-gate if (!isspace((unsigned char)*pt)) 2127c478bd9Sstevel@tonic-gate *copy++ = *pt; 2137c478bd9Sstevel@tonic-gate pt++; 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate *copy = '\0'; 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate count++; 2187c478bd9Sstevel@tonic-gate memloc = NULL; 2197c478bd9Sstevel@tonic-gate if (strcmp(temp, "NAME") == 0) 2207c478bd9Sstevel@tonic-gate memloc = &info->name; 2217c478bd9Sstevel@tonic-gate else if (strcmp(temp, "VERSION") == 0) 2227c478bd9Sstevel@tonic-gate memloc = &info->version; 2237c478bd9Sstevel@tonic-gate else if (strcmp(temp, "ARCH") == 0) 2247c478bd9Sstevel@tonic-gate memloc = &info->arch; 2257c478bd9Sstevel@tonic-gate else if (strcmp(temp, "VENDOR") == 0) 2267c478bd9Sstevel@tonic-gate memloc = &info->vendor; 2277c478bd9Sstevel@tonic-gate else if (strcmp(temp, "BASEDIR") == 0) 2287c478bd9Sstevel@tonic-gate memloc = &info->basedir; 2297c478bd9Sstevel@tonic-gate else if (strcmp(temp, "CATEGORY") == 0) 2307c478bd9Sstevel@tonic-gate memloc = &info->catg; 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate temp[0] = '\0'; 2337c478bd9Sstevel@tonic-gate if (memloc == NULL) 2347c478bd9Sstevel@tonic-gate continue; /* not a parameter we're looking for */ 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate *memloc = strdup(value); 2377c478bd9Sstevel@tonic-gate if (!*memloc) { 2387c478bd9Sstevel@tonic-gate (void) fclose(fp); 2397c478bd9Sstevel@tonic-gate errno = ENOMEM; 2407c478bd9Sstevel@tonic-gate return (-1); /* malloc from strdup failed */ 2417c478bd9Sstevel@tonic-gate } 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate (void) fclose(fp); 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate if (!count) { 2467c478bd9Sstevel@tonic-gate errno = ESRCH; 2477c478bd9Sstevel@tonic-gate return (-1); 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate info->status = (strcmp(pkgdir, get_PKGLOC()) ? PI_SPOOLED : 2517c478bd9Sstevel@tonic-gate PI_INSTALLED); 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate if (info->status == PI_INSTALLED) { 254*4656d474SGarrett D'Amore (void) snprintf(temp, sizeof (temp), 255*4656d474SGarrett D'Amore "%s/%s/!I-Lock!", pkgdir, pkginst); 2567c478bd9Sstevel@tonic-gate if (access(temp, 0) == 0) 2577c478bd9Sstevel@tonic-gate info->status = PI_PARTIAL; 2587c478bd9Sstevel@tonic-gate else { 259*4656d474SGarrett D'Amore (void) snprintf(temp, sizeof (temp), 260*4656d474SGarrett D'Amore "%s/%s/!R-Lock!", pkgdir, pkginst); 2617c478bd9Sstevel@tonic-gate if (access(temp, 0) == 0) 2627c478bd9Sstevel@tonic-gate info->status = PI_PARTIAL; 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate } 2657c478bd9Sstevel@tonic-gate info->pkginst = strdup(pkginst); 2667c478bd9Sstevel@tonic-gate return (0); 2677c478bd9Sstevel@tonic-gate } 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate static int 2707c478bd9Sstevel@tonic-gate ckinst(char *pkginst, char *pkgarch, char *pkgvers, char *ckarch, char *ckvers) 2717c478bd9Sstevel@tonic-gate { 2727c478bd9Sstevel@tonic-gate if (ckarch && archcmp(ckarch, pkgarch)) 2737c478bd9Sstevel@tonic-gate return (-1); 2747c478bd9Sstevel@tonic-gate if (ckvers) { 2757c478bd9Sstevel@tonic-gate /* Check for exact version match */ 2767c478bd9Sstevel@tonic-gate if (verscmp(ckvers, pkgvers)) { 2777c478bd9Sstevel@tonic-gate /* Check for compatable version */ 2787c478bd9Sstevel@tonic-gate if (compver(pkginst, ckvers)) 2797c478bd9Sstevel@tonic-gate return (-1); 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate return (0); 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate /*VARARGS*/ 2867c478bd9Sstevel@tonic-gate char * 2877c478bd9Sstevel@tonic-gate fpkginst(char *pkg, ...) 2887c478bd9Sstevel@tonic-gate { 2897c478bd9Sstevel@tonic-gate static char pkginst[PKGSIZ+1]; 2907c478bd9Sstevel@tonic-gate static DIR *pdirfp; 2917c478bd9Sstevel@tonic-gate struct dirent64 *dp; 292*4656d474SGarrett D'Amore char *ckarch, *ckvers; 2937c478bd9Sstevel@tonic-gate va_list ap; 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate va_start(ap, pkg); 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate if (pkg == NULL) { 2987c478bd9Sstevel@tonic-gate /* request to close or rewind the file */ 2997c478bd9Sstevel@tonic-gate if (pdirfp) { 3007c478bd9Sstevel@tonic-gate (void) closedir(pdirfp); 3017c478bd9Sstevel@tonic-gate pdirfp = NULL; 3027c478bd9Sstevel@tonic-gate } 3037c478bd9Sstevel@tonic-gate return (NULL); 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate ckarch = va_arg(ap, char *); 3077c478bd9Sstevel@tonic-gate ckvers = va_arg(ap, char *); 3087c478bd9Sstevel@tonic-gate va_end(ap); 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate if (!pkgdir) 3117c478bd9Sstevel@tonic-gate pkgdir = get_PKGLOC(); 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate if (!pdirfp && ((pdirfp = opendir(pkgdir)) == NULL)) { 3147c478bd9Sstevel@tonic-gate errno = EACCES; 3157c478bd9Sstevel@tonic-gate return (NULL); 3167c478bd9Sstevel@tonic-gate } 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate while ((dp = readdir64(pdirfp)) != NULL) { 3197c478bd9Sstevel@tonic-gate if (dp->d_name[0] == '.') 3207c478bd9Sstevel@tonic-gate continue; 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate if (pkgnmchk(dp->d_name, pkg, 0)) 3237c478bd9Sstevel@tonic-gate continue; /* ignore invalid SVR4 package names */ 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate if (ckinfo(dp->d_name, ckarch, ckvers)) 3267c478bd9Sstevel@tonic-gate continue; 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate /* 3297c478bd9Sstevel@tonic-gate * Leave directory open in case user requests another 3307c478bd9Sstevel@tonic-gate * instance. 3317c478bd9Sstevel@tonic-gate */ 3327c478bd9Sstevel@tonic-gate (void) strcpy(pkginst, dp->d_name); 3337c478bd9Sstevel@tonic-gate return (pkginst); 3347c478bd9Sstevel@tonic-gate } 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate errno = ESRCH; 3377c478bd9Sstevel@tonic-gate /* close any file we might have open */ 3387c478bd9Sstevel@tonic-gate (void) closedir(pdirfp); 3397c478bd9Sstevel@tonic-gate pdirfp = NULL; 3407c478bd9Sstevel@tonic-gate return (NULL); 3417c478bd9Sstevel@tonic-gate } 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate static int 3447c478bd9Sstevel@tonic-gate verscmp(char *request, char *actual) 3457c478bd9Sstevel@tonic-gate { 3467c478bd9Sstevel@tonic-gate /* eat leading white space */ 3477c478bd9Sstevel@tonic-gate while (isspace((unsigned char)*actual)) 3487c478bd9Sstevel@tonic-gate actual++; 3497c478bd9Sstevel@tonic-gate while (isspace((unsigned char)*request)) 3507c478bd9Sstevel@tonic-gate request++; 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate while (*request || *actual) { 3537c478bd9Sstevel@tonic-gate /* 3547c478bd9Sstevel@tonic-gate * Once the pointers don't match, return an error condition. 3557c478bd9Sstevel@tonic-gate */ 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate if (*request++ != *actual++) 3587c478bd9Sstevel@tonic-gate return (-1); 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate /* eat white space if any in both the strings */ 3617c478bd9Sstevel@tonic-gate if (isspace((unsigned char)*request)) { 3627c478bd9Sstevel@tonic-gate if (*actual && !isspace((unsigned char)*actual)) 3637c478bd9Sstevel@tonic-gate return (-1); 3647c478bd9Sstevel@tonic-gate while (isspace((unsigned char)*request)) 3657c478bd9Sstevel@tonic-gate request++; 3667c478bd9Sstevel@tonic-gate while (isspace((unsigned char)*actual)) 3677c478bd9Sstevel@tonic-gate actual++; 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate } 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate return (0); 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate static int 3767c478bd9Sstevel@tonic-gate compver(char *pkginst, char *version) 3777c478bd9Sstevel@tonic-gate { 3787c478bd9Sstevel@tonic-gate FILE *fp; 3797c478bd9Sstevel@tonic-gate char temp[256]; 3807c478bd9Sstevel@tonic-gate 381*4656d474SGarrett D'Amore (void) snprintf(temp, sizeof (temp), 382*4656d474SGarrett D'Amore "%s/%s/install/compver", get_PKGLOC(), pkginst); 3837c478bd9Sstevel@tonic-gate if ((fp = fopen(temp, "r")) == NULL) 3847c478bd9Sstevel@tonic-gate return (-1); 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate while (fgets(temp, 256, fp)) { 3877c478bd9Sstevel@tonic-gate if (*temp == '#') 3887c478bd9Sstevel@tonic-gate continue; 3897c478bd9Sstevel@tonic-gate if (verscmp(temp, version) == 0) { 3907c478bd9Sstevel@tonic-gate (void) fclose(fp); 3917c478bd9Sstevel@tonic-gate return (0); 3927c478bd9Sstevel@tonic-gate } 3937c478bd9Sstevel@tonic-gate } 3947c478bd9Sstevel@tonic-gate (void) fclose(fp); 3957c478bd9Sstevel@tonic-gate return (-1); 3967c478bd9Sstevel@tonic-gate } 3977c478bd9Sstevel@tonic-gate 3987c478bd9Sstevel@tonic-gate static int 3997c478bd9Sstevel@tonic-gate archcmp(char *arch, char *archlist) 4007c478bd9Sstevel@tonic-gate { 4017c478bd9Sstevel@tonic-gate char *pt; 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate if (arch == NULL) 4047c478bd9Sstevel@tonic-gate return (0); 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate /* arch and archlist must not contain whitespace! */ 4077c478bd9Sstevel@tonic-gate 4087c478bd9Sstevel@tonic-gate while (*archlist) { 4097c478bd9Sstevel@tonic-gate for (pt = arch; *pt && (*pt == *archlist); ) 4107c478bd9Sstevel@tonic-gate pt++, archlist++; 4117c478bd9Sstevel@tonic-gate if (!*pt && (!*archlist || (*archlist == ','))) 4127c478bd9Sstevel@tonic-gate return (0); 4137c478bd9Sstevel@tonic-gate while (*archlist) { 4147c478bd9Sstevel@tonic-gate if (*archlist++ == ',') 4157c478bd9Sstevel@tonic-gate break; 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate return (-1); 4197c478bd9Sstevel@tonic-gate } 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate static int 4227c478bd9Sstevel@tonic-gate ckinfo(char *inst, char *arch, char *vers) 4237c478bd9Sstevel@tonic-gate { 4247c478bd9Sstevel@tonic-gate FILE *fp; 4257c478bd9Sstevel@tonic-gate char temp[128]; 4267c478bd9Sstevel@tonic-gate char file[PATH_MAX]; 4277c478bd9Sstevel@tonic-gate char *pt, *copy, *value, *myarch, *myvers; 4287c478bd9Sstevel@tonic-gate int errflg; 4297c478bd9Sstevel@tonic-gate 430*4656d474SGarrett D'Amore (void) snprintf(file, sizeof (file), "%s/%s/pkginfo", pkgdir, inst); 4317c478bd9Sstevel@tonic-gate if ((fp = fopen(file, "r")) == NULL) 4327c478bd9Sstevel@tonic-gate return (1); 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate if ((arch == NULL) && (vers == NULL)) { 4357c478bd9Sstevel@tonic-gate (void) fclose(fp); 4367c478bd9Sstevel@tonic-gate return (0); 4377c478bd9Sstevel@tonic-gate } 4387c478bd9Sstevel@tonic-gate temp[0] = '\0'; 4397c478bd9Sstevel@tonic-gate myarch = myvers = NULL; 4407c478bd9Sstevel@tonic-gate while (value = fpkgparam(fp, temp)) { 4417c478bd9Sstevel@tonic-gate if (strcmp(temp, "ARCH") == 0) { 4427c478bd9Sstevel@tonic-gate /* remove all whitespace from value */ 4437c478bd9Sstevel@tonic-gate pt = copy = value; 4447c478bd9Sstevel@tonic-gate while (*pt) { 4457c478bd9Sstevel@tonic-gate if (!isspace((unsigned char)*pt)) 4467c478bd9Sstevel@tonic-gate *copy++ = *pt; 4477c478bd9Sstevel@tonic-gate pt++; 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate *copy = '\0'; 4507c478bd9Sstevel@tonic-gate myarch = value; 4517c478bd9Sstevel@tonic-gate if (myvers) 4527c478bd9Sstevel@tonic-gate break; 4537c478bd9Sstevel@tonic-gate } else if (strcmp(temp, "VERSION") == 0) { 4547c478bd9Sstevel@tonic-gate myvers = value; 4557c478bd9Sstevel@tonic-gate if (myarch) 4567c478bd9Sstevel@tonic-gate break; 4577c478bd9Sstevel@tonic-gate } else 4587c478bd9Sstevel@tonic-gate free(value); 4597c478bd9Sstevel@tonic-gate temp[0] = '\0'; 4607c478bd9Sstevel@tonic-gate } 4617c478bd9Sstevel@tonic-gate (void) fclose(fp); 4627c478bd9Sstevel@tonic-gate errflg = 0; 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate if (ckinst(inst, myarch, myvers, arch, vers)) 4657c478bd9Sstevel@tonic-gate errflg++; 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate if (myarch) 4687c478bd9Sstevel@tonic-gate free(myarch); 4697c478bd9Sstevel@tonic-gate if (myvers) 4707c478bd9Sstevel@tonic-gate free(myvers); 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate return (errflg); 4737c478bd9Sstevel@tonic-gate } 474