Merge commit 'a058d1cc571af5fbcfe7f1d719df1abbfdb722f3' into merges
[unleashed.git] / usr / src / cmd / allocate / mkdevalloc.c
blob448605a63d2b0c112a8234267913f2ff9dcfaa57
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
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....
31 * devices are:
32 * tape (cartridge)
33 * /dev/rst*
34 * /dev/nrst*
35 * /dev/rmt/...
36 * audio
37 * /dev/audio
38 * /dev/audioctl
39 * /dev/sound/...
40 * floppy
41 * /dev/diskette
42 * /dev/fd*
43 * /dev/rdiskette
44 * /dev/rfd*
45 * CD
46 * /dev/sr*
47 * /dev/nsr*
48 * /dev/dsk/c?t?d0s?
49 * /dev/rdsk/c?t?d0s?
53 #include <errno.h>
54 #include <fcntl.h>
55 #include <sys/types.h> /* for stat(2), etc. */
56 #include <sys/stat.h>
57 #include <dirent.h> /* for readdir(3), etc. */
58 #include <unistd.h> /* for readlink(2) */
59 #include <stropts.h>
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) */
64 #include <sys/dkio.h>
65 #include <locale.h>
66 #include <libintl.h>
67 #include <libdevinfo.h>
68 #include <secdb.h>
69 #include <deflt.h>
70 #include <auth_attr.h>
71 #include <auth_list.h>
72 #include <bsm/devices.h>
73 #include <bsm/devalloc.h>
75 #ifndef TEXT_DOMAIN
76 #define TEXT_DOMAIN "SUNW_OST_OSCMD"
77 #endif
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/..." */
86 struct tape {
87 char *name;
88 char *device;
89 int number;
90 } *tape;
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/..." */
99 struct audio {
100 char *name;
101 char *device;
102 int number;
103 } *audio;
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?" */
109 struct cd {
110 char *name;
111 char *device;
112 int id;
113 int controller;
114 int number;
115 } *cd;
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?" */
124 struct rmdisk {
125 char *name;
126 char *device;
127 int id;
128 int controller;
129 int number;
130 } *rmdisk, *rmdisk_r;
131 #define DFLT_RMDISK 10 /* size of initial array */
133 /* "/dev/fd0*", "/dev/rfd0*", "/dev/fd1*", "/dev/rfd1*" */
134 struct fp {
135 char *name;
136 char *device;
137 int number;
138 } *fp;
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();
147 static int docd();
148 static void initmem();
149 static int expandmem(int, void **, int);
150 static void no_memory(void);
152 int do_devalloc = 0;
153 int do_devmaps = 0;
154 int do_files = 0;
155 devlist_t devlist;
158 main(int argc, char **argv)
160 int cd_count = 0;
161 char *progname;
163 (void) setlocale(LC_ALL, "");
164 (void) textdomain(TEXT_DOMAIN);
166 if ((progname = strrchr(argv[0], '/')) == NULL)
167 progname = argv[0];
168 else
169 progname++;
170 if (strcmp(progname, MKDEVALLOC) == 0)
171 do_devalloc = 1;
172 else if (strcmp(progname, MKDEVMAPS) == 0)
173 do_devmaps = 1;
174 else
175 exit(1);
177 initmem(); /* initialize memory */
178 dotape();
179 doaudio();
180 dofloppy();
181 cd_count = docd();
183 return (0);
186 static void
187 dotape()
189 DIR *dirp;
190 struct dirent *dep; /* directory entry pointer */
191 int i, j;
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 */
198 int tape_count;
199 int first = 0;
200 char *dname, *dtype, *dclean;
201 da_args dargs;
202 deventry_t *entry;
204 ntape = DFLT_NTAPE;
207 * look for rst* and nrst*
210 if ((dirp = opendir("/dev")) == NULL) {
211 perror(gettext("open /dev failure"));
212 exit(1);
215 i = 0;
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))
220 continue;
222 /* if array full, then expand it */
223 if (i == ntape) {
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);
231 if (nm == NULL)
232 no_memory();
233 (void) strcpy(nm, "/dev/");
234 (void) strcat(nm, dep->d_name);
235 tape[i].name = nm;
237 /* ignore if not symbolic link (note i not incremented) */
238 if (lstat(tape[i].name, &stat) < 0) {
239 perror("stat(2) failed ");
240 exit(1);
242 if ((stat.st_mode & S_IFMT) != S_IFLNK)
243 continue;
245 /* get name from symbolic link */
246 if ((sz = readlink(tape[i].name, linkvalue,
247 sizeof (linkvalue))) < 0)
248 continue;
249 nm = (char *)malloc(sz + 1);
250 if (nm == NULL)
251 no_memory();
252 (void) strncpy(nm, linkvalue, sz);
253 nm[sz] = '\0';
254 tape[i].device = nm;
256 /* get device number */
257 cp = strrchr(tape[i].device, '/');
258 cp++; /* advance to device # */
259 (void) sscanf(cp, "%d", &tape[i].number);
261 i++;
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"));
272 exit(1);
275 while (dep = readdir(dirp)) {
276 /* skip . .. etc... */
277 if (strncmp(dep->d_name, ".", 1) == 0)
278 continue;
280 /* if array full, then expand it */
281 if (i == ntape) {
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);
289 if (nm == NULL)
290 no_memory();
291 (void) strcpy(nm, "/dev/rmt/");
292 (void) strcat(nm, dep->d_name);
293 tape[i].name = nm;
295 /* save device name (rmt/ + d_name + \0) */
296 nm = (char *)malloc(SIZE_OF_TMP + strlen(dep->d_name) + 1);
297 if (nm == NULL)
298 no_memory();
299 (void) strcpy(nm, "rmt/");
300 (void) strcat(nm, dep->d_name);
301 tape[i].device = nm;
303 (void) sscanf(dep->d_name, "%d", &tape[i].number);
305 i++;
307 tape_count = i;
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))
315 continue;
316 tape[j].number = -1;
320 dname = "st";
321 dtype = "st";
322 dclean = TAPE_CLEAN;
323 for (i = 0; i < 8; i++) {
324 for (j = 0; j < tape_count; j++) {
325 if (tape[j].number != i)
326 continue;
327 if (do_files) {
328 (void) da_add_list(&devlist, tape[j].name, i,
329 DA_TAPE);
330 } else if (do_devalloc) {
331 /* print device_allocate for tape devices */
332 (void) printf(
333 "st%d;st;reserved;reserved;%s;",
334 i, DEFAULT_DEV_ALLOC_AUTH);
335 (void) printf("%s%s\n", SECLIB,
336 "/st_clean");
337 break;
338 } else if (do_devmaps) {
339 /* print device_maps for tape devices */
340 if (first) {
341 (void) printf(" ");
342 } else {
343 (void) printf("st%d:\\\n", i);
344 (void) printf("\trmt:\\\n");
345 (void) printf("\t");
346 first++;
348 (void) printf("%s", tape[j].name);
351 if (do_devmaps && first) {
352 (void) printf("\n\n");
353 first = 0;
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);
367 static void
368 doaudio()
370 DIR *dirp;
371 struct dirent *dep; /* directory entry pointer */
372 int i, j;
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 */
379 int audio_count = 0;
380 int len, slen;
381 int first = 0;
382 char dname[128];
383 char *dclean;
384 da_args dargs;
385 deventry_t *entry;
387 naudio = DFLT_NAUDIO;
389 if ((dirp = opendir("/dev")) == NULL) {
390 perror(gettext("open /dev failure"));
391 exit(1);
394 i = 0;
395 while (dep = readdir(dirp)) {
396 if (strcmp(dep->d_name, "audio") &&
397 strcmp(dep->d_name, "audioctl"))
398 continue;
400 /* if array full, then expand it */
401 if (i == naudio) {
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);
409 if (nm == NULL)
410 no_memory();
411 (void) strcpy(nm, "/dev/");
412 (void) strcat(nm, dep->d_name);
413 audio[i].name = nm;
415 /* ignore if not symbolic link (note i not incremented) */
416 if (lstat(audio[i].name, &stat) < 0) {
417 perror(gettext("stat(2) failed "));
418 exit(1);
420 if ((stat.st_mode & S_IFMT) != S_IFLNK)
421 continue;
423 /* get name from symbolic link */
424 if ((sz = readlink(audio[i].name, linkvalue,
425 sizeof (linkvalue))) < 0)
426 continue;
427 nm = (char *)malloc(sz + 1);
428 if (nm == NULL)
429 no_memory();
430 (void) strncpy(nm, linkvalue, sz);
431 nm[sz] = '\0';
432 audio[i].device = nm;
434 cp = strrchr(audio[i].device, '/');
435 cp++; /* advance to device # */
436 (void) sscanf(cp, "%d", &audio[i].number);
438 i++;
441 (void) closedir(dirp);
443 if ((dirp = opendir("/dev/sound")) == NULL) {
444 goto skip;
447 while (dep = readdir(dirp)) {
448 /* skip . .. etc... */
449 if (strncmp(dep->d_name, ".", 1) == 0)
450 continue;
452 /* if array full, then expand it */
453 if (i == naudio) {
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);
462 if (nm == NULL)
463 no_memory();
464 (void) strcpy(nm, "/dev/sound/");
465 (void) strcat(nm, dep->d_name);
466 audio[i].name = nm;
468 nm = (char *)malloc(SIZE_OF_SOUND + 1 +
469 strlen(dep->d_name) + 1);
470 if (nm == NULL)
471 no_memory();
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);
478 i++;
481 (void) closedir(dirp);
483 skip:
484 audio_count = i;
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))
490 continue;
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)
503 continue;
504 if (do_files) {
505 (void) da_add_list(&devlist, audio[j].name,
506 i, DA_AUDIO);
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,
513 "/audio_clean");
514 break;
515 } else if (do_devmaps) {
516 /* print device_maps for audio devices */
517 if (first) {
518 (void) printf(" ");
519 } else {
520 (void) printf("audio:\\\n");
521 (void) printf("\taudio:\\\n");
522 (void) printf("\t");
523 first++;
525 (void) printf("%s", audio[j].name);
528 if (do_devmaps && first) {
529 (void) printf("\n\n");
530 first = 0;
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);
545 static void
546 dofloppy()
548 DIR *dirp;
549 struct dirent *dep; /* directory entry pointer */
550 int i, j;
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;
558 int first = 0;
559 char *dname, *dclean;
560 da_args dargs;
561 deventry_t *entry;
563 nfp = DFLT_NFP;
566 * look for fd* and rfd*
569 if ((dirp = opendir("/dev")) == NULL) {
570 perror(gettext("open /dev failure"));
571 exit(1);
574 i = 0;
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))
581 continue;
583 /* if array full, then expand it */
584 if (i == nfp) {
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);
591 if (nm == NULL)
592 no_memory();
593 (void) strcpy(nm, "/dev/");
594 (void) strcat(nm, dep->d_name);
595 fp[i].name = nm;
597 /* ignore if not symbolic link (note i not incremented) */
598 if (lstat(fp[i].name, &stat) < 0) {
599 perror(gettext("stat(2) failed "));
600 exit(1);
602 if ((stat.st_mode&S_IFMT) != S_IFLNK)
603 continue;
605 /* get name from symbolic link */
606 if ((sz = readlink(fp[i].name, linkvalue,
607 sizeof (linkvalue))) < 0)
608 continue;
609 nm = (char *)malloc(sz+1);
610 if (nm == NULL)
611 no_memory();
612 (void) strncpy(nm, linkvalue, sz);
613 nm[sz] = '\0';
614 fp[i].device = nm;
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);
623 i++;
626 (void) closedir(dirp);
628 floppy_count = i;
630 /* print out device_allocate entries for floppy devices */
631 dname = "fd";
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)
636 continue;
637 if (do_files) {
638 (void) da_add_list(&devlist, fp[j].name, i,
639 DA_FLOPPY);
640 } else if (do_devalloc) {
641 /* print device_allocate for floppy devices */
642 (void) printf(
643 "fd%d;fd;reserved;reserved;%s;",
644 i, DEFAULT_DEV_ALLOC_AUTH);
645 (void) printf("%s%s\n", SECLIB,
646 "/fd_clean");
647 break;
648 } else if (do_devmaps) {
649 /* print device_maps for floppy devices */
650 if (first) {
651 (void) printf(" ");
652 } else {
653 (void) printf("fd%d:\\\n", i);
654 (void) printf("\tfd:\\\n");
655 (void) printf("\t");
656 if (i == 0) {
657 (void) printf("/dev/diskette ");
658 (void) printf(
659 "/dev/rdiskette ");
661 first++;
663 (void) printf("%s", fp[j].name);
666 if (do_devmaps && first) {
667 (void) printf("\n\n");
668 first = 0;
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);
683 static int
684 docd()
686 DIR *dirp;
687 struct dirent *dep; /* directory entry pointer */
688 int i, j;
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 */
697 int cd_count = 0;
698 int first = 0;
699 char *dname, *dclean;
700 da_args dargs;
701 deventry_t *entry;
703 ncd = DFLT_NCD;
706 * look for sr* and rsr*
709 if ((dirp = opendir("/dev")) == NULL) {
710 perror(gettext("open /dev failure"));
711 exit(1);
714 i = 0;
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))
719 continue;
721 /* if array full, then expand it */
722 if (i == ncd) {
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);
729 if (nm == NULL)
730 no_memory();
731 (void) strcpy(nm, "/dev/");
732 (void) strcat(nm, dep->d_name);
733 cd[i].name = nm;
735 /* ignore if not symbolic link (note i not incremented) */
736 if (lstat(cd[i].name, &stat) < 0) {
737 perror(gettext("stat(2) failed "));
738 exit(1);
740 if ((stat.st_mode & S_IFMT) != S_IFLNK)
741 continue;
743 /* get name from symbolic link */
744 if ((sz = readlink(cd[i].name, linkvalue, sizeof (linkvalue))) <
746 continue;
748 nm = (char *)malloc(sz + 1);
749 if (nm == NULL)
750 no_memory();
751 (void) strncpy(nm, linkvalue, sz);
752 nm[sz] = '\0';
753 cd[i].device = nm;
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;
760 i++;
762 cd_count = i;
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)");
772 exit(1);
775 while (dep = readdir(dirp)) {
776 /* skip . .. etc... */
777 if (strncmp(dep->d_name, ".", 1) == 0)
778 continue;
780 /* get device # (disk #) */
781 if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2)
782 continue;
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)
787 goto found;
789 continue;
791 /* add new entry to table (/dev/dsk + / + d_name + \0) */
792 found:
793 /* if array full, then expand it */
794 if (i == ncd) {
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);
800 if (nm == NULL)
801 no_memory();
802 (void) strcpy(nm, "/dev/dsk/");
803 (void) strcat(nm, dep->d_name);
804 cd[i].name = nm;
806 cd[i].id = cd[j].id;
808 cd[i].device = "";
810 cd[i].number = id;
812 i++;
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"));
823 exit(1);
826 while (dep = readdir(dirp)) {
827 /* skip . .. etc... */
828 if (strncmp(dep->d_name, ".", 1) == 0)
829 continue;
831 /* get device # (disk #) */
832 if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2)
833 continue;
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)
838 goto found1;
840 continue;
842 /* add new entry to table (/dev/rdsk + / + d_name + \0) */
843 found1:
844 /* if array full, then expand it */
845 if (i == ncd) {
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);
851 if (nm == NULL)
852 no_memory();
853 (void) strcpy(nm, "/dev/rdsk/");
854 (void) strcat(nm, dep->d_name);
855 cd[i].name = nm;
857 cd[i].id = cd[j].id;
859 cd[i].device = "";
861 cd[i].number = id;
863 cd[i].controller = ctrl;
865 i++;
868 (void) closedir(dirp);
870 cd_count = i;
872 dname = "sr";
873 dclean = CD_CLEAN;
874 for (i = 0; i < 8; i++) {
875 for (j = 0; j < cd_count; j++) {
876 if (cd[j].id != i)
877 continue;
878 if (do_files) {
879 (void) da_add_list(&devlist, cd[j].name, i,
880 DA_CD);
881 } else if (do_devalloc) {
882 /* print device_allocate for cd devices */
883 (void) printf(
884 "sr%d;sr;reserved;reserved;%s;",
885 i, DEFAULT_DEV_ALLOC_AUTH);
886 (void) printf("%s%s\n", SECLIB,
887 "/sr_clean");
888 break;
889 } else if (do_devmaps) {
890 /* print device_maps for cd devices */
891 if (first) {
892 (void) printf(" ");
893 } else {
894 (void) printf("sr%d:\\\n", i);
895 (void) printf("\tsr:\\\n");
896 (void) printf("\t");
897 first++;
899 (void) printf("%s", cd[j].name);
902 if (do_devmaps && first) {
903 (void) printf("\n\n");
904 first = 0;
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);
917 return (cd_count);
920 /* set default array sizes */
921 static void
922 initmem()
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)
930 no_memory();
932 devlist.audio = devlist.cd = devlist.floppy = devlist.rmdisk =
933 devlist.tape = NULL;
936 /* note n will be # elments in array (and could be 0) */
937 static int
938 expandmem(int n, void **array, int size)
940 void *old = *array;
941 void *new;
943 /* get new array space (n + DELTA) */
944 new = (void *)calloc(n + DELTA, size);
946 if (new == NULL) {
947 perror("memory allocation failed");
948 exit(1);
951 /* copy old array into new space */
952 bcopy(old, new, n * size);
954 /* now release old arrary */
955 free(old);
957 *array = new;
959 return (n + DELTA);
962 static void
963 no_memory(void)
965 (void) fprintf(stderr, "%s: %s\n", "mkdevalloc",
966 gettext("out of memory"));
967 exit(1);
968 /* NOT REACHED */