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 28*9781SMoriah.Waterland@Sun.COM /* 29*9781SMoriah.Waterland@Sun.COM * Module: pkgstr.c 30*9781SMoriah.Waterland@Sun.COM * Synopsis: general string services 31*9781SMoriah.Waterland@Sun.COM * Taxonomy: project private 32*9781SMoriah.Waterland@Sun.COM * Debug Flag: str 33*9781SMoriah.Waterland@Sun.COM * Description: 34*9781SMoriah.Waterland@Sun.COM * 35*9781SMoriah.Waterland@Sun.COM * This module implements general string utility services 36*9781SMoriah.Waterland@Sun.COM * 37*9781SMoriah.Waterland@Sun.COM * Public Methods: 38*9781SMoriah.Waterland@Sun.COM * 39*9781SMoriah.Waterland@Sun.COM * pkgstrAddToken - Add a token to a string 40*9781SMoriah.Waterland@Sun.COM * pkgstrContainsToken - Determine if a string contains a specified token 41*9781SMoriah.Waterland@Sun.COM * pkgstrConvertPathToBasename - Return copy of base name in path string 42*9781SMoriah.Waterland@Sun.COM * pkgstrConvertPathToDirname - Return copy of directory name in path string 43*9781SMoriah.Waterland@Sun.COM * pkgstrConvertUllToTimeString_r - convert unsigned long long to time string 44*9781SMoriah.Waterland@Sun.COM * pkgstrExpandTokens - Expand tokens from string appending tokens to another 45*9781SMoriah.Waterland@Sun.COM * pkgstrGetToken - Get a token from a string 46*9781SMoriah.Waterland@Sun.COM * pkgstrGetToken_r - Get a token from a string into a fixed buffer 47*9781SMoriah.Waterland@Sun.COM * pkgstrLocatePathBasename - Locate position of base name in path string 48*9781SMoriah.Waterland@Sun.COM * pkgstrNumTokens - Determine number of tokens in string 49*9781SMoriah.Waterland@Sun.COM * pkgstrPrintf - Create a string from a printf style format and arguments 50*9781SMoriah.Waterland@Sun.COM * pkgstrPrintf_r - Create a string from a printf style format and arguments 51*9781SMoriah.Waterland@Sun.COM * into a fixed buffer 52*9781SMoriah.Waterland@Sun.COM * pkgstrRemoveToken - Remove a token from a string 53*9781SMoriah.Waterland@Sun.COM * pkgstrRemoveLeadingWhitespace - remove leading whitespace from string 54*9781SMoriah.Waterland@Sun.COM * pkgstrScaleNumericString - Convert unsigned long long to human 55*9781SMoriah.Waterland@Sun.COM * readable form 56*9781SMoriah.Waterland@Sun.COM */ 57*9781SMoriah.Waterland@Sun.COM 58*9781SMoriah.Waterland@Sun.COM /* 59*9781SMoriah.Waterland@Sun.COM * Unix Includes 60*9781SMoriah.Waterland@Sun.COM */ 61*9781SMoriah.Waterland@Sun.COM 62*9781SMoriah.Waterland@Sun.COM #define __EXTENSIONS__ 63*9781SMoriah.Waterland@Sun.COM 64*9781SMoriah.Waterland@Sun.COM #include <stdio.h> 65*9781SMoriah.Waterland@Sun.COM #include <stdlib.h> 66*9781SMoriah.Waterland@Sun.COM #include <string.h> 67*9781SMoriah.Waterland@Sun.COM #include <libintl.h> 68*9781SMoriah.Waterland@Sun.COM #include <limits.h> 69*9781SMoriah.Waterland@Sun.COM #include <sys/types.h> 70*9781SMoriah.Waterland@Sun.COM #include <assert.h> 71*9781SMoriah.Waterland@Sun.COM #include <errno.h> 72*9781SMoriah.Waterland@Sun.COM #include <libintl.h> 73*9781SMoriah.Waterland@Sun.COM #include <ctype.h> 74*9781SMoriah.Waterland@Sun.COM #include <unistd.h> 75*9781SMoriah.Waterland@Sun.COM #include <strings.h> 76*9781SMoriah.Waterland@Sun.COM #include <stdarg.h> 77*9781SMoriah.Waterland@Sun.COM 78*9781SMoriah.Waterland@Sun.COM /* 79*9781SMoriah.Waterland@Sun.COM * pkglib Includes 80*9781SMoriah.Waterland@Sun.COM */ 81*9781SMoriah.Waterland@Sun.COM 82*9781SMoriah.Waterland@Sun.COM #include "pkglib.h" 83*9781SMoriah.Waterland@Sun.COM #include "pkgstrct.h" 84*9781SMoriah.Waterland@Sun.COM #include "libintl.h" 85*9781SMoriah.Waterland@Sun.COM #include "pkglocale.h" 86*9781SMoriah.Waterland@Sun.COM 87*9781SMoriah.Waterland@Sun.COM /* 88*9781SMoriah.Waterland@Sun.COM * External definitions 89*9781SMoriah.Waterland@Sun.COM */ 90*9781SMoriah.Waterland@Sun.COM 91*9781SMoriah.Waterland@Sun.COM /* 92*9781SMoriah.Waterland@Sun.COM * Public methods 93*9781SMoriah.Waterland@Sun.COM */ 94*9781SMoriah.Waterland@Sun.COM 95*9781SMoriah.Waterland@Sun.COM /* 96*9781SMoriah.Waterland@Sun.COM * Name: pkgstrRemoveLeadingWhitespace 97*9781SMoriah.Waterland@Sun.COM * Synopsis: Remove leading whitespace from string 98*9781SMoriah.Waterland@Sun.COM * Description: Remove all leading whitespace characters from a string 99*9781SMoriah.Waterland@Sun.COM * Arguments: a_str - [RO, *RW] - (char **) 100*9781SMoriah.Waterland@Sun.COM * Pointer to handle to string (in allocated storage) to 101*9781SMoriah.Waterland@Sun.COM * remove all leading whitespace from 102*9781SMoriah.Waterland@Sun.COM * Returns: void 103*9781SMoriah.Waterland@Sun.COM * The input string is modified as follows: 104*9781SMoriah.Waterland@Sun.COM * == (char *)NULL: 105*9781SMoriah.Waterland@Sun.COM * - input string was (char *)NULL 106*9781SMoriah.Waterland@Sun.COM * - input string is all whitespace 107*9781SMoriah.Waterland@Sun.COM * != (char *)NULL: 108*9781SMoriah.Waterland@Sun.COM * - copy of input string with leading 109*9781SMoriah.Waterland@Sun.COM * whitespace removed 110*9781SMoriah.Waterland@Sun.COM * CAUTION: The input string must be allocated space (via mem* or 111*9781SMoriah.Waterland@Sun.COM * pkgstr* methods) - it must not be a static or inline 112*9781SMoriah.Waterland@Sun.COM * character string 113*9781SMoriah.Waterland@Sun.COM * NOTE: The input string a_str will be freed with 'free' 114*9781SMoriah.Waterland@Sun.COM * if it is all whitespace, or if it contains any leading 115*9781SMoriah.Waterland@Sun.COM * whitespace characters 116*9781SMoriah.Waterland@Sun.COM * NOTE: Any string returned is placed in new storage for the 117*9781SMoriah.Waterland@Sun.COM * calling method. The caller must use 'free' to dispose 118*9781SMoriah.Waterland@Sun.COM * of the storage once the string is no longer needed. 119*9781SMoriah.Waterland@Sun.COM * Errors: If the string cannot be created, the process exits 120*9781SMoriah.Waterland@Sun.COM */ 121*9781SMoriah.Waterland@Sun.COM 122*9781SMoriah.Waterland@Sun.COM void 123*9781SMoriah.Waterland@Sun.COM pkgstrRemoveLeadingWhitespace(char **a_str) 124*9781SMoriah.Waterland@Sun.COM { 125*9781SMoriah.Waterland@Sun.COM char *o_str; 126*9781SMoriah.Waterland@Sun.COM 127*9781SMoriah.Waterland@Sun.COM /* entry assertions */ 128*9781SMoriah.Waterland@Sun.COM 129*9781SMoriah.Waterland@Sun.COM assert(a_str != (char **)NULL); 130*9781SMoriah.Waterland@Sun.COM 131*9781SMoriah.Waterland@Sun.COM /* if string is null, just return */ 132*9781SMoriah.Waterland@Sun.COM 133*9781SMoriah.Waterland@Sun.COM if (*a_str == (char *)NULL) { 134*9781SMoriah.Waterland@Sun.COM return; 135*9781SMoriah.Waterland@Sun.COM } 136*9781SMoriah.Waterland@Sun.COM o_str = *a_str; 137*9781SMoriah.Waterland@Sun.COM 138*9781SMoriah.Waterland@Sun.COM /* if string is empty, deallocate and return NULL */ 139*9781SMoriah.Waterland@Sun.COM 140*9781SMoriah.Waterland@Sun.COM if (*o_str == '\0') { 141*9781SMoriah.Waterland@Sun.COM /* free string - handle is reset to NULL by free */ 142*9781SMoriah.Waterland@Sun.COM free(*a_str); 143*9781SMoriah.Waterland@Sun.COM *a_str = (char *)NULL; 144*9781SMoriah.Waterland@Sun.COM return; 145*9781SMoriah.Waterland@Sun.COM } 146*9781SMoriah.Waterland@Sun.COM 147*9781SMoriah.Waterland@Sun.COM /* if first character is not a space, just return */ 148*9781SMoriah.Waterland@Sun.COM 149*9781SMoriah.Waterland@Sun.COM if (!isspace(*o_str)) { 150*9781SMoriah.Waterland@Sun.COM return; 151*9781SMoriah.Waterland@Sun.COM } 152*9781SMoriah.Waterland@Sun.COM 153*9781SMoriah.Waterland@Sun.COM /* advance past all space characters */ 154*9781SMoriah.Waterland@Sun.COM 155*9781SMoriah.Waterland@Sun.COM while ((*o_str != '\0') && (isspace(*o_str))) { 156*9781SMoriah.Waterland@Sun.COM o_str++; 157*9781SMoriah.Waterland@Sun.COM } 158*9781SMoriah.Waterland@Sun.COM 159*9781SMoriah.Waterland@Sun.COM /* if string was all space characters, deallocate and return NULL */ 160*9781SMoriah.Waterland@Sun.COM 161*9781SMoriah.Waterland@Sun.COM if (*o_str == '\0') { 162*9781SMoriah.Waterland@Sun.COM /* free string - *a_str is reset to NULL by free */ 163*9781SMoriah.Waterland@Sun.COM free(*a_str); 164*9781SMoriah.Waterland@Sun.COM *a_str = (char *)NULL; 165*9781SMoriah.Waterland@Sun.COM return; 166*9781SMoriah.Waterland@Sun.COM } 167*9781SMoriah.Waterland@Sun.COM 168*9781SMoriah.Waterland@Sun.COM /* have non-space/null byte, return dup, deallocate original */ 169*9781SMoriah.Waterland@Sun.COM 170*9781SMoriah.Waterland@Sun.COM o_str = strdup(o_str); 171*9781SMoriah.Waterland@Sun.COM assert(o_str != (char *)NULL); 172*9781SMoriah.Waterland@Sun.COM if (o_str != (char *)NULL) { 173*9781SMoriah.Waterland@Sun.COM free(*a_str); 174*9781SMoriah.Waterland@Sun.COM *a_str = o_str; 175*9781SMoriah.Waterland@Sun.COM } 176*9781SMoriah.Waterland@Sun.COM } 177*9781SMoriah.Waterland@Sun.COM 178*9781SMoriah.Waterland@Sun.COM unsigned long 179*9781SMoriah.Waterland@Sun.COM pkgstrNumTokens(char *a_string, char *a_separators) 180*9781SMoriah.Waterland@Sun.COM { 181*9781SMoriah.Waterland@Sun.COM int index; 182*9781SMoriah.Waterland@Sun.COM 183*9781SMoriah.Waterland@Sun.COM if (a_string == (char *)NULL) { 184*9781SMoriah.Waterland@Sun.COM return (0); 185*9781SMoriah.Waterland@Sun.COM } 186*9781SMoriah.Waterland@Sun.COM 187*9781SMoriah.Waterland@Sun.COM if (*a_string == '\0') { 188*9781SMoriah.Waterland@Sun.COM return (0); 189*9781SMoriah.Waterland@Sun.COM } 190*9781SMoriah.Waterland@Sun.COM 191*9781SMoriah.Waterland@Sun.COM for (index = 0 ; ; index ++) { 192*9781SMoriah.Waterland@Sun.COM char *p; 193*9781SMoriah.Waterland@Sun.COM 194*9781SMoriah.Waterland@Sun.COM p = pkgstrGetToken((char *)NULL, a_string, index, a_separators); 195*9781SMoriah.Waterland@Sun.COM if (p == (char *)NULL) { 196*9781SMoriah.Waterland@Sun.COM return (index); 197*9781SMoriah.Waterland@Sun.COM } 198*9781SMoriah.Waterland@Sun.COM free(p); 199*9781SMoriah.Waterland@Sun.COM } 200*9781SMoriah.Waterland@Sun.COM } 201*9781SMoriah.Waterland@Sun.COM 202*9781SMoriah.Waterland@Sun.COM /* 203*9781SMoriah.Waterland@Sun.COM * Name: pkgstrPrintf_r 204*9781SMoriah.Waterland@Sun.COM * Synopsis: Create string from printf style format and arguments 205*9781SMoriah.Waterland@Sun.COM * Description: Call to convert a printf style format and arguments into a 206*9781SMoriah.Waterland@Sun.COM * string of characters placed in allocated storage 207*9781SMoriah.Waterland@Sun.COM * Arguments: a_buf - [RO, *RW] - (char *) 208*9781SMoriah.Waterland@Sun.COM * - Pointer to buffer used as storage space for the 209*9781SMoriah.Waterland@Sun.COM * returned string created 210*9781SMoriah.Waterland@Sun.COM * a_bufLen - [RO, *RO] - (int) 211*9781SMoriah.Waterland@Sun.COM * - Size of 'a_buf' in bytes - a maximum of 'a_bufLen-1' 212*9781SMoriah.Waterland@Sun.COM * bytes will be placed in 'a_buf' - the returned 213*9781SMoriah.Waterland@Sun.COM * string is always null terminated 214*9781SMoriah.Waterland@Sun.COM * a_format - [RO, RO*] (char *) 215*9781SMoriah.Waterland@Sun.COM * printf-style format for string to be formatted 216*9781SMoriah.Waterland@Sun.COM * VARG_LIST - [RO] (?) 217*9781SMoriah.Waterland@Sun.COM * arguments as appropriate to 'format' specified 218*9781SMoriah.Waterland@Sun.COM * Returns: void 219*9781SMoriah.Waterland@Sun.COM */ 220*9781SMoriah.Waterland@Sun.COM 221*9781SMoriah.Waterland@Sun.COM /*PRINTFLIKE3*/ 222*9781SMoriah.Waterland@Sun.COM void 223*9781SMoriah.Waterland@Sun.COM pkgstrPrintf_r(char *a_buf, int a_bufLen, char *a_format, ...) 224*9781SMoriah.Waterland@Sun.COM { 225*9781SMoriah.Waterland@Sun.COM va_list ap; 226*9781SMoriah.Waterland@Sun.COM size_t vres = 0; 227*9781SMoriah.Waterland@Sun.COM 228*9781SMoriah.Waterland@Sun.COM /* entry assertions */ 229*9781SMoriah.Waterland@Sun.COM 230*9781SMoriah.Waterland@Sun.COM assert(a_format != (char *)NULL); 231*9781SMoriah.Waterland@Sun.COM assert(*a_format != '\0'); 232*9781SMoriah.Waterland@Sun.COM assert(a_buf != (char *)NULL); 233*9781SMoriah.Waterland@Sun.COM assert(a_bufLen > 1); 234*9781SMoriah.Waterland@Sun.COM 235*9781SMoriah.Waterland@Sun.COM /* generate the results of the printf conversion */ 236*9781SMoriah.Waterland@Sun.COM 237*9781SMoriah.Waterland@Sun.COM va_start(ap, a_format); 238*9781SMoriah.Waterland@Sun.COM vres = vsnprintf(a_buf, a_bufLen-1, a_format, ap); 239*9781SMoriah.Waterland@Sun.COM va_end(ap); 240*9781SMoriah.Waterland@Sun.COM 241*9781SMoriah.Waterland@Sun.COM assert(vres > 0); 242*9781SMoriah.Waterland@Sun.COM assert(vres < a_bufLen); 243*9781SMoriah.Waterland@Sun.COM 244*9781SMoriah.Waterland@Sun.COM a_buf[a_bufLen-1] = '\0'; 245*9781SMoriah.Waterland@Sun.COM } 246*9781SMoriah.Waterland@Sun.COM 247*9781SMoriah.Waterland@Sun.COM /* 248*9781SMoriah.Waterland@Sun.COM * Name: pkgstrPrintf 249*9781SMoriah.Waterland@Sun.COM * Synopsis: Create string from printf style format and arguments 250*9781SMoriah.Waterland@Sun.COM * Description: Call to convert a printf style format and arguments into a 251*9781SMoriah.Waterland@Sun.COM * string of characters placed in allocated storage 252*9781SMoriah.Waterland@Sun.COM * Arguments: format - [RO, RO*] (char *) 253*9781SMoriah.Waterland@Sun.COM * printf-style format for string to be formatted 254*9781SMoriah.Waterland@Sun.COM * VARG_LIST - [RO] (?) 255*9781SMoriah.Waterland@Sun.COM * arguments as appropriate to 'format' specified 256*9781SMoriah.Waterland@Sun.COM * Returns: char * 257*9781SMoriah.Waterland@Sun.COM * A string representing the printf conversion results 258*9781SMoriah.Waterland@Sun.COM * NOTE: Any string returned is placed in new storage for the 259*9781SMoriah.Waterland@Sun.COM * calling method. The caller must use 'free' to dispose 260*9781SMoriah.Waterland@Sun.COM * of the storage once the string is no longer needed. 261*9781SMoriah.Waterland@Sun.COM * Errors: If the string cannot be created, the process exits 262*9781SMoriah.Waterland@Sun.COM */ 263*9781SMoriah.Waterland@Sun.COM 264*9781SMoriah.Waterland@Sun.COM /*PRINTFLIKE1*/ 265*9781SMoriah.Waterland@Sun.COM char * 266*9781SMoriah.Waterland@Sun.COM pkgstrPrintf(char *a_format, ...) 267*9781SMoriah.Waterland@Sun.COM { 268*9781SMoriah.Waterland@Sun.COM va_list ap; 269*9781SMoriah.Waterland@Sun.COM size_t vres = 0; 270*9781SMoriah.Waterland@Sun.COM char bfr[1]; 271*9781SMoriah.Waterland@Sun.COM char *rstr = (char *)NULL; 272*9781SMoriah.Waterland@Sun.COM 273*9781SMoriah.Waterland@Sun.COM /* entry assertions */ 274*9781SMoriah.Waterland@Sun.COM 275*9781SMoriah.Waterland@Sun.COM assert(a_format != (char *)NULL); 276*9781SMoriah.Waterland@Sun.COM assert(*a_format != '\0'); 277*9781SMoriah.Waterland@Sun.COM 278*9781SMoriah.Waterland@Sun.COM /* determine size of the message in bytes */ 279*9781SMoriah.Waterland@Sun.COM 280*9781SMoriah.Waterland@Sun.COM va_start(ap, a_format); 281*9781SMoriah.Waterland@Sun.COM vres = vsnprintf(bfr, 1, a_format, ap); 282*9781SMoriah.Waterland@Sun.COM va_end(ap); 283*9781SMoriah.Waterland@Sun.COM 284*9781SMoriah.Waterland@Sun.COM assert(vres > 0); 285*9781SMoriah.Waterland@Sun.COM assert(vres < LINE_MAX); 286*9781SMoriah.Waterland@Sun.COM 287*9781SMoriah.Waterland@Sun.COM /* allocate storage to hold the message */ 288*9781SMoriah.Waterland@Sun.COM 289*9781SMoriah.Waterland@Sun.COM rstr = (char *)calloc(1, vres+2); 290*9781SMoriah.Waterland@Sun.COM assert(rstr != (char *)NULL); 291*9781SMoriah.Waterland@Sun.COM if (rstr == (char *)NULL) { 292*9781SMoriah.Waterland@Sun.COM return ((char *)NULL); 293*9781SMoriah.Waterland@Sun.COM } 294*9781SMoriah.Waterland@Sun.COM 295*9781SMoriah.Waterland@Sun.COM /* generate the results of the printf conversion */ 296*9781SMoriah.Waterland@Sun.COM 297*9781SMoriah.Waterland@Sun.COM va_start(ap, a_format); 298*9781SMoriah.Waterland@Sun.COM vres = vsnprintf(rstr, vres+1, a_format, ap); 299*9781SMoriah.Waterland@Sun.COM va_end(ap); 300*9781SMoriah.Waterland@Sun.COM 301*9781SMoriah.Waterland@Sun.COM assert(vres > 0); 302*9781SMoriah.Waterland@Sun.COM assert(vres < LINE_MAX); 303*9781SMoriah.Waterland@Sun.COM assert(*rstr != '\0'); 304*9781SMoriah.Waterland@Sun.COM 305*9781SMoriah.Waterland@Sun.COM /* return the results */ 306*9781SMoriah.Waterland@Sun.COM 307*9781SMoriah.Waterland@Sun.COM return (rstr); 308*9781SMoriah.Waterland@Sun.COM } 309*9781SMoriah.Waterland@Sun.COM 310*9781SMoriah.Waterland@Sun.COM /* 311*9781SMoriah.Waterland@Sun.COM * Name: pkgstrExpandTokens 312*9781SMoriah.Waterland@Sun.COM * Synopsis: Expand tokens from string appending tokens to another 313*9781SMoriah.Waterland@Sun.COM * Description: Given a string and a list of one or more separators, 314*9781SMoriah.Waterland@Sun.COM * expand each token from the string and append those tokens 315*9781SMoriah.Waterland@Sun.COM * to a string that is in allocated space - create new string 316*9781SMoriah.Waterland@Sun.COM * if no string to append to exists. 317*9781SMoriah.Waterland@Sun.COM * Arguments: a_old - [RO, *RW] - (char **) 318*9781SMoriah.Waterland@Sun.COM * - Pointer to handle to string to append token to 319*9781SMoriah.Waterland@Sun.COM * == (char *)NULL - new string is created 320*9781SMoriah.Waterland@Sun.COM * a_separator - [RO, *RO] - (char *) 321*9781SMoriah.Waterland@Sun.COM * - separator to end tokens returned 322*9781SMoriah.Waterland@Sun.COM * a_separators - [RO, *RO] - (char *) 323*9781SMoriah.Waterland@Sun.COM * - String containing one or more characters that 324*9781SMoriah.Waterland@Sun.COM * can separate one "token" from a_string from another 325*9781SMoriah.Waterland@Sun.COM * Returns: void 326*9781SMoriah.Waterland@Sun.COM * NOTE: Any token string returned is placed in new storage for the 327*9781SMoriah.Waterland@Sun.COM * calling method. The caller must use 'free' to dispose 328*9781SMoriah.Waterland@Sun.COM * of the storage once the token string is no longer needed. 329*9781SMoriah.Waterland@Sun.COM */ 330*9781SMoriah.Waterland@Sun.COM 331*9781SMoriah.Waterland@Sun.COM void 332*9781SMoriah.Waterland@Sun.COM pkgstrExpandTokens(char **a_old, char *a_string, char a_separator, 333*9781SMoriah.Waterland@Sun.COM char *a_separators) 334*9781SMoriah.Waterland@Sun.COM { 335*9781SMoriah.Waterland@Sun.COM int i; 336*9781SMoriah.Waterland@Sun.COM char sep[2] = {'\0', '\0'}; 337*9781SMoriah.Waterland@Sun.COM 338*9781SMoriah.Waterland@Sun.COM /* convert single separator character into character string */ 339*9781SMoriah.Waterland@Sun.COM 340*9781SMoriah.Waterland@Sun.COM sep[0] = a_separator; 341*9781SMoriah.Waterland@Sun.COM 342*9781SMoriah.Waterland@Sun.COM /* 343*9781SMoriah.Waterland@Sun.COM * iterate extracting tokens from the source string and adding 344*9781SMoriah.Waterland@Sun.COM * those tokens to the target string when the tokens are not 345*9781SMoriah.Waterland@Sun.COM * already present in the target string 346*9781SMoriah.Waterland@Sun.COM */ 347*9781SMoriah.Waterland@Sun.COM 348*9781SMoriah.Waterland@Sun.COM for (i = 0; ; i++) { 349*9781SMoriah.Waterland@Sun.COM char *p; 350*9781SMoriah.Waterland@Sun.COM 351*9781SMoriah.Waterland@Sun.COM /* extract the next matching token from the source string */ 352*9781SMoriah.Waterland@Sun.COM 353*9781SMoriah.Waterland@Sun.COM p = pkgstrGetToken((char *)NULL, a_string, i, a_separators); 354*9781SMoriah.Waterland@Sun.COM 355*9781SMoriah.Waterland@Sun.COM /* return if no token is available */ 356*9781SMoriah.Waterland@Sun.COM 357*9781SMoriah.Waterland@Sun.COM if (p == (char *)NULL) { 358*9781SMoriah.Waterland@Sun.COM return; 359*9781SMoriah.Waterland@Sun.COM } 360*9781SMoriah.Waterland@Sun.COM 361*9781SMoriah.Waterland@Sun.COM /* 362*9781SMoriah.Waterland@Sun.COM * obtained token from source string: if the token is not 363*9781SMoriah.Waterland@Sun.COM * in the target string, add the token to the target string 364*9781SMoriah.Waterland@Sun.COM */ 365*9781SMoriah.Waterland@Sun.COM 366*9781SMoriah.Waterland@Sun.COM if (pkgstrContainsToken(*a_old, p, sep) == B_FALSE) { 367*9781SMoriah.Waterland@Sun.COM pkgstrAddToken(a_old, p, *sep); 368*9781SMoriah.Waterland@Sun.COM } 369*9781SMoriah.Waterland@Sun.COM 370*9781SMoriah.Waterland@Sun.COM /* free up temporary storage used by token from source string */ 371*9781SMoriah.Waterland@Sun.COM 372*9781SMoriah.Waterland@Sun.COM free(p); 373*9781SMoriah.Waterland@Sun.COM } 374*9781SMoriah.Waterland@Sun.COM /*NOTREACHED*/ 375*9781SMoriah.Waterland@Sun.COM } 376*9781SMoriah.Waterland@Sun.COM 377*9781SMoriah.Waterland@Sun.COM 378*9781SMoriah.Waterland@Sun.COM /* 379*9781SMoriah.Waterland@Sun.COM * Name: pkgstrGetToken 380*9781SMoriah.Waterland@Sun.COM * Synopsis: Get a separator delimited token from a string 381*9781SMoriah.Waterland@Sun.COM * Description: Given a string and a list of one or more separators, 382*9781SMoriah.Waterland@Sun.COM * return the position specified token (sequence of one or 383*9781SMoriah.Waterland@Sun.COM * more characters that do not include any of the separators) 384*9781SMoriah.Waterland@Sun.COM * Arguments: r_sep - [*RW] - (char *) 385*9781SMoriah.Waterland@Sun.COM * - separator that ended the token returned 386*9781SMoriah.Waterland@Sun.COM * - NOTE: this is a pointer to a "char", e.g.: 387*9781SMoriah.Waterland@Sun.COM * - char a; 388*9781SMoriah.Waterland@Sun.COM * - pkgstrGetToken(&a, ...) 389*9781SMoriah.Waterland@Sun.COM * a_string - [RO, *RO] - (char *) 390*9781SMoriah.Waterland@Sun.COM * - pointer to string to extract token from 391*9781SMoriah.Waterland@Sun.COM * a_index - [RO, *RO] - (int) 392*9781SMoriah.Waterland@Sun.COM * - Index of token to return; '0' is first matching 393*9781SMoriah.Waterland@Sun.COM * token, '1' is second matching token, etc. 394*9781SMoriah.Waterland@Sun.COM * a_separators - [RO, *RO] - (char *) 395*9781SMoriah.Waterland@Sun.COM * - String containing one or more characters that 396*9781SMoriah.Waterland@Sun.COM * can separate one "token" from another 397*9781SMoriah.Waterland@Sun.COM * Returns: char * 398*9781SMoriah.Waterland@Sun.COM * == (char *)NULL - no token matching criteria found 399*9781SMoriah.Waterland@Sun.COM * != (char *)NULL - token matching criteria 400*9781SMoriah.Waterland@Sun.COM * NOTE: Any token string returned is placed in new storage for the 401*9781SMoriah.Waterland@Sun.COM * calling method. The caller must use 'free' to dispose 402*9781SMoriah.Waterland@Sun.COM * of the storage once the token string is no longer needed. 403*9781SMoriah.Waterland@Sun.COM */ 404*9781SMoriah.Waterland@Sun.COM 405*9781SMoriah.Waterland@Sun.COM char * 406*9781SMoriah.Waterland@Sun.COM pkgstrGetToken(char *r_sep, char *a_string, int a_index, char *a_separators) 407*9781SMoriah.Waterland@Sun.COM { 408*9781SMoriah.Waterland@Sun.COM char *p; 409*9781SMoriah.Waterland@Sun.COM char *q; 410*9781SMoriah.Waterland@Sun.COM char *lasts; 411*9781SMoriah.Waterland@Sun.COM 412*9781SMoriah.Waterland@Sun.COM /* entry assertions */ 413*9781SMoriah.Waterland@Sun.COM 414*9781SMoriah.Waterland@Sun.COM assert(a_string != (char *)NULL); 415*9781SMoriah.Waterland@Sun.COM assert(a_index >= 0); 416*9781SMoriah.Waterland@Sun.COM assert(a_separators != (char *)NULL); 417*9781SMoriah.Waterland@Sun.COM assert(*a_separators != '\0'); 418*9781SMoriah.Waterland@Sun.COM 419*9781SMoriah.Waterland@Sun.COM /* if returned separator requested, reset to null until token found */ 420*9781SMoriah.Waterland@Sun.COM 421*9781SMoriah.Waterland@Sun.COM if (r_sep != (char *)NULL) { 422*9781SMoriah.Waterland@Sun.COM *r_sep = '\0'; 423*9781SMoriah.Waterland@Sun.COM } 424*9781SMoriah.Waterland@Sun.COM 425*9781SMoriah.Waterland@Sun.COM /* duplicate original string before breaking down into tokens */ 426*9781SMoriah.Waterland@Sun.COM 427*9781SMoriah.Waterland@Sun.COM p = strdup(a_string); 428*9781SMoriah.Waterland@Sun.COM assert(p != (char *)NULL); 429*9781SMoriah.Waterland@Sun.COM if (p == (char *)NULL) { 430*9781SMoriah.Waterland@Sun.COM return ((char *)NULL); 431*9781SMoriah.Waterland@Sun.COM } 432*9781SMoriah.Waterland@Sun.COM lasts = p; 433*9781SMoriah.Waterland@Sun.COM 434*9781SMoriah.Waterland@Sun.COM /* scan for separators and return 'index'th token found */ 435*9781SMoriah.Waterland@Sun.COM 436*9781SMoriah.Waterland@Sun.COM while (q = strtok_r((char *)NULL, a_separators, &lasts)) { 437*9781SMoriah.Waterland@Sun.COM /* retrieve separator if requested */ 438*9781SMoriah.Waterland@Sun.COM 439*9781SMoriah.Waterland@Sun.COM if (r_sep != (char *)NULL) { 440*9781SMoriah.Waterland@Sun.COM char *x; 441*9781SMoriah.Waterland@Sun.COM 442*9781SMoriah.Waterland@Sun.COM x = strpbrk(a_string, a_separators); 443*9781SMoriah.Waterland@Sun.COM if (x) { 444*9781SMoriah.Waterland@Sun.COM *r_sep = *x; 445*9781SMoriah.Waterland@Sun.COM } 446*9781SMoriah.Waterland@Sun.COM } 447*9781SMoriah.Waterland@Sun.COM 448*9781SMoriah.Waterland@Sun.COM /* if this is the 'index'th token requested return it */ 449*9781SMoriah.Waterland@Sun.COM 450*9781SMoriah.Waterland@Sun.COM if (a_index-- == 0) { 451*9781SMoriah.Waterland@Sun.COM char *tmp; 452*9781SMoriah.Waterland@Sun.COM 453*9781SMoriah.Waterland@Sun.COM /* duplicate token into its own storage */ 454*9781SMoriah.Waterland@Sun.COM 455*9781SMoriah.Waterland@Sun.COM tmp = strdup(q); 456*9781SMoriah.Waterland@Sun.COM assert(tmp != (char *)NULL); 457*9781SMoriah.Waterland@Sun.COM if (tmp == (char *)NULL) { 458*9781SMoriah.Waterland@Sun.COM return ((char *)NULL); 459*9781SMoriah.Waterland@Sun.COM } 460*9781SMoriah.Waterland@Sun.COM 461*9781SMoriah.Waterland@Sun.COM /* free up copy of original input string */ 462*9781SMoriah.Waterland@Sun.COM 463*9781SMoriah.Waterland@Sun.COM free(p); 464*9781SMoriah.Waterland@Sun.COM 465*9781SMoriah.Waterland@Sun.COM /* return token found */ 466*9781SMoriah.Waterland@Sun.COM 467*9781SMoriah.Waterland@Sun.COM return (tmp); 468*9781SMoriah.Waterland@Sun.COM } 469*9781SMoriah.Waterland@Sun.COM } 470*9781SMoriah.Waterland@Sun.COM 471*9781SMoriah.Waterland@Sun.COM /* 472*9781SMoriah.Waterland@Sun.COM * token not found 473*9781SMoriah.Waterland@Sun.COM */ 474*9781SMoriah.Waterland@Sun.COM 475*9781SMoriah.Waterland@Sun.COM /* free up copy of original input string */ 476*9781SMoriah.Waterland@Sun.COM 477*9781SMoriah.Waterland@Sun.COM free(p); 478*9781SMoriah.Waterland@Sun.COM 479*9781SMoriah.Waterland@Sun.COM /* return NULL pointer (token not found) */ 480*9781SMoriah.Waterland@Sun.COM 481*9781SMoriah.Waterland@Sun.COM return ((char *)NULL); 482*9781SMoriah.Waterland@Sun.COM } 483*9781SMoriah.Waterland@Sun.COM 484*9781SMoriah.Waterland@Sun.COM /* 485*9781SMoriah.Waterland@Sun.COM * Name: pkgstrGetToken 486*9781SMoriah.Waterland@Sun.COM * Synopsis: Get separator delimited token from a string into a fixed buffer 487*9781SMoriah.Waterland@Sun.COM * Description: Given a string and a list of one or more separators, 488*9781SMoriah.Waterland@Sun.COM * return the position specified token (sequence of one or 489*9781SMoriah.Waterland@Sun.COM * more characters that do not include any of the separators) 490*9781SMoriah.Waterland@Sun.COM * into a specified buffer of a fixed maximum size 491*9781SMoriah.Waterland@Sun.COM * Arguments: r_sep - [*RW] - (char *) 492*9781SMoriah.Waterland@Sun.COM * - separator that ended the token returned 493*9781SMoriah.Waterland@Sun.COM * - NOTE: this is a pointer to a "char", e.g.: 494*9781SMoriah.Waterland@Sun.COM * - char a; 495*9781SMoriah.Waterland@Sun.COM * - pkgstrGetToken(&a, ...) 496*9781SMoriah.Waterland@Sun.COM * a_string - [RO, *RO] - (char *) 497*9781SMoriah.Waterland@Sun.COM * - pointer to string to extract token from 498*9781SMoriah.Waterland@Sun.COM * a_index - [RO, *RO] - (int) 499*9781SMoriah.Waterland@Sun.COM * - Index of token to return; '0' is first matching 500*9781SMoriah.Waterland@Sun.COM * token, '1' is second matching token, etc. 501*9781SMoriah.Waterland@Sun.COM * a_separators - [RO, *RO] - (char *) 502*9781SMoriah.Waterland@Sun.COM * - String containing one or more characters that 503*9781SMoriah.Waterland@Sun.COM * can separate one "token" from another 504*9781SMoriah.Waterland@Sun.COM * a_buf - [RO, *RW] - (char *) 505*9781SMoriah.Waterland@Sun.COM * - Pointer to buffer used as storage space for the 506*9781SMoriah.Waterland@Sun.COM * returned token - the returned token is always 507*9781SMoriah.Waterland@Sun.COM * null terminated 508*9781SMoriah.Waterland@Sun.COM * a_buf[0] == '\0' - no token meeting criteria found 509*9781SMoriah.Waterland@Sun.COM * a_buf[0] != '\0' - token meeting criteria returned 510*9781SMoriah.Waterland@Sun.COM * a_bufLen - [RO, *RO] - (int) 511*9781SMoriah.Waterland@Sun.COM * - Size of 'a_buf' in bytes - a maximum of 'a_bufLen-1' 512*9781SMoriah.Waterland@Sun.COM * bytes will be placed in 'a_buf' - the returned 513*9781SMoriah.Waterland@Sun.COM * token is always null terminated 514*9781SMoriah.Waterland@Sun.COM * Returns: void 515*9781SMoriah.Waterland@Sun.COM */ 516*9781SMoriah.Waterland@Sun.COM 517*9781SMoriah.Waterland@Sun.COM void 518*9781SMoriah.Waterland@Sun.COM pkgstrGetToken_r(char *r_sep, char *a_string, int a_index, 519*9781SMoriah.Waterland@Sun.COM char *a_separators, char *a_buf, int a_bufLen) 520*9781SMoriah.Waterland@Sun.COM { 521*9781SMoriah.Waterland@Sun.COM char *p; 522*9781SMoriah.Waterland@Sun.COM char *q; 523*9781SMoriah.Waterland@Sun.COM char *lasts; 524*9781SMoriah.Waterland@Sun.COM 525*9781SMoriah.Waterland@Sun.COM /* entry assertions */ 526*9781SMoriah.Waterland@Sun.COM 527*9781SMoriah.Waterland@Sun.COM assert(a_string != (char *)NULL); 528*9781SMoriah.Waterland@Sun.COM assert(a_index >= 0); 529*9781SMoriah.Waterland@Sun.COM assert(a_separators != (char *)NULL); 530*9781SMoriah.Waterland@Sun.COM assert(*a_separators != '\0'); 531*9781SMoriah.Waterland@Sun.COM assert(a_buf != (char *)NULL); 532*9781SMoriah.Waterland@Sun.COM assert(a_bufLen > 0); 533*9781SMoriah.Waterland@Sun.COM 534*9781SMoriah.Waterland@Sun.COM /* reset returned separator */ 535*9781SMoriah.Waterland@Sun.COM 536*9781SMoriah.Waterland@Sun.COM if (r_sep != (char *)NULL) { 537*9781SMoriah.Waterland@Sun.COM *r_sep = '\0'; 538*9781SMoriah.Waterland@Sun.COM } 539*9781SMoriah.Waterland@Sun.COM 540*9781SMoriah.Waterland@Sun.COM /* zero out contents of return buffer */ 541*9781SMoriah.Waterland@Sun.COM 542*9781SMoriah.Waterland@Sun.COM bzero(a_buf, a_bufLen); 543*9781SMoriah.Waterland@Sun.COM 544*9781SMoriah.Waterland@Sun.COM /* duplicate original string before breaking down into tokens */ 545*9781SMoriah.Waterland@Sun.COM 546*9781SMoriah.Waterland@Sun.COM p = strdup(a_string); 547*9781SMoriah.Waterland@Sun.COM assert(p != (char *)NULL); 548*9781SMoriah.Waterland@Sun.COM if (p == (char *)NULL) { 549*9781SMoriah.Waterland@Sun.COM return; 550*9781SMoriah.Waterland@Sun.COM } 551*9781SMoriah.Waterland@Sun.COM lasts = p; 552*9781SMoriah.Waterland@Sun.COM 553*9781SMoriah.Waterland@Sun.COM /* scan for separators and return 'index'th token found */ 554*9781SMoriah.Waterland@Sun.COM 555*9781SMoriah.Waterland@Sun.COM while (q = strtok_r((char *)NULL, a_separators, &lasts)) { 556*9781SMoriah.Waterland@Sun.COM /* retrieve separator if requested */ 557*9781SMoriah.Waterland@Sun.COM 558*9781SMoriah.Waterland@Sun.COM if (r_sep != (char *)NULL) { 559*9781SMoriah.Waterland@Sun.COM char *x; 560*9781SMoriah.Waterland@Sun.COM x = strpbrk(a_string, a_separators); 561*9781SMoriah.Waterland@Sun.COM if (x) { 562*9781SMoriah.Waterland@Sun.COM *r_sep = *x; 563*9781SMoriah.Waterland@Sun.COM } 564*9781SMoriah.Waterland@Sun.COM } 565*9781SMoriah.Waterland@Sun.COM 566*9781SMoriah.Waterland@Sun.COM /* if this is the 'index'th token requested return it */ 567*9781SMoriah.Waterland@Sun.COM 568*9781SMoriah.Waterland@Sun.COM if (a_index-- == 0) { 569*9781SMoriah.Waterland@Sun.COM /* copy as many characters as possible to return buf */ 570*9781SMoriah.Waterland@Sun.COM 571*9781SMoriah.Waterland@Sun.COM (void) strncpy(a_buf, q, a_bufLen-1); 572*9781SMoriah.Waterland@Sun.COM break; 573*9781SMoriah.Waterland@Sun.COM } 574*9781SMoriah.Waterland@Sun.COM } 575*9781SMoriah.Waterland@Sun.COM 576*9781SMoriah.Waterland@Sun.COM /* free up copy of original input string */ 577*9781SMoriah.Waterland@Sun.COM 578*9781SMoriah.Waterland@Sun.COM free(p); 579*9781SMoriah.Waterland@Sun.COM } 580*9781SMoriah.Waterland@Sun.COM 581*9781SMoriah.Waterland@Sun.COM /* 582*9781SMoriah.Waterland@Sun.COM * Name: pkgstrAddToken 583*9781SMoriah.Waterland@Sun.COM * Synopsis: Add a token to a string 584*9781SMoriah.Waterland@Sun.COM * Description: Append a token (sequence of one or more characters) to a 585*9781SMoriah.Waterland@Sun.COM * string that is in allocated space - create new string if 586*9781SMoriah.Waterland@Sun.COM * no string to append to exists 587*9781SMoriah.Waterland@Sun.COM * Arguments: a_old - [RO, *RW] - (char **) 588*9781SMoriah.Waterland@Sun.COM * - Pointer to handle to string to append token to 589*9781SMoriah.Waterland@Sun.COM * == (char *)NULL - new string is created 590*9781SMoriah.Waterland@Sun.COM * a_new - [RO, *RO] - (char *) 591*9781SMoriah.Waterland@Sun.COM * - Pointer to string representing token to append 592*9781SMoriah.Waterland@Sun.COM * to the end of the "a_old" string 593*9781SMoriah.Waterland@Sun.COM * == (char *)NULL - no action is performed 594*9781SMoriah.Waterland@Sun.COM * a_new[0] == '\0' - no action is performed 595*9781SMoriah.Waterland@Sun.COM * a_separator - [RO, *RO] - (char) 596*9781SMoriah.Waterland@Sun.COM * - One character placed between the old (existing) 597*9781SMoriah.Waterland@Sun.COM * string and the new token to be added IF the old 598*9781SMoriah.Waterland@Sun.COM * string exists and is not empty (zero length) 599*9781SMoriah.Waterland@Sun.COM * Returns: void 600*9781SMoriah.Waterland@Sun.COM * CAUTION: The old (existing) string must be allocated space (via lu_mem* 601*9781SMoriah.Waterland@Sun.COM * or pkgstr* methods) - it must not be a static or inline 602*9781SMoriah.Waterland@Sun.COM * character string 603*9781SMoriah.Waterland@Sun.COM * NOTE: The old (existing) string may be freed with 'free' 604*9781SMoriah.Waterland@Sun.COM * if a token is appended to it 605*9781SMoriah.Waterland@Sun.COM * NOTE: Any string returned in 'a_old' is placed in new storage for the 606*9781SMoriah.Waterland@Sun.COM * calling method. The caller must use 'free' to dispose 607*9781SMoriah.Waterland@Sun.COM * of the storage once the token string is no longer needed. 608*9781SMoriah.Waterland@Sun.COM */ 609*9781SMoriah.Waterland@Sun.COM 610*9781SMoriah.Waterland@Sun.COM void 611*9781SMoriah.Waterland@Sun.COM pkgstrAddToken(char **a_old, char *a_new, char a_separator) 612*9781SMoriah.Waterland@Sun.COM { 613*9781SMoriah.Waterland@Sun.COM /* entry assertions */ 614*9781SMoriah.Waterland@Sun.COM 615*9781SMoriah.Waterland@Sun.COM assert(a_old != (char **)NULL); 616*9781SMoriah.Waterland@Sun.COM assert(a_separator != '\0'); 617*9781SMoriah.Waterland@Sun.COM 618*9781SMoriah.Waterland@Sun.COM /* if token to add is null, just return */ 619*9781SMoriah.Waterland@Sun.COM 620*9781SMoriah.Waterland@Sun.COM if (a_new == (char *)NULL) { 621*9781SMoriah.Waterland@Sun.COM return; 622*9781SMoriah.Waterland@Sun.COM } 623*9781SMoriah.Waterland@Sun.COM 624*9781SMoriah.Waterland@Sun.COM /* if token to add is empty (zero length), just return */ 625*9781SMoriah.Waterland@Sun.COM 626*9781SMoriah.Waterland@Sun.COM if (*a_new == '\0') { 627*9781SMoriah.Waterland@Sun.COM return; 628*9781SMoriah.Waterland@Sun.COM } 629*9781SMoriah.Waterland@Sun.COM 630*9781SMoriah.Waterland@Sun.COM /* make sure that new token does not contain the separator */ 631*9781SMoriah.Waterland@Sun.COM 632*9781SMoriah.Waterland@Sun.COM assert(strchr(a_new, (int)a_separator) == (char *)NULL); 633*9781SMoriah.Waterland@Sun.COM 634*9781SMoriah.Waterland@Sun.COM /* if old string is empty (zero length), deallocate */ 635*9781SMoriah.Waterland@Sun.COM 636*9781SMoriah.Waterland@Sun.COM if ((*a_old != (char *)NULL) && ((*a_old)[0] == '\0')) { 637*9781SMoriah.Waterland@Sun.COM /* *a_old is set to NULL by free */ 638*9781SMoriah.Waterland@Sun.COM free(*a_old); 639*9781SMoriah.Waterland@Sun.COM *a_old = (char *)NULL; 640*9781SMoriah.Waterland@Sun.COM } 641*9781SMoriah.Waterland@Sun.COM 642*9781SMoriah.Waterland@Sun.COM /* if old string is exists, append separator and token */ 643*9781SMoriah.Waterland@Sun.COM 644*9781SMoriah.Waterland@Sun.COM if (*a_old != (char *)NULL) { 645*9781SMoriah.Waterland@Sun.COM char *p; 646*9781SMoriah.Waterland@Sun.COM p = pkgstrPrintf("%s%c%s", *a_old, a_separator, a_new); 647*9781SMoriah.Waterland@Sun.COM free(*a_old); 648*9781SMoriah.Waterland@Sun.COM *a_old = p; 649*9781SMoriah.Waterland@Sun.COM return; 650*9781SMoriah.Waterland@Sun.COM } 651*9781SMoriah.Waterland@Sun.COM 652*9781SMoriah.Waterland@Sun.COM /* old string does not exist - return duplicate of token */ 653*9781SMoriah.Waterland@Sun.COM 654*9781SMoriah.Waterland@Sun.COM assert(*a_old == (char *)NULL); 655*9781SMoriah.Waterland@Sun.COM *a_old = strdup(a_new); 656*9781SMoriah.Waterland@Sun.COM assert(*a_old != (char *)NULL); 657*9781SMoriah.Waterland@Sun.COM } 658*9781SMoriah.Waterland@Sun.COM 659*9781SMoriah.Waterland@Sun.COM /* 660*9781SMoriah.Waterland@Sun.COM * Name: pkgstrContainsToken 661*9781SMoriah.Waterland@Sun.COM * Synopsis: Does a given string contain a specified substring 662*9781SMoriah.Waterland@Sun.COM * Description: Determine if a given substring exists in a larger string 663*9781SMoriah.Waterland@Sun.COM * Arguments: a_string - [RO, *RO] - (char *) 664*9781SMoriah.Waterland@Sun.COM * Pointer to string to look for substring in 665*9781SMoriah.Waterland@Sun.COM * a_token - [RO, *RO] - (char *) 666*9781SMoriah.Waterland@Sun.COM * Pointer to substring to look for in larger string 667*9781SMoriah.Waterland@Sun.COM * Results: boolean_t 668*9781SMoriah.Waterland@Sun.COM * B_TRUE - substring exists in larger string 669*9781SMoriah.Waterland@Sun.COM * B_FALSE - substring does NOT exist in larger string 670*9781SMoriah.Waterland@Sun.COM * NOTE: The substring must match on a "token" basis; that is, the 671*9781SMoriah.Waterland@Sun.COM * substring must exist in the larger string delineated with 672*9781SMoriah.Waterland@Sun.COM * either spaces or tabs to match. 673*9781SMoriah.Waterland@Sun.COM */ 674*9781SMoriah.Waterland@Sun.COM 675*9781SMoriah.Waterland@Sun.COM boolean_t 676*9781SMoriah.Waterland@Sun.COM pkgstrContainsToken(char *a_string, char *a_token, char *a_separators) 677*9781SMoriah.Waterland@Sun.COM { 678*9781SMoriah.Waterland@Sun.COM char *lasts; 679*9781SMoriah.Waterland@Sun.COM char *current; 680*9781SMoriah.Waterland@Sun.COM char *p; 681*9781SMoriah.Waterland@Sun.COM 682*9781SMoriah.Waterland@Sun.COM /* entry assertions */ 683*9781SMoriah.Waterland@Sun.COM 684*9781SMoriah.Waterland@Sun.COM assert(a_separators != (char *)NULL); 685*9781SMoriah.Waterland@Sun.COM assert(*a_separators != '\0'); 686*9781SMoriah.Waterland@Sun.COM 687*9781SMoriah.Waterland@Sun.COM /* if token is not supplied, return false */ 688*9781SMoriah.Waterland@Sun.COM 689*9781SMoriah.Waterland@Sun.COM if (a_token == (char *)NULL) { 690*9781SMoriah.Waterland@Sun.COM return (B_FALSE); 691*9781SMoriah.Waterland@Sun.COM } 692*9781SMoriah.Waterland@Sun.COM 693*9781SMoriah.Waterland@Sun.COM /* if no string provided, return false */ 694*9781SMoriah.Waterland@Sun.COM 695*9781SMoriah.Waterland@Sun.COM if (a_string == (char *)NULL) { 696*9781SMoriah.Waterland@Sun.COM return (B_FALSE); 697*9781SMoriah.Waterland@Sun.COM } 698*9781SMoriah.Waterland@Sun.COM 699*9781SMoriah.Waterland@Sun.COM /* if string empty (zero length), return false */ 700*9781SMoriah.Waterland@Sun.COM 701*9781SMoriah.Waterland@Sun.COM if (*a_string == '\0') { 702*9781SMoriah.Waterland@Sun.COM return (B_FALSE); 703*9781SMoriah.Waterland@Sun.COM } 704*9781SMoriah.Waterland@Sun.COM 705*9781SMoriah.Waterland@Sun.COM /* duplicate larger string because strtok_r changes it */ 706*9781SMoriah.Waterland@Sun.COM 707*9781SMoriah.Waterland@Sun.COM p = strdup(a_string); 708*9781SMoriah.Waterland@Sun.COM assert(p != (char *)NULL); 709*9781SMoriah.Waterland@Sun.COM if (p == (char *)NULL) { 710*9781SMoriah.Waterland@Sun.COM return (B_FALSE); 711*9781SMoriah.Waterland@Sun.COM } 712*9781SMoriah.Waterland@Sun.COM 713*9781SMoriah.Waterland@Sun.COM lasts = p; 714*9781SMoriah.Waterland@Sun.COM 715*9781SMoriah.Waterland@Sun.COM /* scan each token looking for a match */ 716*9781SMoriah.Waterland@Sun.COM 717*9781SMoriah.Waterland@Sun.COM while ((current = strtok_r((char *)NULL, a_separators, &lasts)) != 718*9781SMoriah.Waterland@Sun.COM (char *)NULL) { 719*9781SMoriah.Waterland@Sun.COM if (streq(current, a_token)) { 720*9781SMoriah.Waterland@Sun.COM free(p); 721*9781SMoriah.Waterland@Sun.COM return (B_TRUE); 722*9781SMoriah.Waterland@Sun.COM } 723*9781SMoriah.Waterland@Sun.COM } 724*9781SMoriah.Waterland@Sun.COM 725*9781SMoriah.Waterland@Sun.COM /* free up temporary storage */ 726*9781SMoriah.Waterland@Sun.COM 727*9781SMoriah.Waterland@Sun.COM free(p); 728*9781SMoriah.Waterland@Sun.COM 729*9781SMoriah.Waterland@Sun.COM /* not found */ 730*9781SMoriah.Waterland@Sun.COM 731*9781SMoriah.Waterland@Sun.COM return (B_FALSE); 732*9781SMoriah.Waterland@Sun.COM } 733*9781SMoriah.Waterland@Sun.COM 734*9781SMoriah.Waterland@Sun.COM /* 735*9781SMoriah.Waterland@Sun.COM * Name: pkgstrRemoveToken 736*9781SMoriah.Waterland@Sun.COM * Synopsis: Remove a token from a string 737*9781SMoriah.Waterland@Sun.COM * Description: Remove a token (sequence of one or more characters) from a 738*9781SMoriah.Waterland@Sun.COM * string that is in allocated space 739*9781SMoriah.Waterland@Sun.COM * Arguments: r_string - [RO, *RW] - (char **) 740*9781SMoriah.Waterland@Sun.COM * - Pointer to handle to string to remove token from 741*9781SMoriah.Waterland@Sun.COM * a_token - [RO, *RO] - (char *) 742*9781SMoriah.Waterland@Sun.COM * Pointer to token (substring) to look for and remove 743*9781SMoriah.Waterland@Sun.COM * from r_string provided 744*9781SMoriah.Waterland@Sun.COM * a_separators - [RO, *RO] - (char *) 745*9781SMoriah.Waterland@Sun.COM * - String containing one or more characters that 746*9781SMoriah.Waterland@Sun.COM * separate one "token" from another in r_string 747*9781SMoriah.Waterland@Sun.COM * a_index - [RO, *RO] - (int) 748*9781SMoriah.Waterland@Sun.COM * - Index of token to remove; '0' is first matching 749*9781SMoriah.Waterland@Sun.COM * token, '1' is second matching token, etc. 750*9781SMoriah.Waterland@Sun.COM * Returns: void 751*9781SMoriah.Waterland@Sun.COM * CAUTION: The input string must be allocated space (via lu_mem* or 752*9781SMoriah.Waterland@Sun.COM * pkgstr* methods) - it must not be a static or inline 753*9781SMoriah.Waterland@Sun.COM * character string 754*9781SMoriah.Waterland@Sun.COM * NOTE: The input string r_string will be freed with 'free' 755*9781SMoriah.Waterland@Sun.COM * if the token to be removed is found 756*9781SMoriah.Waterland@Sun.COM * NOTE: Any token string returned is placed in new storage for the 757*9781SMoriah.Waterland@Sun.COM * calling method. The caller must use 'free' to dispose 758*9781SMoriah.Waterland@Sun.COM * of the storage once the token string is no longer needed. 759*9781SMoriah.Waterland@Sun.COM * Errors: If the new token string cannot be created, the process exits 760*9781SMoriah.Waterland@Sun.COM */ 761*9781SMoriah.Waterland@Sun.COM 762*9781SMoriah.Waterland@Sun.COM void 763*9781SMoriah.Waterland@Sun.COM pkgstrRemoveToken(char **r_string, char *a_token, char *a_separators, 764*9781SMoriah.Waterland@Sun.COM int a_index) 765*9781SMoriah.Waterland@Sun.COM { 766*9781SMoriah.Waterland@Sun.COM char *a_string; 767*9781SMoriah.Waterland@Sun.COM char *copyString; 768*9781SMoriah.Waterland@Sun.COM char sep = 0; 769*9781SMoriah.Waterland@Sun.COM int copyLength; 770*9781SMoriah.Waterland@Sun.COM int i; 771*9781SMoriah.Waterland@Sun.COM 772*9781SMoriah.Waterland@Sun.COM /* entry assertions */ 773*9781SMoriah.Waterland@Sun.COM 774*9781SMoriah.Waterland@Sun.COM assert(r_string != (char **)NULL); 775*9781SMoriah.Waterland@Sun.COM assert(a_token != (char *)NULL); 776*9781SMoriah.Waterland@Sun.COM assert(*a_token != '\0'); 777*9781SMoriah.Waterland@Sun.COM assert(a_separators != (char *)NULL); 778*9781SMoriah.Waterland@Sun.COM assert(*a_separators != '\0'); 779*9781SMoriah.Waterland@Sun.COM 780*9781SMoriah.Waterland@Sun.COM /* simple case: input string is null; return empty string */ 781*9781SMoriah.Waterland@Sun.COM 782*9781SMoriah.Waterland@Sun.COM a_string = *r_string; 783*9781SMoriah.Waterland@Sun.COM if (*a_string == '\0') { 784*9781SMoriah.Waterland@Sun.COM return; 785*9781SMoriah.Waterland@Sun.COM } 786*9781SMoriah.Waterland@Sun.COM 787*9781SMoriah.Waterland@Sun.COM /* simple case: token == input string; return empty string */ 788*9781SMoriah.Waterland@Sun.COM 789*9781SMoriah.Waterland@Sun.COM if (streq(a_string, a_token)) { 790*9781SMoriah.Waterland@Sun.COM /* deallocate input string; free sets *r_string to NULL */ 791*9781SMoriah.Waterland@Sun.COM 792*9781SMoriah.Waterland@Sun.COM free(*r_string); 793*9781SMoriah.Waterland@Sun.COM *r_string = (char *)NULL; 794*9781SMoriah.Waterland@Sun.COM return; 795*9781SMoriah.Waterland@Sun.COM } 796*9781SMoriah.Waterland@Sun.COM 797*9781SMoriah.Waterland@Sun.COM /* simple case: token not in input string: return */ 798*9781SMoriah.Waterland@Sun.COM 799*9781SMoriah.Waterland@Sun.COM if (!pkgstrContainsToken(a_string, a_token, a_separators)) { 800*9781SMoriah.Waterland@Sun.COM return; 801*9781SMoriah.Waterland@Sun.COM } 802*9781SMoriah.Waterland@Sun.COM 803*9781SMoriah.Waterland@Sun.COM /* 804*9781SMoriah.Waterland@Sun.COM * Pick apart the old string building the new one as we go along 805*9781SMoriah.Waterland@Sun.COM * removing the first occurance of the token provided 806*9781SMoriah.Waterland@Sun.COM */ 807*9781SMoriah.Waterland@Sun.COM 808*9781SMoriah.Waterland@Sun.COM copyLength = (strlen(a_string)-strlen(a_token))+2; 809*9781SMoriah.Waterland@Sun.COM copyString = calloc(1, copyLength); 810*9781SMoriah.Waterland@Sun.COM assert(copyString != (char *)NULL); 811*9781SMoriah.Waterland@Sun.COM if (copyString == (char *)NULL) { 812*9781SMoriah.Waterland@Sun.COM return; 813*9781SMoriah.Waterland@Sun.COM } 814*9781SMoriah.Waterland@Sun.COM 815*9781SMoriah.Waterland@Sun.COM for (i = 0; ; i++) { 816*9781SMoriah.Waterland@Sun.COM char *p; 817*9781SMoriah.Waterland@Sun.COM 818*9781SMoriah.Waterland@Sun.COM p = pkgstrGetToken(&sep, a_string, i, a_separators); 819*9781SMoriah.Waterland@Sun.COM if (p == (char *)NULL) { 820*9781SMoriah.Waterland@Sun.COM break; 821*9781SMoriah.Waterland@Sun.COM } 822*9781SMoriah.Waterland@Sun.COM 823*9781SMoriah.Waterland@Sun.COM if (streq(p, a_token) && (a_index-- == 0)) { 824*9781SMoriah.Waterland@Sun.COM continue; 825*9781SMoriah.Waterland@Sun.COM } 826*9781SMoriah.Waterland@Sun.COM 827*9781SMoriah.Waterland@Sun.COM if (*copyString) { 828*9781SMoriah.Waterland@Sun.COM assert(sep != '\0'); 829*9781SMoriah.Waterland@Sun.COM (void) strncat(copyString, &sep, 1); 830*9781SMoriah.Waterland@Sun.COM } 831*9781SMoriah.Waterland@Sun.COM 832*9781SMoriah.Waterland@Sun.COM (void) strcat(copyString, p); 833*9781SMoriah.Waterland@Sun.COM } 834*9781SMoriah.Waterland@Sun.COM 835*9781SMoriah.Waterland@Sun.COM free(*r_string); 836*9781SMoriah.Waterland@Sun.COM assert(*copyString); 837*9781SMoriah.Waterland@Sun.COM *r_string = copyString; 838*9781SMoriah.Waterland@Sun.COM } 839*9781SMoriah.Waterland@Sun.COM 840*9781SMoriah.Waterland@Sun.COM /* 841*9781SMoriah.Waterland@Sun.COM * Name: pkgstrScaleNumericString 842*9781SMoriah.Waterland@Sun.COM * Synopsis: Convert unsigned long long to human readable form 843*9781SMoriah.Waterland@Sun.COM * Description: Convert a string containing an unsigned long long representation 844*9781SMoriah.Waterland@Sun.COM * and convert it into a human readable numeric string. The number 845*9781SMoriah.Waterland@Sun.COM * is scaled down until it is small enough to be in a good human 846*9781SMoriah.Waterland@Sun.COM * readable format i.e. in the range 0 thru scale-1. 847*9781SMoriah.Waterland@Sun.COM * Arguments: a_buf - [RO, *RW] - (char *) 848*9781SMoriah.Waterland@Sun.COM * Pointer to buffer containing string representation 849*9781SMoriah.Waterland@Sun.COM * of unsigned long long to convert 850*9781SMoriah.Waterland@Sun.COM * scale - [RO, *RO] - (unsigned long long) 851*9781SMoriah.Waterland@Sun.COM * Value to scale the number into 852*9781SMoriah.Waterland@Sun.COM * Returns: a_buf - contains human readable scaled representation of 853*9781SMoriah.Waterland@Sun.COM * original value contained in the buffer 854*9781SMoriah.Waterland@Sun.COM * Note: The value "(unsigned long long)-1" is a special case and 855*9781SMoriah.Waterland@Sun.COM * is always converted to "-1". 856*9781SMoriah.Waterland@Sun.COM * Errors: If the string cannot be created, the process exits 857*9781SMoriah.Waterland@Sun.COM */ 858*9781SMoriah.Waterland@Sun.COM 859*9781SMoriah.Waterland@Sun.COM void 860*9781SMoriah.Waterland@Sun.COM pkgstrScaleNumericString(char *a_buf, unsigned long long scale) 861*9781SMoriah.Waterland@Sun.COM { 862*9781SMoriah.Waterland@Sun.COM static char *M = " KMGTPE"; /* Measurement: */ 863*9781SMoriah.Waterland@Sun.COM /* kilo, mega, giga, tera, peta, exa */ 864*9781SMoriah.Waterland@Sun.COM 865*9781SMoriah.Waterland@Sun.COM unsigned long long number = 0; /* convert this number */ 866*9781SMoriah.Waterland@Sun.COM unsigned long long save = 0; 867*9781SMoriah.Waterland@Sun.COM char *uom = M; /* unit of measurement, initially ' ' (=M[0]) */ 868*9781SMoriah.Waterland@Sun.COM 869*9781SMoriah.Waterland@Sun.COM /* entry assertions */ 870*9781SMoriah.Waterland@Sun.COM 871*9781SMoriah.Waterland@Sun.COM assert(scale > (unsigned long long)0); 872*9781SMoriah.Waterland@Sun.COM assert(scale <= (unsigned long long)1048576); 873*9781SMoriah.Waterland@Sun.COM 874*9781SMoriah.Waterland@Sun.COM /* 875*9781SMoriah.Waterland@Sun.COM * Get the number - if no number of empty number, just return 876*9781SMoriah.Waterland@Sun.COM */ 877*9781SMoriah.Waterland@Sun.COM 878*9781SMoriah.Waterland@Sun.COM if (a_buf == (char *)NULL) { 879*9781SMoriah.Waterland@Sun.COM return; 880*9781SMoriah.Waterland@Sun.COM } 881*9781SMoriah.Waterland@Sun.COM 882*9781SMoriah.Waterland@Sun.COM if (*a_buf == '\0') { 883*9781SMoriah.Waterland@Sun.COM (void) strcpy(a_buf, "0"); 884*9781SMoriah.Waterland@Sun.COM return; 885*9781SMoriah.Waterland@Sun.COM } 886*9781SMoriah.Waterland@Sun.COM 887*9781SMoriah.Waterland@Sun.COM /* convert out the number from the input buffer */ 888*9781SMoriah.Waterland@Sun.COM 889*9781SMoriah.Waterland@Sun.COM number = strtoull(a_buf, (char **)NULL, 10); 890*9781SMoriah.Waterland@Sun.COM 891*9781SMoriah.Waterland@Sun.COM /* if conversion error, return "-1" */ 892*9781SMoriah.Waterland@Sun.COM 893*9781SMoriah.Waterland@Sun.COM if ((long long)number == (long long)-1) { 894*9781SMoriah.Waterland@Sun.COM (void) strcpy(a_buf, "-1"); 895*9781SMoriah.Waterland@Sun.COM return; 896*9781SMoriah.Waterland@Sun.COM } 897*9781SMoriah.Waterland@Sun.COM 898*9781SMoriah.Waterland@Sun.COM /* 899*9781SMoriah.Waterland@Sun.COM * Now have number as a count of scale units. 900*9781SMoriah.Waterland@Sun.COM * Stop scaling when we reached exa-bytes, then something is 901*9781SMoriah.Waterland@Sun.COM * probably wrong with our number (it is improbably large) 902*9781SMoriah.Waterland@Sun.COM */ 903*9781SMoriah.Waterland@Sun.COM 904*9781SMoriah.Waterland@Sun.COM while ((number >= scale) && (*uom != 'E')) { 905*9781SMoriah.Waterland@Sun.COM uom++; /* next unit of measurement */ 906*9781SMoriah.Waterland@Sun.COM save = number; 907*9781SMoriah.Waterland@Sun.COM number = (number + (scale / 2)) / scale; 908*9781SMoriah.Waterland@Sun.COM } 909*9781SMoriah.Waterland@Sun.COM 910*9781SMoriah.Waterland@Sun.COM /* check if we should output a decimal place after the point */ 911*9781SMoriah.Waterland@Sun.COM 912*9781SMoriah.Waterland@Sun.COM if (save && ((save / scale) < 10)) { 913*9781SMoriah.Waterland@Sun.COM /* sprintf() will round for us */ 914*9781SMoriah.Waterland@Sun.COM float fnum = (float)save / scale; 915*9781SMoriah.Waterland@Sun.COM (void) sprintf(a_buf, "%4.1f%c", fnum, *uom); 916*9781SMoriah.Waterland@Sun.COM } else { 917*9781SMoriah.Waterland@Sun.COM (void) sprintf(a_buf, "%4llu%c", number, *uom); 918*9781SMoriah.Waterland@Sun.COM } 919*9781SMoriah.Waterland@Sun.COM } 920*9781SMoriah.Waterland@Sun.COM 921*9781SMoriah.Waterland@Sun.COM /* 922*9781SMoriah.Waterland@Sun.COM * Name: pkgstrLocatePathBasename 923*9781SMoriah.Waterland@Sun.COM * Synopsis: Locate position of base name in path string 924*9781SMoriah.Waterland@Sun.COM * Description: Locate the base name (last path item) in a path and 925*9781SMoriah.Waterland@Sun.COM * return a pointer to the first byte of the base name 926*9781SMoriah.Waterland@Sun.COM * within the given path 927*9781SMoriah.Waterland@Sun.COM * Arguments: a_path - [RO, *RO] - (char *) 928*9781SMoriah.Waterland@Sun.COM * - Pointer to string representing path to scan 929*9781SMoriah.Waterland@Sun.COM * Returns: char * 930*9781SMoriah.Waterland@Sun.COM * - Pointer into string of first byte of path base name 931*9781SMoriah.Waterland@Sun.COM * - == (char *)NULL - input path is (char *)NULL 932*9781SMoriah.Waterland@Sun.COM */ 933*9781SMoriah.Waterland@Sun.COM 934*9781SMoriah.Waterland@Sun.COM char * 935*9781SMoriah.Waterland@Sun.COM pkgstrLocatePathBasename(char *a_path) 936*9781SMoriah.Waterland@Sun.COM { 937*9781SMoriah.Waterland@Sun.COM char *p; 938*9781SMoriah.Waterland@Sun.COM 939*9781SMoriah.Waterland@Sun.COM /* if path is NULL, return NULL */ 940*9781SMoriah.Waterland@Sun.COM 941*9781SMoriah.Waterland@Sun.COM if (!a_path) { 942*9781SMoriah.Waterland@Sun.COM return (a_path); 943*9781SMoriah.Waterland@Sun.COM } 944*9781SMoriah.Waterland@Sun.COM 945*9781SMoriah.Waterland@Sun.COM /* locate last occurance of '/' in path */ 946*9781SMoriah.Waterland@Sun.COM 947*9781SMoriah.Waterland@Sun.COM p = strrchr(a_path, '/'); 948*9781SMoriah.Waterland@Sun.COM if (p != (char *)NULL) { 949*9781SMoriah.Waterland@Sun.COM /* base name located - return -> first byte */ 950*9781SMoriah.Waterland@Sun.COM return (p+1); 951*9781SMoriah.Waterland@Sun.COM } 952*9781SMoriah.Waterland@Sun.COM 953*9781SMoriah.Waterland@Sun.COM /* no occurance of '/' - entry path must be basename */ 954*9781SMoriah.Waterland@Sun.COM 955*9781SMoriah.Waterland@Sun.COM return (a_path); 956*9781SMoriah.Waterland@Sun.COM } 957*9781SMoriah.Waterland@Sun.COM 958*9781SMoriah.Waterland@Sun.COM /* 959*9781SMoriah.Waterland@Sun.COM * Name: pkgstrConvertPathToBasename 960*9781SMoriah.Waterland@Sun.COM * Synopsis: Return copy of base name in path string 961*9781SMoriah.Waterland@Sun.COM * Description: Locate the base name (last path item) in a path and 962*9781SMoriah.Waterland@Sun.COM * return a copy of the base name in allocated storage 963*9781SMoriah.Waterland@Sun.COM * Arguments: a_path - [RO, *RO] - (char *) 964*9781SMoriah.Waterland@Sun.COM * - Pointer to string representing path to scan 965*9781SMoriah.Waterland@Sun.COM * Returns: char * 966*9781SMoriah.Waterland@Sun.COM * - String containing path base name 967*9781SMoriah.Waterland@Sun.COM * - == (char *)NULL - input path is (char *)NULL 968*9781SMoriah.Waterland@Sun.COM * NOTE: Any string returned is placed in new storage for the 969*9781SMoriah.Waterland@Sun.COM * calling method. The caller must use 'free' to dispose 970*9781SMoriah.Waterland@Sun.COM * of the storage once the string is no longer needed. 971*9781SMoriah.Waterland@Sun.COM * Errors: If the string cannot be created, the process exits 972*9781SMoriah.Waterland@Sun.COM */ 973*9781SMoriah.Waterland@Sun.COM 974*9781SMoriah.Waterland@Sun.COM char * 975*9781SMoriah.Waterland@Sun.COM pkgstrConvertPathToBasename(char *a_path) 976*9781SMoriah.Waterland@Sun.COM { 977*9781SMoriah.Waterland@Sun.COM char *p; 978*9781SMoriah.Waterland@Sun.COM 979*9781SMoriah.Waterland@Sun.COM /* if path is NULL, return NULL */ 980*9781SMoriah.Waterland@Sun.COM 981*9781SMoriah.Waterland@Sun.COM if (a_path == (char *)NULL) { 982*9781SMoriah.Waterland@Sun.COM return ((char *)NULL); 983*9781SMoriah.Waterland@Sun.COM } 984*9781SMoriah.Waterland@Sun.COM 985*9781SMoriah.Waterland@Sun.COM /* if path is empty (zero length), return NULL */ 986*9781SMoriah.Waterland@Sun.COM 987*9781SMoriah.Waterland@Sun.COM if (*a_path == '\0') { 988*9781SMoriah.Waterland@Sun.COM return ((char *)NULL); 989*9781SMoriah.Waterland@Sun.COM } 990*9781SMoriah.Waterland@Sun.COM 991*9781SMoriah.Waterland@Sun.COM /* locate last occurance of '/' in path */ 992*9781SMoriah.Waterland@Sun.COM 993*9781SMoriah.Waterland@Sun.COM p = strrchr(a_path, '/'); 994*9781SMoriah.Waterland@Sun.COM if (p == (char *)NULL) { 995*9781SMoriah.Waterland@Sun.COM /* no occurance of '/' - entry path must be basename */ 996*9781SMoriah.Waterland@Sun.COM 997*9781SMoriah.Waterland@Sun.COM return (strdup(a_path)); 998*9781SMoriah.Waterland@Sun.COM } 999*9781SMoriah.Waterland@Sun.COM 1000*9781SMoriah.Waterland@Sun.COM /* base name located - return string from -> first byte */ 1001*9781SMoriah.Waterland@Sun.COM 1002*9781SMoriah.Waterland@Sun.COM return (strdup(p+1)); 1003*9781SMoriah.Waterland@Sun.COM } 1004*9781SMoriah.Waterland@Sun.COM 1005*9781SMoriah.Waterland@Sun.COM /* 1006*9781SMoriah.Waterland@Sun.COM * Name: pkgstrConvertPathToDirname 1007*9781SMoriah.Waterland@Sun.COM * Synopsis: Return copy of directory in path string 1008*9781SMoriah.Waterland@Sun.COM * Description: Locate the directory name (everything but last path item) in a 1009*9781SMoriah.Waterland@Sun.COM * path and return a copy of the dir name in allocated storage 1010*9781SMoriah.Waterland@Sun.COM * Arguments: a_path - [RO, *RO] - (char *) 1011*9781SMoriah.Waterland@Sun.COM * - Pointer to string representing path to scan 1012*9781SMoriah.Waterland@Sun.COM * Returns: char * 1013*9781SMoriah.Waterland@Sun.COM * - String containing path directory name 1014*9781SMoriah.Waterland@Sun.COM * - == (char *)NULL - input path is (char *)NULL, 1015*9781SMoriah.Waterland@Sun.COM * or a_path is empty (*a_path == '\0'), or the 1016*9781SMoriah.Waterland@Sun.COM * a_path has no directory name in it. 1017*9781SMoriah.Waterland@Sun.COM * NOTE: Any string returned is placed in new storage for the 1018*9781SMoriah.Waterland@Sun.COM * calling method. The caller must use 'free' to dispose 1019*9781SMoriah.Waterland@Sun.COM * of the storage once the string is no longer needed. 1020*9781SMoriah.Waterland@Sun.COM * Errors: If the string cannot be created, the process exits 1021*9781SMoriah.Waterland@Sun.COM */ 1022*9781SMoriah.Waterland@Sun.COM 1023*9781SMoriah.Waterland@Sun.COM char * 1024*9781SMoriah.Waterland@Sun.COM pkgstrConvertPathToDirname(char *a_path) 1025*9781SMoriah.Waterland@Sun.COM { 1026*9781SMoriah.Waterland@Sun.COM char *p; 1027*9781SMoriah.Waterland@Sun.COM char *retPath; 1028*9781SMoriah.Waterland@Sun.COM 1029*9781SMoriah.Waterland@Sun.COM /* if path is NULL, return NULL */ 1030*9781SMoriah.Waterland@Sun.COM 1031*9781SMoriah.Waterland@Sun.COM if (a_path == (char *)NULL) { 1032*9781SMoriah.Waterland@Sun.COM return ((char *)NULL); 1033*9781SMoriah.Waterland@Sun.COM } 1034*9781SMoriah.Waterland@Sun.COM 1035*9781SMoriah.Waterland@Sun.COM /* if path is empty (zero length), return NULL */ 1036*9781SMoriah.Waterland@Sun.COM 1037*9781SMoriah.Waterland@Sun.COM if (*a_path == '\0') { 1038*9781SMoriah.Waterland@Sun.COM return ((char *)NULL); 1039*9781SMoriah.Waterland@Sun.COM } 1040*9781SMoriah.Waterland@Sun.COM 1041*9781SMoriah.Waterland@Sun.COM /* locate last occurance of '/' in path */ 1042*9781SMoriah.Waterland@Sun.COM 1043*9781SMoriah.Waterland@Sun.COM p = strrchr(a_path, '/'); 1044*9781SMoriah.Waterland@Sun.COM if (p == (char *)NULL) { 1045*9781SMoriah.Waterland@Sun.COM /* no occurance of '/' - entire path must be basename */ 1046*9781SMoriah.Waterland@Sun.COM 1047*9781SMoriah.Waterland@Sun.COM return ((char *)NULL); 1048*9781SMoriah.Waterland@Sun.COM } 1049*9781SMoriah.Waterland@Sun.COM 1050*9781SMoriah.Waterland@Sun.COM /* duplicate original path */ 1051*9781SMoriah.Waterland@Sun.COM 1052*9781SMoriah.Waterland@Sun.COM retPath = strdup(a_path); 1053*9781SMoriah.Waterland@Sun.COM assert(retPath != (char *)NULL); 1054*9781SMoriah.Waterland@Sun.COM if (retPath == (char *)NULL) { 1055*9781SMoriah.Waterland@Sun.COM return ((char *)NULL); 1056*9781SMoriah.Waterland@Sun.COM } 1057*9781SMoriah.Waterland@Sun.COM 1058*9781SMoriah.Waterland@Sun.COM /* remove all trailing '/'s from copy of path */ 1059*9781SMoriah.Waterland@Sun.COM 1060*9781SMoriah.Waterland@Sun.COM for (p = strrchr(retPath, '/'); (p > retPath) && (*p == '/'); p--) { 1061*9781SMoriah.Waterland@Sun.COM *p = '\0'; 1062*9781SMoriah.Waterland@Sun.COM } 1063*9781SMoriah.Waterland@Sun.COM 1064*9781SMoriah.Waterland@Sun.COM /* if entire path was '/'s, return null string - no directory present */ 1065*9781SMoriah.Waterland@Sun.COM 1066*9781SMoriah.Waterland@Sun.COM if (*retPath == '\0') { 1067*9781SMoriah.Waterland@Sun.COM free(retPath); 1068*9781SMoriah.Waterland@Sun.COM return ((char *)NULL); 1069*9781SMoriah.Waterland@Sun.COM } 1070*9781SMoriah.Waterland@Sun.COM 1071*9781SMoriah.Waterland@Sun.COM /* path has at least one non-'/' in it - return -> directory portion */ 1072*9781SMoriah.Waterland@Sun.COM 1073*9781SMoriah.Waterland@Sun.COM return (retPath); 1074*9781SMoriah.Waterland@Sun.COM } 1075*9781SMoriah.Waterland@Sun.COM 1076*9781SMoriah.Waterland@Sun.COM /* 1077*9781SMoriah.Waterland@Sun.COM * Name: pkgstrConvertUllToTimeString_r 1078*9781SMoriah.Waterland@Sun.COM * Synopsis: Convert an unsigned long long into a "time string" 1079*9781SMoriah.Waterland@Sun.COM * Description: Given an unsigned long long, return a "time string" which is a 1080*9781SMoriah.Waterland@Sun.COM * conversion of the unsigned long long interpreted as a number of 1081*9781SMoriah.Waterland@Sun.COM * nanoseconds into a "hour:minute:second.ns" ascii string 1082*9781SMoriah.Waterland@Sun.COM * Arguments: a_time - [RO, *RO] - (unsigned long long)n 1083*9781SMoriah.Waterland@Sun.COM * - value to convert 1084*9781SMoriah.Waterland@Sun.COM * a_buf - [RO, *RW] - (char *) 1085*9781SMoriah.Waterland@Sun.COM * - Pointer to buffer used as storage space for the 1086*9781SMoriah.Waterland@Sun.COM * returned string 1087*9781SMoriah.Waterland@Sun.COM * a_bufLen - [RO, *RO] - (int) 1088*9781SMoriah.Waterland@Sun.COM * - Size of 'a_buf' in bytes - a maximum of 'a_bufLen-1' 1089*9781SMoriah.Waterland@Sun.COM * bytes will be placed in 'a_buf' 1090*9781SMoriah.Waterland@Sun.COM * Returns: char * 1091*9781SMoriah.Waterland@Sun.COM * - String containing converted value 1092*9781SMoriah.Waterland@Sun.COM * NOTE: Any string returned is placed in new storage for the 1093*9781SMoriah.Waterland@Sun.COM * calling method. The caller must use 'free' to dispose 1094*9781SMoriah.Waterland@Sun.COM * of the storage once the string is no longer needed. 1095*9781SMoriah.Waterland@Sun.COM * Errors: If the string cannot be created, the process exits 1096*9781SMoriah.Waterland@Sun.COM */ 1097*9781SMoriah.Waterland@Sun.COM 1098*9781SMoriah.Waterland@Sun.COM void 1099*9781SMoriah.Waterland@Sun.COM pkgstrConvertUllToTimeString_r(unsigned long long a_time, 1100*9781SMoriah.Waterland@Sun.COM char *a_buf, int a_bufLen) 1101*9781SMoriah.Waterland@Sun.COM { 1102*9781SMoriah.Waterland@Sun.COM unsigned long long seconds; 1103*9781SMoriah.Waterland@Sun.COM unsigned long long minutes; 1104*9781SMoriah.Waterland@Sun.COM unsigned long long hours; 1105*9781SMoriah.Waterland@Sun.COM unsigned long long ns; 1106*9781SMoriah.Waterland@Sun.COM 1107*9781SMoriah.Waterland@Sun.COM /* entry assertions */ 1108*9781SMoriah.Waterland@Sun.COM 1109*9781SMoriah.Waterland@Sun.COM assert(a_buf != (char *)NULL); 1110*9781SMoriah.Waterland@Sun.COM assert(a_bufLen > 0); 1111*9781SMoriah.Waterland@Sun.COM 1112*9781SMoriah.Waterland@Sun.COM /* if time is 0, return immediate result */ 1113*9781SMoriah.Waterland@Sun.COM 1114*9781SMoriah.Waterland@Sun.COM if (a_time == 0) { 1115*9781SMoriah.Waterland@Sun.COM pkgstrPrintf_r(a_buf, a_bufLen, "%s", "0:00:00.000000000"); 1116*9781SMoriah.Waterland@Sun.COM return; 1117*9781SMoriah.Waterland@Sun.COM } 1118*9781SMoriah.Waterland@Sun.COM 1119*9781SMoriah.Waterland@Sun.COM /* break out individual time components */ 1120*9781SMoriah.Waterland@Sun.COM 1121*9781SMoriah.Waterland@Sun.COM ns = a_time % 1000000000ll; /* nanoseconds left over from seconds */ 1122*9781SMoriah.Waterland@Sun.COM seconds = a_time / 1000000000ll; /* total seconds */ 1123*9781SMoriah.Waterland@Sun.COM minutes = seconds / 60ll; /* total minutes */ 1124*9781SMoriah.Waterland@Sun.COM seconds = seconds % 60ll; /* seconds left over from minutes */ 1125*9781SMoriah.Waterland@Sun.COM hours = minutes / 60ll; /* total hours */ 1126*9781SMoriah.Waterland@Sun.COM minutes = minutes % 60ll; /* minutes left over from hours */ 1127*9781SMoriah.Waterland@Sun.COM 1128*9781SMoriah.Waterland@Sun.COM /* return a converted string */ 1129*9781SMoriah.Waterland@Sun.COM 1130*9781SMoriah.Waterland@Sun.COM pkgstrPrintf_r(a_buf, a_bufLen, "%llu:%02llu:%02llu.%09llu", 1131*9781SMoriah.Waterland@Sun.COM hours, minutes, seconds, ns); 1132*9781SMoriah.Waterland@Sun.COM } 1133