slave.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 584 行 · 第 1/2 页

C
584
字号
			msg->tsp_type = TSP_SETDATEREQ;			msg->tsp_vers = TSPVERSION;			(void)strcpy(msg->tsp_name, hostname);			for (ntp = nettab; ntp != NULL; ntp = ntp->next) {				if (ntp->status == SLAVE)					break;			}			if (ntp == NULL)				break;			answer = acksend(msg, &ntp->dest_addr, (char *)ANYADDR,			    TSP_DATEACK, ntp);			if (answer != NULL) {				msg->tsp_type = TSP_ACK;				bytenetorder(msg);				length = sizeof(struct sockaddr_in);				if (sendto(sock, (char *)msg,				    sizeof(struct tsp), 0, &saveaddr,				    length) < 0) {					syslog(LOG_ERR, "sendto: %m");					exit(1);				}				senddateack = ON;			}			break;		case TSP_SETDATEREQ:			saveaddr = from;			if (status != SUBMASTER || fromnet->status != MASTER)				break;			for (ntp = nettab; ntp != NULL; ntp = ntp->next) {				if (ntp->status == SLAVE)					break;			}			ind = findhost(msg->tsp_name);			if (ind < 0) {			    syslog(LOG_WARNING,				"DATEREQ from uncontrolled machine");			    break;			}			syslog(LOG_DEBUG,			    "forwarding date change request for %s",			    msg->tsp_name);			(void)strcpy(msg->tsp_name, hostname);			answer = acksend(msg, &ntp->dest_addr, (char *)ANYADDR,			    TSP_DATEACK, ntp);			if (answer != NULL) {				msg->tsp_type = TSP_DATEACK;				bytenetorder(msg);				length = sizeof(struct sockaddr_in);				if (sendto(sock, (char *)msg,				    sizeof(struct tsp), 0, &saveaddr,				    length) < 0) {					syslog(LOG_ERR, "sendto: %m");					exit(1);				}			}			break;		case TSP_TRACEON:			if (!(trace)) {				fd = fopen(tracefile, "w");				setlinebuf(fd);				fprintf(fd, "Tracing started on: %s\n\n", 								date());			}			trace = ON;			break;		case TSP_TRACEOFF:			if (trace) {				fprintf(fd, "Tracing ended on: %s\n", date());				(void)fclose(fd);			}#ifdef GPROF			moncontrol(0);			_mcleanup();			moncontrol(1);#endif			trace = OFF;			break;		case TSP_SLAVEUP:			if ((status & MASTER) && fromnet->status == MASTER) {				ind = addmach(msg->tsp_name, &from);				newslave(ind, msg->tsp_seq);			}			break;		case TSP_ELECTION:			if (fromnet->status == SLAVE) {				(void)gettimeofday(&time, (struct timezone *)0);				electiontime = time.tv_sec + delay2;				seq = 0;            /* reset sequence number */				if (time.tv_sec < refusetime)					msg->tsp_type = TSP_REFUSE;				else {					msg->tsp_type = TSP_ACCEPT;					refusetime = time.tv_sec + 30;				}				(void)strcpy(candidate, msg->tsp_name);				(void)strcpy(msg->tsp_name, hostname);				answerdelay();				server = from;				answer = acksend(msg, &server, candidate, TSP_ACK,				    (struct netinfo *)NULL);				if (answer == NULL)					syslog(LOG_WARNING,					   "no answer from master candidate\n");			} else {	/* fromnet->status == MASTER */				to.tsp_type = TSP_QUIT;				(void)strcpy(to.tsp_name, hostname);				server = from;				answer = acksend(&to, &server, msg->tsp_name,				    TSP_ACK, (struct netinfo *)NULL);				if (answer == NULL) {					syslog(LOG_WARNING,					    "election error: no reply to QUIT");				} else {					(void) addmach(msg->tsp_name, &from);				}			}			break;                case TSP_CONFLICT:			if (fromnet->status != MASTER)				break;                        /*                         * After a network partition, there can be                         * more than one master: the first slave to                         * come up will notify here the situation.                         */                        (void)strcpy(to.tsp_name, hostname);                        if (fromnet == NULL)                                break;                        for(;;) {                                to.tsp_type = TSP_RESOLVE;                                answer = acksend(&to, &fromnet->dest_addr,                                    (char *)ANYADDR, TSP_MASTERACK, fromnet);                                if (answer == NULL)                                        break;                                to.tsp_type = TSP_QUIT;                                server = from;                                msg = acksend(&to, &server, answer->tsp_name,                                    TSP_ACK, (struct netinfo *)NULL);                                if (msg == NULL) {                                        syslog(LOG_WARNING,					    "conflict error: no reply to QUIT");				} else {                                        (void) addmach(answer->tsp_name, &from);				}                        }                        masterup(fromnet);                        break;		case TSP_MSITE:			if (!slavenet)				break;			msaveaddr = from;			msg->tsp_type = TSP_MSITEREQ;			msg->tsp_vers = TSPVERSION;			(void)strcpy(msg->tsp_name, hostname);			answer = acksend(msg, &slavenet->dest_addr,					 (char *)ANYADDR, TSP_ACK, slavenet);			if (answer != NULL) {				msg->tsp_type = TSP_ACK;				length = sizeof(struct sockaddr_in);				bytenetorder(msg);				if (sendto(sock, (char *)msg, 						sizeof(struct tsp), 0,						&msaveaddr, length) < 0) {					syslog(LOG_ERR, "sendto: %m");					exit(1);				}			}			break;		case TSP_ACCEPT:		case TSP_REFUSE:			break;		case TSP_RESOLVE:			break;		case TSP_QUIT:			/* become slave */#ifdef MEASURE			if (fp != NULL) {				(void)fclose(fp);				fp = NULL;			}#endif			longjmp(jmpenv, 2);			break;#ifdef TESTING		case TSP_TEST:			electiontime = 0;			break;#endif		case TSP_MSITEREQ:			if (status & MASTER)				break;			if (trace) {				fprintf(fd, "garbage: ");				print(msg, &from);			}			break;		case TSP_LOOP:			/* looking for loops of masters */			if ( !(status & MASTER))				break;			if (fromnet->status == SLAVE) {			    if ( !strcmp(msg->tsp_name, hostname)) {				  for(;;) {				    to.tsp_type = TSP_RESOLVE;				    answer = acksend(&to, &fromnet->dest_addr,					(char *)ANYADDR, TSP_MASTERACK,					fromnet);				    if (answer == NULL)					    break;				    to.tsp_type = TSP_QUIT;				    (void)strcpy(to.tsp_name, hostname);				    server = from;				    answer = acksend(&to, &server,					answer->tsp_name, TSP_ACK,					(struct netinfo *)NULL);				    if (answer == NULL) {					syslog(LOG_ERR, "loop kill error");				    } else {					electiontime = 0;				    }				  }			    } else {				if (msg->tsp_hopcnt-- <= 0)				    break;				bytenetorder(msg);				ntp = nettab;				for (; ntp != NULL; ntp = ntp->next)				    if (ntp->status == MASTER)					if (sendto(sock, (char *)msg, 					    sizeof(struct tsp), 0,					    &ntp->dest_addr, length) < 0) {						syslog(LOG_ERR, "sendto: %m");						exit(1);					}			    }			} else {			    /*			     * We should not have received this from a net			     * we are master on.  There must be two masters			     * in this case.			     */			    if (fromnet->my_addr.s_addr == from.sin_addr.s_addr)				break;			    for (;;) {				to.tsp_type = TSP_RESOLVE;				answer = acksend(&to, &fromnet->dest_addr,				    (char *)ANYADDR, TSP_MASTERACK,				    fromnet);				if (answer == NULL)					break;				to.tsp_type = TSP_QUIT;				(void)strcpy(to.tsp_name, hostname);				server = from;				answer = acksend(&to, &server, answer->tsp_name,				    TSP_ACK, (struct netinfo *)NULL);				if (answer == NULL) {					syslog(LOG_ERR, "loop kill error2");				} else {					(void)addmach(msg->tsp_name, &from);				}			    }			}			break;		default:			if (trace) {				fprintf(fd, "garbage: ");				print(msg, &from);			}			break;		}	}	goto loop;}/* * Used before answering a broadcast message to avoid network * contention and likely collisions. */answerdelay(){	struct timeval timeout;	timeout.tv_sec = 0;	timeout.tv_usec = delay1;	(void)select(0, (fd_set *)NULL, (fd_set *)NULL, (fd_set *)NULL,	    &timeout);	return;}

⌨️ 快捷键说明

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