1*f875b4ebSrica /*
2*f875b4ebSrica * CDDL HEADER START
3*f875b4ebSrica *
4*f875b4ebSrica * The contents of this file are subject to the terms of the
5*f875b4ebSrica * Common Development and Distribution License (the "License").
6*f875b4ebSrica * You may not use this file except in compliance with the License.
7*f875b4ebSrica *
8*f875b4ebSrica * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*f875b4ebSrica * or http://www.opensolaris.org/os/licensing.
10*f875b4ebSrica * See the License for the specific language governing permissions
11*f875b4ebSrica * and limitations under the License.
12*f875b4ebSrica *
13*f875b4ebSrica * When distributing Covered Code, include this CDDL HEADER in each
14*f875b4ebSrica * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*f875b4ebSrica * If applicable, add the following below this CDDL HEADER, with the
16*f875b4ebSrica * fields enclosed by brackets "[]" replaced with your own identifying
17*f875b4ebSrica * information: Portions Copyright [yyyy] [name of copyright owner]
18*f875b4ebSrica *
19*f875b4ebSrica * CDDL HEADER END
20*f875b4ebSrica */
21*f875b4ebSrica
22*f875b4ebSrica /*
23*f875b4ebSrica * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24*f875b4ebSrica * Use is subject to license terms.
25*f875b4ebSrica */
26*f875b4ebSrica
27*f875b4ebSrica #pragma ident "%Z%%M% %I% %E% SMI"
28*f875b4ebSrica
29*f875b4ebSrica /*
30*f875b4ebSrica * add_allocatable -
31*f875b4ebSrica * a command-line interface to add device to device_allocate and
32*f875b4ebSrica * device_maps.
33*f875b4ebSrica */
34*f875b4ebSrica
35*f875b4ebSrica #ifndef __EXTENSIONS__
36*f875b4ebSrica #define __EXTENSIONS__ /* needed for _strtok_r */
37*f875b4ebSrica #endif
38*f875b4ebSrica
39*f875b4ebSrica #include <sys/types.h>
40*f875b4ebSrica #include <unistd.h>
41*f875b4ebSrica #include <stdlib.h>
42*f875b4ebSrica #include <strings.h>
43*f875b4ebSrica #include <string.h>
44*f875b4ebSrica #include <locale.h>
45*f875b4ebSrica #include <libintl.h>
46*f875b4ebSrica #include <pwd.h>
47*f875b4ebSrica #include <nss_dbdefs.h>
48*f875b4ebSrica #include <auth_attr.h>
49*f875b4ebSrica #include <auth_list.h>
50*f875b4ebSrica #include <zone.h>
51*f875b4ebSrica #include <tsol/label.h>
52*f875b4ebSrica #include <bsm/devices.h>
53*f875b4ebSrica #include <bsm/devalloc.h>
54*f875b4ebSrica
55*f875b4ebSrica #define NO_OVERRIDE -1
56*f875b4ebSrica
57*f875b4ebSrica int check_args(da_args *);
58*f875b4ebSrica int process_args(int, char **, da_args *, char *);
59*f875b4ebSrica int scan_label(char *, char *);
60*f875b4ebSrica void usage(da_args *, char *);
61*f875b4ebSrica
62*f875b4ebSrica int system_labeled = 0;
63*f875b4ebSrica
64*f875b4ebSrica int
main(int argc,char * argv[])65*f875b4ebSrica main(int argc, char *argv[])
66*f875b4ebSrica {
67*f875b4ebSrica int rc;
68*f875b4ebSrica uid_t uid;
69*f875b4ebSrica char *progname;
70*f875b4ebSrica char pwbuf[NSS_LINELEN_PASSWD];
71*f875b4ebSrica struct passwd pwd;
72*f875b4ebSrica da_args dargs;
73*f875b4ebSrica devinfo_t devinfo;
74*f875b4ebSrica
75*f875b4ebSrica (void) setlocale(LC_ALL, "");
76*f875b4ebSrica #if !defined(TEXT_DOMAIN)
77*f875b4ebSrica #define TEXT_DOMAIN "SYS_TEST"
78*f875b4ebSrica #endif
79*f875b4ebSrica (void) textdomain(TEXT_DOMAIN);
80*f875b4ebSrica if ((progname = strrchr(argv[0], '/')) == NULL)
81*f875b4ebSrica progname = argv[0];
82*f875b4ebSrica else
83*f875b4ebSrica progname++;
84*f875b4ebSrica
85*f875b4ebSrica system_labeled = is_system_labeled();
86*f875b4ebSrica if (system_labeled) {
87*f875b4ebSrica /*
88*f875b4ebSrica * this command can be run only in the global zone.
89*f875b4ebSrica */
90*f875b4ebSrica if (getzoneid() != GLOBAL_ZONEID) {
91*f875b4ebSrica (void) fprintf(stderr, "%s%s", progname,
92*f875b4ebSrica gettext(" : must be run in global zone\n"));
93*f875b4ebSrica exit(1);
94*f875b4ebSrica }
95*f875b4ebSrica } else {
96*f875b4ebSrica /*
97*f875b4ebSrica * this command works in Trusted Extensions only.
98*f875b4ebSrica */
99*f875b4ebSrica (void) fprintf(stderr, "%s%s", progname,
100*f875b4ebSrica gettext(" : need to install Trusted Extensions\n"));
101*f875b4ebSrica exit(1);
102*f875b4ebSrica }
103*f875b4ebSrica
104*f875b4ebSrica dargs.optflag = 0;
105*f875b4ebSrica dargs.rootdir = NULL;
106*f875b4ebSrica dargs.devnames = NULL;
107*f875b4ebSrica dargs.devinfo = &devinfo;
108*f875b4ebSrica
109*f875b4ebSrica if (strcmp(progname, "add_allocatable") == 0) {
110*f875b4ebSrica dargs.optflag |= DA_ADD;
111*f875b4ebSrica } else if (strcmp(progname, "remove_allocatable") == 0) {
112*f875b4ebSrica dargs.optflag |= DA_REMOVE;
113*f875b4ebSrica } else {
114*f875b4ebSrica usage(&dargs, progname);
115*f875b4ebSrica exit(1);
116*f875b4ebSrica }
117*f875b4ebSrica
118*f875b4ebSrica uid = getuid();
119*f875b4ebSrica if ((getpwuid_r(uid, &pwd, pwbuf, sizeof (pwbuf))) == NULL) {
120*f875b4ebSrica (void) fprintf(stderr, "%s%s", progname,
121*f875b4ebSrica gettext(" : getpwuid_r failed: "));
122*f875b4ebSrica (void) fprintf(stderr, "%s\n", strerror(errno));
123*f875b4ebSrica exit(2);
124*f875b4ebSrica }
125*f875b4ebSrica
126*f875b4ebSrica if (chkauthattr(DEVICE_CONFIG_AUTH, pwd.pw_name) != 1) {
127*f875b4ebSrica (void) fprintf(stderr, "%s%s%s", progname,
128*f875b4ebSrica gettext(" : user lacks authorization: \n"),
129*f875b4ebSrica DEVICE_CONFIG_AUTH);
130*f875b4ebSrica exit(4);
131*f875b4ebSrica }
132*f875b4ebSrica
133*f875b4ebSrica if (process_args(argc, argv, &dargs, progname) != 0) {
134*f875b4ebSrica usage(&dargs, progname);
135*f875b4ebSrica exit(1);
136*f875b4ebSrica }
137*f875b4ebSrica
138*f875b4ebSrica if (dargs.optflag & DA_ADD) {
139*f875b4ebSrica if (check_args(&dargs) == NO_OVERRIDE) {
140*f875b4ebSrica (void) fprintf(stderr, "%s%s%s%s", progname,
141*f875b4ebSrica gettext(" : entry exists for "),
142*f875b4ebSrica dargs.devinfo->devname, gettext("\n"));
143*f875b4ebSrica usage(&dargs, progname);
144*f875b4ebSrica exit(3);
145*f875b4ebSrica }
146*f875b4ebSrica }
147*f875b4ebSrica
148*f875b4ebSrica if (dargs.optflag & DA_DEFATTRS)
149*f875b4ebSrica rc = da_update_defattrs(&dargs);
150*f875b4ebSrica else
151*f875b4ebSrica rc = da_update_device(&dargs);
152*f875b4ebSrica
153*f875b4ebSrica if ((rc != 0) && (!(dargs.optflag & DA_SILENT))) {
154*f875b4ebSrica if (rc == -2)
155*f875b4ebSrica (void) fprintf(stderr, "%s%s", progname,
156*f875b4ebSrica gettext(" : device name/type/list missing\n"));
157*f875b4ebSrica else if (dargs.optflag & DA_ADD)
158*f875b4ebSrica (void) fprintf(stderr, "%s%s", progname,
159*f875b4ebSrica gettext(" : error adding/updating device\n"));
160*f875b4ebSrica else if (dargs.optflag & DA_REMOVE)
161*f875b4ebSrica (void) fprintf(stderr, "%s%s", progname,
162*f875b4ebSrica gettext(" : error removing device\n"));
163*f875b4ebSrica rc = 2; /* exit code for 'Unknown system error' in man page */
164*f875b4ebSrica }
165*f875b4ebSrica
166*f875b4ebSrica return (rc);
167*f875b4ebSrica }
168*f875b4ebSrica
169*f875b4ebSrica int
process_args(int argc,char ** argv,da_args * dargs,char * progname)170*f875b4ebSrica process_args(int argc, char **argv, da_args *dargs, char *progname)
171*f875b4ebSrica {
172*f875b4ebSrica int c;
173*f875b4ebSrica int aflag, cflag, dflag, fflag, lflag, nflag, oflag, tflag;
174*f875b4ebSrica extern char *optarg;
175*f875b4ebSrica devinfo_t *devinfo;
176*f875b4ebSrica
177*f875b4ebSrica devinfo = dargs->devinfo;
178*f875b4ebSrica aflag = cflag = dflag = fflag = lflag = nflag = oflag = tflag = 0;
179*f875b4ebSrica devinfo->devname = devinfo->devtype = devinfo->devauths =
180*f875b4ebSrica devinfo->devexec = devinfo->devopts = devinfo->devlist = NULL;
181*f875b4ebSrica devinfo->instance = 0;
182*f875b4ebSrica
183*f875b4ebSrica while ((c = getopt(argc, argv, "a:c:dfl:n:o:st:")) != EOF) {
184*f875b4ebSrica switch (c) {
185*f875b4ebSrica case 'a':
186*f875b4ebSrica devinfo->devauths = optarg;
187*f875b4ebSrica aflag++;
188*f875b4ebSrica break;
189*f875b4ebSrica case 'c':
190*f875b4ebSrica devinfo->devexec = optarg;
191*f875b4ebSrica if (strlen(devinfo->devexec) == 0) {
192*f875b4ebSrica if (!(dargs->optflag & DA_SILENT))
193*f875b4ebSrica (void) fprintf(stderr, "%s%s", progname,
194*f875b4ebSrica gettext(" : device clean program"
195*f875b4ebSrica " name not found\n"));
196*f875b4ebSrica return (1);
197*f875b4ebSrica }
198*f875b4ebSrica cflag++;
199*f875b4ebSrica break;
200*f875b4ebSrica case 'd':
201*f875b4ebSrica dargs->optflag |= DA_DEFATTRS;
202*f875b4ebSrica dflag++;
203*f875b4ebSrica break;
204*f875b4ebSrica case 'l':
205*f875b4ebSrica devinfo->devlist = optarg;
206*f875b4ebSrica if (strlen(devinfo->devlist) == 0) {
207*f875b4ebSrica if (!(dargs->optflag & DA_SILENT))
208*f875b4ebSrica (void) fprintf(stderr, "%s%s", progname,
209*f875b4ebSrica gettext(" : device file list"
210*f875b4ebSrica " not found\n"));
211*f875b4ebSrica return (1);
212*f875b4ebSrica }
213*f875b4ebSrica lflag++;
214*f875b4ebSrica break;
215*f875b4ebSrica case 'f':
216*f875b4ebSrica dargs->optflag |= DA_FORCE;
217*f875b4ebSrica fflag++;
218*f875b4ebSrica break;
219*f875b4ebSrica case 'n':
220*f875b4ebSrica devinfo->devname = optarg;
221*f875b4ebSrica if (strlen(devinfo->devname) == 0) {
222*f875b4ebSrica if (!(dargs->optflag & DA_SILENT))
223*f875b4ebSrica (void) fprintf(stderr, "%s%s", progname,
224*f875b4ebSrica gettext(" : device name "
225*f875b4ebSrica "not found\n"));
226*f875b4ebSrica return (1);
227*f875b4ebSrica }
228*f875b4ebSrica nflag++;
229*f875b4ebSrica break;
230*f875b4ebSrica case 'o':
231*f875b4ebSrica /* check for field delimiters in the option */
232*f875b4ebSrica if (strpbrk(optarg, ":;=") == NULL) {
233*f875b4ebSrica if (!(dargs->optflag & DA_SILENT)) {
234*f875b4ebSrica (void) fprintf(stderr, "%s%s%s",
235*f875b4ebSrica progname,
236*f875b4ebSrica gettext(" : invalid "
237*f875b4ebSrica "key=val string: "),
238*f875b4ebSrica optarg);
239*f875b4ebSrica (void) fprintf(stderr, "%s",
240*f875b4ebSrica gettext("\n"));
241*f875b4ebSrica }
242*f875b4ebSrica return (1);
243*f875b4ebSrica }
244*f875b4ebSrica devinfo->devopts = optarg;
245*f875b4ebSrica if (dargs->optflag & DA_ADD) {
246*f875b4ebSrica if (scan_label(devinfo->devopts, progname) != 0)
247*f875b4ebSrica return (1);
248*f875b4ebSrica }
249*f875b4ebSrica oflag++;
250*f875b4ebSrica break;
251*f875b4ebSrica case 's':
252*f875b4ebSrica dargs->optflag |= DA_SILENT;
253*f875b4ebSrica break;
254*f875b4ebSrica case 't':
255*f875b4ebSrica devinfo->devtype = optarg;
256*f875b4ebSrica if (strlen(devinfo->devtype) == 0) {
257*f875b4ebSrica if (!(dargs->optflag & DA_SILENT))
258*f875b4ebSrica (void) fprintf(stderr, "%s%s", progname,
259*f875b4ebSrica gettext(" : device type "
260*f875b4ebSrica "not found\n"));
261*f875b4ebSrica return (1);
262*f875b4ebSrica }
263*f875b4ebSrica tflag++;
264*f875b4ebSrica break;
265*f875b4ebSrica default :
266*f875b4ebSrica return (1);
267*f875b4ebSrica }
268*f875b4ebSrica }
269*f875b4ebSrica
270*f875b4ebSrica
271*f875b4ebSrica if (dargs->optflag & DA_ADD) {
272*f875b4ebSrica if (dflag) {
273*f875b4ebSrica /* -d requires -t, but does not like -n */
274*f875b4ebSrica if (nflag || tflag == 0)
275*f875b4ebSrica return (1);
276*f875b4ebSrica } else if (nflag == 0 && tflag == 0 && lflag == 0) {
277*f875b4ebSrica /* require at least -n or -t or -l to be specified */
278*f875b4ebSrica if (!(dargs->optflag & DA_SILENT))
279*f875b4ebSrica (void) fprintf(stderr, "%s%s", progname,
280*f875b4ebSrica gettext(" : required options missing\n"));
281*f875b4ebSrica return (1);
282*f875b4ebSrica }
283*f875b4ebSrica } else if (dargs->optflag & DA_REMOVE) {
284*f875b4ebSrica if (dflag) {
285*f875b4ebSrica /* -d requires -t, but does not like -n */
286*f875b4ebSrica if (nflag || tflag == 0)
287*f875b4ebSrica return (1);
288*f875b4ebSrica } else if (nflag == 0 && tflag == 0) {
289*f875b4ebSrica /* require at least -n or -t to be specified */
290*f875b4ebSrica if (!(dargs->optflag & DA_SILENT))
291*f875b4ebSrica (void) fprintf(stderr, "%s%s", progname,
292*f875b4ebSrica gettext(" : required options missing\n"));
293*f875b4ebSrica return (1);
294*f875b4ebSrica }
295*f875b4ebSrica /* there's a bunch not accepted by remove_allocatable */
296*f875b4ebSrica if (aflag || cflag || lflag || oflag)
297*f875b4ebSrica return (1);
298*f875b4ebSrica } else {
299*f875b4ebSrica return (1);
300*f875b4ebSrica }
301*f875b4ebSrica
302*f875b4ebSrica /* check for option specified more than once */
303*f875b4ebSrica if (aflag > 1 || cflag > 1 || lflag > 1 || fflag > 1 ||
304*f875b4ebSrica nflag > 1 || tflag > 1) {
305*f875b4ebSrica if (!(dargs->optflag & DA_SILENT))
306*f875b4ebSrica (void) fprintf(stderr, "%s%s", progname,
307*f875b4ebSrica gettext(" : multiple-defined options\n"));
308*f875b4ebSrica return (1);
309*f875b4ebSrica }
310*f875b4ebSrica
311*f875b4ebSrica return (0);
312*f875b4ebSrica }
313*f875b4ebSrica
314*f875b4ebSrica int
verify_label(char * token,char * progname)315*f875b4ebSrica verify_label(char *token, char *progname)
316*f875b4ebSrica {
317*f875b4ebSrica int error = 0;
318*f875b4ebSrica char *p, *val, *str;
319*f875b4ebSrica
320*f875b4ebSrica if ((strstr(token, DAOPT_MINLABEL) == NULL) &&
321*f875b4ebSrica (strstr(token, DAOPT_MAXLABEL) == NULL)) {
322*f875b4ebSrica /* no label specified */
323*f875b4ebSrica return (0);
324*f875b4ebSrica }
325*f875b4ebSrica if ((val = strchr(token, '=')) == NULL)
326*f875b4ebSrica return (1);
327*f875b4ebSrica val++;
328*f875b4ebSrica /*
329*f875b4ebSrica * if non-default labels are specified, check if they are correct
330*f875b4ebSrica */
331*f875b4ebSrica if ((strcmp(val, DA_DEFAULT_MIN) != 0) &&
332*f875b4ebSrica (strcmp(val, DA_DEFAULT_MAX) != 0)) {
333*f875b4ebSrica m_label_t *slabel = NULL;
334*f875b4ebSrica
335*f875b4ebSrica str = strdup(val);
336*f875b4ebSrica /* get rid of double quotes if they exist */
337*f875b4ebSrica while (*str == '"')
338*f875b4ebSrica str++;
339*f875b4ebSrica if ((p = strchr(str, '"')) != NULL)
340*f875b4ebSrica *p = '\0';
341*f875b4ebSrica if (str_to_label(str, &slabel, MAC_LABEL, L_NO_CORRECTION,
342*f875b4ebSrica &error) == -1) {
343*f875b4ebSrica (void) fprintf(stderr, "%s%s%s", progname,
344*f875b4ebSrica gettext(" : bad label input: "),
345*f875b4ebSrica val);
346*f875b4ebSrica (void) fprintf(stderr, "%s", gettext("\n"));
347*f875b4ebSrica free(str);
348*f875b4ebSrica m_label_free(slabel);
349*f875b4ebSrica return (1);
350*f875b4ebSrica }
351*f875b4ebSrica free(str);
352*f875b4ebSrica m_label_free(slabel);
353*f875b4ebSrica }
354*f875b4ebSrica
355*f875b4ebSrica return (0);
356*f875b4ebSrica }
357*f875b4ebSrica
358*f875b4ebSrica int
scan_label(char * devopts,char * progname)359*f875b4ebSrica scan_label(char *devopts, char *progname)
360*f875b4ebSrica {
361*f875b4ebSrica char *tok = NULL;
362*f875b4ebSrica char *lasts, *optsarg;
363*f875b4ebSrica
364*f875b4ebSrica if (devopts == NULL)
365*f875b4ebSrica return (0);
366*f875b4ebSrica
367*f875b4ebSrica if ((optsarg = strdup(devopts)) == NULL)
368*f875b4ebSrica return (1);
369*f875b4ebSrica
370*f875b4ebSrica if ((tok = strtok_r(optsarg, KV_TOKEN_DELIMIT, &lasts)) == NULL)
371*f875b4ebSrica return (1);
372*f875b4ebSrica
373*f875b4ebSrica if (verify_label(tok, progname) != 0) {
374*f875b4ebSrica free(optsarg);
375*f875b4ebSrica return (1);
376*f875b4ebSrica }
377*f875b4ebSrica
378*f875b4ebSrica while ((tok = strtok_r(NULL, KV_TOKEN_DELIMIT, &lasts)) != NULL) {
379*f875b4ebSrica if (verify_label(tok, progname) != 0) {
380*f875b4ebSrica free(optsarg);
381*f875b4ebSrica return (1);
382*f875b4ebSrica }
383*f875b4ebSrica }
384*f875b4ebSrica
385*f875b4ebSrica return (0);
386*f875b4ebSrica }
387*f875b4ebSrica
388*f875b4ebSrica int
check_args(da_args * dargs)389*f875b4ebSrica check_args(da_args *dargs)
390*f875b4ebSrica {
391*f875b4ebSrica int nlen;
392*f875b4ebSrica char *kval, *nopts, *ntok, *nstr,
393*f875b4ebSrica *defmin, *defmax, *defauths, *defexec;
394*f875b4ebSrica kva_t *kva;
395*f875b4ebSrica devinfo_t *devinfo;
396*f875b4ebSrica devalloc_t *da = NULL;
397*f875b4ebSrica da_defs_t *da_defs = NULL;
398*f875b4ebSrica
399*f875b4ebSrica devinfo = dargs->devinfo;
400*f875b4ebSrica /*
401*f875b4ebSrica * check if we're updating an existing entry without -f
402*f875b4ebSrica */
403*f875b4ebSrica setdaent();
404*f875b4ebSrica da = getdanam(devinfo->devname);
405*f875b4ebSrica enddaent();
406*f875b4ebSrica if (da && !(dargs->optflag & DA_FORCE)) {
407*f875b4ebSrica freedaent(da);
408*f875b4ebSrica return (NO_OVERRIDE);
409*f875b4ebSrica }
410*f875b4ebSrica if ((devinfo->devopts == NULL) ||
411*f875b4ebSrica (strstr(devinfo->devopts, DAOPT_MINLABEL) == NULL) ||
412*f875b4ebSrica (strstr(devinfo->devopts, DAOPT_MAXLABEL) == NULL) ||
413*f875b4ebSrica (devinfo->devauths == NULL) ||
414*f875b4ebSrica (devinfo->devexec == NULL)) {
415*f875b4ebSrica /* fill in defaults as required */
416*f875b4ebSrica defmin = DA_DEFAULT_MIN;
417*f875b4ebSrica defmax = DA_DEFAULT_MAX;
418*f875b4ebSrica defauths = DEFAULT_DEV_ALLOC_AUTH;
419*f875b4ebSrica defexec = DA_DEFAULT_CLEAN;
420*f875b4ebSrica setdadefent();
421*f875b4ebSrica if (da_defs = getdadeftype(devinfo->devtype)) {
422*f875b4ebSrica kva = da_defs->devopts;
423*f875b4ebSrica if ((kval = kva_match(kva, DAOPT_MINLABEL)) != NULL)
424*f875b4ebSrica defmin = strdup(kval);
425*f875b4ebSrica if ((kval = kva_match(kva, DAOPT_MAXLABEL)) != NULL)
426*f875b4ebSrica defmax = strdup(kval);
427*f875b4ebSrica if ((kval = kva_match(kva, DAOPT_AUTHS)) != NULL)
428*f875b4ebSrica defauths = strdup(kval);
429*f875b4ebSrica if ((kval = kva_match(kva, DAOPT_CSCRIPT)) != NULL)
430*f875b4ebSrica defexec = strdup(kval);
431*f875b4ebSrica freedadefent(da_defs);
432*f875b4ebSrica }
433*f875b4ebSrica enddadefent();
434*f875b4ebSrica if (devinfo->devauths == NULL)
435*f875b4ebSrica devinfo->devauths = defauths;
436*f875b4ebSrica if (devinfo->devexec == NULL)
437*f875b4ebSrica devinfo->devexec = defexec;
438*f875b4ebSrica if (devinfo->devopts == NULL) {
439*f875b4ebSrica /* add default minlabel and maxlabel */
440*f875b4ebSrica nlen = strlen(DAOPT_MINLABEL) + strlen(KV_ASSIGN) +
441*f875b4ebSrica strlen(defmin) + strlen(KV_TOKEN_DELIMIT) +
442*f875b4ebSrica strlen(DAOPT_MAXLABEL) + strlen(KV_ASSIGN) +
443*f875b4ebSrica strlen(defmax) + 1; /* +1 for terminator */
444*f875b4ebSrica if (nopts = (char *)malloc(nlen)) {
445*f875b4ebSrica (void) snprintf(nopts, nlen, "%s%s%s%s%s%s%s",
446*f875b4ebSrica DAOPT_MINLABEL, KV_ASSIGN, defmin,
447*f875b4ebSrica KV_TOKEN_DELIMIT,
448*f875b4ebSrica DAOPT_MAXLABEL, KV_ASSIGN, defmax);
449*f875b4ebSrica devinfo->devopts = nopts;
450*f875b4ebSrica }
451*f875b4ebSrica } else {
452*f875b4ebSrica if (strstr(devinfo->devopts, DAOPT_MINLABEL) == NULL) {
453*f875b4ebSrica /* add default minlabel */
454*f875b4ebSrica ntok = DAOPT_MINLABEL;
455*f875b4ebSrica nstr = defmin;
456*f875b4ebSrica nlen = strlen(devinfo->devopts) +
457*f875b4ebSrica strlen(KV_TOKEN_DELIMIT) +
458*f875b4ebSrica strlen(ntok) + strlen(KV_ASSIGN) +
459*f875b4ebSrica strlen(nstr) + 1;
460*f875b4ebSrica if (nopts = (char *)malloc(nlen)) {
461*f875b4ebSrica (void) snprintf(nopts, nlen,
462*f875b4ebSrica "%s%s%s%s%s",
463*f875b4ebSrica devinfo->devopts, KV_TOKEN_DELIMIT,
464*f875b4ebSrica ntok, KV_ASSIGN, nstr);
465*f875b4ebSrica devinfo->devopts = nopts;
466*f875b4ebSrica }
467*f875b4ebSrica }
468*f875b4ebSrica if (strstr(devinfo->devopts, DAOPT_MAXLABEL) == NULL) {
469*f875b4ebSrica /* add default maxlabel */
470*f875b4ebSrica ntok = DAOPT_MAXLABEL;
471*f875b4ebSrica nstr = defmax;
472*f875b4ebSrica nlen = strlen(devinfo->devopts) +
473*f875b4ebSrica strlen(KV_TOKEN_DELIMIT) +
474*f875b4ebSrica strlen(ntok) + strlen(KV_ASSIGN) +
475*f875b4ebSrica strlen(nstr) + 1;
476*f875b4ebSrica if (nopts = (char *)malloc(nlen)) {
477*f875b4ebSrica (void) snprintf(nopts, nlen,
478*f875b4ebSrica "%s%s%s%s%s",
479*f875b4ebSrica devinfo->devopts, KV_TOKEN_DELIMIT,
480*f875b4ebSrica ntok, KV_ASSIGN, nstr);
481*f875b4ebSrica devinfo->devopts = nopts;
482*f875b4ebSrica }
483*f875b4ebSrica }
484*f875b4ebSrica }
485*f875b4ebSrica }
486*f875b4ebSrica
487*f875b4ebSrica return (0);
488*f875b4ebSrica }
489*f875b4ebSrica
490*f875b4ebSrica void
usage(da_args * dargs,char * progname)491*f875b4ebSrica usage(da_args *dargs, char *progname)
492*f875b4ebSrica {
493*f875b4ebSrica if (dargs->optflag & DA_SILENT)
494*f875b4ebSrica return;
495*f875b4ebSrica if (dargs->optflag & DA_ADD)
496*f875b4ebSrica (void) fprintf(stderr, "%s%s%s", gettext("Usage: "), progname,
497*f875b4ebSrica gettext(" [-f][-s][-d] -n name -t type -l device-list"
498*f875b4ebSrica "\n\t[-a authorization] [-c cleaning program] "
499*f875b4ebSrica "[-o key=value]\n"));
500*f875b4ebSrica else if (dargs->optflag & DA_REMOVE)
501*f875b4ebSrica (void) fprintf(stderr, "%s%s%s", gettext("Usage: "), progname,
502*f875b4ebSrica gettext(" [-f][-s][-d] [-n name|-t type]\n"));
503*f875b4ebSrica else
504*f875b4ebSrica (void) fprintf(stderr, gettext("Invalid usage\n"), progname);
505*f875b4ebSrica }
506