1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #include <stdio.h> 34*7c478bd9Sstevel@tonic-gate #include <ctype.h> 35*7c478bd9Sstevel@tonic-gate #include <string.h> 36*7c478bd9Sstevel@tonic-gate #include <signal.h> 37*7c478bd9Sstevel@tonic-gate #include <valtools.h> 38*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 39*7c478bd9Sstevel@tonic-gate #include <locale.h> 40*7c478bd9Sstevel@tonic-gate #include <libintl.h> 41*7c478bd9Sstevel@tonic-gate #include <limits.h> 42*7c478bd9Sstevel@tonic-gate #include <wchar.h> 43*7c478bd9Sstevel@tonic-gate #include "usage.h" 44*7c478bd9Sstevel@tonic-gate #include "libadm.h" 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate #define BADPID (-2) 47*7c478bd9Sstevel@tonic-gate #define INVISMAXSIZE 36 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate static char *prog; 50*7c478bd9Sstevel@tonic-gate static char *deflt = NULL, *prompt = NULL, *error = NULL, *help = NULL; 51*7c478bd9Sstevel@tonic-gate static int kpid = BADPID; 52*7c478bd9Sstevel@tonic-gate static int signo; 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate static char *label, **invis; 55*7c478bd9Sstevel@tonic-gate static int ninvis = 0; 56*7c478bd9Sstevel@tonic-gate static int max = 1; 57*7c478bd9Sstevel@tonic-gate static int attr = CKALPHA; 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate #define MAXSIZE 128 60*7c478bd9Sstevel@tonic-gate #define LSIZE 1024 61*7c478bd9Sstevel@tonic-gate #define INTERR \ 62*7c478bd9Sstevel@tonic-gate "%s: ERROR: internal error occurred while attempting menu setup\n" 63*7c478bd9Sstevel@tonic-gate #define MYOPTS \ 64*7c478bd9Sstevel@tonic-gate "\t-f file #file containing choices\n" \ 65*7c478bd9Sstevel@tonic-gate "\t-l label #menu label\n" \ 66*7c478bd9Sstevel@tonic-gate "\t-i invis [, ...] #invisible menu choices\n" \ 67*7c478bd9Sstevel@tonic-gate "\t-m max #maximum choices user may select\n" \ 68*7c478bd9Sstevel@tonic-gate "\t-n #do not sort choices alphabetically\n" \ 69*7c478bd9Sstevel@tonic-gate "\t-o #don't prompt if only one choice\n" \ 70*7c478bd9Sstevel@tonic-gate "\t-u #unnumbered choices\n" 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate static const char husage[] = "Wh"; 73*7c478bd9Sstevel@tonic-gate static const char eusage[] = "We"; 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate static void 76*7c478bd9Sstevel@tonic-gate usage(void) 77*7c478bd9Sstevel@tonic-gate { 78*7c478bd9Sstevel@tonic-gate switch (*prog) { 79*7c478bd9Sstevel@tonic-gate default: 80*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 81*7c478bd9Sstevel@tonic-gate gettext("usage: %s [options] [choice [...]]\n"), prog); 82*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(OPTMESG)); 83*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(MYOPTS)); 84*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(STDOPTS)); 85*7c478bd9Sstevel@tonic-gate break; 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate case 'h': 88*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 89*7c478bd9Sstevel@tonic-gate gettext("usage: %s [options] [choice [...]]\n"), prog); 90*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(OPTMESG)); 91*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 92*7c478bd9Sstevel@tonic-gate gettext("\t-W width\n\t-h help\n")); 93*7c478bd9Sstevel@tonic-gate break; 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate case 'e': 96*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 97*7c478bd9Sstevel@tonic-gate gettext("usage: %s [options] [choice [...]]\n"), prog); 98*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(OPTMESG)); 99*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 100*7c478bd9Sstevel@tonic-gate gettext("\t-W width\n\t-e error\n")); 101*7c478bd9Sstevel@tonic-gate break; 102*7c478bd9Sstevel@tonic-gate } 103*7c478bd9Sstevel@tonic-gate exit(1); 104*7c478bd9Sstevel@tonic-gate } 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate /* 107*7c478bd9Sstevel@tonic-gate * Given argv[0], return a pointer to the basename of the program. 108*7c478bd9Sstevel@tonic-gate */ 109*7c478bd9Sstevel@tonic-gate static char * 110*7c478bd9Sstevel@tonic-gate prog_name(char *arg0) 111*7c478bd9Sstevel@tonic-gate { 112*7c478bd9Sstevel@tonic-gate char *str; 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate /* first strip trailing '/' characters (exec() allows these!) */ 115*7c478bd9Sstevel@tonic-gate str = arg0 + strlen(arg0); 116*7c478bd9Sstevel@tonic-gate while (str > arg0 && *--str == '/') 117*7c478bd9Sstevel@tonic-gate *str = '\0'; 118*7c478bd9Sstevel@tonic-gate if ((str = strrchr(arg0, '/')) != NULL) 119*7c478bd9Sstevel@tonic-gate return (str + 1); 120*7c478bd9Sstevel@tonic-gate return (arg0); 121*7c478bd9Sstevel@tonic-gate } 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate int 124*7c478bd9Sstevel@tonic-gate main(int argc, char **argv) 125*7c478bd9Sstevel@tonic-gate { 126*7c478bd9Sstevel@tonic-gate CKMENU *mp; 127*7c478bd9Sstevel@tonic-gate FILE *fp = NULL; 128*7c478bd9Sstevel@tonic-gate int c, i; 129*7c478bd9Sstevel@tonic-gate char **item; 130*7c478bd9Sstevel@tonic-gate char temp[LSIZE * MB_LEN_MAX]; 131*7c478bd9Sstevel@tonic-gate size_t mmax; 132*7c478bd9Sstevel@tonic-gate size_t invismaxsize = INVISMAXSIZE; 133*7c478bd9Sstevel@tonic-gate size_t n, r; 134*7c478bd9Sstevel@tonic-gate wchar_t wline[LSIZE], wtemp[LSIZE]; 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 139*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 140*7c478bd9Sstevel@tonic-gate #endif 141*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate prog = prog_name(argv[0]); 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate invis = (char **)calloc(invismaxsize, sizeof (char *)); 146*7c478bd9Sstevel@tonic-gate if (!invis) { 147*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 148*7c478bd9Sstevel@tonic-gate gettext("Not enough memory\n")); 149*7c478bd9Sstevel@tonic-gate exit(1); 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "m:oni:l:f:ud:p:e:h:k:s:QW:?")) != EOF) { 152*7c478bd9Sstevel@tonic-gate /* check for invalid option */ 153*7c478bd9Sstevel@tonic-gate if ((*prog == 'e') && !strchr(eusage, c)) 154*7c478bd9Sstevel@tonic-gate usage(); /* no valid options */ 155*7c478bd9Sstevel@tonic-gate if ((*prog == 'h') && !strchr(husage, c)) 156*7c478bd9Sstevel@tonic-gate usage(); 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate switch (c) { 159*7c478bd9Sstevel@tonic-gate case 'Q': 160*7c478bd9Sstevel@tonic-gate ckquit = 0; 161*7c478bd9Sstevel@tonic-gate break; 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate case 'W': 164*7c478bd9Sstevel@tonic-gate ckwidth = atol(optarg); 165*7c478bd9Sstevel@tonic-gate if (ckwidth < 0) { 166*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 167*7c478bd9Sstevel@tonic-gate gettext("%s: ERROR: negative display width specified\n"), 168*7c478bd9Sstevel@tonic-gate prog); 169*7c478bd9Sstevel@tonic-gate exit(1); 170*7c478bd9Sstevel@tonic-gate } 171*7c478bd9Sstevel@tonic-gate break; 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate case 'm': 174*7c478bd9Sstevel@tonic-gate max = atoi(optarg); 175*7c478bd9Sstevel@tonic-gate if (max > SHRT_MAX || max < SHRT_MIN) { 176*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 177*7c478bd9Sstevel@tonic-gate gettext("%s: ERROR: too large or too small max value specified\n"), 178*7c478bd9Sstevel@tonic-gate prog); 179*7c478bd9Sstevel@tonic-gate exit(1); 180*7c478bd9Sstevel@tonic-gate } 181*7c478bd9Sstevel@tonic-gate break; 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate case 'o': 184*7c478bd9Sstevel@tonic-gate attr |= CKONEFLAG; 185*7c478bd9Sstevel@tonic-gate break; 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate case 'n': 188*7c478bd9Sstevel@tonic-gate attr &= ~CKALPHA; 189*7c478bd9Sstevel@tonic-gate break; 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate case 'i': 192*7c478bd9Sstevel@tonic-gate invis[ninvis++] = optarg; 193*7c478bd9Sstevel@tonic-gate if (ninvis == invismaxsize) { 194*7c478bd9Sstevel@tonic-gate invismaxsize += INVISMAXSIZE; 195*7c478bd9Sstevel@tonic-gate invis = (char **)realloc(invis, 196*7c478bd9Sstevel@tonic-gate invismaxsize * sizeof (char *)); 197*7c478bd9Sstevel@tonic-gate if (!invis) { 198*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 199*7c478bd9Sstevel@tonic-gate gettext("Not enough memory\n")); 200*7c478bd9Sstevel@tonic-gate exit(1); 201*7c478bd9Sstevel@tonic-gate } 202*7c478bd9Sstevel@tonic-gate (void) memset(invis + ninvis, 0, 203*7c478bd9Sstevel@tonic-gate (invismaxsize - ninvis) * 204*7c478bd9Sstevel@tonic-gate sizeof (char *)); 205*7c478bd9Sstevel@tonic-gate } 206*7c478bd9Sstevel@tonic-gate break; 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate case 'l': 209*7c478bd9Sstevel@tonic-gate label = optarg; 210*7c478bd9Sstevel@tonic-gate break; 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate case 'f': 213*7c478bd9Sstevel@tonic-gate if ((fp = fopen(optarg, "r")) == NULL) { 214*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 215*7c478bd9Sstevel@tonic-gate gettext("%s: ERROR: can't open %s\n"), 216*7c478bd9Sstevel@tonic-gate prog, optarg); 217*7c478bd9Sstevel@tonic-gate exit(1); 218*7c478bd9Sstevel@tonic-gate } 219*7c478bd9Sstevel@tonic-gate break; 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate case 'u': 222*7c478bd9Sstevel@tonic-gate attr |= CKUNNUM; 223*7c478bd9Sstevel@tonic-gate break; 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate case 'd': 226*7c478bd9Sstevel@tonic-gate deflt = optarg; 227*7c478bd9Sstevel@tonic-gate break; 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gate case 'p': 230*7c478bd9Sstevel@tonic-gate prompt = optarg; 231*7c478bd9Sstevel@tonic-gate break; 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate case 'e': 234*7c478bd9Sstevel@tonic-gate error = optarg; 235*7c478bd9Sstevel@tonic-gate break; 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate case 'h': 238*7c478bd9Sstevel@tonic-gate help = optarg; 239*7c478bd9Sstevel@tonic-gate break; 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate case 'k': 242*7c478bd9Sstevel@tonic-gate kpid = atoi(optarg); 243*7c478bd9Sstevel@tonic-gate break; 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate case 's': 246*7c478bd9Sstevel@tonic-gate signo = atoi(optarg); 247*7c478bd9Sstevel@tonic-gate break; 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate default: 250*7c478bd9Sstevel@tonic-gate usage(); 251*7c478bd9Sstevel@tonic-gate } 252*7c478bd9Sstevel@tonic-gate } 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate if (signo) { 255*7c478bd9Sstevel@tonic-gate if (kpid == BADPID) 256*7c478bd9Sstevel@tonic-gate usage(); 257*7c478bd9Sstevel@tonic-gate } else 258*7c478bd9Sstevel@tonic-gate signo = SIGTERM; 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate mp = allocmenu(label, attr); 261*7c478bd9Sstevel@tonic-gate if (fp) { 262*7c478bd9Sstevel@tonic-gate *wtemp = L'\0'; 263*7c478bd9Sstevel@tonic-gate while (fgetws(wline, LSIZE, fp)) { 264*7c478bd9Sstevel@tonic-gate /* 265*7c478bd9Sstevel@tonic-gate * Skip comment lines, those beginning with '#'. 266*7c478bd9Sstevel@tonic-gate * Note: AT&T forgot this & needs the next 2 lines. 267*7c478bd9Sstevel@tonic-gate */ 268*7c478bd9Sstevel@tonic-gate if (*wline == L'#') 269*7c478bd9Sstevel@tonic-gate continue; 270*7c478bd9Sstevel@tonic-gate n = wcslen(wline); 271*7c478bd9Sstevel@tonic-gate if ((n != 0) && (wline[n - 1] == L'\n')) 272*7c478bd9Sstevel@tonic-gate wline[n - 1] = L'\0'; 273*7c478bd9Sstevel@tonic-gate /* 274*7c478bd9Sstevel@tonic-gate * if the line begins with a space character, 275*7c478bd9Sstevel@tonic-gate * this is a continuous line to the previous line. 276*7c478bd9Sstevel@tonic-gate */ 277*7c478bd9Sstevel@tonic-gate if (iswspace(*wline)) { 278*7c478bd9Sstevel@tonic-gate (void) wcscat(wtemp, L"\n"); 279*7c478bd9Sstevel@tonic-gate (void) wcscat(wtemp, wline); 280*7c478bd9Sstevel@tonic-gate } else { 281*7c478bd9Sstevel@tonic-gate if (*wtemp) { 282*7c478bd9Sstevel@tonic-gate n = wcslen(wtemp); 283*7c478bd9Sstevel@tonic-gate r = wcstombs(temp, wtemp, 284*7c478bd9Sstevel@tonic-gate n * MB_LEN_MAX); 285*7c478bd9Sstevel@tonic-gate if (r == (size_t)-1) { 286*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 287*7c478bd9Sstevel@tonic-gate gettext("Invalid character in the menu definition.\n")); 288*7c478bd9Sstevel@tonic-gate exit(1); 289*7c478bd9Sstevel@tonic-gate } 290*7c478bd9Sstevel@tonic-gate if (setitem(mp, temp)) { 291*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 292*7c478bd9Sstevel@tonic-gate gettext(INTERR), prog); 293*7c478bd9Sstevel@tonic-gate exit(1); 294*7c478bd9Sstevel@tonic-gate } 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate (void) wcscpy(wtemp, wline); 297*7c478bd9Sstevel@tonic-gate } 298*7c478bd9Sstevel@tonic-gate } 299*7c478bd9Sstevel@tonic-gate if (*wtemp) { 300*7c478bd9Sstevel@tonic-gate n = wcslen(wtemp); 301*7c478bd9Sstevel@tonic-gate r = wcstombs(temp, wtemp, n * MB_LEN_MAX); 302*7c478bd9Sstevel@tonic-gate if (r == (size_t)-1) { 303*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 304*7c478bd9Sstevel@tonic-gate gettext("Invalid character in the menu definition.\n")); 305*7c478bd9Sstevel@tonic-gate exit(1); 306*7c478bd9Sstevel@tonic-gate } 307*7c478bd9Sstevel@tonic-gate if (setitem(mp, temp)) { 308*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(INTERR), prog); 309*7c478bd9Sstevel@tonic-gate exit(1); 310*7c478bd9Sstevel@tonic-gate } 311*7c478bd9Sstevel@tonic-gate } 312*7c478bd9Sstevel@tonic-gate } 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate while (optind < argc) { 315*7c478bd9Sstevel@tonic-gate if (setitem(mp, argv[optind++])) { 316*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(INTERR), prog); 317*7c478bd9Sstevel@tonic-gate exit(1); 318*7c478bd9Sstevel@tonic-gate } 319*7c478bd9Sstevel@tonic-gate } 320*7c478bd9Sstevel@tonic-gate 321*7c478bd9Sstevel@tonic-gate for (n = 0; n < ninvis; ) { 322*7c478bd9Sstevel@tonic-gate if (setinvis(mp, invis[n++])) { 323*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(INTERR), prog); 324*7c478bd9Sstevel@tonic-gate exit(1); 325*7c478bd9Sstevel@tonic-gate } 326*7c478bd9Sstevel@tonic-gate } 327*7c478bd9Sstevel@tonic-gate 328*7c478bd9Sstevel@tonic-gate if (*prog == 'e') { 329*7c478bd9Sstevel@tonic-gate ckindent = 0; 330*7c478bd9Sstevel@tonic-gate ckitem_err(mp, error); 331*7c478bd9Sstevel@tonic-gate exit(0); 332*7c478bd9Sstevel@tonic-gate } else if (*prog == 'h') { 333*7c478bd9Sstevel@tonic-gate ckindent = 0; 334*7c478bd9Sstevel@tonic-gate ckitem_hlp(mp, help); 335*7c478bd9Sstevel@tonic-gate exit(0); 336*7c478bd9Sstevel@tonic-gate } 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate if (max < 1) { 339*7c478bd9Sstevel@tonic-gate mmax = mp->nchoices; 340*7c478bd9Sstevel@tonic-gate } else { 341*7c478bd9Sstevel@tonic-gate mmax = max; 342*7c478bd9Sstevel@tonic-gate } 343*7c478bd9Sstevel@tonic-gate 344*7c478bd9Sstevel@tonic-gate /* 345*7c478bd9Sstevel@tonic-gate * if -o option is specified, mp->nchoices is 1, and if no invisible 346*7c478bd9Sstevel@tonic-gate * item is specified, ckitem() will consume two entries of item, 347*7c478bd9Sstevel@tonic-gate * even though 'max' is set to 1. So to take care of that problem, we 348*7c478bd9Sstevel@tonic-gate * allocate one extra element for item 349*7c478bd9Sstevel@tonic-gate */ 350*7c478bd9Sstevel@tonic-gate item = (char **)calloc(mmax+1, sizeof (char *)); 351*7c478bd9Sstevel@tonic-gate if (!item) { 352*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 353*7c478bd9Sstevel@tonic-gate gettext("Not enough memory\n")); 354*7c478bd9Sstevel@tonic-gate exit(1); 355*7c478bd9Sstevel@tonic-gate } 356*7c478bd9Sstevel@tonic-gate n = ckitem(mp, item, max, deflt, error, help, prompt); 357*7c478bd9Sstevel@tonic-gate if (n == 3) { 358*7c478bd9Sstevel@tonic-gate if (kpid > -2) 359*7c478bd9Sstevel@tonic-gate (void) kill(kpid, signo); 360*7c478bd9Sstevel@tonic-gate (void) puts("q"); 361*7c478bd9Sstevel@tonic-gate } else if (n == 0) { 362*7c478bd9Sstevel@tonic-gate i = 0; 363*7c478bd9Sstevel@tonic-gate while (item[i]) 364*7c478bd9Sstevel@tonic-gate (void) puts(item[i++]); 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate return (n); 367*7c478bd9Sstevel@tonic-gate } 368