1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * scan /dev directory for mountable objects and construct device_allocate
29 * file for allocate....
30 *
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?
50 *
51 */
52
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>
74 #include <tsol/label.h>
75
76 #ifndef TEXT_DOMAIN
77 #define TEXT_DOMAIN "SUNW_OST_OSCMD"
78 #endif
79
80 #define MKDEVALLOC "mkdevalloc"
81 #define MKDEVMAPS "mkdevmaps"
82
83 #define DELTA 5 /* array size delta when full */
84 #define SECLIB "/etc/security/lib"
85
86 /* "/dev/rst...", "/dev/nrst...", "/dev/rmt/..." */
87 struct tape {
88 char *name;
89 char *device;
90 int number;
91 } *tape;
92 #define DFLT_NTAPE 10 /* size of initial array */
93 #define SIZE_OF_RST 3 /* |rmt| */
94 #define SIZE_OF_NRST 4 /* |nrmt| */
95 #define SIZE_OF_TMP 4 /* |/tmp| */
96 #define SIZE_OF_RMT 8 /* |/dev/rmt| */
97 #define TAPE_CLEAN SECLIB"/st_clean"
98
99 /* "/dev/audio", "/dev/audioctl", "/dev/sound/..." */
100 struct audio {
101 char *name;
102 char *device;
103 int number;
104 } *audio;
105 #define DFLT_NAUDIO 10 /* size of initial array */
106 #define SIZE_OF_SOUND 10 /* |/dev/sound| */
107 #define AUDIO_CLEAN SECLIB"/audio_clean"
108
109 /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */
110 struct cd {
111 char *name;
112 char *device;
113 int id;
114 int controller;
115 int number;
116 } *cd;
117 #define DFLT_NCD 10 /* size of initial array */
118 #define SIZE_OF_SR 2 /* |sr| */
119 #define SIZE_OF_RSR 3 /* |rsr| */
120 #define SIZE_OF_DSK 8 /* |/dev/dsk| */
121 #define SIZE_OF_RDSK 9 /* |/dev/rdsk| */
122 #define CD_CLEAN SECLIB"/sr_clean"
123
124 /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */
125 struct rmdisk {
126 char *name;
127 char *device;
128 int id;
129 int controller;
130 int number;
131 } *rmdisk, *rmdisk_r;
132 #define DFLT_RMDISK 10 /* size of initial array */
133
134 /* "/dev/fd0*", "/dev/rfd0*", "/dev/fd1*", "/dev/rfd1*" */
135 struct fp {
136 char *name;
137 char *device;
138 int number;
139 } *fp;
140 #define DFLT_NFP 10 /* size of initial array */
141 #define SIZE_OF_FD0 3 /* |fd0| */
142 #define SIZE_OF_RFD0 4 /* |rfd0| */
143 #define FLOPPY_CLEAN SECLIB"/fd_clean"
144
145 static void dotape();
146 static void doaudio();
147 static void dofloppy();
148 static int docd();
149 static void dormdisk(int);
150 static void initmem();
151 static int expandmem(int, void **, int);
152 static void no_memory(void);
153
154 int system_labeled = 0;
155 int do_devalloc = 0;
156 int do_devmaps = 0;
157 int do_files = 0;
158 devlist_t devlist;
159
160 int
main(int argc,char ** argv)161 main(int argc, char **argv)
162 {
163 int cd_count = 0;
164 char *progname;
165
166 (void) setlocale(LC_ALL, "");
167 (void) textdomain(TEXT_DOMAIN);
168
169 if ((progname = strrchr(argv[0], '/')) == NULL)
170 progname = argv[0];
171 else
172 progname++;
173 if (strcmp(progname, MKDEVALLOC) == 0)
174 do_devalloc = 1;
175 else if (strcmp(progname, MKDEVMAPS) == 0)
176 do_devmaps = 1;
177 else
178 exit(1);
179
180 system_labeled = is_system_labeled();
181
182 if (!system_labeled) {
183 /*
184 * is_system_labeled() will return false in case we are
185 * starting before the first reboot after Trusted Extensions
186 * is enabled. Check the setting in /etc/system to see if
187 * TX is enabled (even if not yet booted).
188 */
189 if (defopen("/etc/system") == 0) {
190 if (defread("set sys_labeling=1") != NULL)
191 system_labeled = 1;
192
193 /* close defaults file */
194 (void) defopen(NULL);
195 }
196 }
197
198 #ifdef DEBUG
199 /* test hook: see also devfsadm.c and allocate.c */
200 if (!system_labeled) {
201 struct stat tx_stat;
202
203 system_labeled = is_system_labeled_debug(&tx_stat);
204 if (system_labeled) {
205 fprintf(stderr, "/ALLOCATE_FORCE_LABEL is set,\n"
206 "forcing system label on for testing...\n");
207 }
208 }
209 #endif
210
211 if (system_labeled && do_devalloc && (argc == 2) &&
212 (strcmp(argv[1], DA_IS_LABELED) == 0)) {
213 /*
214 * write device entries to device_allocate and device_maps.
215 * default is to print them on stdout.
216 */
217 do_files = 1;
218 }
219
220 initmem(); /* initialize memory */
221 dotape();
222 doaudio();
223 dofloppy();
224 cd_count = docd();
225 if (system_labeled)
226 dormdisk(cd_count);
227
228 return (0);
229 }
230
231 static void
dotape()232 dotape()
233 {
234 DIR *dirp;
235 struct dirent *dep; /* directory entry pointer */
236 int i, j;
237 char *nm; /* name/device of special device */
238 char linkvalue[2048]; /* symlink value */
239 struct stat stat; /* determine if it's a symlink */
240 int sz; /* size of symlink value */
241 char *cp; /* pointer into string */
242 int ntape; /* max array size */
243 int tape_count;
244 int first = 0;
245 char *dname, *dtype, *dclean;
246 da_args dargs;
247 deventry_t *entry;
248
249 ntape = DFLT_NTAPE;
250
251 /*
252 * look for rst* and nrst*
253 */
254
255 if ((dirp = opendir("/dev")) == NULL) {
256 perror(gettext("open /dev failure"));
257 exit(1);
258 }
259
260 i = 0;
261 while (dep = readdir(dirp)) {
262 /* ignore if neither rst* nor nrst* */
263 if (strncmp(dep->d_name, "rst", SIZE_OF_RST) &&
264 strncmp(dep->d_name, "nrst", SIZE_OF_NRST))
265 continue;
266
267 /* if array full, then expand it */
268 if (i == ntape) {
269 /* will exit(1) if insufficient memory */
270 ntape = expandmem(i, (void **)&tape,
271 sizeof (struct tape));
272 }
273
274 /* save name (/dev + / + d_name + \0) */
275 nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
276 if (nm == NULL)
277 no_memory();
278 (void) strcpy(nm, "/dev/");
279 (void) strcat(nm, dep->d_name);
280 tape[i].name = nm;
281
282 /* ignore if not symbolic link (note i not incremented) */
283 if (lstat(tape[i].name, &stat) < 0) {
284 perror("stat(2) failed ");
285 exit(1);
286 }
287 if ((stat.st_mode & S_IFMT) != S_IFLNK)
288 continue;
289
290 /* get name from symbolic link */
291 if ((sz = readlink(tape[i].name, linkvalue,
292 sizeof (linkvalue))) < 0)
293 continue;
294 nm = (char *)malloc(sz + 1);
295 if (nm == NULL)
296 no_memory();
297 (void) strncpy(nm, linkvalue, sz);
298 nm[sz] = '\0';
299 tape[i].device = nm;
300
301 /* get device number */
302 cp = strrchr(tape[i].device, '/');
303 cp++; /* advance to device # */
304 (void) sscanf(cp, "%d", &tape[i].number);
305
306 i++;
307 }
308
309 (void) closedir(dirp);
310
311 /*
312 * scan /dev/rmt and add entry to table
313 */
314
315 if ((dirp = opendir("/dev/rmt")) == NULL) {
316 perror(gettext("open /dev failure"));
317 exit(1);
318 }
319
320 while (dep = readdir(dirp)) {
321 /* skip . .. etc... */
322 if (strncmp(dep->d_name, ".", 1) == 0)
323 continue;
324
325 /* if array full, then expand it */
326 if (i == ntape) {
327 /* will exit(1) if insufficient memory */
328 ntape = expandmem(i, (void **)&tape,
329 sizeof (struct tape));
330 }
331
332 /* save name (/dev/rmt + / + d_name + \0) */
333 nm = (char *)malloc(SIZE_OF_RMT + 1 + strlen(dep->d_name) + 1);
334 if (nm == NULL)
335 no_memory();
336 (void) strcpy(nm, "/dev/rmt/");
337 (void) strcat(nm, dep->d_name);
338 tape[i].name = nm;
339
340 /* save device name (rmt/ + d_name + \0) */
341 nm = (char *)malloc(SIZE_OF_TMP + strlen(dep->d_name) + 1);
342 if (nm == NULL)
343 no_memory();
344 (void) strcpy(nm, "rmt/");
345 (void) strcat(nm, dep->d_name);
346 tape[i].device = nm;
347
348 (void) sscanf(dep->d_name, "%d", &tape[i].number);
349
350 i++;
351 }
352 tape_count = i;
353
354 (void) closedir(dirp);
355
356 /* remove duplicate entries */
357 for (i = 0; i < tape_count - 1; i++) {
358 for (j = i + 1; j < tape_count; j++) {
359 if (strcmp(tape[i].device, tape[j].device))
360 continue;
361 tape[j].number = -1;
362 }
363 }
364
365 if (system_labeled) {
366 dname = DA_TAPE_NAME;
367 dtype = DA_TAPE_TYPE;
368 dclean = DA_DEFAULT_TAPE_CLEAN;
369 } else {
370 dname = "st";
371 dtype = "st";
372 dclean = TAPE_CLEAN;
373 }
374 for (i = 0; i < 8; i++) {
375 for (j = 0; j < tape_count; j++) {
376 if (tape[j].number != i)
377 continue;
378 if (do_files) {
379 (void) da_add_list(&devlist, tape[j].name, i,
380 DA_TAPE);
381 } else if (do_devalloc) {
382 /* print device_allocate for tape devices */
383 if (system_labeled) {
384 (void) printf("%s%d%s\\\n",
385 dname, i, KV_DELIMITER);
386 (void) printf("\t%s%s\\\n",
387 DA_TAPE_TYPE, KV_DELIMITER);
388 (void) printf("\t%s%s\\\n",
389 DA_RESERVED, KV_DELIMITER);
390 (void) printf("\t%s%s\\\n",
391 DA_RESERVED, KV_DELIMITER);
392 (void) printf("\t%s%s\\\n",
393 DEFAULT_DEV_ALLOC_AUTH,
394 KV_DELIMITER);
395 (void) printf("\t%s\n\n", dclean);
396 } else {
397 (void) printf(
398 "st%d;st;reserved;reserved;%s;",
399 i, DEFAULT_DEV_ALLOC_AUTH);
400 (void) printf("%s%s\n", SECLIB,
401 "/st_clean");
402 }
403 break;
404 } else if (do_devmaps) {
405 /* print device_maps for tape devices */
406 if (first) {
407 (void) printf(" ");
408 } else {
409 if (system_labeled) {
410 (void) printf("%s%d%s\\\n",
411 dname, i, KV_TOKEN_DELIMIT);
412 (void) printf("\t%s%s\\\n",
413 dtype, KV_TOKEN_DELIMIT);
414 (void) printf("\t");
415 } else {
416 (void) printf("st%d:\\\n", i);
417 (void) printf("\trmt:\\\n");
418 (void) printf("\t");
419 }
420 first++;
421 }
422 (void) printf("%s", tape[j].name);
423 }
424 }
425 if (do_devmaps && first) {
426 (void) printf("\n\n");
427 first = 0;
428 }
429 }
430 if (do_files && tape_count) {
431 dargs.rootdir = NULL;
432 dargs.devnames = NULL;
433 dargs.optflag = DA_ADD;
434 for (entry = devlist.tape; entry != NULL; entry = entry->next) {
435 dargs.devinfo = &(entry->devinfo);
436 (void) da_update_device(&dargs);
437 }
438 }
439 }
440
441 static void
doaudio()442 doaudio()
443 {
444 DIR *dirp;
445 struct dirent *dep; /* directory entry pointer */
446 int i, j;
447 char *nm; /* name/device of special device */
448 char linkvalue[2048]; /* symlink value */
449 struct stat stat; /* determine if it's a symlink */
450 int sz; /* size of symlink value */
451 char *cp; /* pointer into string */
452 int naudio; /* max array size */
453 int audio_count = 0;
454 int len, slen;
455 int first = 0;
456 char dname[128];
457 char *dclean;
458 da_args dargs;
459 deventry_t *entry;
460
461 naudio = DFLT_NAUDIO;
462
463 if ((dirp = opendir("/dev")) == NULL) {
464 perror(gettext("open /dev failure"));
465 exit(1);
466 }
467
468 i = 0;
469 while (dep = readdir(dirp)) {
470 if (strcmp(dep->d_name, "audio") &&
471 strcmp(dep->d_name, "audioctl"))
472 continue;
473
474 /* if array full, then expand it */
475 if (i == naudio) {
476 /* will exit(1) if insufficient memory */
477 naudio = expandmem(i, (void **)&audio,
478 sizeof (struct audio));
479 }
480
481 /* save name (/dev + 1 + d_name + \0) */
482 nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
483 if (nm == NULL)
484 no_memory();
485 (void) strcpy(nm, "/dev/");
486 (void) strcat(nm, dep->d_name);
487 audio[i].name = nm;
488
489 /* ignore if not symbolic link (note i not incremented) */
490 if (lstat(audio[i].name, &stat) < 0) {
491 perror(gettext("stat(2) failed "));
492 exit(1);
493 }
494 if ((stat.st_mode & S_IFMT) != S_IFLNK)
495 continue;
496
497 /* get name from symbolic link */
498 if ((sz = readlink(audio[i].name, linkvalue,
499 sizeof (linkvalue))) < 0)
500 continue;
501 nm = (char *)malloc(sz + 1);
502 if (nm == NULL)
503 no_memory();
504 (void) strncpy(nm, linkvalue, sz);
505 nm[sz] = '\0';
506 audio[i].device = nm;
507
508 cp = strrchr(audio[i].device, '/');
509 cp++; /* advance to device # */
510 (void) sscanf(cp, "%d", &audio[i].number);
511
512 i++;
513 }
514
515 (void) closedir(dirp);
516
517 if ((dirp = opendir("/dev/sound")) == NULL) {
518 goto skip;
519 }
520
521 while (dep = readdir(dirp)) {
522 /* skip . .. etc... */
523 if (strncmp(dep->d_name, ".", 1) == 0)
524 continue;
525
526 /* if array full, then expand it */
527 if (i == naudio) {
528 /* will exit(1) if insufficient memory */
529 naudio = expandmem(i, (void **)&audio,
530 sizeof (struct audio));
531 }
532
533 /* save name (/dev/sound + / + d_name + \0) */
534 nm = (char *)malloc(SIZE_OF_SOUND + 1 +
535 strlen(dep->d_name) + 1);
536 if (nm == NULL)
537 no_memory();
538 (void) strcpy(nm, "/dev/sound/");
539 (void) strcat(nm, dep->d_name);
540 audio[i].name = nm;
541
542 nm = (char *)malloc(SIZE_OF_SOUND + 1 +
543 strlen(dep->d_name) + 1);
544 if (nm == NULL)
545 no_memory();
546 (void) strcpy(nm, "/dev/sound/");
547 (void) strcat(nm, dep->d_name);
548 audio[i].device = nm;
549
550 (void) sscanf(dep->d_name, "%d", &audio[i].number);
551
552 i++;
553 }
554
555 (void) closedir(dirp);
556
557 skip:
558 audio_count = i;
559
560 /* remove duplicate entries */
561 for (i = 0; i < audio_count - 1; i++) {
562 for (j = i + 1; j < audio_count; j++) {
563 if (strcmp(audio[i].device, audio[j].device))
564 continue;
565 audio[j].number = -1;
566 }
567 }
568
569 /* print out device_allocate entries for audio devices */
570 (void) strcpy(dname, DA_AUDIO_NAME);
571 slen = strlen(DA_AUDIO_NAME);
572 len = sizeof (dname) - slen;
573 dclean = system_labeled ? DA_DEFAULT_AUDIO_CLEAN : AUDIO_CLEAN;
574 for (i = 0; i < 8; i++) {
575 for (j = 0; j < audio_count; j++) {
576 if (audio[j].number != i)
577 continue;
578 if (system_labeled)
579 (void) snprintf(dname+slen, len, "%d", i);
580 if (do_files) {
581 (void) da_add_list(&devlist, audio[j].name,
582 i, DA_AUDIO);
583 } else if (do_devalloc) {
584 /* print device_allocate for audio devices */
585 if (system_labeled) {
586 (void) printf("%s%s\\\n",
587 dname, KV_DELIMITER);
588 (void) printf("\t%s%s\\\n",
589 DA_AUDIO_TYPE, KV_DELIMITER);
590 (void) printf("\t%s%s\\\n",
591 DA_RESERVED, KV_DELIMITER);
592 (void) printf("\t%s%s\\\n",
593 DA_RESERVED, KV_DELIMITER);
594 (void) printf("\t%s%s\\\n",
595 DEFAULT_DEV_ALLOC_AUTH,
596 KV_DELIMITER);
597 (void) printf("\t%s\n\n", dclean);
598 } else {
599 (void) printf("audio;audio;");
600 (void) printf("reserved;reserved;%s;",
601 DEFAULT_DEV_ALLOC_AUTH);
602 (void) printf("%s%s\n", SECLIB,
603 "/audio_clean");
604 }
605 break;
606 } else if (do_devmaps) {
607 /* print device_maps for audio devices */
608 if (first) {
609 (void) printf(" ");
610 } else {
611 if (system_labeled) {
612 (void) printf("%s%s\\\n",
613 dname, KV_TOKEN_DELIMIT);
614 (void) printf("\t%s%s\\\n",
615 DA_AUDIO_TYPE,
616 KV_TOKEN_DELIMIT);
617 (void) printf("\t");
618 } else {
619 (void) printf("audio:\\\n");
620 (void) printf("\taudio:\\\n");
621 (void) printf("\t");
622 }
623 first++;
624 }
625 (void) printf("%s", audio[j].name);
626 }
627 }
628 if (do_devmaps && first) {
629 (void) printf("\n\n");
630 first = 0;
631 }
632 }
633 if (do_files && audio_count) {
634 dargs.rootdir = NULL;
635 dargs.devnames = NULL;
636 dargs.optflag = DA_ADD;
637 for (entry = devlist.audio; entry != NULL;
638 entry = entry->next) {
639 dargs.devinfo = &(entry->devinfo);
640 (void) da_update_device(&dargs);
641 }
642 }
643 }
644
645 static void
dofloppy()646 dofloppy()
647 {
648 DIR *dirp;
649 struct dirent *dep; /* directory entry pointer */
650 int i, j;
651 char *nm; /* name/device of special device */
652 char linkvalue[2048]; /* symlink value */
653 struct stat stat; /* determine if it's a symlink */
654 int sz; /* size of symlink value */
655 char *cp; /* pointer into string */
656 int nfp; /* max array size */
657 int floppy_count = 0;
658 int first = 0;
659 char *dname, *dclean;
660 da_args dargs;
661 deventry_t *entry;
662
663 nfp = DFLT_NFP;
664
665 /*
666 * look for fd* and rfd*
667 */
668
669 if ((dirp = opendir("/dev")) == NULL) {
670 perror(gettext("open /dev failure"));
671 exit(1);
672 }
673
674 i = 0;
675 while (dep = readdir(dirp)) {
676 /* ignore if neither rst* nor nrst* */
677 if (strncmp(dep->d_name, "fd0", SIZE_OF_FD0) &&
678 strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0) &&
679 strncmp(dep->d_name, "fd1", SIZE_OF_FD0) &&
680 strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0))
681 continue;
682
683 /* if array full, then expand it */
684 if (i == nfp) {
685 /* will exit(1) if insufficient memory */
686 nfp = expandmem(i, (void **)&fp, sizeof (struct fp));
687 }
688
689 /* save name (/dev + 1 + d_name + \0) */
690 nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
691 if (nm == NULL)
692 no_memory();
693 (void) strcpy(nm, "/dev/");
694 (void) strcat(nm, dep->d_name);
695 fp[i].name = nm;
696
697 /* ignore if not symbolic link (note i not incremented) */
698 if (lstat(fp[i].name, &stat) < 0) {
699 perror(gettext("stat(2) failed "));
700 exit(1);
701 }
702 if ((stat.st_mode&S_IFMT) != S_IFLNK)
703 continue;
704
705 /* get name from symbolic link */
706 if ((sz = readlink(fp[i].name, linkvalue,
707 sizeof (linkvalue))) < 0)
708 continue;
709 nm = (char *)malloc(sz+1);
710 if (nm == NULL)
711 no_memory();
712 (void) strncpy(nm, linkvalue, sz);
713 nm[sz] = '\0';
714 fp[i].device = nm;
715
716 /* get device number */
717 cp = strchr(fp[i].name, 'd');
718 cp++; /* advance to device # */
719 cp = strchr(cp, 'd');
720 cp++; /* advance to device # */
721 (void) sscanf(cp, "%d", &fp[i].number);
722
723 i++;
724 }
725
726 (void) closedir(dirp);
727
728 floppy_count = i;
729
730 /* print out device_allocate entries for floppy devices */
731 if (system_labeled) {
732 dname = DA_FLOPPY_NAME;
733 dclean = DA_DEFAULT_DISK_CLEAN;
734 } else {
735 dname = "fd";
736 dclean = FLOPPY_CLEAN;
737 }
738 for (i = 0; i < 8; i++) {
739 for (j = 0; j < floppy_count; j++) {
740 if (fp[j].number != i)
741 continue;
742 if (do_files) {
743 (void) da_add_list(&devlist, fp[j].name, i,
744 DA_FLOPPY);
745 } else if (do_devalloc) {
746 /* print device_allocate for floppy devices */
747 if (system_labeled) {
748 (void) printf("%s%d%s\\\n",
749 dname, i, KV_DELIMITER);
750 (void) printf("\t%s%s\\\n",
751 DA_FLOPPY_TYPE, KV_DELIMITER);
752 (void) printf("\t%s%s\\\n",
753 DA_RESERVED, KV_DELIMITER);
754 (void) printf("\t%s%s\\\n",
755 DA_RESERVED, KV_DELIMITER);
756 (void) printf("\t%s%s\\\n",
757 DEFAULT_DEV_ALLOC_AUTH,
758 KV_DELIMITER);
759 (void) printf("\t%s\n\n", dclean);
760 } else {
761 (void) printf(
762 "fd%d;fd;reserved;reserved;%s;",
763 i, DEFAULT_DEV_ALLOC_AUTH);
764 (void) printf("%s%s\n", SECLIB,
765 "/fd_clean");
766 }
767 break;
768 } else if (do_devmaps) {
769 /* print device_maps for floppy devices */
770 if (first) {
771 (void) printf(" ");
772 } else {
773 if (system_labeled) {
774 (void) printf("%s%d%s\\\n",
775 dname, i, KV_TOKEN_DELIMIT);
776 (void) printf("\t%s%s\\\n",
777 DA_FLOPPY_TYPE,
778 KV_TOKEN_DELIMIT);
779 (void) printf("\t");
780 } else {
781 (void) printf("fd%d:\\\n", i);
782 (void) printf("\tfd:\\\n");
783 (void) printf("\t");
784 }
785 if (i == 0) {
786 (void) printf("/dev/diskette ");
787 (void) printf(
788 "/dev/rdiskette ");
789 }
790 first++;
791 }
792 (void) printf("%s", fp[j].name);
793 }
794 }
795 if (do_devmaps && first) {
796 (void) printf("\n\n");
797 first = 0;
798 }
799 }
800 if (do_files && floppy_count) {
801 dargs.rootdir = NULL;
802 dargs.devnames = NULL;
803 dargs.optflag = DA_ADD;
804 for (entry = devlist.floppy; entry != NULL;
805 entry = entry->next) {
806 dargs.devinfo = &(entry->devinfo);
807 (void) da_update_device(&dargs);
808 }
809 }
810 }
811
812 static int
docd()813 docd()
814 {
815 DIR *dirp;
816 struct dirent *dep; /* directory entry pointer */
817 int i, j;
818 char *nm; /* name/device of special device */
819 char linkvalue[2048]; /* symlink value */
820 struct stat stat; /* determine if it's a symlink */
821 int sz; /* size of symlink value */
822 char *cp; /* pointer into string */
823 int id; /* disk id */
824 int ctrl; /* disk controller */
825 int ncd; /* max array size */
826 int cd_count = 0;
827 int first = 0;
828 char *dname, *dclean;
829 da_args dargs;
830 deventry_t *entry;
831
832 ncd = DFLT_NCD;
833
834 /*
835 * look for sr* and rsr*
836 */
837
838 if ((dirp = opendir("/dev")) == NULL) {
839 perror(gettext("open /dev failure"));
840 exit(1);
841 }
842
843 i = 0;
844 while (dep = readdir(dirp)) {
845 /* ignore if neither sr* nor rsr* */
846 if (strncmp(dep->d_name, "sr", SIZE_OF_SR) &&
847 strncmp(dep->d_name, "rsr", SIZE_OF_RSR))
848 continue;
849
850 /* if array full, then expand it */
851 if (i == ncd) {
852 /* will exit(1) if insufficient memory */
853 ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
854 }
855
856 /* save name (/dev + / + d_name + \0) */
857 nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
858 if (nm == NULL)
859 no_memory();
860 (void) strcpy(nm, "/dev/");
861 (void) strcat(nm, dep->d_name);
862 cd[i].name = nm;
863
864 /* ignore if not symbolic link (note i not incremented) */
865 if (lstat(cd[i].name, &stat) < 0) {
866 perror(gettext("stat(2) failed "));
867 exit(1);
868 }
869 if ((stat.st_mode & S_IFMT) != S_IFLNK)
870 continue;
871
872 /* get name from symbolic link */
873 if ((sz = readlink(cd[i].name, linkvalue, sizeof (linkvalue))) <
874 0)
875 continue;
876
877 nm = (char *)malloc(sz + 1);
878 if (nm == NULL)
879 no_memory();
880 (void) strncpy(nm, linkvalue, sz);
881 nm[sz] = '\0';
882 cd[i].device = nm;
883
884 cp = strrchr(cd[i].device, '/');
885 cp++; /* advance to device # */
886 (void) sscanf(cp, "c%dt%d", &cd[i].controller, &cd[i].number);
887 cd[i].id = cd[i].number;
888
889 i++;
890 }
891 cd_count = i;
892
893 (void) closedir(dirp);
894
895 /*
896 * scan /dev/dsk for cd devices
897 */
898
899 if ((dirp = opendir("/dev/dsk")) == NULL) {
900 perror("gettext(open /dev/dsk failure)");
901 exit(1);
902 }
903
904 while (dep = readdir(dirp)) {
905 /* skip . .. etc... */
906 if (strncmp(dep->d_name, ".", 1) == 0)
907 continue;
908
909 /* get device # (disk #) */
910 if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2)
911 continue;
912
913 /* see if this is one of the cd special devices */
914 for (j = 0; j < cd_count; j++) {
915 if (cd[j].number == id && cd[j].controller == ctrl)
916 goto found;
917 }
918 continue;
919
920 /* add new entry to table (/dev/dsk + / + d_name + \0) */
921 found:
922 /* if array full, then expand it */
923 if (i == ncd) {
924 /* will exit(1) if insufficient memory */
925 ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
926 }
927
928 nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1);
929 if (nm == NULL)
930 no_memory();
931 (void) strcpy(nm, "/dev/dsk/");
932 (void) strcat(nm, dep->d_name);
933 cd[i].name = nm;
934
935 cd[i].id = cd[j].id;
936
937 cd[i].device = "";
938
939 cd[i].number = id;
940
941 i++;
942 }
943
944 (void) closedir(dirp);
945
946 /*
947 * scan /dev/rdsk for cd devices
948 */
949
950 if ((dirp = opendir("/dev/rdsk")) == NULL) {
951 perror(gettext("open /dev/dsk failure"));
952 exit(1);
953 }
954
955 while (dep = readdir(dirp)) {
956 /* skip . .. etc... */
957 if (strncmp(dep->d_name, ".", 1) == 0)
958 continue;
959
960 /* get device # (disk #) */
961 if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2)
962 continue;
963
964 /* see if this is one of the cd special devices */
965 for (j = 0; j < cd_count; j++) {
966 if (cd[j].number == id && cd[j].controller == ctrl)
967 goto found1;
968 }
969 continue;
970
971 /* add new entry to table (/dev/rdsk + / + d_name + \0) */
972 found1:
973 /* if array full, then expand it */
974 if (i == ncd) {
975 /* will exit(1) if insufficient memory */
976 ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
977 }
978
979 nm = (char *)malloc(SIZE_OF_RDSK + 1 + strlen(dep->d_name) + 1);
980 if (nm == NULL)
981 no_memory();
982 (void) strcpy(nm, "/dev/rdsk/");
983 (void) strcat(nm, dep->d_name);
984 cd[i].name = nm;
985
986 cd[i].id = cd[j].id;
987
988 cd[i].device = "";
989
990 cd[i].number = id;
991
992 cd[i].controller = ctrl;
993
994 i++;
995 }
996
997 (void) closedir(dirp);
998
999 cd_count = i;
1000
1001 if (system_labeled) {
1002 dname = DA_CD_NAME;
1003 dclean = DA_DEFAULT_DISK_CLEAN;
1004 } else {
1005 dname = "sr";
1006 dclean = CD_CLEAN;
1007 }
1008 for (i = 0; i < 8; i++) {
1009 for (j = 0; j < cd_count; j++) {
1010 if (cd[j].id != i)
1011 continue;
1012 if (do_files) {
1013 (void) da_add_list(&devlist, cd[j].name, i,
1014 DA_CD);
1015 } else if (do_devalloc) {
1016 /* print device_allocate for cd devices */
1017 if (system_labeled) {
1018 (void) printf("%s%d%s\\\n",
1019 dname, i, KV_DELIMITER);
1020 (void) printf("\t%s%s\\\n",
1021 DA_CD_TYPE, KV_DELIMITER);
1022 (void) printf("\t%s%s\\\n",
1023 DA_RESERVED, KV_DELIMITER);
1024 (void) printf("\t%s%s\\\n",
1025 DA_RESERVED, KV_DELIMITER);
1026 (void) printf("\t%s%s\\\n",
1027 DEFAULT_DEV_ALLOC_AUTH,
1028 KV_DELIMITER);
1029 (void) printf("\t%s\n\n", dclean);
1030 } else {
1031 (void) printf(
1032 "sr%d;sr;reserved;reserved;%s;",
1033 i, DEFAULT_DEV_ALLOC_AUTH);
1034 (void) printf("%s%s\n", SECLIB,
1035 "/sr_clean");
1036 }
1037 break;
1038 } else if (do_devmaps) {
1039 /* print device_maps for cd devices */
1040 if (first) {
1041 (void) printf(" ");
1042 } else {
1043 if (system_labeled) {
1044 (void) printf("%s%d%s\\\n",
1045 dname, i, KV_TOKEN_DELIMIT);
1046 (void) printf("\t%s%s\\\n",
1047 DA_CD_TYPE,
1048 KV_TOKEN_DELIMIT);
1049 (void) printf("\t");
1050 } else {
1051 (void) printf("sr%d:\\\n", i);
1052 (void) printf("\tsr:\\\n");
1053 (void) printf("\t");
1054 }
1055 first++;
1056 }
1057 (void) printf("%s", cd[j].name);
1058 }
1059 }
1060 if (do_devmaps && first) {
1061 (void) printf("\n\n");
1062 first = 0;
1063 }
1064 }
1065 if (do_files && cd_count) {
1066 dargs.rootdir = NULL;
1067 dargs.devnames = NULL;
1068 dargs.optflag = DA_ADD;
1069 for (entry = devlist.cd; entry != NULL; entry = entry->next) {
1070 dargs.devinfo = &(entry->devinfo);
1071 (void) da_update_device(&dargs);
1072 }
1073 }
1074
1075 return (cd_count);
1076 }
1077
1078 static void
dormdisk(int cd_count)1079 dormdisk(int cd_count)
1080 {
1081 DIR *dirp;
1082 struct dirent *dep; /* directory entry pointer */
1083 int i, j;
1084 char *nm; /* name/device of special device */
1085 int id; /* disk id */
1086 int ctrl; /* disk controller */
1087 int nrmdisk; /* max array size */
1088 int fd = -1;
1089 int rmdisk_count;
1090 int first = 0;
1091 int is_cd;
1092 int checked;
1093 int removable;
1094 char path[MAXPATHLEN];
1095 da_args dargs;
1096 deventry_t *entry;
1097
1098 nrmdisk = DFLT_RMDISK;
1099 i = rmdisk_count = 0;
1100
1101 /*
1102 * scan /dev/dsk for rmdisk devices
1103 */
1104 if ((dirp = opendir("/dev/dsk")) == NULL) {
1105 perror("gettext(open /dev/dsk failure)");
1106 exit(1);
1107 }
1108
1109 while (dep = readdir(dirp)) {
1110 is_cd = 0;
1111 checked = 0;
1112 removable = 0;
1113 /* skip . .. etc... */
1114 if (strncmp(dep->d_name, ".", 1) == 0)
1115 continue;
1116
1117 /* get device # (disk #) */
1118 if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2)
1119 continue;
1120
1121 /* see if we've already examined this device */
1122 for (j = 0; j < i; j++) {
1123 if (id == rmdisk[j].id &&
1124 ctrl == rmdisk[j].controller &&
1125 (strcmp(dep->d_name, rmdisk[j].name) == 0)) {
1126 checked = 1;
1127 break;
1128 }
1129 if (id == rmdisk[j].id && ctrl != rmdisk[j].controller)
1130 /*
1131 * c2t0d0s0 is a different rmdisk than c3t0d0s0.
1132 */
1133 id = rmdisk[j].id + 1;
1134 }
1135 if (checked)
1136 continue;
1137
1138 /* ignore if this is a cd */
1139 for (j = 0; j < cd_count; j++) {
1140 if (id == cd[j].id && ctrl == cd[j].controller) {
1141 is_cd = 1;
1142 break;
1143 }
1144 }
1145 if (is_cd)
1146 continue;
1147
1148 /* see if device is removable */
1149 (void) snprintf(path, sizeof (path), "%s%s", "/dev/rdsk/",
1150 dep->d_name);
1151 if ((fd = open(path, O_RDONLY | O_NONBLOCK)) < 0)
1152 continue;
1153 (void) ioctl(fd, DKIOCREMOVABLE, &removable);
1154 (void) close(fd);
1155 if (removable == 0)
1156 continue;
1157
1158 /*
1159 * add new entry to table (/dev/dsk + / + d_name + \0)
1160 * if array full, then expand it
1161 */
1162 if (i == nrmdisk) {
1163 /* will exit(1) if insufficient memory */
1164 nrmdisk = expandmem(i, (void **)&rmdisk,
1165 sizeof (struct rmdisk));
1166 /* When we expand rmdisk, need to expand rmdisk_r */
1167 (void) expandmem(i, (void **)&rmdisk_r,
1168 sizeof (struct rmdisk));
1169 }
1170 nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1);
1171 if (nm == NULL)
1172 no_memory();
1173 (void) strcpy(nm, "/dev/dsk/");
1174 (void) strcat(nm, dep->d_name);
1175 rmdisk[i].name = nm;
1176 rmdisk[i].id = id;
1177 rmdisk[i].controller = ctrl;
1178 rmdisk[i].device = "";
1179 rmdisk[i].number = id;
1180 rmdisk_r[i].name = strdup(path);
1181 i++;
1182 }
1183
1184 rmdisk_count = i;
1185 (void) closedir(dirp);
1186
1187 for (i = 0, j = rmdisk_count; i < rmdisk_count; i++, j++) {
1188 if (j == nrmdisk) {
1189 /* will exit(1) if insufficient memory */
1190 nrmdisk = expandmem(j, (void **)&rmdisk,
1191 sizeof (struct rmdisk));
1192 }
1193 rmdisk[j].name = rmdisk_r[i].name;
1194 rmdisk[j].id = rmdisk[i].id;
1195 rmdisk[j].controller = rmdisk[i].controller;
1196 rmdisk[j].device = rmdisk[i].device;
1197 rmdisk[j].number = rmdisk[i].number;
1198 }
1199 rmdisk_count = j;
1200
1201 for (i = 0; i < 8; i++) {
1202 for (j = 0; j < rmdisk_count; j++) {
1203 if (rmdisk[j].id != i)
1204 continue;
1205 if (do_files) {
1206 (void) da_add_list(&devlist, rmdisk[j].name, i,
1207 DA_RMDISK);
1208 } else if (do_devalloc) {
1209 /* print device_allocate for rmdisk devices */
1210 (void) printf("%s%d%s\\\n",
1211 DA_RMDISK_NAME, i, KV_DELIMITER);
1212 (void) printf("\t%s%s\\\n",
1213 DA_RMDISK_TYPE, KV_DELIMITER);
1214 (void) printf("\t%s%s\\\n",
1215 DA_RESERVED, KV_DELIMITER);
1216 (void) printf("\t%s%s\\\n",
1217 DA_RESERVED, KV_DELIMITER);
1218 (void) printf("\t%s%s\\\n",
1219 DEFAULT_DEV_ALLOC_AUTH, KV_DELIMITER);
1220 (void) printf("\t%s\n", DA_DEFAULT_DISK_CLEAN);
1221 break;
1222 } else if (do_devmaps) {
1223 /* print device_maps for rmdisk devices */
1224 if (first) {
1225 (void) printf(" ");
1226 } else {
1227 (void) printf("%s%d%s\\\n",
1228 DA_RMDISK_NAME, i,
1229 KV_TOKEN_DELIMIT);
1230 (void) printf("\t%s%s\\\n",
1231 DA_RMDISK_TYPE, KV_TOKEN_DELIMIT);
1232 (void) printf("\t");
1233 first++;
1234 }
1235 (void) printf("%s", rmdisk[j].name);
1236 }
1237 }
1238 if (do_devmaps && first) {
1239 (void) printf("\n\n");
1240 first = 0;
1241 }
1242 }
1243 if (do_files && rmdisk_count) {
1244 dargs.rootdir = NULL;
1245 dargs.devnames = NULL;
1246 dargs.optflag = DA_ADD;
1247 for (entry = devlist.rmdisk; entry != NULL;
1248 entry = entry->next) {
1249 dargs.devinfo = &(entry->devinfo);
1250 (void) da_update_device(&dargs);
1251 }
1252 }
1253 }
1254
1255 /* set default array sizes */
1256 static void
initmem()1257 initmem()
1258 {
1259 tape = (struct tape *)calloc(DFLT_NTAPE, sizeof (struct tape));
1260 audio = (struct audio *)calloc(DFLT_NAUDIO, sizeof (struct audio));
1261 cd = (struct cd *)calloc(DFLT_NCD, sizeof (struct cd));
1262 fp = (struct fp *)calloc(DFLT_NFP, sizeof (struct fp));
1263 if (system_labeled) {
1264 rmdisk = (struct rmdisk *)calloc(DFLT_RMDISK,
1265 sizeof (struct rmdisk));
1266 if (rmdisk == NULL)
1267 no_memory();
1268 rmdisk_r = (struct rmdisk *)calloc(DFLT_RMDISK,
1269 sizeof (struct rmdisk));
1270 if (rmdisk_r == NULL)
1271 no_memory();
1272 }
1273
1274 if (tape == NULL || audio == NULL || cd == NULL || fp == NULL)
1275 no_memory();
1276
1277 devlist.audio = devlist.cd = devlist.floppy = devlist.rmdisk =
1278 devlist.tape = NULL;
1279 }
1280
1281 /* note n will be # elments in array (and could be 0) */
1282 static int
expandmem(int n,void ** array,int size)1283 expandmem(int n, void **array, int size)
1284 {
1285 void *old = *array;
1286 void *new;
1287
1288 /* get new array space (n + DELTA) */
1289 new = (void *)calloc(n + DELTA, size);
1290
1291 if (new == NULL) {
1292 perror("memory allocation failed");
1293 exit(1);
1294 }
1295
1296 /* copy old array into new space */
1297 bcopy(old, new, n * size);
1298
1299 /* now release old arrary */
1300 free(old);
1301
1302 *array = new;
1303
1304 return (n + DELTA);
1305 }
1306
1307 static void
no_memory(void)1308 no_memory(void)
1309 {
1310 (void) fprintf(stderr, "%s: %s\n", "mkdevalloc",
1311 gettext("out of memory"));
1312 exit(1);
1313 /* NOT REACHED */
1314 }
1315