📄 timed.c
字号:
#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 + -