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

📄 timed.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef sgi	(void)_daemonize(debug ? _DF_NOFORK|_DF_NOCHDIR : 0, sock, -1, -1);#else	if (!debug)		daemon(debug, 0);#endif /* sgi */	if (trace)		traceon();	openlog("timed", LOG_CONS|LOG_PID, LOG_DAEMON);	/*	 * keep returning here	 */	ret = setjmp(jmpenv);	savefromnet = fromnet;	setstatus();	if (Mflag) {		switch (ret) {		case 0:			checkignorednets();			pickslavenet(0);			break;		case 1:			/* Just lost our master */			if (slavenet != 0)				slavenet->status = election(slavenet);			if (!slavenet || slavenet->status == MASTER) {				checkignorednets();				pickslavenet(0);			} else {				makeslave(slavenet);	/* prune extras */			}			break;		case 2:			/* Just been told to quit */			justquit = 1;			pickslavenet(savefromnet);			break;		}		setstatus();		if (!(status & MASTER) && sock_raw != -1) {			/* sock_raw is not being used now */			(void)close(sock_raw);			sock_raw = -1;		}		if (status == MASTER)			master();		else			slave();	} else {		if (sock_raw != -1) {			(void)close(sock_raw);			sock_raw = -1;		}		if (ret) {			/* we just lost our master or were told to quit */			justquit = 1;		}		for (ntp = nettab; ntp != NULL; ntp = ntp->next) {			if (ntp->status == MASTER)				rmnetmachs(ntp);				ntp->status = NOMASTER;		}		checkignorednets();		pickslavenet(0);		setstatus();		slave();	}	/* NOTREACHED */#ifdef lint	return(0);#endif}/* * suppress an upstart, untrustworthy, self-appointed master */voidsuppress(addr, name,net)	struct sockaddr_in *addr;	char *name;	struct netinfo *net;{	struct sockaddr_in tgt;	char tname[MAXHOSTNAMELEN];	struct tsp msg;	static struct timeval wait;	if (trace)		fprintf(fd, "suppress: %s\n", name);	tgt = *addr;	(void)strcpy(tname, name);	while (0 != readmsg(TSP_ANY, ANYADDR, &wait, net)) {		if (trace)			fprintf(fd, "suppress:\tdiscarded packet from %s\n",				    name);	}	syslog(LOG_NOTICE, "suppressing false master %s", tname);	msg.tsp_type = TSP_QUIT;	(void)strcpy(msg.tsp_name, hostname);	(void)acksend(&msg, &tgt, tname, TSP_ACK, 0, 1);}voidlookformaster(ntp)	struct netinfo *ntp;{	struct tsp resp, conflict, *answer;	struct timeval ntime;	char mastername[MAXHOSTNAMELEN];	struct sockaddr_in masteraddr;	get_goodgroup(0);	ntp->status = SLAVE;	/* look for master */	resp.tsp_type = TSP_MASTERREQ;	(void)strcpy(resp.tsp_name, hostname);	answer = acksend(&resp, &ntp->dest_addr, ANYADDR,			 TSP_MASTERACK, ntp, 0);	if (answer != 0 && !good_host_name(answer->tsp_name)) {		suppress(&from, answer->tsp_name, ntp);		ntp->status = NOMASTER;		answer = 0;	}	if (answer == 0) {		/*		 * Various conditions can cause conflict: races between		 * two just started timedaemons when no master is		 * present, or timedaemons started during an election.		 * A conservative approach is taken.  Give up and became a		 * slave, postponing election of a master until first		 * timer expires.		 */		ntime.tv_sec = ntime.tv_usec = 0;		answer = readmsg(TSP_MASTERREQ, ANYADDR, &ntime, ntp);		if (answer != 0) {			if (!good_host_name(answer->tsp_name)) {				suppress(&from, answer->tsp_name, ntp);				ntp->status = NOMASTER;			}			return;		}		ntime.tv_sec = ntime.tv_usec = 0;		answer = readmsg(TSP_MASTERUP, ANYADDR, &ntime, ntp);		if (answer != 0) {			if (!good_host_name(answer->tsp_name)) {				suppress(&from, answer->tsp_name, ntp);				ntp->status = NOMASTER;			}			return;		}		ntime.tv_sec = ntime.tv_usec = 0;		answer = readmsg(TSP_ELECTION, ANYADDR, &ntime, ntp);		if (answer != 0) {			if (!good_host_name(answer->tsp_name)) {				suppress(&from, answer->tsp_name, ntp);				ntp->status = NOMASTER;			}			return;		}		if (Mflag)			ntp->status = MASTER;		else			ntp->status = NOMASTER;		return;	}	ntp->status = SLAVE;	(void)strcpy(mastername, answer->tsp_name);	masteraddr = from;	/*	 * If network has been partitioned, there might be other	 * masters; tell the one we have just acknowledged that	 * it has to gain control over the others.	 */	ntime.tv_sec = 0;	ntime.tv_usec = 300000;	answer = readmsg(TSP_MASTERACK, ANYADDR, &ntime, ntp);	/*	 * checking also not to send CONFLICT to ack'ed master	 * due to duplicated MASTERACKs	 */	if (answer != NULL &&	    strcmp(answer->tsp_name, mastername) != 0) {		conflict.tsp_type = TSP_CONFLICT;		(void)strcpy(conflict.tsp_name, hostname);		if (!acksend(&conflict, &masteraddr, mastername,			     TSP_ACK, 0, 0)) {			syslog(LOG_ERR,			       "error on sending TSP_CONFLICT");		}	}}/* * based on the current network configuration, set the status, and count * networks; */voidsetstatus(){	struct netinfo *ntp;	status = 0;	nmasternets = nslavenets = nnets = nignorednets = 0;	if (trace)		fprintf(fd, "Net status:\n");	for (ntp = nettab; ntp != NULL; ntp = ntp->next) {		switch ((int)ntp->status) {		case MASTER:			nmasternets++;			break;		case SLAVE:			nslavenets++;			break;		case NOMASTER:		case IGNORE:			nignorednets++;			break;		}		if (trace) {			fprintf(fd, "\t%-16s", inet_ntoa(ntp->net));			switch ((int)ntp->status) {			case NOMASTER:				fprintf(fd, "NOMASTER\n");				break;			case MASTER:				fprintf(fd, "MASTER\n");				break;			case SLAVE:				fprintf(fd, "SLAVE\n");				break;			case IGNORE:				fprintf(fd, "IGNORE\n");				break;			default:				fprintf(fd, "invalid state %d\n",					(int)ntp->status);				break;			}		}		nnets++;		status |= ntp->status;	}	status &= ~IGNORE;	if (trace)		fprintf(fd,			"\tnets=%d masters=%d slaves=%d ignored=%d delay2=%d\n",			nnets, nmasternets, nslavenets, nignorednets, delay2);}voidmakeslave(net)	struct netinfo *net;{	register struct netinfo *ntp;	for (ntp = nettab; ntp != NULL; ntp = ntp->next) {		if (ntp->status == SLAVE && ntp != net)			ntp->status = IGNORE;	}	slavenet = net;}/* * Try to become master over ignored nets.. */static voidcheckignorednets(){	register struct netinfo *ntp;	for (ntp = nettab; ntp != NULL; ntp = ntp->next) {		if (!Mflag && ntp->status == SLAVE)			break;		if (ntp->status == IGNORE || ntp->status == NOMASTER) {			lookformaster(ntp);			if (!Mflag && ntp->status == SLAVE)				break;		}	}}/* * choose a good network on which to be a slave *	The ignored networks must have already been checked. *	Take a hint about for a good network. */static voidpickslavenet(ntp)	struct netinfo *ntp;{	if (slavenet != 0 && slavenet->status == SLAVE) {		makeslave(slavenet);		/* prune extras */		return;	}	if (ntp == 0 || ntp->status != SLAVE) {		for (ntp = nettab; ntp != 0; ntp = ntp->next) {			if (ntp->status == SLAVE)				break;		}	}	makeslave(ntp);}/* * returns a random number in the range [inf, sup] */longcasual(inf, sup)	long inf, sup;{	double value;	value = ((double)(random() & 0x7fffffff)) / (0x7fffffff*1.0);	return(inf + (sup - inf)*value);}char *date(){#ifdef sgi	struct	timeval tv;	static char tm[32];	(void)gettimeofday(&tv, (struct timezone *)0);	(void)cftime(tm, "%D %T", &tv.tv_sec);	return (tm);#else	struct	timeval tv;	(void)gettimeofday(&tv, (struct timezone *)0);	return (ctime(&tv.tv_sec));#endif /* sgi */}voidaddnetname(name)	char *name;{	register struct nets **netlist = &nets;	while (*netlist)		netlist = &((*netlist)->next);	*netlist = (struct nets *)malloc(sizeof **netlist);	if (*netlist == 0) {		fprintf(stderr,"malloc failed\n");		exit(1);	}	bzero((char *)*netlist, sizeof(**netlist));	(*netlist)->name = name;}/* note a host as trustworthy */static voidadd_good_host(name, perm)	char *name;	int perm;			/* 1=not part of the netgroup */{	register struct goodhost *ghp;	register struct hostent *hentp;	ghp = (struct goodhost*)malloc(sizeof(*ghp));	if (!ghp) {		syslog(LOG_ERR, "malloc failed");		exit(1);	}	bzero((char*)ghp, sizeof(*ghp));	(void)strncpy(&ghp->name[0], name, sizeof(ghp->name));	ghp->next = goodhosts;	ghp->perm = perm;	goodhosts = ghp;	hentp = gethostbyname(name);	if (0 == hentp && perm)		(void)fprintf(stderr, "unknown host %s\n", name);}/* update our image of the net-group of trustworthy hosts */voidget_goodgroup(force)	int force;{# define NG_DELAY (30*60*CLK_TCK)	/* 30 minutes */	static unsigned long last_update = -NG_DELAY;	unsigned long new_update;	struct hosttbl *htp;	struct goodhost *ghp, **ghpp;	char *mach, *usr, *dom;	struct tms tm;	/* if no netgroup, then we are finished */	if (goodgroup == 0 || !Mflag)		return;	/* Do not chatter with the netgroup master too often.	 */	new_update = times(&tm);	if (new_update < last_update + NG_DELAY	    && !force)		return;	last_update = new_update;	/* forget the old temporary entries */	ghpp = &goodhosts;	while (0 != (ghp = *ghpp)) {		if (!ghp->perm) {			*ghpp = ghp->next;			free((char*)ghp);		} else {			ghpp = &ghp->next;		}	}#ifdef HAVENIS	/* quit now if we are not one of the trusted masters	 */	if (!innetgr(goodgroup, &hostname[0], 0,0)) {		if (trace)			(void)fprintf(fd, "get_goodgroup: %s not in %s\n",				      &hostname[0], goodgroup);		return;	}	if (trace)		(void)fprintf(fd, "get_goodgroup: %s in %s\n",				  &hostname[0], goodgroup);	/* mark the entire netgroup as trusted */	(void)setnetgrent(goodgroup);	while (getnetgrent(&mach,&usr,&dom)) {		if (0 != mach)			add_good_host(mach,0);	}	(void)endnetgrent();	/* update list of slaves */	for (htp = self.l_fwd; htp != &self; htp = htp->l_fwd) {		htp->good = good_host_name(&htp->name[0]);	}#endif /* HAVENIS */}/* see if a machine is trustworthy */int					/* 1=trust hp to change our date */good_host_name(name)	char *name;{	register struct goodhost *ghp = goodhosts;	register char c;	if (!ghp || !Mflag)		/* trust everyone if no one named */		return 1;	c = *name;	do {		if (c == ghp->name[0]		    && !strcasecmp(name, ghp->name))			return 1;	/* found him, so say so */	} while (0 != (ghp = ghp->next));	if (!strcasecmp(name,hostname))	/* trust ourself */		return 1;	return 0;			/* did not find him */}

⌨️ 快捷键说明

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