This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / usr.sbin / diskless_cfg / diskless_cfg.c
CommitLineData
491fc627
MR
1/*************************************************************************
2
3Diskless Configuration Program
4
5Based loosely on the 4.4BSD diskless setup code
6
7*************************************************************************/
8#include <stdio.h>
9#include <fcntl.h>
10#include <sys/stat.h>
11#include <netdb.h>
12
356efd09
MR
13#ifdef sun
14#include <rpc/types.h>
15#include <sys/errno.h>
16#include <nfs/nfs.h>
17#endif
18
491fc627
MR
19#ifdef i386 /* Native 386bsd system */
20#include <sys/param.h>
21#include <sys/socket.h>
22#include <sys/mount.h>
23#include <net/if.h>
24#include <nfs/nfsv2.h>
25#include <nfs/nfsdiskless.h>
26#else /* Other Host system */
27#include "diskless.h"
28#include "nfsdiskless.h"
29#endif
30
31#ifndef i386 /* Most other systems BIG ENDIAN */
32#define BIG_ENDIAN
33#endif
34
35struct nfs_diskless nfs_diskless;
36
37#define NFS_SOCKET 2049
38
39#define KW_HELP 0
40#define KW_INTERFACE 1
41#define KW_ROOTFS 2
42#define KW_SWAP 3
43#define KW_RSIZE 4
44#define KW_WSIZE 5
45#define KW_NETMASK 6
46#define KW_HOSTNAME 7
47#define KW_KERNEL 8
356efd09 48#define KW_GATEWAY 9
491fc627
MR
49
50struct {
51 char *name;
52 int keyval;
53} keywords[] = {
54 { "-intf", KW_INTERFACE },
55 { "-rootfs", KW_ROOTFS },
56 { "-swap", KW_SWAP },
57 { "-netmask", KW_NETMASK },
58 { "-rsize", KW_RSIZE },
59 { "-wsize", KW_WSIZE },
60 { "-hostname", KW_HOSTNAME },
356efd09 61 { "-gateway", KW_GATEWAY },
491fc627
MR
62 { NULL, KW_HELP }
63};
64
65char *hostname = "386bsd";
356efd09 66char *gateway = NULL;
491fc627
MR
67char cfg[64];
68char *rootpath = "/var/386bsd";
69char *swappath = "/var/swap/386bsd";
70char servername[256];
71int rsize = 8192;
72int wsize = 8192;
73
74main(argc, argv)
75 int argc; char *argv[];
76{
77 int fd,i,j,cmd;
78 unsigned int broadcast, netmask, myip;
79 struct hostent *hp;
80 struct stat statbuf;
81 char buf[1024];
82 char *p, *q;
83
84 netmask = 0;
85 bzero(&nfs_diskless, 0, sizeof(struct nfs_diskless));
86 strcpy(nfs_diskless.myif.ifra_name,"ed0");
87 nfs_diskless.myif.ifra_addr.sa_len = sizeof(struct sockaddr);
88 nfs_diskless.myif.ifra_addr.sa_family = AF_INET;
89 nfs_diskless.myif.ifra_broadaddr.sa_len = sizeof(struct sockaddr);
90 nfs_diskless.myif.ifra_broadaddr.sa_family = AF_INET;
91 nfs_diskless.myif.ifra_mask.sa_len = sizeof(struct sockaddr);
92 nfs_diskless.myif.ifra_mask.sa_family = AF_UNSPEC;
93 nfs_diskless.swap_args.sotype = i386order(SOCK_DGRAM);
94 nfs_diskless.swap_args.flags = i386order(NFSMNT_WSIZE | NFSMNT_RSIZE);
95 nfs_diskless.swap_args.timeo = i386order(10);
96 nfs_diskless.swap_args.retrans = i386order(100);
97 nfs_diskless.swap_saddr.sa_len = sizeof(struct sockaddr);
98 nfs_diskless.swap_saddr.sa_family = AF_INET;
99 nfs_diskless.root_args.sotype = i386order(SOCK_DGRAM);
100 nfs_diskless.root_args.flags = i386order(NFSMNT_WSIZE | NFSMNT_RSIZE);
101 nfs_diskless.root_args.timeo = i386order(10);
102 nfs_diskless.root_args.retrans = i386order(100);
103 nfs_diskless.root_saddr.sa_len = sizeof(struct sockaddr);
104 nfs_diskless.root_saddr.sa_family = AF_INET;
105
106 if (gethostname(servername, 256) < 0) {
107 fprintf(stderr,"%s: unable to get host server name\n",argv[0]);
108 exit(2);
109 }
110 if ((hp = gethostbyname(servername)) == NULL) {
111 fprintf(stderr,"%s: unable to get host address\n",argv[0]);
112 exit(2);
113 }
114 p = servername;
115 while (*p && (*p != '.')) p++;
116 *p = 0;
117 nfs_diskless.swap_saddr.sa_data[0] = nfs_diskless.root_saddr.sa_data[0]
118 = NFS_SOCKET >> 8;
119 nfs_diskless.swap_saddr.sa_data[1] = nfs_diskless.root_saddr.sa_data[1]
120 = NFS_SOCKET & 0x00FF;
121 bcopy(*hp->h_addr_list, &nfs_diskless.swap_saddr.sa_data[2], 4);
122 bcopy(*hp->h_addr_list, &nfs_diskless.root_saddr.sa_data[2], 4);
123
124 i = 1;
125 while (i < argc) {
126 cmd = KW_HELP;
127 for (j=0; keywords[j].name; j++) {
128 if (!strcmp(keywords[j].name, argv[i])) {
129 if ((i+1) < argc) {
130 cmd = keywords[j].keyval;
131 break;
132 }
133 }
134 }
135 switch(cmd) {
136 case KW_HELP:
137 help(argv[0], argv[i]);
138 exit(2);
139 case KW_INTERFACE:
140 if (strlen(argv[i+1]) >= IFNAMSIZ) {
141 fprintf(stderr,
142 "%s: interface name '%s' too long.\n",
143 argv[0], argv[i+1]);
144 exit(2);
145 }
146 strcpy(nfs_diskless.myif.ifra_name, argv[i+1]);
147 i += 2;
148 break;
149 case KW_ROOTFS:
150 rootpath = argv[i+1];
151 i += 2;
152 break;
153 case KW_SWAP:
154 swappath = argv[i+1];
155 i += 2;
156 break;
157 case KW_RSIZE:
158 rsize = atoi(argv[i+1]);
159 i += 2;
160 break;
161 case KW_WSIZE:
162 wsize = atoi(argv[i+1]);
163 i += 2;
164 break;
165 case KW_NETMASK:
166 netmask = inet_addr(argv[i+1]);
167 i +=2;
168 break;
169 case KW_HOSTNAME:
170 hostname = argv[i+1];
171 i += 2;
172 break;
356efd09
MR
173 case KW_GATEWAY:
174 gateway = argv[i+1];
175 i += 2;
176 break;
177 }
178 }
179 if(gateway)
180 {
181 if (gethostname(gateway, 256) < 0) {
182 fprintf(stderr,"%s: unable to get gateway host name\n",argv[0]);
183 exit(2);
184 }
185 if ((hp = gethostbyname(gateway)) == NULL) {
186 fprintf(stderr,"%s: unable to get gateway host address\n",argv[0]);
187 exit(2);
491fc627 188 }
356efd09
MR
189 nfs_diskless.mygateway.sa_len = sizeof(struct sockaddr);
190 nfs_diskless.mygateway.sa_family = AF_INET;
191 nfs_diskless.mygateway.sa_data[0] = NFS_SOCKET >> 8;
192 nfs_diskless.mygateway.sa_data[1] = NFS_SOCKET & 0x00FF;
193 bcopy(*hp->h_addr_list, &nfs_diskless.mygateway.sa_data[2], 4);
491fc627
MR
194 }
195 nfs_diskless.swap_args.rsize = i386order(rsize);
196 nfs_diskless.swap_args.wsize = i386order(wsize);
197 nfs_diskless.root_args.rsize = i386order(rsize);
198 nfs_diskless.root_args.wsize = i386order(wsize);
199 if ((hp = gethostbyname(hostname)) == NULL) {
200 fprintf(stderr,"%s: unable to get diskless address\n",argv[0]);
201 exit(2);
202 }
203 bcopy(*hp->h_addr_list, &nfs_diskless.myif.ifra_addr.sa_data[2], 4);
204 if (!netmask) {
205 unsigned char net;
206 net = nfs_diskless.myif.ifra_addr.sa_data[2];
207 if (net <= 127)
208 netmask = inet_addr("255.0.0.0");
209 else if (net < 192)
210 netmask = inet_addr("255.255.0.0");
211 else netmask = inet_addr("255.255.255.0");
212 }
213 bcopy(*hp->h_addr_list, &myip, 4);
214 broadcast = (myip & netmask) | ~netmask;
215 bcopy(&broadcast, &nfs_diskless.myif.ifra_broadaddr.sa_data[2], 4);
216 bcopy(&netmask, &nfs_diskless.myif.ifra_mask.sa_data[2], 4);
217 if (stat(rootpath, &statbuf) < 0) {
218 fprintf(stderr,"%s: unable to stat '%s'\n",
219 argv[0],rootpath);
220 exit(2);
221 }
222 if (!S_ISDIR(statbuf.st_mode)) {
223 fprintf(stderr,"%s: '%s' is not a directory\n",
224 argv[0],rootpath);
225 exit(2);
226 }
227 if (getfh(rootpath, (fhandle_t *)nfs_diskless.root_fh) < 0) {
228 fprintf(stderr,"%s: unable to get handle for '%s'\n",
229 argv[0],rootpath);
230 exit(2);
231 }
232 sprintf(buf,"%s:%s",servername, rootpath);
233 buf[NFSMNAMELEN-1] = 0;
234 strcpy(nfs_diskless.root_hostnam,buf);
235 printf("root is on %s\n",nfs_diskless.root_hostnam);
236 if (stat(swappath, &statbuf) < 0) {
237 fprintf(stderr,"%s: unable to stat '%s'\n",
238 argv[0],swappath);
239 exit(2);
240 }
241 if (!S_ISREG(statbuf.st_mode)) {
242 fprintf(stderr,"%s: '%s' is not a regular file\n",
243 argv[0],swappath);
244 exit(2);
245 }
246 if (getfh(swappath, (fhandle_t *)nfs_diskless.swap_fh) < 0) {
247 fprintf(stderr,"%s: unable to get handle for '%s'\n",
248 argv[0],swappath);
249 exit(2);
250 }
251 sprintf(buf,"%s:%s",servername, swappath);
252 buf[NFSMNAMELEN-1] = 0;
253 strcpy(nfs_diskless.swap_hostnam,buf);
254 printf("swap is on %s\n",nfs_diskless.swap_hostnam);
255 sprintf(cfg,"cfg.%d.%d.%d.%d",
256 ((int)nfs_diskless.myif.ifra_addr.sa_data[2]) & 0x00FF,
257 ((int)nfs_diskless.myif.ifra_addr.sa_data[3]) & 0x00FF,
258 ((int)nfs_diskless.myif.ifra_addr.sa_data[4]) & 0x00FF,
259 ((int)nfs_diskless.myif.ifra_addr.sa_data[5]) & 0x00FF);
260 if ((fd = open(cfg, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) {
261 fprintf(stderr,"%s: unable to open/create %s\n",
262 argv[0],cfg);
263 exit(2);
264 }
265 if (write(fd, &nfs_diskless, sizeof(struct nfs_diskless)) !=
266 sizeof(struct nfs_diskless)) {
267 fprintf(stderr,"%s: unable to write to '%s'\n",
268 argv[0],cfg);
269 exit(2);
270 }
271 close(fd);
272}
273
274/********************************************************************
275HELP - Print help message
276********************************************************************/
277help(prog, keywd)
278 char *prog, *keywd;
279{
280 int i;
281 fprintf(stderr,"%s: invalid keyword '%s' or not enough parameters\n",prog,keywd);
282 fprintf(stderr," valid keywords: ");
283 for (i=0; keywords[i].name; i++) fprintf(stderr,"%s ", keywords[i].name);
284 fprintf(stderr,"\n");
285}
286
287/*********************************************************************
288I386ORDER - Byte swap
289*********************************************************************/
290i386order(i)
291 unsigned int i;
292{
293#ifndef i386
294 return( ((i >> 24) & 0x000000FF) |
295 ((i >> 8) & 0x0000FF00) |
296 ((i << 8) & 0x00FF0000) |
297 ((i << 24) & 0xFF000000));
298#else
299 return(i);
300#endif
301}