xref: /illumos-gate/usr/src/cmd/allocate/mkdevalloc.c (revision 032624d56c174c5c55126582b32e314a6af15522)
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 2005 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 int
129 main(void)
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 	return (0);
145 }
146 
147 static void
148 dotape()
149 {
150 	DIR *dirp;
151 	struct dirent *dep;	/* directory entry pointer */
152 	int	i, j, n;
153 	char	*nm;		/* name/device of special device */
154 	char	linkvalue[2048];	/* symlink value */
155 	struct stat stat;	/* determine if it's a symlink */
156 	int	sz;		/* size of symlink value */
157 	char	*cp;		/* pointer into string */
158 	int	ntape;		/* max array size */
159 
160 	ntape = DFLT_NTAPE;
161 
162 	/*
163 	 * look for rst* and nrst*
164 	 */
165 
166 	if ((dirp = opendir("/dev")) == NULL) {
167 		perror(gettext("open /dev failure"));
168 		exit(1);
169 	}
170 
171 	i = 0;
172 	while (dep = readdir(dirp)) {
173 		/* ignore if neither rst* nor nrst* */
174 		if (strncmp(dep->d_name, "rst", SIZE_OF_RST) &&
175 		    strncmp(dep->d_name, "nrst", SIZE_OF_NRST))
176 			continue;
177 
178 		/* if array full, then expand it */
179 		if (i == ntape) {
180 			/* will exit(1) if insufficient memory */
181 			ntape = expandmem(i, (void **)&tape,
182 					sizeof (struct tape));
183 		}
184 
185 		/* save name (/dev + / + d_name + \0) */
186 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
187 		if (nm == NULL)
188 			no_memory();
189 		(void) strcpy(nm, "/dev/");
190 		(void) strcat(nm, dep->d_name);
191 		tape[i].name = nm;
192 
193 		/* ignore if not symbolic link (note i not incremented) */
194 		if (lstat(tape[i].name, &stat) < 0) {
195 			perror("stat(2) failed ");
196 			exit(1);
197 		}
198 		if ((stat.st_mode & S_IFMT) != S_IFLNK)
199 			continue;
200 
201 		/* get name from symbolic link */
202 		if ((sz = readlink(tape[i].name, linkvalue,
203 				sizeof (linkvalue))) < 0)
204 			continue;
205 		nm = (char *)malloc(sz + 1);
206 		if (nm == NULL)
207 			no_memory();
208 		(void) strncpy(nm, linkvalue, sz);
209 		nm[sz] = '\0';
210 		tape[i].device = nm;
211 
212 		/* get device number */
213 		cp = strrchr(tape[i].device, '/');
214 		cp++;				/* advance to device # */
215 		(void) sscanf(cp, "%d", &tape[i].number);
216 
217 		i++;
218 	}
219 
220 	(void) closedir(dirp);
221 
222 	/*
223 	 * scan /dev/rmt and add entry to table
224 	 */
225 
226 	if ((dirp = opendir("/dev/rmt")) == NULL) {
227 		perror(gettext("open /dev failure"));
228 		exit(1);
229 	}
230 
231 	while (dep = readdir(dirp)) {
232 		/* skip . .. etc... */
233 		if (strncmp(dep->d_name, ".", 1) == NULL)
234 			continue;
235 
236 		/* if array full, then expand it */
237 		if (i == ntape) {
238 			/* will exit(1) if insufficient memory */
239 			ntape = expandmem(i, (void **)&tape,
240 					sizeof (struct tape));
241 		}
242 
243 		/* save name (/dev/rmt + / + d_name + \0) */
244 		nm = (char *)malloc(SIZE_OF_RMT + 1 + strlen(dep->d_name) + 1);
245 		if (nm == NULL)
246 			no_memory();
247 		(void) strcpy(nm, "/dev/rmt/");
248 		(void) strcat(nm, dep->d_name);
249 		tape[i].name = nm;
250 
251 		/* save device name (rmt/ + d_name + \0) */
252 		nm = (char *)malloc(SIZE_OF_TMP + strlen(dep->d_name) + 1);
253 		if (nm == NULL)
254 			no_memory();
255 		(void) strcpy(nm, "rmt/");
256 		(void) strcat(nm, dep->d_name);
257 		tape[i].device = nm;
258 
259 		(void) sscanf(dep->d_name, "%d", &tape[i].number);
260 
261 		i++;
262 	}
263 	n = i;
264 
265 	(void) closedir(dirp);
266 
267 	/* remove duplicate entries */
268 	for (i = 0; i < n - 1; i++) {
269 		for (j = i + 1; j < n; j++) {
270 			if (strcmp(tape[i].device, tape[j].device))
271 				continue;
272 			tape[j].number = -1;
273 		}
274 	}
275 
276 	/* print out device_allocate entries for tape devices */
277 	for (i = 0; i < 8; i++) {
278 		for (j = 0; j < n; j++) {
279 			if (tape[j].number == i) {
280 				(void) printf(
281 					"st%d;st;reserved;reserved;%s;",
282 					i, DEFAULT_DEV_ALLOC_AUTH);
283 				(void) printf("%s%s\n", SECLIB, "/st_clean");
284 				break;
285 			}
286 		}
287 	}
288 }
289 
290 static void
291 doaudio()
292 {
293 	DIR *dirp;
294 	struct dirent *dep;	/* directory entry pointer */
295 	int	i, j, n;
296 	char	*nm;		/* name/device of special device */
297 	char	linkvalue[2048];	/* symlink value */
298 	struct stat stat;	/* determine if it's a symlink */
299 	int	sz;		/* size of symlink value */
300 	char	*cp;		/* pointer into string */
301 	int	naudio;		/* max array size */
302 
303 	naudio = DFLT_NAUDIO;
304 
305 	if ((dirp = opendir("/dev")) == NULL) {
306 		perror(gettext("open /dev failure"));
307 		exit(1);
308 	}
309 
310 	i = 0;
311 	while (dep = readdir(dirp)) {
312 		if (strcmp(dep->d_name, "audio") &&
313 		    strcmp(dep->d_name, "audioctl"))
314 			continue;
315 
316 		/* if array full, then expand it */
317 		if (i == naudio) {
318 			/* will exit(1) if insufficient memory */
319 			naudio = expandmem(i, (void **)&audio,
320 					sizeof (struct audio));
321 		}
322 
323 		/* save name (/dev + 1 + d_name + \0) */
324 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
325 		if (nm == NULL)
326 			no_memory();
327 		(void) strcpy(nm, "/dev/");
328 		(void) strcat(nm, dep->d_name);
329 		audio[i].name = nm;
330 
331 		/* ignore if not symbolic link (note i not incremented) */
332 		if (lstat(audio[i].name, &stat) < 0) {
333 			perror(gettext("stat(2) failed "));
334 			exit(1);
335 		}
336 		if ((stat.st_mode & S_IFMT) != S_IFLNK)
337 			continue;
338 
339 		/* get name from symbolic link */
340 		if ((sz = readlink(audio[i].name, linkvalue,
341 				sizeof (linkvalue))) < 0)
342 			continue;
343 		nm = (char *)malloc(sz + 1);
344 		if (nm == NULL)
345 			no_memory();
346 		(void) strncpy(nm, linkvalue, sz);
347 		nm[sz] = '\0';
348 		audio[i].device = nm;
349 
350 		cp = strrchr(audio[i].device, '/');
351 		cp++;				/* advance to device # */
352 		(void) sscanf(cp, "%d", &audio[i].number);
353 
354 		i++;
355 	}
356 
357 	(void) closedir(dirp);
358 
359 	if ((dirp = opendir("/dev/sound")) == NULL) {
360 		goto skip;
361 	}
362 
363 	while (dep = readdir(dirp)) {
364 		/* skip . .. etc... */
365 		if (strncmp(dep->d_name, ".", 1) == NULL)
366 			continue;
367 
368 		/* if array full, then expand it */
369 		if (i == naudio) {
370 			/* will exit(1) if insufficient memory */
371 			naudio = expandmem(i, (void **)&audio,
372 					sizeof (struct audio));
373 		}
374 
375 		/* save name (/dev/sound + / + d_name + \0) */
376 		nm = (char *)malloc(SIZE_OF_SOUND + 1 +
377 		    strlen(dep->d_name) + 1);
378 		if (nm == NULL)
379 			no_memory();
380 		(void) strcpy(nm, "/dev/sound/");
381 		(void) strcat(nm, dep->d_name);
382 		audio[i].name = nm;
383 
384 		nm = (char *)malloc(SIZE_OF_SOUND + 1 +
385 		    strlen(dep->d_name) + 1);
386 		if (nm == NULL)
387 			no_memory();
388 		(void) strcpy(nm, "/dev/sound/");
389 		(void) strcat(nm, dep->d_name);
390 		audio[i].device = nm;
391 
392 		(void) sscanf(dep->d_name, "%d", &audio[i].number);
393 
394 		i++;
395 	}
396 
397 	(void) closedir(dirp);
398 
399 skip:
400 	n = i;
401 
402 	/* remove duplicate entries */
403 	for (i = 0; i < n - 1; i++) {
404 		for (j = i + 1; j < n; j++) {
405 			if (strcmp(audio[i].device, audio[j].device))
406 				continue;
407 			audio[j].number = -1;
408 		}
409 	}
410 
411 	/* print out device_allocate entries for tape devices */
412 	for (i = 0; i < 8; i++) {
413 		for (j = 0; j < n; j++) {
414 			if (audio[j].number == i) {
415 				(void) printf("audio;audio;");
416 				(void) printf("reserved;reserved;%s;",
417 				    DEFAULT_DEV_ALLOC_AUTH);
418 				(void) printf("%s%s\n", SECLIB, "/audio_clean");
419 				break;
420 			}
421 		}
422 	}
423 }
424 
425 static void
426 dofloppy()
427 {
428 	DIR *dirp;
429 	struct dirent *dep;	/* directory entry pointer */
430 	int i, j, n;
431 	char *nm;		/* name/device of special device */
432 	char linkvalue[2048];	/* symlink value */
433 	struct stat stat;	/* determine if it's a symlink */
434 	int sz;			/* size of symlink value */
435 	char *cp;		/* pointer into string */
436 	int nfp;		/* max array size */
437 
438 	nfp = DFLT_NFP;
439 
440 	/*
441 	 * look for fd* and rfd*
442 	 */
443 
444 	if ((dirp = opendir("/dev")) == NULL) {
445 		perror(gettext("open /dev failure"));
446 		exit(1);
447 	}
448 
449 	i = 0;
450 	while (dep = readdir(dirp)) {
451 		/* ignore if neither rst* nor nrst* */
452 		if (strncmp(dep->d_name, "fd0", SIZE_OF_FD0) &&
453 		    strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0) &&
454 		    strncmp(dep->d_name, "fd1", SIZE_OF_FD0) &&
455 		    strncmp(dep->d_name, "rfd0", SIZE_OF_RFD0))
456 			continue;
457 
458 		/* if array full, then expand it */
459 		if (i == nfp) {
460 			/* will exit(1) if insufficient memory */
461 			nfp = expandmem(i, (void **)&fp, sizeof (struct fp));
462 		}
463 
464 		/* save name (/dev + 1 + d_name + \0) */
465 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
466 		if (nm == NULL)
467 			no_memory();
468 		(void) strcpy(nm, "/dev/");
469 		(void) strcat(nm, dep->d_name);
470 		fp[i].name = nm;
471 
472 		/* ignore if not symbolic link (note i not incremented) */
473 		if (lstat(fp[i].name, &stat) < 0) {
474 			perror(gettext("stat(2) failed "));
475 			exit(1);
476 		}
477 		if ((stat.st_mode&S_IFMT) != S_IFLNK)
478 			continue;
479 
480 		/* get name from symbolic link */
481 		if ((sz = readlink(fp[i].name, linkvalue,
482 		    sizeof (linkvalue))) < 0)
483 			continue;
484 		nm = (char *)malloc(sz+1);
485 		if (nm == NULL)
486 			no_memory();
487 		(void) strncpy(nm, linkvalue, sz);
488 		nm[sz] = '\0';
489 		fp[i].device = nm;
490 
491 		/* get device number */
492 		cp = strchr(fp[i].name, 'd');
493 		cp++;				/* advance to device # */
494 		cp = strchr(cp, 'd');
495 		cp++;				/* advance to device # */
496 		(void) sscanf(cp, "%d", &fp[i].number);
497 
498 		i++;
499 	}
500 
501 	(void) closedir(dirp);
502 
503 	n = i;
504 
505 	/* print out device_allocate entries for tape devices */
506 	for (i = 0; i < 8; i++) {
507 	    for (j = 0; j < n; j++) {
508 		if (fp[j].number == i) {
509 		    (void) printf("fd%d;fd;reserved;reserved;%s;",
510 			i, DEFAULT_DEV_ALLOC_AUTH);
511 		    (void) printf("/etc/security/lib/fd_clean\n");
512 		    break;
513 		}
514 	    }
515 	}
516 }
517 
518 static void
519 docd()
520 {
521 	DIR *dirp;
522 	struct dirent *dep;	/* directory entry pointer */
523 	int	i, j, n;
524 	char	*nm;		/* name/device of special device */
525 	char	linkvalue[2048];	/* symlink value */
526 	struct stat stat;	/* determine if it's a symlink */
527 	int	sz;		/* size of symlink value */
528 	char	*cp;		/* pointer into string */
529 	int	id;		/* disk id */
530 	int	ctrl;		/* disk controller */
531 	int	ncd;		/* max array size */
532 
533 	ncd = DFLT_NCD;
534 
535 	/*
536 	 * look for sr* and rsr*
537 	 */
538 
539 	if ((dirp = opendir("/dev")) == NULL) {
540 		perror(gettext("open /dev failure"));
541 		exit(1);
542 	}
543 
544 	i = 0;
545 	while (dep = readdir(dirp)) {
546 		/* ignore if neither sr* nor rsr* */
547 		if (strncmp(dep->d_name, "sr", SIZE_OF_SR) &&
548 		    strncmp(dep->d_name, "rsr", SIZE_OF_RSR))
549 			continue;
550 
551 		/* if array full, then expand it */
552 		if (i == ncd) {
553 			/* will exit(1) if insufficient memory */
554 			ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
555 		}
556 
557 		/* save name (/dev + / + d_name + \0) */
558 		nm = (char *)malloc(SIZE_OF_TMP + 1 + strlen(dep->d_name) + 1);
559 		if (nm == NULL)
560 			no_memory();
561 		(void) strcpy(nm, "/dev/");
562 		(void) strcat(nm, dep->d_name);
563 		cd[i].name = nm;
564 
565 		/* save id # */
566 		if (dep->d_name[0] == 'r')
567 			(void) sscanf(dep->d_name, "rsr%d", &cd[i].id);
568 		else
569 			(void) sscanf(dep->d_name, "sr%d", &cd[i].id);
570 
571 		/* ignore if not symbolic link (note i not incremented) */
572 		if (lstat(cd[i].name, &stat) < 0) {
573 			perror(gettext("stat(2) failed "));
574 			exit(1);
575 		}
576 		if ((stat.st_mode & S_IFMT) != S_IFLNK)
577 			continue;
578 
579 		/* get name from symbolic link */
580 		if ((sz = readlink(cd[i].name, linkvalue, sizeof (linkvalue))) <
581 		    0)
582 			continue;
583 		nm = (char *)malloc(sz + 1);
584 		if (nm == NULL)
585 			no_memory();
586 		(void) strncpy(nm, linkvalue, sz);
587 		nm[sz] = '\0';
588 		cd[i].device = nm;
589 
590 		cp = strrchr(cd[i].device, '/');
591 		cp++;				/* advance to device # */
592 		(void) sscanf(cp, "c%dt%d", &cd[i].controller, &cd[i].number);
593 
594 		i++;
595 	}
596 	n = i;
597 
598 	(void) closedir(dirp);
599 
600 	/*
601 	 * scan /dev/dsk for cd devices
602 	 */
603 
604 	if ((dirp = opendir("/dev/dsk")) == NULL) {
605 		perror("gettext(open /dev/dsk failure)");
606 		exit(1);
607 	}
608 
609 	while (dep = readdir(dirp)) {
610 		/* skip . .. etc... */
611 		if (strncmp(dep->d_name, ".", 1) == NULL)
612 			continue;
613 
614 		/* get device # (disk #) */
615 		if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) <= 0)
616 			continue;
617 
618 		/* see if this is one of the cd special devices */
619 		for (j = 0; j < n; j++) {
620 			if (cd[j].number == id && cd[j].controller == ctrl)
621 				goto found;
622 		}
623 		continue;
624 
625 		/* add new entry to table (/dev/dsk + / + d_name + \0) */
626 found:
627 		/* if array full, then expand it */
628 		if (i == ncd) {
629 			/* will exit(1) if insufficient memory */
630 			ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
631 		}
632 
633 		nm = (char *)malloc(SIZE_OF_DSK + 1 + strlen(dep->d_name) + 1);
634 		if (nm == NULL)
635 			no_memory();
636 		(void) strcpy(nm, "/dev/dsk/");
637 		(void) strcat(nm, dep->d_name);
638 		cd[i].name = nm;
639 
640 		cd[i].id = cd[j].id;
641 
642 		cd[i].device = "";
643 
644 		cd[i].number = id;
645 
646 		i++;
647 	}
648 
649 	(void) closedir(dirp);
650 
651 	/*
652 	 * scan /dev/rdsk for cd devices
653 	 */
654 
655 	if ((dirp = opendir("/dev/rdsk")) == NULL) {
656 		perror(gettext("open /dev/dsk failure"));
657 		exit(1);
658 	}
659 
660 	while (dep = readdir(dirp)) {
661 		/* skip . .. etc... */
662 		if (strncmp(dep->d_name, ".", 1) == NULL)
663 			continue;
664 
665 		/* get device # (disk #) */
666 		if (sscanf(dep->d_name, "c%dt%d", &ctrl, &id) != 2)
667 			continue;
668 
669 		/* see if this is one of the cd special devices */
670 		for (j = 0; j < n; j++) {
671 			if (cd[j].number == id && cd[j].controller == ctrl)
672 				goto found1;
673 		}
674 		continue;
675 
676 		/* add new entry to table (/dev/rdsk + / + d_name + \0) */
677 found1:
678 		/* if array full, then expand it */
679 		if (i == ncd) {
680 			/* will exit(1) if insufficient memory */
681 			ncd = expandmem(i, (void **)&cd, sizeof (struct cd));
682 		}
683 
684 		nm = (char *)malloc(SIZE_OF_RDSK + 1 + strlen(dep->d_name) + 1);
685 		if (nm == NULL)
686 			no_memory();
687 		(void) strcpy(nm, "/dev/rdsk/");
688 		(void) strcat(nm, dep->d_name);
689 		cd[i].name = nm;
690 
691 		cd[i].id = cd[j].id;
692 
693 		cd[i].device = "";
694 
695 		cd[i].number = id;
696 
697 		cd[i].controller = ctrl;
698 
699 		i++;
700 	}
701 
702 	(void) closedir(dirp);
703 
704 	n = i;
705 
706 	/* print out device_maps entries for tape devices */
707 	for (i = 0; i < 8; i++) {
708 		for (j = 0; j < n; j++) {
709 			if (cd[j].id == i) {
710 				(void) printf(
711 					"sr%d;sr;reserved;reserved;%s;",
712 					i, DEFAULT_DEV_ALLOC_AUTH);
713 				(void) printf("%s%s\n", SECLIB, "/sr_clean");
714 				break;
715 			}
716 		}
717 	}
718 }
719 
720 /* set default array sizes */
721 static void
722 initmem()
723 {
724 	tape  = (struct tape *)calloc(DFLT_NTAPE, sizeof (struct tape));
725 	audio = (struct audio *)calloc(DFLT_NAUDIO, sizeof (struct audio));
726 	cd    = (struct cd *)calloc(DFLT_NCD, sizeof (struct cd));
727 	fp    = (struct fp *)calloc(DFLT_NFP, sizeof (struct fp));
728 
729 	if (tape == NULL || audio == NULL || cd == NULL || fp == NULL)
730 		no_memory();
731 }
732 
733 /* note n will be # elments in array (and could be 0) */
734 static int
735 expandmem(int n, void **array, int size)
736 {
737 	void *old = *array;
738 	void *new;
739 
740 	/* get new array space (n + DELTA) */
741 	new = (void *)calloc(n + DELTA,  size);
742 
743 	if (new == NULL) {
744 		perror("memory allocation failed");
745 		exit(1);
746 	}
747 
748 	/* copy old array into new space */
749 	bcopy(old, new, n * size);
750 
751 	/* now release old arrary */
752 	free(old);
753 
754 	*array = new;
755 
756 	return (n + DELTA);
757 }
758 
759 static void
760 no_memory(void)
761 {
762 	(void) fprintf(stderr, "%s: %s\n", "mkdevalloc",
763 	    gettext("out of memory"));
764 	exit(1);
765 	/* NOT REACHED */
766 }
767