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]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * scan /dev directory for mountable objects and construct device_allocate
29 * file for allocate....
55 #include <sys/types.h> /* for stat(2), etc. */
57 #include <dirent.h> /* for readdir(3), etc. */
58 #include <unistd.h> /* for readlink(2) */
60 #include <string.h> /* for strcpy(3), etc. */
61 #include <strings.h> /* for bcopy(3C), etc. */
62 #include <stdio.h> /* for perror(3) */
63 #include <stdlib.h> /* for atoi(3) */
67 #include <libdevinfo.h>
70 #include <auth_attr.h>
71 #include <auth_list.h>
72 #include <bsm/devices.h>
73 #include <bsm/devalloc.h>
76 #define TEXT_DOMAIN "SUNW_OST_OSCMD"
79 #define MKDEVALLOC "mkdevalloc"
80 #define MKDEVMAPS "mkdevmaps"
82 #define DELTA 5 /* array size delta when full */
83 #define SECLIB "/etc/security/lib"
85 /* "/dev/rst...", "/dev/nrst...", "/dev/rmt/..." */
91 #define DFLT_NTAPE 10 /* size of initial array */
92 #define SIZE_OF_RST 3 /* |rmt| */
93 #define SIZE_OF_NRST 4 /* |nrmt| */
94 #define SIZE_OF_TMP 4 /* |/tmp| */
95 #define SIZE_OF_RMT 8 /* |/dev/rmt| */
96 #define TAPE_CLEAN SECLIB"/st_clean"
98 /* "/dev/audio", "/dev/audioctl", "/dev/sound/..." */
104 #define DFLT_NAUDIO 10 /* size of initial array */
105 #define SIZE_OF_SOUND 10 /* |/dev/sound| */
106 #define AUDIO_CLEAN SECLIB"/audio_clean"
108 /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */
116 #define DFLT_NCD 10 /* size of initial array */
117 #define SIZE_OF_SR 2 /* |sr| */
118 #define SIZE_OF_RSR 3 /* |rsr| */
119 #define SIZE_OF_DSK 8 /* |/dev/dsk| */
120 #define SIZE_OF_RDSK 9 /* |/dev/rdsk| */
121 #define CD_CLEAN SECLIB"/sr_clean"
123 /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */
130 } *rmdisk
, *rmdisk_r
;
131 #define DFLT_RMDISK 10 /* size of initial array */
133 /* "/dev/fd0*", "/dev/rfd0*", "/dev/fd1*", "/dev/rfd1*" */
139 #define DFLT_NFP 10 /* size of initial array */
140 #define SIZE_OF_FD0 3 /* |fd0| */
141 #define SIZE_OF_RFD0 4 /* |rfd0| */
142 #define FLOPPY_CLEAN SECLIB"/fd_clean"
144 static void dotape();
145 static void doaudio();
146 static void dofloppy();
148 static void initmem();
149 static int expandmem(int, void **, int);
150 static void no_memory(void);
158 main(int argc
, char **argv
)
163 (void) setlocale(LC_ALL
, "");
164 (void) textdomain(TEXT_DOMAIN
);
166 if ((progname
= strrchr(argv
[0], '/')) == NULL
)
170 if (strcmp(progname
, MKDEVALLOC
) == 0)
172 else if (strcmp(progname
, MKDEVMAPS
) == 0)
177 initmem(); /* initialize memory */
190 struct dirent
*dep
; /* directory entry pointer */
192 char *nm
; /* name/device of special device */
193 char linkvalue
[2048]; /* symlink value */
194 struct stat stat
; /* determine if it's a symlink */
195 int sz
; /* size of symlink value */
196 char *cp
; /* pointer into string */
197 int ntape
; /* max array size */
200 char *dname
, *dtype
, *dclean
;
207 * look for rst* and nrst*
210 if ((dirp
= opendir("/dev")) == NULL
) {
211 perror(gettext("open /dev failure"));
216 while (dep
= readdir(dirp
)) {
217 /* ignore if neither rst* nor nrst* */
218 if (strncmp(dep
->d_name
, "rst", SIZE_OF_RST
) &&
219 strncmp(dep
->d_name
, "nrst", SIZE_OF_NRST
))
222 /* if array full, then expand it */
224 /* will exit(1) if insufficient memory */
225 ntape
= expandmem(i
, (void **)&tape
,
226 sizeof (struct tape
));
229 /* save name (/dev + / + d_name + \0) */
230 nm
= (char *)malloc(SIZE_OF_TMP
+ 1 + strlen(dep
->d_name
) + 1);
233 (void) strcpy(nm
, "/dev/");
234 (void) strcat(nm
, dep
->d_name
);
237 /* ignore if not symbolic link (note i not incremented) */
238 if (lstat(tape
[i
].name
, &stat
) < 0) {
239 perror("stat(2) failed ");
242 if ((stat
.st_mode
& S_IFMT
) != S_IFLNK
)
245 /* get name from symbolic link */
246 if ((sz
= readlink(tape
[i
].name
, linkvalue
,
247 sizeof (linkvalue
))) < 0)
249 nm
= (char *)malloc(sz
+ 1);
252 (void) strncpy(nm
, linkvalue
, sz
);
256 /* get device number */
257 cp
= strrchr(tape
[i
].device
, '/');
258 cp
++; /* advance to device # */
259 (void) sscanf(cp
, "%d", &tape
[i
].number
);
264 (void) closedir(dirp
);
267 * scan /dev/rmt and add entry to table
270 if ((dirp
= opendir("/dev/rmt")) == NULL
) {
271 perror(gettext("open /dev failure"));
275 while (dep
= readdir(dirp
)) {
276 /* skip . .. etc... */
277 if (strncmp(dep
->d_name
, ".", 1) == 0)
280 /* if array full, then expand it */
282 /* will exit(1) if insufficient memory */
283 ntape
= expandmem(i
, (void **)&tape
,
284 sizeof (struct tape
));
287 /* save name (/dev/rmt + / + d_name + \0) */
288 nm
= (char *)malloc(SIZE_OF_RMT
+ 1 + strlen(dep
->d_name
) + 1);
291 (void) strcpy(nm
, "/dev/rmt/");
292 (void) strcat(nm
, dep
->d_name
);
295 /* save device name (rmt/ + d_name + \0) */
296 nm
= (char *)malloc(SIZE_OF_TMP
+ strlen(dep
->d_name
) + 1);
299 (void) strcpy(nm
, "rmt/");
300 (void) strcat(nm
, dep
->d_name
);
303 (void) sscanf(dep
->d_name
, "%d", &tape
[i
].number
);
309 (void) closedir(dirp
);
311 /* remove duplicate entries */
312 for (i
= 0; i
< tape_count
- 1; i
++) {
313 for (j
= i
+ 1; j
< tape_count
; j
++) {
314 if (strcmp(tape
[i
].device
, tape
[j
].device
))
323 for (i
= 0; i
< 8; i
++) {
324 for (j
= 0; j
< tape_count
; j
++) {
325 if (tape
[j
].number
!= i
)
328 (void) da_add_list(&devlist
, tape
[j
].name
, i
,
330 } else if (do_devalloc
) {
331 /* print device_allocate for tape devices */
333 "st%d;st;reserved;reserved;%s;",
334 i
, DEFAULT_DEV_ALLOC_AUTH
);
335 (void) printf("%s%s\n", SECLIB
,
338 } else if (do_devmaps
) {
339 /* print device_maps for tape devices */
343 (void) printf("st%d:\\\n", i
);
344 (void) printf("\trmt:\\\n");
348 (void) printf("%s", tape
[j
].name
);
351 if (do_devmaps
&& first
) {
352 (void) printf("\n\n");
356 if (do_files
&& tape_count
) {
357 dargs
.rootdir
= NULL
;
358 dargs
.devnames
= NULL
;
359 dargs
.optflag
= DA_ADD
;
360 for (entry
= devlist
.tape
; entry
!= NULL
; entry
= entry
->next
) {
361 dargs
.devinfo
= &(entry
->devinfo
);
362 (void) da_update_device(&dargs
);
371 struct dirent
*dep
; /* directory entry pointer */
373 char *nm
; /* name/device of special device */
374 char linkvalue
[2048]; /* symlink value */
375 struct stat stat
; /* determine if it's a symlink */
376 int sz
; /* size of symlink value */
377 char *cp
; /* pointer into string */
378 int naudio
; /* max array size */
387 naudio
= DFLT_NAUDIO
;
389 if ((dirp
= opendir("/dev")) == NULL
) {
390 perror(gettext("open /dev failure"));
395 while (dep
= readdir(dirp
)) {
396 if (strcmp(dep
->d_name
, "audio") &&
397 strcmp(dep
->d_name
, "audioctl"))
400 /* if array full, then expand it */
402 /* will exit(1) if insufficient memory */
403 naudio
= expandmem(i
, (void **)&audio
,
404 sizeof (struct audio
));
407 /* save name (/dev + 1 + d_name + \0) */
408 nm
= (char *)malloc(SIZE_OF_TMP
+ 1 + strlen(dep
->d_name
) + 1);
411 (void) strcpy(nm
, "/dev/");
412 (void) strcat(nm
, dep
->d_name
);
415 /* ignore if not symbolic link (note i not incremented) */
416 if (lstat(audio
[i
].name
, &stat
) < 0) {
417 perror(gettext("stat(2) failed "));
420 if ((stat
.st_mode
& S_IFMT
) != S_IFLNK
)
423 /* get name from symbolic link */
424 if ((sz
= readlink(audio
[i
].name
, linkvalue
,
425 sizeof (linkvalue
))) < 0)
427 nm
= (char *)malloc(sz
+ 1);
430 (void) strncpy(nm
, linkvalue
, sz
);
432 audio
[i
].device
= nm
;
434 cp
= strrchr(audio
[i
].device
, '/');
435 cp
++; /* advance to device # */
436 (void) sscanf(cp
, "%d", &audio
[i
].number
);
441 (void) closedir(dirp
);
443 if ((dirp
= opendir("/dev/sound")) == NULL
) {
447 while (dep
= readdir(dirp
)) {
448 /* skip . .. etc... */
449 if (strncmp(dep
->d_name
, ".", 1) == 0)
452 /* if array full, then expand it */
454 /* will exit(1) if insufficient memory */
455 naudio
= expandmem(i
, (void **)&audio
,
456 sizeof (struct audio
));
459 /* save name (/dev/sound + / + d_name + \0) */
460 nm
= (char *)malloc(SIZE_OF_SOUND
+ 1 +
461 strlen(dep
->d_name
) + 1);
464 (void) strcpy(nm
, "/dev/sound/");
465 (void) strcat(nm
, dep
->d_name
);
468 nm
= (char *)malloc(SIZE_OF_SOUND
+ 1 +
469 strlen(dep
->d_name
) + 1);
472 (void) strcpy(nm
, "/dev/sound/");
473 (void) strcat(nm
, dep
->d_name
);
474 audio
[i
].device
= nm
;
476 (void) sscanf(dep
->d_name
, "%d", &audio
[i
].number
);
481 (void) closedir(dirp
);
486 /* remove duplicate entries */
487 for (i
= 0; i
< audio_count
- 1; i
++) {
488 for (j
= i
+ 1; j
< audio_count
; j
++) {
489 if (strcmp(audio
[i
].device
, audio
[j
].device
))
491 audio
[j
].number
= -1;
495 /* print out device_allocate entries for audio devices */
496 (void) strcpy(dname
, DA_AUDIO_NAME
);
497 slen
= strlen(DA_AUDIO_NAME
);
498 len
= sizeof (dname
) - slen
;
499 dclean
= AUDIO_CLEAN
;
500 for (i
= 0; i
< 8; i
++) {
501 for (j
= 0; j
< audio_count
; j
++) {
502 if (audio
[j
].number
!= i
)
505 (void) da_add_list(&devlist
, audio
[j
].name
,
507 } else if (do_devalloc
) {
508 /* print device_allocate for audio devices */
509 (void) printf("audio;audio;");
510 (void) printf("reserved;reserved;%s;",
511 DEFAULT_DEV_ALLOC_AUTH
);
512 (void) printf("%s%s\n", SECLIB
,
515 } else if (do_devmaps
) {
516 /* print device_maps for audio devices */
520 (void) printf("audio:\\\n");
521 (void) printf("\taudio:\\\n");
525 (void) printf("%s", audio
[j
].name
);
528 if (do_devmaps
&& first
) {
529 (void) printf("\n\n");
533 if (do_files
&& audio_count
) {
534 dargs
.rootdir
= NULL
;
535 dargs
.devnames
= NULL
;
536 dargs
.optflag
= DA_ADD
;
537 for (entry
= devlist
.audio
; entry
!= NULL
;
538 entry
= entry
->next
) {
539 dargs
.devinfo
= &(entry
->devinfo
);
540 (void) da_update_device(&dargs
);
549 struct dirent
*dep
; /* directory entry pointer */
551 char *nm
; /* name/device of special device */
552 char linkvalue
[2048]; /* symlink value */
553 struct stat stat
; /* determine if it's a symlink */
554 int sz
; /* size of symlink value */
555 char *cp
; /* pointer into string */
556 int nfp
; /* max array size */
557 int floppy_count
= 0;
559 char *dname
, *dclean
;
566 * look for fd* and rfd*
569 if ((dirp
= opendir("/dev")) == NULL
) {
570 perror(gettext("open /dev failure"));
575 while (dep
= readdir(dirp
)) {
576 /* ignore if neither rst* nor nrst* */
577 if (strncmp(dep
->d_name
, "fd0", SIZE_OF_FD0
) &&
578 strncmp(dep
->d_name
, "rfd0", SIZE_OF_RFD0
) &&
579 strncmp(dep
->d_name
, "fd1", SIZE_OF_FD0
) &&
580 strncmp(dep
->d_name
, "rfd0", SIZE_OF_RFD0
))
583 /* if array full, then expand it */
585 /* will exit(1) if insufficient memory */
586 nfp
= expandmem(i
, (void **)&fp
, sizeof (struct fp
));
589 /* save name (/dev + 1 + d_name + \0) */
590 nm
= (char *)malloc(SIZE_OF_TMP
+ 1 + strlen(dep
->d_name
) + 1);
593 (void) strcpy(nm
, "/dev/");
594 (void) strcat(nm
, dep
->d_name
);
597 /* ignore if not symbolic link (note i not incremented) */
598 if (lstat(fp
[i
].name
, &stat
) < 0) {
599 perror(gettext("stat(2) failed "));
602 if ((stat
.st_mode
&S_IFMT
) != S_IFLNK
)
605 /* get name from symbolic link */
606 if ((sz
= readlink(fp
[i
].name
, linkvalue
,
607 sizeof (linkvalue
))) < 0)
609 nm
= (char *)malloc(sz
+1);
612 (void) strncpy(nm
, linkvalue
, sz
);
616 /* get device number */
617 cp
= strchr(fp
[i
].name
, 'd');
618 cp
++; /* advance to device # */
619 cp
= strchr(cp
, 'd');
620 cp
++; /* advance to device # */
621 (void) sscanf(cp
, "%d", &fp
[i
].number
);
626 (void) closedir(dirp
);
630 /* print out device_allocate entries for floppy devices */
632 dclean
= FLOPPY_CLEAN
;
633 for (i
= 0; i
< 8; i
++) {
634 for (j
= 0; j
< floppy_count
; j
++) {
635 if (fp
[j
].number
!= i
)
638 (void) da_add_list(&devlist
, fp
[j
].name
, i
,
640 } else if (do_devalloc
) {
641 /* print device_allocate for floppy devices */
643 "fd%d;fd;reserved;reserved;%s;",
644 i
, DEFAULT_DEV_ALLOC_AUTH
);
645 (void) printf("%s%s\n", SECLIB
,
648 } else if (do_devmaps
) {
649 /* print device_maps for floppy devices */
653 (void) printf("fd%d:\\\n", i
);
654 (void) printf("\tfd:\\\n");
657 (void) printf("/dev/diskette ");
663 (void) printf("%s", fp
[j
].name
);
666 if (do_devmaps
&& first
) {
667 (void) printf("\n\n");
671 if (do_files
&& floppy_count
) {
672 dargs
.rootdir
= NULL
;
673 dargs
.devnames
= NULL
;
674 dargs
.optflag
= DA_ADD
;
675 for (entry
= devlist
.floppy
; entry
!= NULL
;
676 entry
= entry
->next
) {
677 dargs
.devinfo
= &(entry
->devinfo
);
678 (void) da_update_device(&dargs
);
687 struct dirent
*dep
; /* directory entry pointer */
689 char *nm
; /* name/device of special device */
690 char linkvalue
[2048]; /* symlink value */
691 struct stat stat
; /* determine if it's a symlink */
692 int sz
; /* size of symlink value */
693 char *cp
; /* pointer into string */
694 int id
; /* disk id */
695 int ctrl
; /* disk controller */
696 int ncd
; /* max array size */
699 char *dname
, *dclean
;
706 * look for sr* and rsr*
709 if ((dirp
= opendir("/dev")) == NULL
) {
710 perror(gettext("open /dev failure"));
715 while (dep
= readdir(dirp
)) {
716 /* ignore if neither sr* nor rsr* */
717 if (strncmp(dep
->d_name
, "sr", SIZE_OF_SR
) &&
718 strncmp(dep
->d_name
, "rsr", SIZE_OF_RSR
))
721 /* if array full, then expand it */
723 /* will exit(1) if insufficient memory */
724 ncd
= expandmem(i
, (void **)&cd
, sizeof (struct cd
));
727 /* save name (/dev + / + d_name + \0) */
728 nm
= (char *)malloc(SIZE_OF_TMP
+ 1 + strlen(dep
->d_name
) + 1);
731 (void) strcpy(nm
, "/dev/");
732 (void) strcat(nm
, dep
->d_name
);
735 /* ignore if not symbolic link (note i not incremented) */
736 if (lstat(cd
[i
].name
, &stat
) < 0) {
737 perror(gettext("stat(2) failed "));
740 if ((stat
.st_mode
& S_IFMT
) != S_IFLNK
)
743 /* get name from symbolic link */
744 if ((sz
= readlink(cd
[i
].name
, linkvalue
, sizeof (linkvalue
))) <
748 nm
= (char *)malloc(sz
+ 1);
751 (void) strncpy(nm
, linkvalue
, sz
);
755 cp
= strrchr(cd
[i
].device
, '/');
756 cp
++; /* advance to device # */
757 (void) sscanf(cp
, "c%dt%d", &cd
[i
].controller
, &cd
[i
].number
);
758 cd
[i
].id
= cd
[i
].number
;
764 (void) closedir(dirp
);
767 * scan /dev/dsk for cd devices
770 if ((dirp
= opendir("/dev/dsk")) == NULL
) {
771 perror("gettext(open /dev/dsk failure)");
775 while (dep
= readdir(dirp
)) {
776 /* skip . .. etc... */
777 if (strncmp(dep
->d_name
, ".", 1) == 0)
780 /* get device # (disk #) */
781 if (sscanf(dep
->d_name
, "c%dt%d", &ctrl
, &id
) != 2)
784 /* see if this is one of the cd special devices */
785 for (j
= 0; j
< cd_count
; j
++) {
786 if (cd
[j
].number
== id
&& cd
[j
].controller
== ctrl
)
791 /* add new entry to table (/dev/dsk + / + d_name + \0) */
793 /* if array full, then expand it */
795 /* will exit(1) if insufficient memory */
796 ncd
= expandmem(i
, (void **)&cd
, sizeof (struct cd
));
799 nm
= (char *)malloc(SIZE_OF_DSK
+ 1 + strlen(dep
->d_name
) + 1);
802 (void) strcpy(nm
, "/dev/dsk/");
803 (void) strcat(nm
, dep
->d_name
);
815 (void) closedir(dirp
);
818 * scan /dev/rdsk for cd devices
821 if ((dirp
= opendir("/dev/rdsk")) == NULL
) {
822 perror(gettext("open /dev/dsk failure"));
826 while (dep
= readdir(dirp
)) {
827 /* skip . .. etc... */
828 if (strncmp(dep
->d_name
, ".", 1) == 0)
831 /* get device # (disk #) */
832 if (sscanf(dep
->d_name
, "c%dt%d", &ctrl
, &id
) != 2)
835 /* see if this is one of the cd special devices */
836 for (j
= 0; j
< cd_count
; j
++) {
837 if (cd
[j
].number
== id
&& cd
[j
].controller
== ctrl
)
842 /* add new entry to table (/dev/rdsk + / + d_name + \0) */
844 /* if array full, then expand it */
846 /* will exit(1) if insufficient memory */
847 ncd
= expandmem(i
, (void **)&cd
, sizeof (struct cd
));
850 nm
= (char *)malloc(SIZE_OF_RDSK
+ 1 + strlen(dep
->d_name
) + 1);
853 (void) strcpy(nm
, "/dev/rdsk/");
854 (void) strcat(nm
, dep
->d_name
);
863 cd
[i
].controller
= ctrl
;
868 (void) closedir(dirp
);
874 for (i
= 0; i
< 8; i
++) {
875 for (j
= 0; j
< cd_count
; j
++) {
879 (void) da_add_list(&devlist
, cd
[j
].name
, i
,
881 } else if (do_devalloc
) {
882 /* print device_allocate for cd devices */
884 "sr%d;sr;reserved;reserved;%s;",
885 i
, DEFAULT_DEV_ALLOC_AUTH
);
886 (void) printf("%s%s\n", SECLIB
,
889 } else if (do_devmaps
) {
890 /* print device_maps for cd devices */
894 (void) printf("sr%d:\\\n", i
);
895 (void) printf("\tsr:\\\n");
899 (void) printf("%s", cd
[j
].name
);
902 if (do_devmaps
&& first
) {
903 (void) printf("\n\n");
907 if (do_files
&& cd_count
) {
908 dargs
.rootdir
= NULL
;
909 dargs
.devnames
= NULL
;
910 dargs
.optflag
= DA_ADD
;
911 for (entry
= devlist
.cd
; entry
!= NULL
; entry
= entry
->next
) {
912 dargs
.devinfo
= &(entry
->devinfo
);
913 (void) da_update_device(&dargs
);
920 /* set default array sizes */
924 tape
= (struct tape
*)calloc(DFLT_NTAPE
, sizeof (struct tape
));
925 audio
= (struct audio
*)calloc(DFLT_NAUDIO
, sizeof (struct audio
));
926 cd
= (struct cd
*)calloc(DFLT_NCD
, sizeof (struct cd
));
927 fp
= (struct fp
*)calloc(DFLT_NFP
, sizeof (struct fp
));
929 if (tape
== NULL
|| audio
== NULL
|| cd
== NULL
|| fp
== NULL
)
932 devlist
.audio
= devlist
.cd
= devlist
.floppy
= devlist
.rmdisk
=
936 /* note n will be # elments in array (and could be 0) */
938 expandmem(int n
, void **array
, int size
)
943 /* get new array space (n + DELTA) */
944 new = (void *)calloc(n
+ DELTA
, size
);
947 perror("memory allocation failed");
951 /* copy old array into new space */
952 bcopy(old
, new, n
* size
);
954 /* now release old arrary */
965 (void) fprintf(stderr
, "%s: %s\n", "mkdevalloc",
966 gettext("out of memory"));