⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diskless_setup.c

📁 早期freebsd实现
💻 C
字号:
/* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Rick Macklem at The University of Guelph. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)diskless_setup.c	5.1 (Berkeley) 7/16/89";#endif /* not lint */#include <stdio.h>#include <fcntl.h>#include <netdb.h>#include <strings.h>#include <sys/types.h>#include <sys/param.h>#include <sys/stat.h>#include <sys/time.h>#include <pwd.h>#include <grp.h>#ifdef BSD4_4#include <sys/socket.h>#include <sys/ucred.h>#include <sys/mount.h>#include <net/if.h>#include <netinet/in.h>#include <nfs/nfsv2.h>#include <nfs/nfs.h>#include <nfs/nqnfs.h>#include <nfs/nfsdiskless.h>#else#include "socket.h"#include "ucred.h"#include "mount.h"#include "if.h"#include "in.h"#include "nfsv2.h"#include "nfs.h"#include "nqnfs.h"#include "nfsdiskless.h"#endif	/* BSD4_4 */#include "pathnames.h"struct nfs_args def_args = {	(struct sockaddr *)0,	sizeof (struct sockaddr_in),	SOCK_DGRAM,	0,	(nfsv2fh_t *)0,	0,	NFS_WSIZE,	NFS_RSIZE,	NFS_TIMEO,	NFS_RETRANS,	NFS_MAXGRPS,	NFS_DEFRAHEAD,	NQ_MAXLEASE,	NQ_DEADTHRESH,	(char *)0,};void nfsargs_hton(), fatal_err();/* * Setup of server to handle a diskless/dataless client. Most of the work is * just filling in all the fields of the nfs_diskless data structure. * This structure is then either written to a file named "diskless.<host>" * or stuffed into the client's vmunix file at the specified offset. * For now it is a bare bones tool with command line options only. * NB: It will need to be compiled with the sys/<files>.h for a 4.4BSD *     kernel, although it should be runable on most nfs Unix servers. *     (Except <sys/types.h> and <sys/param.h> which should be native *      files for the server OS) */main(argc, argv)	int argc;	char *argv[];{	int fd = -1, c, i, j, sblks, sfd;	register struct hostent *hp;	register struct sockaddr_in *claddr, *cmaddr, *cbaddr;	struct nfs_diskless nd;	struct stat sb;	struct passwd *pwd;	struct group *grp;	struct timeval tv;	char **cpp;	short ngroups;	u_long taddr;	char fname[MAXPATHLEN], servernm[MAXHOSTNAMELEN], *cp, buf[10240];	u_char fh[100];	extern int optind;	extern char *optarg;	/*	 * First initialize nd with all the defaults.	 */	if (gethostname(servernm, MAXHOSTNAMELEN) < 0)		fatal_err("Can't get server host name\n");	if ((hp = gethostbyname(servernm)) == NULL)		fatal_err("Can't get host addr\n");	nfsargs_hton(&def_args);	nd.swap_args = def_args;	nd.swap_saddr.sin_addr.s_addr = *((u_long *) *hp->h_addr_list);	nd.swap_saddr.sin_len = sizeof (struct sockaddr_in);	nd.swap_saddr.sin_family = AF_INET;	nd.swap_saddr.sin_port = htons(NFS_PORT);	strncpy(nd.swap_hostnam, hp->h_name, MNAMELEN - 1);	nd.swap_hostnam[MNAMELEN - 1] = '\0';	nd.swap_nblks = 0;	nd.root_args = def_args;	nd.root_saddr.sin_len = sizeof (struct sockaddr_in);	nd.root_saddr.sin_family = AF_INET;	nd.root_saddr.sin_addr.s_addr = *((u_long *) *hp->h_addr_list);	nd.root_saddr.sin_port = htons(NFS_PORT);	strncpy(nd.root_hostnam, hp->h_name, MNAMELEN - 1);	nd.root_hostnam[MNAMELEN - 1] = '\0';	/*	 * Put the current time in the structure. This should be replaced	 * by the bootstrap server, if possible.	 */	gettimeofday(&tv, (struct timezone *)0);	nd.root_time = htonl(tv.tv_sec);	if (*argv[argc - 1] == '-' ||		(hp = gethostbyname(argv[argc - 1])) == NULL)		fatal_err("Can't get client addr\n");	if (hp->h_addrtype != AF_INET || *hp->h_addr_list == NULL)		fatal_err("Bad client hostent\n");	strncpy(nd.my_hostnam, hp->h_name, MAXHOSTNAMELEN);	nd.my_hostnam[MAXHOSTNAMELEN - 1] = '\0';	claddr = (struct sockaddr_in *)&nd.myif.ifra_addr;	cmaddr = (struct sockaddr_in *)&nd.myif.ifra_mask;	cbaddr = (struct sockaddr_in *)&nd.myif.ifra_broadaddr;	claddr->sin_len = sizeof (struct sockaddr_in);	claddr->sin_family = AF_INET;	claddr->sin_port = 0;	cmaddr->sin_len = sizeof (struct sockaddr_in);	cmaddr->sin_family = AF_INET;	cmaddr->sin_port = 0;	cbaddr->sin_len = sizeof (struct sockaddr_in);	cbaddr->sin_family = AF_INET;	cbaddr->sin_port = 0;	claddr->sin_addr.s_addr = *((u_long *) *hp->h_addr_list);	taddr = ntohl(claddr->sin_addr.s_addr);	/*	 * Default net mask to internet address class. Can be overridden	 * by using the -m option.	 */	if (IN_CLASSA(taddr))		cmaddr->sin_addr.s_addr = inet_addr("255.0.0.0");	else if (IN_CLASSB(taddr))		cmaddr->sin_addr.s_addr = inet_addr("255.255.0.0");	else		cmaddr->sin_addr.s_addr = inet_addr("255.255.255.0");	nd.myif.ifra_name[0] = '\0';	nd.mygateway.sin_len = 0;	/*	 * Now, process all the command line options and override defaults.	 */	while ((c = getopt(argc, argv, "os:h:m:a:g:l:x:r:c:")) != EOF) {		switch (c) {		case 'o':			fd = 1;			break;		case 's':			sblks = atoi(optarg);			if (sblks < 0 || sblks > 500000)				fatal_err("Swap size out of range\n");			strcpy(fname, _PATH_SWAP);			strcat(fname, ".");			strcat(fname, hp->h_name);			if ((sfd = open(fname, O_WRONLY | O_CREAT | O_TRUNC,				0600)) < 0)				fatal_err("Can't create swapfile\n");			if (fchmod(sfd, 0600) < 0)				fatal_err("Can't chmod swap file\n");			if (fchown(sfd, -2, -2) < 0)				fatal_err("Can't chown swap file\n");			for (i = 0; i < sblks; ) {				j = MIN(sblks - i, 20);				if (write(sfd, buf, j * 512) < 0)					fatal_err("Swapfile out of space\n");				i += j * 512;			}			close(sfd);			nd.swap_nblks = htonl(sblks);			bzero((caddr_t)fh, 100);			if (getfh(fname, fh) < 0)				fatal_err("Can't get swap fh\n");			bcopy((caddr_t)fh, nd.swap_fh, NFS_FHSIZE);			break;		case 'h':			if ((taddr = inet_addr(optarg)) == -1)				fatal_err("Bad -h addr\n");			claddr->sin_addr.s_addr = taddr;			break;		case 'm':			if ((taddr = inet_addr(optarg)) == -1)				fatal_err("Bad -m addr\n");			cmaddr->sin_addr.s_addr = taddr;			break;		case 'a':			if ((taddr = inet_addr(optarg)) == -1)				fatal_err("Bad -a addr\n");			nd.swap_saddr.sin_addr.s_addr = taddr;			nd.root_saddr.sin_addr.s_addr = taddr;			break;		case 'g':			if ((taddr = inet_addr(optarg)) == -1)				fatal_err("Bad -g addr\n");			nd.mygateway.sin_addr.s_addr = taddr;			nd.mygateway.sin_len = sizeof (struct sockaddr_in);			nd.mygateway.sin_family = AF_INET;			nd.mygateway.sin_port = 0;			break;		case 'l':			strncpy(nd.myif.ifra_name, optarg, IFNAMSIZ - 1);			nd.myif.ifra_name[IFNAMSIZ - 1] = '\0';			break;		case 'x':			if ((cp = index(optarg, ':')) == (char *)0)				fatal_err("No : in -x arg\n");			*cp++ = '\0';			i = atoi(cp);			if ((fd = open(optarg, O_RDWR, 0)) < 0)				fatal_err("Can't open for -x\n");			if (i < 0 || fstat(fd, &sb) < 0 ||				i > (sb.st_size - sizeof (struct nfs_diskless)))				fatal_err("Bad -x arg\n");			lseek(fd, i, 0);			break;		case 'r':			bzero((caddr_t)fh, 100);			if (getfh(optarg, fh) < 0)				fatal_err("Can't get root fh\n");			bcopy((caddr_t)fh, nd.root_fh, NFS_FHSIZE);			break;		case 'c':			if (pwd = getpwnam(optarg)) {			    nd.swap_ucred.cr_uid = htonl(pwd->pw_uid);			    nd.swap_ucred.cr_groups[0] = htonl(pwd->pw_gid);			    ngroups = 1;			    setgrent();			    while (grp = getgrent()) {				if (grp->gr_gid == pwd->pw_gid)				    continue;				cpp = grp->gr_mem;				while (*cpp) {				    if (!strcmp(*cpp, pwd->pw_name))					break;				    cpp++;				}				if (*cpp) {				    nd.swap_ucred.cr_groups[ngroups++] =					htonl(grp->gr_gid);				    if (ngroups == NGROUPS)					break;				}			    }			    endgrent();			    nd.swap_ucred.cr_ngroups = htons(ngroups);			} else			    fatal_err("Swap_username bad\n");			break;		default:			fprintf(stderr, "Bad arg %c\n", c);			exit(1);		};	}	/*	 * Finish up and write it out.	 */	cbaddr->sin_addr.s_addr =		(claddr->sin_addr.s_addr & cmaddr->sin_addr.s_addr) |		 ~(cmaddr->sin_addr.s_addr);	if (fd == -1) {		strcpy(fname, _PATH_DISKLESS);		strcat(fname, ".");		strcat(fname, hp->h_name);		if ((fd = open(fname, O_CREAT | O_TRUNC | O_WRONLY, 0600)) < 0) 			fatal_err("Can't create diskless file\n");	}	if (write(fd, &nd, sizeof (nd)) != sizeof (nd))		fatal_err("Can't write diskless file\n");}/* * Convert the integer fields of the nfs_args structure from host byte order * to net byte order. */voidnfsargs_hton(nfsp)	register struct nfs_args *nfsp;{	nfsp->sotype = htonl(nfsp->sotype);	nfsp->proto = htonl(nfsp->proto);	nfsp->flags = htonl(nfsp->flags);	nfsp->wsize = htonl(nfsp->wsize);	nfsp->rsize = htonl(nfsp->rsize);	nfsp->timeo = htonl(nfsp->timeo);	nfsp->retrans = htonl(nfsp->retrans);	nfsp->maxgrouplist = htonl(nfsp->maxgrouplist);	nfsp->readahead = htonl(nfsp->readahead);	nfsp->leaseterm = htonl(nfsp->leaseterm);	nfsp->deadthresh = htonl(nfsp->deadthresh);}/* * Just print out an error message and exit. */voidfatal_err(str)	char *str;{	fprintf(stderr, str);	exit(1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -