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