4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
21 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22 * Use is subject to license terms.
25 #pragma ident "%Z%%M% %I% %E% SMI"
35 #include <sys/param.h>
36 #include <sys/types.h>
39 #include <bsm/devices.h>
40 #define DMPFILE "/etc/security/device_maps"
42 #define RETRY_COUNT 10
46 #if !defined(TEXT_DOMAIN)
47 #define TEXT_DOMAIN "SUNW_BSM_DMINFO"
53 char *getdmapdfield();
54 static void printdmapent();
55 static void dmapi_err();
57 static char *prog_name
;
60 * printdmapent(dmapp) prints a devmap_t structure pointed to by dmapp.
66 (void) printf("%s:", dmapp
->dmap_devname
);
67 (void) printf("%s:", dmapp
->dmap_devtype
);
68 (void) printf("%s", dmapp
->dmap_devlist
);
74 * dmapi_err(exit_code,err_msg) prints message pointed to by err_msg to
75 * stderr. Then prints usage message to stderr. Then exits program with
80 dmapi_err(int exit_code
, char *err_msg
)
82 if (err_msg
!= NULL
) {
83 (void) fprintf(stderr
, "dmapinfo:%s\n", err_msg
);
85 if (exit_code
== EINVOKE
) {
86 (void) fprintf(stderr
,
87 "Usage: %s [-v] [-a] [-f filename] %s\n",
90 (void) fprintf(stderr
,
91 " %s [-v] [-a] [-f filename] %s\n",
94 (void) fprintf(stderr
,
95 " %s [-v] [-a] [-f filename] %s\n",
98 (void) fprintf(stderr
,
99 " %s [-v] [-a] [-f filename] %s\n",
108 main(int argc
, char **argv
)
115 char *filename
= DMPFILE
;
127 /* Internationalization */
128 (void) setlocale(LC_ALL
, "");
129 (void) textdomain(TEXT_DOMAIN
);
132 * point prog_name to invocation name
134 if ((tptr
= strrchr(*argv
, '/')) != NULL
)
143 while ((argc
>= 1) && (argv
[0][0] == '-')) {
144 switch (argv
[0][1]) {
149 if ((name
) || (device
) || (update
) || (tp
)) {
151 gettext("option conflict"));
160 gettext("missing file name"));
165 if ((name
) || (device
) || (update
) || (tp
)) {
167 gettext("option conflict"));
172 if ((name
) || (device
) || (update
) || (tp
)) {
174 gettext("option conflict"));
179 if ((name
) || (device
) || (update
) || (tp
)) {
181 gettext("option conflict"));
190 gettext("bad option"));
197 * -d(device) -n(name) and -u(update) switches require at least one
201 setdmapfile(filename
);
202 if ((device
) || (name
) || (update
) || (tp
)) {
205 gettext("insufficient args for this option"));
210 * -u(update) switch requires only one argument
214 gettext("too many args for this option"));
217 * read entry argument from stdin into a devmap_t known as dmap
219 if ((dmap
.dmap_devname
= getdmapfield(*argv
)) == NULL
) {
221 gettext("Bad dmap_devname in entry argument"));
223 if ((dmap
.dmap_devtype
= getdmapfield(NULL
)) ==
226 gettext("Bad dmap_devtype in entry Argument"));
228 if ((dmap
.dmap_devlist
= getdmapfield(NULL
)) ==
231 gettext("Bad dmap_devlist in entry argument"));
234 * Find out how long device list is and create a buffer to
235 * hold it. Then copy it there. This is done since we do not
236 * want to corrupt the existing string.
238 cntr
= strlen(dmap
.dmap_devlist
) + 1;
239 mptr
= calloc((unsigned)cntr
, sizeof (char));
242 (void) fprintf(stderr
,
244 "dmapinfo: Cannot calloc memory\n"));
248 (void) strcpy(mptr
, dmap
.dmap_devlist
);
250 * open the device maps file for read/ write. We are not
251 * sure we want to write to it yet but we may and this is a
252 * easy way to get the file descriptor. We want the file
253 * descriptor so we can lock the file.
255 if ((des
= open(filename
, O_RDWR
)) < 0) {
257 (void) fprintf(stderr
,
258 gettext("dmapinfo: Cannot open %s\n"),
265 while ((status
= flock(des
, LOCK_EX
| LOCK_NB
) == -1) &&
266 (cntr
++ < RETRY_COUNT
)) {
267 (void) sleep(RETRY_SLEEP
);
270 while (((status
= lockf(des
, F_TLOCK
, 0)) == -1) &&
271 (cntr
++ < RETRY_COUNT
)) {
272 (void) sleep(RETRY_SLEEP
);
277 (void) fprintf(stderr
,
278 gettext("dmapinfo: Cannot lock %s\n"), filename
);
283 * Now that we have the device_maps file then lets check
284 * for previous entrys with the same name. If it already
285 * exists then we will exit with status of 1.
288 (void) fprintf(stderr
,
289 gettext("dmapinfo: Checking %s for name (%s).\n"),
290 filename
, dmap
.dmap_devname
);
292 if (getdmapnam(dmap
.dmap_devname
) != NULL
) {
294 (void) fprintf(stderr
,
295 gettext("dmapinfo: Device name (%s) found in %s.\n"),
296 dmap
.dmap_devname
, filename
);
301 (void) fprintf(stderr
,
302 gettext("dmapinfo: Device name (%s) not found in %s.\n"),
303 dmap
.dmap_devname
, filename
);
306 * We now Know name does not exist and now we need to check
307 * to see if any of the devices in the device list are in the
308 * device maps file. If the already exist then we will exit
309 * with a status of 1.
312 nptr
= getdmapdfield(nptr
);
315 (void) fprintf(stderr
,
317 "Check %s for device (%s).\n"),
320 if (getdmapdev(nptr
) != NULL
) {
322 (void) fprintf(stderr
,
324 "Device (%s) found in %s.\n"),
330 (void) fprintf(stderr
,
332 "Device (%s) not found in %s.\n"),
335 nptr
= getdmapdfield(NULL
);
338 * Good the entry is uniq. So lets find out how long it is
339 * and add it to the end of device maps file in a pretty
343 (void) fprintf(stderr
, "dmapinfo: Adding entry to %s\n",
347 cntr
= strlen(dmap
.dmap_devname
);
348 cntr
+= strlen(dmap
.dmap_devtype
);
349 cntr
+= strlen(dmap
.dmap_devlist
);
351 tptr
= calloc((unsigned)cntr
, sizeof (char));
355 (void) strcat(tptr
, dmap
.dmap_devname
);
356 (void) strcat(tptr
, ":\\\n\t");
357 (void) strcat(tptr
, dmap
.dmap_devtype
);
358 (void) strcat(tptr
, ":\\\n\t");
359 (void) strcat(tptr
, dmap
.dmap_devlist
);
360 (void) strcat(tptr
, ":\\\n\t");
361 (void) strcat(tptr
, "\n");
364 if (lseek(des
, 0L, L_XTND
) == -1L) {
368 if (lseek(des
, 0L, SEEK_END
) == -1L) {
372 if (write(des
, tptr
, cntr
) == -1) {
375 if (close(des
) == -1) {
379 (void) fprintf(stderr
, "dmapinfo: Entry added to %s\n",
385 * Look for devices in device_maps file. If verbose switch is set
386 * then print entry(s) found. If "any" switch is set then, if any
387 * device is found will result in a exit status of 0. If "any" switch
388 * is not set then, if any device is not will result in a exit status
394 if ((dmapp
= getdmapdev(*argv
)) != NULL
) {
399 } else if (any
== 0) {
412 * Look for names in device_maps file. If verbose switch is set
413 * then print entry(s) found. If "any" switch is set then, if any
414 * name is found will result in a exit status of 0. If "any" switch
415 * is not set then, if any name is not will result in a exit status
421 if ((dmapp
= getdmapnam(*argv
)) != NULL
) {
437 * Read all entrys from device maps file. If verbose flag is set
438 * then all the device maps files are printed. This is useful for
439 * piping to grep. Also this option used without the verbose option
440 * is useful to check for device maps file and for at least one
441 * entry. If the device maps file is found and there is one entry
442 * the return status is 0.
448 while ((dmapp
= getdmaptype(*argv
)) != 0) {
454 if ((any
== 0) && (cntr
== 0)) {
467 * Read all entrys from device maps file. If verbose flag is set
468 * then all the device maps files are printed. This is useful for
469 * piping to grep. Also this option used without the verbose option
470 * is useful to check for device maps file and for atleast one
471 * entry. If the device maps file is found and there is one entry
472 * the return status is 0.
476 while ((dmapp
= getdmapent()) != 0) {