xref: /illumos-gate/usr/src/cmd/allocate/mkdevalloc.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 1992-2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * scan /dev directory for mountable objects and construct device_allocate
31  * file for allocate....
32  *
33  * devices are:
34  *	tape (cartridge)
35  *		/dev/rst*
36  *		/dev/nrst*
37  *		/dev/rmt/...
38  *	audio
39  *		/dev/audio
40  *		/dev/audioctl
41  *		/dev/sound/...
42  *	floppy
43  *		/dev/diskette
44  *		/dev/fd*
45  *		/dev/rdiskette
46  *		/dev/rfd*
47  *	CD
48  *		/dev/sr*
49  *		/dev/nsr*
50  *		/dev/dsk/c?t?d0s?
51  *		/dev/rdsk/c?t?d0s?
52  */
53 
54 #include <sys/types.h>	/* for stat(2), etc. */
55 #include <sys/stat.h>
56 #include <dirent.h>	/* for readdir(3), etc. */
57 #include <unistd.h>	/* for readlink(2) */
58 #include <string.h>	/* for strcpy(3), etc. */
59 #include <strings.h>	/* for bcopy(3C), etc. */
60 #include <stdio.h>	/* for perror(3) */
61 #include <stdlib.h>	/* for atoi(3) */
62 #include <locale.h>
63 #include <libintl.h>
64 #include <auth_attr.h>
65 #include <auth_list.h>
66 #include "allocate.h"   /* for SECLIB */
67 
68 #ifndef TEXT_DOMAIN
69 #define	TEXT_DOMAIN	"SUNW_OST_OSCMD"
70 #endif
71 
72 #define	DELTA	5	/* array size delta when full */
73 
74 /* "/dev/rst...", "/dev/nrst...", "/dev/rmt/..." */
75 struct tape {
76 	char	*name;
77 	char	*device;
78 	int	number;
79 } *tape;
80 #define	DFLT_NTAPE  10		/* size of initial array */
81 #define	SIZE_OF_RST  3		/* |rmt| */
82 #define	SIZE_OF_NRST 4		/* |nrmt| */
83 #define	SIZE_OF_TMP  4		/* |/tmp| */
84 #define	SIZE_OF_RMT  8		/* |/dev/rmt| */
85 
86 /* "/dev/audio", "/dev/audioctl", "/dev/sound/..." */
87 struct audio {
88 	char	*name;
89 	char	*device;
90 	int	number;
91 } *audio;
92 #define	DFLT_NAUDIO   10	/* size of initial array */
93 #define	SIZE_OF_SOUND 10	/* |/dev/sound| */
94 
95 /* "/dev/sr", "/dev/nsr", "/dev/dsk/c?t?d0s?", "/dev/rdsk/c?t?d0s?" */
96 struct cd {
97 	char	*name;
98 	char	*device;
99 	int	id;
100 	int	controller;
101 	int	number;
102 } *cd;
103 #define	DFLT_NCD    10		/* size of initial array */
104 #define	SIZE_OF_SR   2		/* |sr| */
105 #define	SIZE_OF_RSR  3		/* |rsr| */
106 #define	SIZE_OF_DSK  8		/* |/dev/dsk| */
107 #define	SIZE_OF_RDSK 9		/* |/dev/rdsk| */
108 
109 
110 /* "/dev/fd0*", "/dev/rfd0*", "/dev/fd1*", "/dev/rfd1*" */
111 struct fp {
112 	char *name;
113 	char *device;
114 	int number;
115 } *fp;
116 #define	DFLT_NFP    10		/* size of initial array */
117 #define	SIZE_OF_FD0  3		/* |fd0| */
118 #define	SIZE_OF_RFD0 4		/* |rfd0| */
119 
120 static void dotape();
121 static void doaudio();
122 static void dofloppy();
123 static void docd();
124 static void initmem();
125 static int  expandmem(int, void **, int);
126 static void no_memory(void);
127 
128 void
129 main()
130 {
131 	(void) setlocale(LC_ALL, "");
132 	(void) textdomain(TEXT_DOMAIN);
133 
134 	initmem();		/* initialize memory */
135 
136 	dotape();		/* do tape */
137 
138 	doaudio();		/* do audio */
139 
140 	dofloppy();		/* do floppy */
141 
142 	docd();			/* do cd */
143 }
144 
145 static void
146 dotape()
147 {
148 	DIR *dirp;
149 	struct dirent *dep;	/* directory entry pointer */
150 	int	i, j, n;
151 	char	*nm;		/* name/device of special device */
152 	char	linkvalue[2048];	/* symlink value */
153 	struct stat stat;	/* determine if it's a symlink */
154 	int	sz;		/* size of symlink value */
155 	char	*cp;		/* pointer into string */
156 	int	ntape;		/* max array size */
157 
158 	ntape = DFLT_NTAPE;
159 
160 	/*
161 	 * look for rst* and nrst*
162 	 */
163 
164 	if ((dirp = opendir("/dev")) == NULL) {
165 		perror(gettext("open /dev failure"));
166 		exit(1);
167 	}
168 
169 	i = 0;
170 	while (dep = readdir(dirp)) {
171 		/* ignore if neither rst* nor nrst* */
172 		if (strncmp(dep->d_name, "rst", SIZE_OF_RST) &&
173 		    strncmp(dep->d_name, "nrst", SIZE_OF_NRST))
174 			continue;
175 
176 		/* if array full, then expand it */
177 		if (i == ntape) {
178 			/* will exit(1) if insufficient memory */
179 			ntape = expandmem(i, (void **)&tape,
180 					sizeof (struct tape));
181 		}
182 
183 		/* save name (/dev + / + d_name + \0) */
184 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
185 		if (nm == NULL)
186 			no_memory();
187 		(void) strcpy(nm, "/dev/");
188 		(void) strcat(nm, dep->d_name);
189 		tape[i].name = nm;
190 
191 		/* ignore if not symbolic link (note i not incremented) */
192 		if (lstat(tape[i].name, &stat) < 0) {
193 			perror("stat(2) failed ");
194 			exit(1);
195 		}
196 		if ((stat.st_mode & S_IFMT) != S_IFLNK)
197 			continue;
198 
199 		/* get name from symbolic link */
200 		if ((sz = readlink(tape[i].name, linkvalue,
201 				sizeof (linkvalue))) < 0)
202 			continue;
203 		nm = (char *)malloc(sz + 1);
204 		if (nm == NULL)
205 			no_memory();
206 		(void) strncpy(nm, linkvalue, sz);
207 		nm[sz] = '\0';
208 		tape[i].device = nm;
209 
210 		/* get device number */
211 		cp = strrchr(tape[i].device, '/');
212 		cp++;				/* advance to device # */
213 		(void) sscanf(cp, "%d", &tape[i].number);
214 
215 		i++;
216 	}
217 
218 	(void) closedir(dirp);
219 
220 	/*
221 	 * scan /dev/rmt and add entry to table
222 	 */
223 
224 	if ((dirp = opendir("/dev/rmt")) == NULL) {
225 		perror(gettext("open /dev failure"));
226 		exit(1);
227 	}
228 
229 	while (dep = readdir(dirp)) {
230 		/* skip . .. etc... */
231 		if (strncmp(dep->d_name, ".", 1) == NULL)
232 			continue;
233 
234 		/* if array full, then expand it */
235 		if (i == ntape) {
236 			/* will exit(1) if insufficient memory */
237 			ntape = expandmem(i, (void **)&tape,
238 					sizeof (struct tape));
239 		}
240 
241 		/* save name (/dev/rmt + / + d_name + \0) */
242 		nm = (char *)malloc(SIZE_OF_RMT + 1 + strlen(dep->d_name) + 1);
243 		if (nm == NULL)
244 			no_memory();
245 		(void) strcpy(nm, "/dev/rmt/");
246 		(void) strcat(nm, dep->d_name);
247 		tape[i].name = nm;
248 
249 		/* save device name (rmt/ + d_name + \0) */
250 		nm = (char *)malloc(SIZE_OF_TMP + strlen(dep->d_name) + 1);
251 		if (nm == NULL)
252 			no_memory();
253 		(void) strcpy(nm, "rmt/");
254 		(void) strcat(nm, dep->d_name);
255 		tape[i].device = nm;
256 
257 		(void) sscanf(dep->d_name, "%d", &tape[i].number);
258 
259 		i++;
260 	}
261 	n = i;
262 
263 	(void) closedir(dirp);
264 
265 	/* remove duplicate entries */
266 	for (i = 0; i < n - 1; i++) {
267 		for (j = i + 1; j < n; j++) {
268 			if (strcmp(tape[i].device, tape[j].device))
269 				continue;
270 			tape[j].number = -1;
271 		}
272 	}
273 
274 	/* print out device_allocate entries for tape devices */
275 	for (i = 0; i < 8; i++) {
276 		for (j = 0; j < n; j++) {
277 			if (tape[j].number == i) {
278 				(void) printf(
279 					"st%d;st;reserved;reserved;%s;",
280 					i, DEFAULT_DEV_ALLOC_AUTH);
281 				(void) printf("%s%s\n", SECLIB, "/st_clean");
282 				break;
283 			}
284 		}
285 	}
286 }
287 
288 static void
289 doaudio()
290 {
291 	DIR *dirp;
292 	struct dirent *dep;	/* directory entry pointer */
293 	int	i, j, n;
294 	char	*nm;		/* name/device of special device */
295 	char	linkvalue[2048];	/* symlink value */
296 	struct stat stat;	/* determine if it's a symlink */
297 	int	sz;		/* size of symlink value */
298 	char	*cp;		/* pointer into string */
299 	int	naudio;		/* max array size */
300 
301 	naudio = DFLT_NAUDIO;
302 
303 	if ((dirp = opendir("/dev")) == NULL) {
304 		perror(gettext("open /dev failure"));
305 		exit(1);
306 	}
307 
308 	i = 0;
309 	while (dep = readdir(dirp)) {
310 		if (strcmp(dep->d_name, "audio") &&
311 		    strcmp(dep->d_name, "audioctl"))
312 			continue;
313 
314 		/* if array full, then expand it */
315 		if (i == naudio) {
316 			/* will exit(1) if insufficient memory */
317 			naudio = expandmem(i, (void **)&audio,
318 					sizeof (struct audio));
319 		}
320 
321 		/* save name (/dev + 1 + d_name + \0) */
322 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
323 		if (nm == NULL)
324 			no_memory();
325 		(void) strcpy(nm, "/dev/");
326 		(void) strcat(nm, dep->d_name);
327 		audio[i].name = nm;
328 
329 		/* ignore if not symbolic link (note i not incremented) */
330 		if (lstat(audio[i].name, &stat) < 0) {
331 			perror(gettext("stat(2) failed "));
332 			exit(1);
333 		}
334 		if ((stat.st_mode & S_IFMT) != S_IFLNK)
335 			continue;
336 
337 		/* get name from symbolic link */
338 		if ((sz = readlink(audio[i].name, linkvalue,
339 				sizeof (linkvalue))) < 0)
340 			continue;
341 		nm = (char *)malloc(sz + 1);
342 		if (nm == NULL)
343 			no_memory();
344 		(void) strncpy(nm, linkvalue, sz);
345 		nm[sz] = '\0';
346 		audio[i].device = nm;
347 
348 		cp = strrchr(audio[i].device, '/');
349 		cp++;				/* advance to device # */
350 		(void) sscanf(cp, "%d", &audio[i].number);
351 
352 		i++;
353 	}
354 
355 	(void) closedir(dirp);
356 
357 	if ((dirp = opendir("/dev/sound")) == NULL) {
358 		goto skip;
359 	}
360 
361 	while (dep = readdir(dirp)) {
362 		/* skip . .. etc... */
363 		if (strncmp(dep->d_name, ".", 1) == NULL)
364 			continue;
365 
366 		/* if array full, then expand it */
367 		if (i == naudio) {
368 			/* will exit(1) if insufficient memory */
369 			naudio = expandmem(i, (void **)&audio,
370 					sizeof (struct audio));
371 		}
372 
373 		/* save name (/dev/sound + / + d_name + \0) */
374 		nm = (char *)malloc(SIZE_OF_SOUND + 1 +
375 		    strlen(dep->d_name) + 1);
376 		if (nm == NULL)
377 			no_memory();
378 		(void) strcpy(nm, "/dev/sound/");
379 		(void) strcat(nm, dep->d_name);
380 		audio[i].name = nm;
381 
382 		nm = (char *)malloc(SIZE_OF_SOUND + 1 +
383 		    strlen(dep->d_name) + 1);
384 		if (nm == NULL)
385 			no_memory();
386 		(void) strcpy(nm, "/dev/sound/");
387 		(void) strcat(nm, dep->d_name);
388 		audio[i].device = nm;
389 
390 		(void) sscanf(dep->d_name, "%d", &audio[i].number);
391 
392 		i++;
393 	}
394 
395 	(void) closedir(dirp);
396 
397 skip:
398 	n = i;
399 
400 	/* remove duplicate entries */
401 	for (i = 0; i < n - 1; i++) {
402 		for (j = i + 1; j < n; j++) {
403 			if (strcmp(audio[i].device, audio[j].device))
404 				continue;
405 			audio[j].number = -1;
406 		}
407 	}
408 
409 	/* print out device_allocate entries for tape devices */
410 	for (i = 0; i < 8; i++) {
411 		for (j = 0; j < n; j++) {
412 			if (audio[j].number == i) {
413 				(void) printf("audio;audio;");
414 				(void) printf("reserved;reserved;%s;",
415 				    DEFAULT_DEV_ALLOC_AUTH);
416 				(void) printf("%s%s\n", SECLIB, "/audio_clean");
417 				break;
418 			}
419 		}
420 	}
421 }
422 
423 static void
424 dofloppy()
425 {
426 	DIR *dirp;
427 	struct dirent *dep;	/* directory entry pointer */
428 	int i, j, n;
429 	char *nm;		/* name/device of special device */
430 	char linkvalue[2048];	/* symlink value */
431 	struct stat stat;	/* determine if it's a symlink */
432 	int sz;			/* size of symlink value */
433 	char *cp;		/* pointer into string */
434 	int nfp;		/* max array size */
435 
436 	nfp = DFLT_NFP;
437 
438 	/*
439 	 * look for fd* and rfd*
440 	 */
441 
442 	if ((dirp = opendir("/dev")) == NULL) {
443 		perror(gettext("open /dev failure"));
444 		exit(1);
445 	}
446 
447 	i = 0;
448 	while (dep = readdir(dirp)) {
449 		/* ignore if neither rst* nor nrst* */
450 		if (strncmp(dep->d_name, "fd0", SIZE_OF_FD0) &&
451 		    strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0) &&
452 		    strncmp(dep->d_name, "fd1", SIZE_OF_FD0) &&
453 		    strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0))
454 			continue;
455 
456 		/* if array full, then expand it */
457 		if (i == nfp) {
458 			/* will exit(1) if insufficient memory */
459 			nfp = expandmem(i, (void **)&fp, sizeof (struct fp));
460 		}
461 
462 		/* save name (/dev + 1 + d_name + \0) */
463 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
464 		if (nm == NULL)
465 			no_memory();
466 		(void) strcpy(nm, "/dev/");
467 		(void) strcat(nm, dep->d_name);
468 		fp[i].name = nm;
469 
470 		/* ignore if not symbolic link (note i not incremented) */
471 		if (lstat(fp[i].name, &stat) < 0) {
472 			perror(gettext("stat(2) failed "));
473 			exit(1);
474 		}
475 		if ((stat.st_mode&S_IFMT) != S_IFLNK)
476 			continue;
477 
478 		/* get name from symbolic link */
479 		if ((sz = readlink(fp[i].name, linkvalue,
480 		    sizeof (linkvalue))) < 0)
481 			continue;
482 		nm = (char *)malloc(sz+1);
483 		if (nm == NULL)
484 			no_memory();
485 		(void) strncpy(nm, linkvalue, sz);
486 		nm[sz] = '\0';
487 		fp[i].device = nm;
488 
489 		/* get device number */
490 		cp = strchr(fp[i].name, 'd');
491 		cp++;				/* advance to device # */
492 		cp = strchr(cp, 'd');
493 		cp++;				/* advance to device # */
494 		(void) sscanf(cp, "%d", &fp[i].number);
495 
496 		i++;
497 	}
498 
499 	(void) closedir(dirp);
500 
501 	n = i;
502 
503 	/* print out device_allocate entries for tape devices */
504 	for (i = 0; i < 8; i++) {
505 	    for (j = 0; j < n; j++) {
506 		if (fp[j].number == i) {
507 		    (void) printf("fd%d;fd;reserved;reserved;%s;",
508 			i, DEFAULT_DEV_ALLOC_AUTH);
509 		    (void) printf("/etc/security/lib/fd_clean\n");
510 		    break;
511 		}
512 	    }
513 	}
514 }
515 
516 static void
517 docd()
518 {
519 	DIR *dirp;
520 	struct dirent *dep;	/* directory entry pointer */
521 	int	i, j, n;
522 	char	*nm;		/* name/device of special device */
523 	char	linkvalue[2048];	/* symlink value */
524 	struct stat stat;	/* determine if it's a symlink */
525 	int	sz;		/* size of symlink value */
526 	char	*cp;		/* pointer into string */
527 	int	id;		/* disk id */
528 	int	ctrl;		/* disk controller */
529 	int	ncd;		/* max array size */
530 
531 	ncd = DFLT_NCD;
532 
533 	/*
534 	 * look for sr* and rsr*
535 	 */
536 
537 	if ((dirp = opendir("/dev")) == NULL) {
538 		perror(gettext("open /dev failure"));
539 		exit(1);
540 	}
541 
542 	i = 0;
543 	while (dep = readdir(dirp)) {
544 		/* ignore if neither sr* nor rsr* */
545 		if (strncmp(dep->d_name, "sr", SIZE_OF_SR) &&
546 		    strncmp(dep->d_name, "rsr", SIZE_OF_RSR))
547 			continue;
548 
549 		/* if array full, then expand it */
550 		if (i == ncd) {
551 			/* will exit(1) if insufficient memory */
552 			ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
553 		}
554 
555 		/* save name (/dev + / + d_name + \0) */
556 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
557 		if (nm == NULL)
558 			no_memory();
559 		(void) strcpy(nm, "/dev/");
560 		(void) strcat(nm, dep->d_name);
561 		cd[i].name = nm;
562 
563 		/* save id # */
564 		if (dep->d_name[0] == 'r')
565 			(void) sscanf(dep->d_name, "rsr%d", &cd[i].id);
566 		else
567 			(void) sscanf(dep->d_name, "sr%d", &cd[i].id);
568 
569 		/* ignore if not symbolic link (note i not incremented) */
570 		if (lstat(cd[i].name, &stat) < 0) {
571 			perror(gettext("stat(2) failed "));
572 			exit(1);
573 		}
574 		if ((stat.st_mode & S_IFMT) != S_IFLNK)
575 			continue;
576 
577 		/* get name from symbolic link */
578 		if ((sz = readlink(cd[i].name, linkvalue, sizeof (linkvalue))) <
579 		    0)
580 			continue;
581 		nm = (char *)malloc(sz + 1);
582 		if (nm == NULL)
583 			no_memory();
584 		(void) strncpy(nm, linkvalue, sz);
585 		nm[sz] = '\0';
586 		cd[i].device = nm;
587 
588 		cp = strrchr(cd[i].device, '/');
589 		cp++;				/* advance to device # */
590 		(void) sscanf(cp, "c%dt%d", &cd[i].controller, &cd[i].number);
591 
592 		i++;
593 	}
594 	n = i;
595 
596 	(void) closedir(dirp);
597 
598 	/*
599 	 * scan /dev/dsk for cd devices
600 	 */
601 
602 	if ((dirp = opendir("/dev/dsk")) == NULL) {
603 		perror("gettext(open /dev/dsk failure)");
604 		exit(1);
605 	}
606 
607 	while (dep = readdir(dirp)) {
608 		/* skip . .. etc... */
609 		if (strncmp(dep->d_name, ".", 1) == NULL)
610 			continue;
611 
612 		/* get device # (disk #) */
613 		if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) <= 0)
614 			continue;
615 
616 		/* see if this is one of the cd special devices */
617 		for (j = 0; j < n; j++) {
618 			if (cd[j].number == id && cd[j].controller == ctrl)
619 				goto found;
620 		}
621 		continue;
622 
623 		/* add new entry to table (/dev/dsk + / + d_name + \0) */
624 found:
625 		/* if array full, then expand it */
626 		if (i == ncd) {
627 			/* will exit(1) if insufficient memory */
628 			ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
629 		}
630 
631 		nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1);
632 		if (nm == NULL)
633 			no_memory();
634 		(void) strcpy(nm, "/dev/dsk/");
635 		(void) strcat(nm, dep->d_name);
636 		cd[i].name = nm;
637 
638 		cd[i].id = cd[j].id;
639 
640 		cd[i].device = "";
641 
642 		cd[i].number = id;
643 
644 		i++;
645 	}
646 
647 	(void) closedir(dirp);
648 
649 	/*
650 	 * scan /dev/rdsk for cd devices
651 	 */
652 
653 	if ((dirp = opendir("/dev/rdsk")) == NULL) {
654 		perror(gettext("open /dev/dsk failure"));
655 		exit(1);
656 	}
657 
658 	while (dep = readdir(dirp)) {
659 		/* skip . .. etc... */
660 		if (strncmp(dep->d_name, ".", 1) == NULL)
661 			continue;
662 
663 		/* get device # (disk #) */
664 		if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2)
665 			continue;
666 
667 		/* see if this is one of the cd special devices */
668 		for (j = 0; j < n; j++) {
669 			if (cd[j].number == id && cd[j].controller == ctrl)
670 				goto found1;
671 		}
672 		continue;
673 
674 		/* add new entry to table (/dev/rdsk + / + d_name + \0) */
675 found1:
676 		/* if array full, then expand it */
677 		if (i == ncd) {
678 			/* will exit(1) if insufficient memory */
679 			ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
680 		}
681 
682 		nm = (char *)malloc(SIZE_OF_RDSK + 1 + strlen(dep->d_name) + 1);
683 		if (nm == NULL)
684 			no_memory();
685 		(void) strcpy(nm, "/dev/rdsk/");
686 		(void) strcat(nm, dep->d_name);
687 		cd[i].name = nm;
688 
689 		cd[i].id = cd[j].id;
690 
691 		cd[i].device = "";
692 
693 		cd[i].number = id;
694 
695 		cd[i].controller = ctrl;
696 
697 		i++;
698 	}
699 
700 	(void) closedir(dirp);
701 
702 	n = i;
703 
704 	/* print out device_maps entries for tape devices */
705 	for (i = 0; i < 8; i++) {
706 		for (j = 0; j < n; j++) {
707 			if (cd[j].id == i) {
708 				(void) printf(
709 					"sr%d;sr;reserved;reserved;%s;",
710 					i, DEFAULT_DEV_ALLOC_AUTH);
711 				(void) printf("%s%s\n", SECLIB, "/sr_clean");
712 				break;
713 			}
714 		}
715 	}
716 }
717 
718 /* set default array sizes */
719 static void
720 initmem()
721 {
722 	tape  = (struct tape *)calloc(DFLT_NTAPE, sizeof (struct tape));
723 	audio = (struct audio *)calloc(DFLT_NAUDIO, sizeof (struct audio));
724 	cd    = (struct cd *)calloc(DFLT_NCD, sizeof (struct cd));
725 	fp    = (struct fp *)calloc(DFLT_NFP, sizeof (struct fp));
726 
727 	if (tape == NULL || audio == NULL || cd == NULL || fp == NULL)
728 		no_memory();
729 }
730 
731 /* note n will be # elments in array (and could be 0) */
732 static int
733 expandmem(int n, void **array, int size)
734 {
735 	void *old = *array;
736 	void *new;
737 
738 	/* get new array space (n + DELTA) */
739 	new = (void *)calloc(n + DELTA,  size);
740 
741 	if (new == NULL) {
742 		perror("memory allocation failed");
743 		exit(1);
744 	}
745 
746 	/* copy old array into new space */
747 	bcopy(old, new, n * size);
748 
749 	/* now release old arrary */
750 	free(old);
751 
752 	*array = new;
753 
754 	return (n + DELTA);
755 }
756 
757 static void
758 no_memory(void)
759 {
760 	(void) fprintf(stderr, "%s: %s\n", "mkdevalloc",
761 	    gettext("out of memory"));
762 	exit(1);
763 	/* NOT REACHED */
764 }
765