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