1*99ebb4caSwyllys /* 2*99ebb4caSwyllys * CDDL HEADER START 3*99ebb4caSwyllys * 4*99ebb4caSwyllys * The contents of this file are subject to the terms of the 5*99ebb4caSwyllys * Common Development and Distribution License (the "License"). 6*99ebb4caSwyllys * You may not use this file except in compliance with the License. 7*99ebb4caSwyllys * 8*99ebb4caSwyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*99ebb4caSwyllys * or http://www.opensolaris.org/os/licensing. 10*99ebb4caSwyllys * See the License for the specific language governing permissions 11*99ebb4caSwyllys * and limitations under the License. 12*99ebb4caSwyllys * 13*99ebb4caSwyllys * When distributing Covered Code, include this CDDL HEADER in each 14*99ebb4caSwyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*99ebb4caSwyllys * If applicable, add the following below this CDDL HEADER, with the 16*99ebb4caSwyllys * fields enclosed by brackets "[]" replaced with your own identifying 17*99ebb4caSwyllys * information: Portions Copyright [yyyy] [name of copyright owner] 18*99ebb4caSwyllys * 19*99ebb4caSwyllys * CDDL HEADER END 20*99ebb4caSwyllys * 21*99ebb4caSwyllys * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 22*99ebb4caSwyllys * Use is subject to license terms. 23*99ebb4caSwyllys */ 24*99ebb4caSwyllys 25*99ebb4caSwyllys #pragma ident "%Z%%M% %I% %E% SMI" 26*99ebb4caSwyllys 27*99ebb4caSwyllys #include <stdio.h> 28*99ebb4caSwyllys #include <strings.h> 29*99ebb4caSwyllys #include <ctype.h> 30*99ebb4caSwyllys #include <libgen.h> 31*99ebb4caSwyllys #include <libintl.h> 32*99ebb4caSwyllys 33*99ebb4caSwyllys #include <libxml/tree.h> 34*99ebb4caSwyllys #include <libxml/parser.h> 35*99ebb4caSwyllys 36*99ebb4caSwyllys #include <kmfapiP.h> 37*99ebb4caSwyllys 38*99ebb4caSwyllys #include "util.h" 39*99ebb4caSwyllys 40*99ebb4caSwyllys /* Supporting structures and global variables for getopt_av(). */ 41*99ebb4caSwyllys typedef struct av_opts_s { 42*99ebb4caSwyllys int shortnm; /* short name character */ 43*99ebb4caSwyllys char *longnm; /* long name string, NOT terminated */ 44*99ebb4caSwyllys int longnm_len; /* length of long name string */ 45*99ebb4caSwyllys boolean_t has_arg; /* takes optional argument */ 46*99ebb4caSwyllys } av_opts; 47*99ebb4caSwyllys 48*99ebb4caSwyllys static av_opts *opts_av = NULL; 49*99ebb4caSwyllys static const char *_save_optstr = NULL; 50*99ebb4caSwyllys static int _save_numopts = 0; 51*99ebb4caSwyllys int optind_av = 1; 52*99ebb4caSwyllys char *optarg_av = NULL; 53*99ebb4caSwyllys 54*99ebb4caSwyllys void 55*99ebb4caSwyllys free_policy_list(POLICY_LIST *plist) 56*99ebb4caSwyllys { 57*99ebb4caSwyllys POLICY_LIST *n = plist, *old; 58*99ebb4caSwyllys 59*99ebb4caSwyllys if (plist == NULL) 60*99ebb4caSwyllys return; 61*99ebb4caSwyllys 62*99ebb4caSwyllys while (n != NULL) { 63*99ebb4caSwyllys old = n; 64*99ebb4caSwyllys KMF_FreePolicyRecord(&n->plc); 65*99ebb4caSwyllys n = n->next; 66*99ebb4caSwyllys free(old); 67*99ebb4caSwyllys } 68*99ebb4caSwyllys plist = NULL; 69*99ebb4caSwyllys } 70*99ebb4caSwyllys 71*99ebb4caSwyllys int 72*99ebb4caSwyllys load_policies(char *file, POLICY_LIST **policy_list) 73*99ebb4caSwyllys { 74*99ebb4caSwyllys int rv = KC_OK; 75*99ebb4caSwyllys KMF_RETURN kmfrv = KMF_OK; 76*99ebb4caSwyllys POLICY_LIST *newitem, *plist = NULL; 77*99ebb4caSwyllys xmlParserCtxtPtr ctxt; 78*99ebb4caSwyllys xmlDocPtr doc = NULL; 79*99ebb4caSwyllys xmlNodePtr cur, node; 80*99ebb4caSwyllys 81*99ebb4caSwyllys /* Create a parser context */ 82*99ebb4caSwyllys ctxt = xmlNewParserCtxt(); 83*99ebb4caSwyllys if (ctxt == NULL) 84*99ebb4caSwyllys return (KMF_ERR_POLICY_DB_FORMAT); 85*99ebb4caSwyllys 86*99ebb4caSwyllys /* Read the policy DB and verify it against the schema. */ 87*99ebb4caSwyllys doc = xmlCtxtReadFile(ctxt, file, NULL, 88*99ebb4caSwyllys XML_PARSE_DTDVALID | XML_PARSE_NOERROR | XML_PARSE_NOWARNING); 89*99ebb4caSwyllys if (doc == NULL || ctxt->valid == 0) { 90*99ebb4caSwyllys kmfrv = KMF_ERR_POLICY_DB_FORMAT; 91*99ebb4caSwyllys goto end; 92*99ebb4caSwyllys } 93*99ebb4caSwyllys 94*99ebb4caSwyllys cur = xmlDocGetRootElement(doc); 95*99ebb4caSwyllys if (cur == NULL) { 96*99ebb4caSwyllys kmfrv = KMF_ERR_POLICY_DB_FORMAT; 97*99ebb4caSwyllys goto end; 98*99ebb4caSwyllys } 99*99ebb4caSwyllys 100*99ebb4caSwyllys node = cur->xmlChildrenNode; 101*99ebb4caSwyllys while (node != NULL) { 102*99ebb4caSwyllys char *c; 103*99ebb4caSwyllys /* 104*99ebb4caSwyllys * Search for the policy that matches the given name. 105*99ebb4caSwyllys */ 106*99ebb4caSwyllys if (!xmlStrcmp((const xmlChar *)node->name, 107*99ebb4caSwyllys (const xmlChar *)KMF_POLICY_ELEMENT)) { 108*99ebb4caSwyllys /* Check the name attribute */ 109*99ebb4caSwyllys c = (char *)xmlGetProp(node, 110*99ebb4caSwyllys (const xmlChar *)KMF_POLICY_NAME_ATTR); 111*99ebb4caSwyllys 112*99ebb4caSwyllys /* If a match, parse the rest of the data */ 113*99ebb4caSwyllys if (c != NULL) { 114*99ebb4caSwyllys xmlFree(c); 115*99ebb4caSwyllys newitem = malloc(sizeof (POLICY_LIST)); 116*99ebb4caSwyllys if (newitem != NULL) { 117*99ebb4caSwyllys (void) memset(newitem, 0, 118*99ebb4caSwyllys sizeof (POLICY_LIST)); 119*99ebb4caSwyllys kmfrv = parsePolicyElement(node, 120*99ebb4caSwyllys &newitem->plc); 121*99ebb4caSwyllys } else { 122*99ebb4caSwyllys kmfrv = KMF_ERR_MEMORY; 123*99ebb4caSwyllys goto end; 124*99ebb4caSwyllys } 125*99ebb4caSwyllys /* add to linked list */ 126*99ebb4caSwyllys if (plist == NULL) { 127*99ebb4caSwyllys plist = newitem; 128*99ebb4caSwyllys } else { 129*99ebb4caSwyllys POLICY_LIST *n = plist; 130*99ebb4caSwyllys while (n->next != NULL) 131*99ebb4caSwyllys n = n->next; 132*99ebb4caSwyllys 133*99ebb4caSwyllys n->next = newitem; 134*99ebb4caSwyllys newitem->next = NULL; 135*99ebb4caSwyllys } 136*99ebb4caSwyllys } 137*99ebb4caSwyllys } 138*99ebb4caSwyllys node = node->next; 139*99ebb4caSwyllys } 140*99ebb4caSwyllys 141*99ebb4caSwyllys end: 142*99ebb4caSwyllys if (ctxt != NULL) 143*99ebb4caSwyllys xmlFreeParserCtxt(ctxt); 144*99ebb4caSwyllys 145*99ebb4caSwyllys if (doc != NULL) 146*99ebb4caSwyllys xmlFreeDoc(doc); 147*99ebb4caSwyllys 148*99ebb4caSwyllys if (kmfrv != KMF_OK) { 149*99ebb4caSwyllys free_policy_list(plist); 150*99ebb4caSwyllys rv = KC_ERR_LOADDB; 151*99ebb4caSwyllys } else { 152*99ebb4caSwyllys *policy_list = plist; 153*99ebb4caSwyllys } 154*99ebb4caSwyllys 155*99ebb4caSwyllys return (rv); 156*99ebb4caSwyllys } 157*99ebb4caSwyllys 158*99ebb4caSwyllys /* 159*99ebb4caSwyllys * Return 0 if there is any error in the input string. 160*99ebb4caSwyllys */ 161*99ebb4caSwyllys uint16_t 162*99ebb4caSwyllys parseKUlist(char *kustring) 163*99ebb4caSwyllys { 164*99ebb4caSwyllys uint16_t cur_bit; 165*99ebb4caSwyllys uint16_t kubits = 0; 166*99ebb4caSwyllys char *p; 167*99ebb4caSwyllys 168*99ebb4caSwyllys p = strtok(kustring, ","); 169*99ebb4caSwyllys while (p != NULL) { 170*99ebb4caSwyllys cur_bit = KMF_StringToKeyUsage(p); 171*99ebb4caSwyllys if (cur_bit == 0) { 172*99ebb4caSwyllys kubits = 0; 173*99ebb4caSwyllys break; 174*99ebb4caSwyllys } 175*99ebb4caSwyllys kubits |= cur_bit; 176*99ebb4caSwyllys p = strtok(NULL, ","); 177*99ebb4caSwyllys } 178*99ebb4caSwyllys 179*99ebb4caSwyllys return (kubits); 180*99ebb4caSwyllys } 181*99ebb4caSwyllys 182*99ebb4caSwyllys static void 183*99ebb4caSwyllys addToEKUList(KMF_EKU_POLICY *ekus, KMF_OID *newoid) 184*99ebb4caSwyllys { 185*99ebb4caSwyllys if (newoid != NULL && ekus != NULL) { 186*99ebb4caSwyllys ekus->eku_count++; 187*99ebb4caSwyllys ekus->ekulist = realloc( 188*99ebb4caSwyllys ekus->ekulist, 189*99ebb4caSwyllys ekus->eku_count * sizeof (KMF_OID)); 190*99ebb4caSwyllys if (ekus->ekulist != NULL) { 191*99ebb4caSwyllys ekus->ekulist[ekus->eku_count-1] = *newoid; 192*99ebb4caSwyllys } 193*99ebb4caSwyllys } 194*99ebb4caSwyllys } 195*99ebb4caSwyllys 196*99ebb4caSwyllys int 197*99ebb4caSwyllys parseEKUNames(char *ekulist, KMF_POLICY_RECORD *plc) 198*99ebb4caSwyllys { 199*99ebb4caSwyllys int rv = KC_OK; 200*99ebb4caSwyllys char *p; 201*99ebb4caSwyllys KMF_OID *newoid; 202*99ebb4caSwyllys KMF_EKU_POLICY *ekus = &plc->eku_set; 203*99ebb4caSwyllys 204*99ebb4caSwyllys if (ekulist == NULL || !strlen(ekulist)) 205*99ebb4caSwyllys return (0); 206*99ebb4caSwyllys 207*99ebb4caSwyllys /* 208*99ebb4caSwyllys * The list should be comma separated list of EKU Names. 209*99ebb4caSwyllys */ 210*99ebb4caSwyllys p = strtok(ekulist, ","); 211*99ebb4caSwyllys 212*99ebb4caSwyllys /* If no tokens found, then maybe its just a single EKU value */ 213*99ebb4caSwyllys if (p == NULL) { 214*99ebb4caSwyllys newoid = kmf_ekuname2oid(ekulist); 215*99ebb4caSwyllys if (newoid != NULL) { 216*99ebb4caSwyllys addToEKUList(ekus, newoid); 217*99ebb4caSwyllys free(newoid); 218*99ebb4caSwyllys } else { 219*99ebb4caSwyllys rv = KC_ERR_USAGE; 220*99ebb4caSwyllys } 221*99ebb4caSwyllys } 222*99ebb4caSwyllys 223*99ebb4caSwyllys while (p != NULL) { 224*99ebb4caSwyllys newoid = kmf_ekuname2oid(p); 225*99ebb4caSwyllys if (newoid != NULL) { 226*99ebb4caSwyllys addToEKUList(ekus, newoid); 227*99ebb4caSwyllys free(newoid); 228*99ebb4caSwyllys } else { 229*99ebb4caSwyllys rv = KC_ERR_USAGE; 230*99ebb4caSwyllys break; 231*99ebb4caSwyllys } 232*99ebb4caSwyllys p = strtok(NULL, ","); 233*99ebb4caSwyllys } 234*99ebb4caSwyllys 235*99ebb4caSwyllys if (rv != KC_OK) 236*99ebb4caSwyllys KMF_FreeEKUPolicy(ekus); 237*99ebb4caSwyllys 238*99ebb4caSwyllys return (rv); 239*99ebb4caSwyllys } 240*99ebb4caSwyllys 241*99ebb4caSwyllys int 242*99ebb4caSwyllys parseEKUOIDs(char *ekulist, KMF_POLICY_RECORD *plc) 243*99ebb4caSwyllys { 244*99ebb4caSwyllys int rv = KC_OK; 245*99ebb4caSwyllys char *p; 246*99ebb4caSwyllys KMF_OID *newoid; 247*99ebb4caSwyllys KMF_EKU_POLICY *ekus = &plc->eku_set; 248*99ebb4caSwyllys 249*99ebb4caSwyllys if (ekulist == NULL || !strlen(ekulist)) 250*99ebb4caSwyllys return (0); 251*99ebb4caSwyllys 252*99ebb4caSwyllys /* 253*99ebb4caSwyllys * The list should be comma separated list of EKU Names. 254*99ebb4caSwyllys */ 255*99ebb4caSwyllys p = strtok(ekulist, ","); 256*99ebb4caSwyllys if (p == NULL) { 257*99ebb4caSwyllys newoid = kmf_string2oid(ekulist); 258*99ebb4caSwyllys if (newoid != NULL) { 259*99ebb4caSwyllys addToEKUList(ekus, newoid); 260*99ebb4caSwyllys free(newoid); 261*99ebb4caSwyllys } else { 262*99ebb4caSwyllys rv = KC_ERR_USAGE; 263*99ebb4caSwyllys } 264*99ebb4caSwyllys } 265*99ebb4caSwyllys 266*99ebb4caSwyllys while (p != NULL && rv == 0) { 267*99ebb4caSwyllys newoid = kmf_string2oid(p); 268*99ebb4caSwyllys if (newoid != NULL) { 269*99ebb4caSwyllys addToEKUList(ekus, newoid); 270*99ebb4caSwyllys free(newoid); 271*99ebb4caSwyllys } else { 272*99ebb4caSwyllys rv = KC_ERR_USAGE; 273*99ebb4caSwyllys break; 274*99ebb4caSwyllys } 275*99ebb4caSwyllys p = strtok(NULL, ","); 276*99ebb4caSwyllys } 277*99ebb4caSwyllys 278*99ebb4caSwyllys if (rv != KC_OK) 279*99ebb4caSwyllys KMF_FreeEKUPolicy(ekus); 280*99ebb4caSwyllys 281*99ebb4caSwyllys return (rv); 282*99ebb4caSwyllys } 283*99ebb4caSwyllys 284*99ebb4caSwyllys int 285*99ebb4caSwyllys get_boolean(char *arg) 286*99ebb4caSwyllys { 287*99ebb4caSwyllys if (arg == NULL) 288*99ebb4caSwyllys return (-1); 289*99ebb4caSwyllys if (strcasecmp(arg, "true") == 0) 290*99ebb4caSwyllys return (1); 291*99ebb4caSwyllys if (strcasecmp(arg, "false") == 0) 292*99ebb4caSwyllys return (0); 293*99ebb4caSwyllys return (-1); 294*99ebb4caSwyllys } 295*99ebb4caSwyllys 296*99ebb4caSwyllys /* 297*99ebb4caSwyllys * This function processes the input string. It removes the beginning 298*99ebb4caSwyllys * and ending blank's first, makes a copy of the resulting string and 299*99ebb4caSwyllys * return it. 300*99ebb4caSwyllys * 301*99ebb4caSwyllys * This function returns NULL, if there is an error in the 302*99ebb4caSwyllys * input string or when the system is out of memory. The output 303*99ebb4caSwyllys * "err_flag" argument will record the error code, if it is not NULL. 304*99ebb4caSwyllys */ 305*99ebb4caSwyllys char * 306*99ebb4caSwyllys get_string(char *str, int *err_flag) 307*99ebb4caSwyllys { 308*99ebb4caSwyllys char *p; 309*99ebb4caSwyllys int len, i; 310*99ebb4caSwyllys char *retstr = NULL; 311*99ebb4caSwyllys 312*99ebb4caSwyllys if (str == NULL) { 313*99ebb4caSwyllys if (err_flag != NULL) 314*99ebb4caSwyllys *err_flag = KC_ERR_USAGE; 315*99ebb4caSwyllys return (NULL); 316*99ebb4caSwyllys } 317*99ebb4caSwyllys 318*99ebb4caSwyllys /* Remove beginning whitespace */ 319*99ebb4caSwyllys p = str; 320*99ebb4caSwyllys while (p != NULL && isspace(*p)) 321*99ebb4caSwyllys p++; 322*99ebb4caSwyllys 323*99ebb4caSwyllys if (p == NULL) { 324*99ebb4caSwyllys if (err_flag != NULL) 325*99ebb4caSwyllys *err_flag = KC_ERR_USAGE; 326*99ebb4caSwyllys return (NULL); 327*99ebb4caSwyllys } 328*99ebb4caSwyllys 329*99ebb4caSwyllys /* Remove the trailing blanks */ 330*99ebb4caSwyllys len = strlen(p); 331*99ebb4caSwyllys while (len > 0 && isspace(p[len-1])) 332*99ebb4caSwyllys len--; 333*99ebb4caSwyllys 334*99ebb4caSwyllys if (len == 0) { 335*99ebb4caSwyllys if (err_flag != NULL) 336*99ebb4caSwyllys *err_flag = KC_ERR_USAGE; 337*99ebb4caSwyllys return (NULL); 338*99ebb4caSwyllys } 339*99ebb4caSwyllys 340*99ebb4caSwyllys /* Check if there is any non-printable character */ 341*99ebb4caSwyllys i = 0; 342*99ebb4caSwyllys while (i < len) { 343*99ebb4caSwyllys if (isprint(p[i])) 344*99ebb4caSwyllys i++; 345*99ebb4caSwyllys else { 346*99ebb4caSwyllys if (err_flag != NULL) 347*99ebb4caSwyllys *err_flag = KC_ERR_USAGE; 348*99ebb4caSwyllys return (NULL); 349*99ebb4caSwyllys } 350*99ebb4caSwyllys } 351*99ebb4caSwyllys 352*99ebb4caSwyllys /* Make a copy of the string and return it */ 353*99ebb4caSwyllys retstr = malloc(len + 1); 354*99ebb4caSwyllys if (retstr == NULL) { 355*99ebb4caSwyllys if (err_flag != NULL) 356*99ebb4caSwyllys *err_flag = KC_ERR_MEMORY; 357*99ebb4caSwyllys return (NULL); 358*99ebb4caSwyllys } 359*99ebb4caSwyllys 360*99ebb4caSwyllys if (err_flag != NULL) 361*99ebb4caSwyllys *err_flag = KC_OK; 362*99ebb4caSwyllys 363*99ebb4caSwyllys (void) strncpy(retstr, p, len); 364*99ebb4caSwyllys retstr[len] = '\0'; 365*99ebb4caSwyllys return (retstr); 366*99ebb4caSwyllys } 367*99ebb4caSwyllys 368*99ebb4caSwyllys /* 369*99ebb4caSwyllys * Breaks out the getopt-style option string into a structure that can be 370*99ebb4caSwyllys * traversed later for calls to getopt_av(). Option string is NOT altered, 371*99ebb4caSwyllys * but the struct fields point to locations within option string. 372*99ebb4caSwyllys */ 373*99ebb4caSwyllys static int 374*99ebb4caSwyllys populate_opts(char *optstring) 375*99ebb4caSwyllys { 376*99ebb4caSwyllys int i; 377*99ebb4caSwyllys av_opts *temp; 378*99ebb4caSwyllys char *marker; 379*99ebb4caSwyllys 380*99ebb4caSwyllys if (optstring == NULL || *optstring == '\0') 381*99ebb4caSwyllys return (0); 382*99ebb4caSwyllys 383*99ebb4caSwyllys /* 384*99ebb4caSwyllys * This tries to imitate getopt(3c) Each option must conform to: 385*99ebb4caSwyllys * <short name char> [ ':' ] [ '(' <long name string> ')' ] 386*99ebb4caSwyllys * If long name is missing, the short name is used for long name. 387*99ebb4caSwyllys */ 388*99ebb4caSwyllys for (i = 0; *optstring != '\0'; i++) { 389*99ebb4caSwyllys if ((temp = (av_opts *)((i == 0) ? malloc(sizeof (av_opts)) : 390*99ebb4caSwyllys realloc(opts_av, (i+1) * sizeof (av_opts)))) == NULL) { 391*99ebb4caSwyllys free(opts_av); 392*99ebb4caSwyllys opts_av = NULL; 393*99ebb4caSwyllys return (0); 394*99ebb4caSwyllys } else 395*99ebb4caSwyllys opts_av = (av_opts *)temp; 396*99ebb4caSwyllys 397*99ebb4caSwyllys marker = optstring; /* may need optstring later */ 398*99ebb4caSwyllys 399*99ebb4caSwyllys opts_av[i].shortnm = *marker++; /* set short name */ 400*99ebb4caSwyllys 401*99ebb4caSwyllys if (*marker == ':') { /* check for opt arg */ 402*99ebb4caSwyllys marker++; 403*99ebb4caSwyllys opts_av[i].has_arg = B_TRUE; 404*99ebb4caSwyllys } 405*99ebb4caSwyllys 406*99ebb4caSwyllys if (*marker == '(') { /* check and set long name */ 407*99ebb4caSwyllys marker++; 408*99ebb4caSwyllys opts_av[i].longnm = marker; 409*99ebb4caSwyllys opts_av[i].longnm_len = strcspn(marker, ")"); 410*99ebb4caSwyllys optstring = marker + opts_av[i].longnm_len + 1; 411*99ebb4caSwyllys } else { 412*99ebb4caSwyllys /* use short name option character */ 413*99ebb4caSwyllys opts_av[i].longnm = optstring; 414*99ebb4caSwyllys opts_av[i].longnm_len = 1; 415*99ebb4caSwyllys optstring = marker; 416*99ebb4caSwyllys } 417*99ebb4caSwyllys } 418*99ebb4caSwyllys 419*99ebb4caSwyllys return (i); 420*99ebb4caSwyllys } 421*99ebb4caSwyllys 422*99ebb4caSwyllys /* 423*99ebb4caSwyllys * getopt_av() is very similar to getopt(3c) in that the takes an option 424*99ebb4caSwyllys * string, compares command line arguments for matches, and returns a single 425*99ebb4caSwyllys * letter option when a match is found. However, getopt_av() differs from 426*99ebb4caSwyllys * getopt(3c) by allowing both longname options and values be found 427*99ebb4caSwyllys * on the command line. 428*99ebb4caSwyllys */ 429*99ebb4caSwyllys int 430*99ebb4caSwyllys getopt_av(int argc, char * const *argv, const char *optstring) 431*99ebb4caSwyllys { 432*99ebb4caSwyllys int i; 433*99ebb4caSwyllys int len; 434*99ebb4caSwyllys 435*99ebb4caSwyllys if (optind_av >= argc) 436*99ebb4caSwyllys return (EOF); 437*99ebb4caSwyllys 438*99ebb4caSwyllys /* First time or when optstring changes from previous one */ 439*99ebb4caSwyllys if (_save_optstr != optstring) { 440*99ebb4caSwyllys if (opts_av != NULL) 441*99ebb4caSwyllys free(opts_av); 442*99ebb4caSwyllys opts_av = NULL; 443*99ebb4caSwyllys _save_optstr = optstring; 444*99ebb4caSwyllys _save_numopts = populate_opts((char *)optstring); 445*99ebb4caSwyllys } 446*99ebb4caSwyllys 447*99ebb4caSwyllys for (i = 0; i < _save_numopts; i++) { 448*99ebb4caSwyllys if (strcmp(argv[optind_av], "--") == 0) { 449*99ebb4caSwyllys optind_av++; 450*99ebb4caSwyllys break; 451*99ebb4caSwyllys } 452*99ebb4caSwyllys 453*99ebb4caSwyllys len = strcspn(argv[optind_av], "="); 454*99ebb4caSwyllys 455*99ebb4caSwyllys if (len == opts_av[i].longnm_len && strncmp(argv[optind_av], 456*99ebb4caSwyllys opts_av[i].longnm, opts_av[i].longnm_len) == 0) { 457*99ebb4caSwyllys /* matched */ 458*99ebb4caSwyllys if (!opts_av[i].has_arg) { 459*99ebb4caSwyllys optind_av++; 460*99ebb4caSwyllys return (opts_av[i].shortnm); 461*99ebb4caSwyllys } 462*99ebb4caSwyllys 463*99ebb4caSwyllys /* needs optarg */ 464*99ebb4caSwyllys if (argv[optind_av][len] == '=') { 465*99ebb4caSwyllys optarg_av = &(argv[optind_av][len+1]); 466*99ebb4caSwyllys optind_av++; 467*99ebb4caSwyllys return (opts_av[i].shortnm); 468*99ebb4caSwyllys } 469*99ebb4caSwyllys 470*99ebb4caSwyllys optarg_av = NULL; 471*99ebb4caSwyllys optind_av++; 472*99ebb4caSwyllys return ((int)'?'); 473*99ebb4caSwyllys } 474*99ebb4caSwyllys } 475*99ebb4caSwyllys 476*99ebb4caSwyllys return (EOF); 477*99ebb4caSwyllys } 478*99ebb4caSwyllys 479*99ebb4caSwyllys void 480*99ebb4caSwyllys print_sanity_error(KMF_RETURN ret) 481*99ebb4caSwyllys { 482*99ebb4caSwyllys switch (ret) { 483*99ebb4caSwyllys case KMF_ERR_POLICY_NAME: 484*99ebb4caSwyllys (void) fprintf(stderr, gettext("Error in the policy name\n")); 485*99ebb4caSwyllys break; 486*99ebb4caSwyllys case KMF_ERR_TA_POLICY: 487*99ebb4caSwyllys (void) fprintf(stderr, 488*99ebb4caSwyllys gettext("Error in trust anchor attributes\n")); 489*99ebb4caSwyllys break; 490*99ebb4caSwyllys case KMF_ERR_OCSP_POLICY: 491*99ebb4caSwyllys (void) fprintf(stderr, 492*99ebb4caSwyllys gettext("Error in OCSP policy attributes\n")); 493*99ebb4caSwyllys break; 494*99ebb4caSwyllys default: 495*99ebb4caSwyllys break; 496*99ebb4caSwyllys } 497*99ebb4caSwyllys } 498