1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
7 * Reserved.  This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License').  You may not use this file
10 * except in compliance with the License.  Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25 * Mach Operating System
26 * Copyright (c) 1990 Carnegie-Mellon University
27 * Copyright (c) 1989 Carnegie-Mellon University
28 * All rights reserved.  The CMU software License Agreement specifies
29 * the terms and conditions for use and redistribution.
30 */
31
32/*
33 * Copyright (c) 1980 Regents of the University of California.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms are permitted
37 * provided that the above copyright notice and this paragraph are
38 * duplicated in all such forms and that any documentation,
39 * advertising materials, and other materials related to such
40 * distribution and use acknowledge that the software was developed
41 * by the University of California, Berkeley.  The name of the
42 * University may not be used to endorse or promote products derived
43 * from this software without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
45 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
46 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
47 */
48
49#ifndef lint
50static char sccsid[] __attribute__((used)) = "@(#)mkswapconf.c	5.6 (Berkeley) 6/18/88";
51#endif /* not lint */
52
53/*
54 * Build a swap configuration file.
55 */
56#include "config.h"
57
58#include <stdio.h>
59#include <unistd.h>	/* for unlink */
60#include <ctype.h>
61
62struct file_list *do_swap(struct file_list *fl);
63void initdevtable(void);
64
65void
66swapconf(void)
67{
68	register struct file_list *fl;
69
70	fl = conf_list;
71	while (fl) {
72		if (fl->f_type != SYSTEMSPEC) {
73			fl = fl->f_next;
74			continue;
75		}
76		fl = do_swap(fl);
77	}
78}
79
80struct file_list *
81do_swap(struct file_list *fl)
82{
83	FILE *fp;
84	char  swapname[80];
85	register struct file_list *swap;
86	dev_t dev;
87
88	if (eq(fl->f_fn, "generic")) {
89		fl = fl->f_next;
90		return (fl->f_next);
91	}
92	if (machine == MACHINE_MMAX) {
93		printf("Error: Multimax must specify swap generic only.\n");
94		exit(1);
95	}
96	(void) sprintf(swapname, "swap%s.c", fl->f_fn);
97	fp = fopen(path(swapname), "w");
98	if (fp == 0) {
99		perror(path(swapname));
100		exit(1);
101	}
102	fprintf(fp, "#include <sys/param.h>\n");
103	fprintf(fp, "#include <sys/conf.h>\n");
104	fprintf(fp, "\n");
105	/*
106	 * If there aren't any swap devices
107	 * specified, just return, the error
108	 * has already been noted.
109	 */
110	swap = fl->f_next;
111	if (swap == 0 || swap->f_type != SWAPSPEC) {
112		(void) unlink(path(swapname));
113		fclose(fp);
114		return (swap);
115	}
116	fprintf(fp, "dev_t\trootdev = makedev(%d, %d);\n",
117		major(fl->f_rootdev), minor(fl->f_rootdev));
118	fprintf(fp, "dev_t\targdev  = makedev(%d, %d);\n",
119		major(fl->f_argdev), minor(fl->f_argdev));
120	fprintf(fp, "dev_t\tdumpdev = makedev(%d, %d);\n",
121		major(fl->f_dumpdev), minor(fl->f_dumpdev));
122	fprintf(fp, "\n");
123	fprintf(fp, "struct\tswdevt swdevt[] = {\n");
124	do {
125		dev = swap->f_swapdev;
126		fprintf(fp, "\t{ makedev(%d, %d),\t0,\t%d },\t/* %s */\n",
127		    major(dev), minor(dev), swap->f_swapsize, swap->f_fn);
128		swap = swap->f_next;
129	} while (swap && swap->f_type == SWAPSPEC);
130	fprintf(fp, "\t{ 0, 0, 0 }\n");
131	fprintf(fp, "};\n");
132	if (machine == MACHINE_MIPSY || machine == MACHINE_MIPS) {
133		fprintf(fp, "\nsetconf()\n");
134		fprintf(fp, "{\n");
135		fprintf(fp, "\t/* resolve reference for non-generic kernels */\n");
136		fprintf(fp, "}\n");
137	}
138	fclose(fp);
139	return (swap);
140}
141
142static	int devtablenotread = 1;
143static	struct devdescription {
144	char	*dev_name;
145	int	dev_major;
146	struct	devdescription *dev_next;
147} *devtable;
148
149/*
150 * Given a device name specification figure out:
151 *	major device number
152 *	partition
153 *	device name
154 *	unit number
155 * This is a hack, but the system still thinks in
156 * terms of major/minor instead of string names.
157 */
158dev_t
159nametodev(char *name, int defunit, char defpartition)
160{
161	char *cp, partition;
162	int unit;
163	register struct devdescription *dp;
164
165	cp = name;
166	if (cp == 0) {
167		fprintf(stderr, "config: internal error, nametodev\n");
168		exit(1);
169	}
170	while (*cp && !isdigit(*cp))
171		cp++;
172	unit = *cp ? atoi(cp) : defunit;
173	if (unit < 0 || unit > 31) {
174		fprintf(stderr,
175"config: %s: invalid device specification, unit out of range\n", name);
176		unit = defunit;			/* carry on more checking */
177	}
178	if (*cp) {
179		*cp++ = '\0';
180		while (*cp && isdigit(*cp))
181			cp++;
182	}
183	partition = *cp ? *cp : defpartition;
184	if (partition < 'a' || partition > 'h') {
185		fprintf(stderr,
186"config: %c: invalid device specification, bad partition\n", *cp);
187		partition = defpartition;	/* carry on */
188	}
189	if (devtablenotread)
190		initdevtable();
191	for (dp = devtable; dp->dev_next; dp = dp->dev_next)
192		if (eq(name, dp->dev_name))
193			break;
194	if (dp == 0) {
195		fprintf(stderr, "config: %s: unknown device\n", name);
196		return (NODEV);
197	}
198	return (makedev(dp->dev_major, (unit << DEV_SHIFT) + (partition - 'a')));
199}
200
201char *
202devtoname(dev_t dev)
203{
204	char buf[80];
205	register struct devdescription *dp;
206
207	if (devtablenotread)
208		initdevtable();
209	for (dp = devtable; dp->dev_next; dp = dp->dev_next)
210		if (major(dev) == dp->dev_major)
211			break;
212	if (dp == 0)
213		dp = devtable;
214	(void) sprintf(buf, "%s%d%c", dp->dev_name,
215		minor(dev) >> DEV_SHIFT, (minor(dev) & DEV_MASK) + 'a');
216	return (ns(buf));
217}
218
219void
220initdevtable(void)
221{
222	char buf[BUFSIZ];
223	char line[BUFSIZ];
224	int maj;
225	register struct devdescription **dp = &devtable;
226	FILE *fp;
227
228	(void) sprintf(buf, "%s/devices.%s", config_directory, machinename);
229	fp = fopenp(VPATH, buf, line, "r");
230	if (fp == NULL) {
231		fprintf(stderr, "config: can't open %s\n", buf);
232		exit(1);
233	}
234	while (fgets(line, BUFSIZ, fp) != 0) {
235		if (*line == '#' || *line == '\n')
236			continue;
237		if (sscanf(line, "%s\t%d\n", buf, &maj) != 2)
238			break;
239		*dp = (struct devdescription *)malloc(sizeof (**dp));
240		(*dp)->dev_name = ns(buf);
241		(*dp)->dev_major = maj;
242		dp = &(*dp)->dev_next;
243	}
244	*dp = 0;
245	fclose(fp);
246	devtablenotread = 0;
247}
248