Ejemplo n.º 1
0
char*
canon(Biobuf *bp, char *header, char *body, int *n)
{
	int hsize, base64;

	static char *raw;

	hsize = 0;
	base64 = 0;
	*header = 0;
	*body = 0;
	if(raw == 0){
		raw = readmsg(bp, &hsize, n);
		if(raw)
			base64 = convert(raw, raw+hsize, header, Hdrsize, 0);
	} else {
		free(raw);
		raw = readmsg(bp, 0, n);
	}
	if(raw){
		if(base64)
			conv64(raw+hsize, raw+*n, body, Bodysize);
		else
			convert(raw+hsize, raw+*n, body, Bodysize, 1);
	}
	return raw;
}
Ejemplo n.º 2
0
void* controler(void *t)	//control the game's order.
{
	int i, n, j;
	struct msgbuf msg;
	char buf[512], current_user_put_pokers[512], current_round_pokers[512], current_user_claim_pokers[512];
	regist();
	poker_gen();
	poker_sender();
	while(1)
	{
		memset(current_round_pokers, '\0', sizeof(current_round_pokers));
		for(i = 0; i < MAXUSERNUM; i++)
		{
			printf("LOG: controler SEND \"TURN\" TO %d\n", connecter_fd[i]);
			write(connecter_fd[i], "TURN", strlen("TURN"));

			//read the real pokers
			msg = readmsg();	
			strcpy(buf, msg.mtext);
			printf("LOG: %d-----%s\n", msg.mtype, msg.mtext);
			sscanf(buf, "%*s%s", current_user_put_pokers); 		
			printf("LOG: %d CURRENT_USER_PUT_POKERS: %s\n", connecter_fd[i], current_user_put_pokers);
			strcat(current_round_pokers, current_user_put_pokers);
			printf("LOG: %d CURRENT_ROUND_POKERS: %s\n", connecter_fd[i], current_round_pokers);

			//read the claim pokers
			msg = readmsg();
			strcpy(buf, msg.mtext);	
			printf("LOG: %d-----%s\n", msg.mtype, msg.mtext);
			sscanf(buf, "%*s%s", current_user_claim_pokers); 		
			printf("LOG: %d CURRENT_USER_CLAIM_POKERS: %s\n", connecter_fd[i], current_user_claim_pokers);
			broadcast(connecter_fd[i], current_user_claim_pokers);

			//Judge Part
			judgement(i, current_round_pokers, current_user_put_pokers, current_user_claim_pokers);

			//Add pokers part, under consideration, add this function further.
			

			printf("%s\n", msg.mtext);
			if (!strcmp(msg.mtext, "OVER"))
			{
				printf("GAME OVER, THE WINNER IS %d\n", msg.mtype);
				break;
			}
		}
	}
}
Ejemplo n.º 3
0
int msglist (void)
{
	int x;
	if (server) {
		x = writemsg (MSGLIST);
		if (x == SCMOK)  x = Tprocess (listT,listone);
		if (x == SCMOK)  x = writestring ((char *)NULL);
		if (x == SCMOK)  x = writeint ((int)scantime);
		if (x == SCMOK)  x = writemend ();
	} else {
		char *name;
		int mode,flags,mtime;
		TREE *t;
		x = readmsg (MSGLIST);
		if (x == SCMOK)  x = readstring (&name);
		while (x == SCMOK) {
			if (name == NULL)  break;
			x = readint (&mode);
			if (x == SCMOK)  x = readint (&flags);
			if (x == SCMOK)  x = readint (&mtime);
			if (x != SCMOK)  break;
			t = Tinsert (&listT,name,TRUE);
			free (name);
			t->Tmode = mode;
			t->Tflags = flags;
			t->Tmtime = mtime;
			x = readstring (&name);
		}
		if (x == SCMOK)  x = readint ((int *)&scantime);
		if (x == SCMOK)  x = readmend ();
	}
	return (x);
}
Ejemplo n.º 4
0
int msgneed (void)
{
	int x;
	if (server) {
		char *name;
		int update;
		TREE *t;
		x = readmsg (MSGNEED);
		if (x == SCMOK)  x = readstring (&name);
		while (x == SCMOK) {
			if (name == NULL)  break;
			x = readint (&update);
			if (x != SCMOK)  break;
			t = Tinsert (&needT,name,TRUE);
			free (name);
			if (update)  t->Tflags |= FUPDATE;
			x = readstring (&name);
		}
		if (x == SCMOK)  x = readmend ();
	} else {
		x = writemsg (MSGNEED);
		if (x == SCMOK)  x = Tprocess (needT,needone);
		if (x == SCMOK)  x = writestring ((char *)NULL);
		if (x == SCMOK)  x = writemend ();
	}
	return (x);
}
Ejemplo n.º 5
0
int msgxpatch (void)
{
	int x;
	int i;

	if (server) {
		x = readmsg (MSGXPATCH);
		if (x != SCMOK)  return (x);
		x = readint (&xargc);
		if (x != SCMOK)  return (x);
		xargc += 2;
		xargv = (char **)calloc (sizeof (char *),(unsigned)xargc+1);
		if (xargv == NULL)
			return (SCMERR);
		for (i = 2; i < xargc; i++) {
			x = readstring (&xargv[i]);
			if (x != SCMOK)  return (x);
		}
		x = readmend ();
	} else {
		x = writemsg (MSGXPATCH);
		if (x != SCMOK)  return (x);
		x = writeint (xargc);
		if (x != SCMOK)  return (x);
		for (i = 0; i < xargc; i++) {
			x = writestring (xargv[i]);
			if (x != SCMOK)  return (x);
		}
		x = writemend ();
	}
	return (x);
}
Ejemplo n.º 6
0
int
main(int argc, const char **argv)
{
	unsigned char *sk, *pk, *n, *m, *c;
	size_t mlen, clen;

	if (argc < 2) {
		puts("usage: cbox SK PK NONCE");
		return 1;
	}

	if (strlen(argv[1]) != crypto_box_SECRETKEYBYTES * 2)
		errx(1, "bad SK length");
	sk = decodehex(argv[1]);

	if (strlen(argv[2]) != crypto_box_PUBLICKEYBYTES * 2)
		errx(1, "bad PK length");
	pk = decodehex(argv[2]);

	if (strlen(argv[3]) != crypto_box_NONCEBYTES * 2)
		errx(1, "bad NONCE length");
	n = decodehex(argv[3]);

	mlen = readmsg(&m);
	if ((c = calloc(mlen, 1)) == NULL)
		err(1, NULL);

	crypto_box(c, m, mlen, n, pk, sk);
	c += crypto_box_BOXZEROBYTES;
	clen = mlen - crypto_box_BOXZEROBYTES;

	if (fwrite(c, 1, clen, stdout) != clen)
		err(1, NULL);
	return 0;
}
Ejemplo n.º 7
0
static int socket_recv(CTXTdeclc int *rc, char** buffer, UInteger *buffer_len, int timeout) {
  SOCKET sock_handle = (SOCKET) ptoc_int(CTXTc 2);
  if (read_select(sock_handle, timeout)) {
    *rc = readmsg(sock_handle, buffer, buffer_len);
    return NORMAL_TERMINATION;
  } else
    return TIMED_OUT;
}
Ejemplo n.º 8
0
/*
 * Acksend implements reliable datagram transmission by using sequence
 * numbers and retransmission when necessary.
 * If `name' is ANYADDR, this routine implements reliable broadcast.
 *
 * Because this function calls readmsg(), none of its args may be in
 *	a message provided by readmsg().
 */
struct tsp *
acksend(struct tsp *message,		/* this message */
	struct sockaddr_in *addr,	/* to here */
	char *name,
	int ack,			/* look for this ack */
	struct netinfo *net,		/* receive from this network */
	int bad)			/* 1=losing patience */
{
	struct timeval twait;
	int count;
	long msec;

	message->tsp_vers = TSPVERSION;
	message->tsp_seq = sequence;
	if (trace) {
		fprintf(fd, "acksend: to %s: ",
			(name == ANYADDR ? "broadcast" : name));
		print(message, addr);
	}
	bytenetorder(message);

	msec = 200;
	count = bad ? 1 : 5;	/* 5 packets in 6.4 seconds */
	answer = NULL;
	do {
		if (!answer) {
			/* do not go crazy transmitting just because the
			 * other guy cannot keep our sequence numbers
			 * straight.
			 */
			if (sendto(sock, (char *)message, sizeof(struct tsp),
				   0, (struct sockaddr*)addr,
				   sizeof(struct sockaddr)) < 0) {
				trace_sendto_err(addr->sin_addr);
				break;
			}
		}

		mstotvround(&twait, msec);
		answer  = readmsg(ack, name, &twait, net);
		if (answer != NULL) {
			if (answer->tsp_seq != sequence) {
				if (trace)
					fprintf(fd,"acksend: seq # %u!=%u\n",
						answer->tsp_seq, sequence);
				continue;
			}
			break;
		}

		msec *= 2;
	} while (--count > 0);
	sequence++;

	return(answer);
}
Ejemplo n.º 9
0
int msgsetup (void)
{
	int x;

	if (server) {
		x = readmsg (MSGSETUP);
		if (x != SCMOK)  return (x);
		if (protver >= 7) {
			x = readint (&xpatch);
			if (x != SCMOK)  return (x);
		} else
			xpatch = FALSE;
		if (xpatch) {
			x = readstring (&xuser);
			if (x != SCMOK)  return (x);
			return (readmend ());
		}
		x = readstring (&collname_g);
		if (x == SCMOK)  x = readint ((int *)&lasttime);
		if (x == SCMOK)  x = readstring (&basedir_g);
		if (x == SCMOK)  x = readint (&basedev);
		if (x == SCMOK)  x = readint (&baseino);
		if (x == SCMOK)  x = readint (&listonly);
		if (x == SCMOK)  x = readint (&newonly);
		if (x == SCMOK)
			if (protver < 6)
				release = (char *)NULL;
			else
				x = readstring (&release);
		if (x == SCMOK)  x = readmend ();
	} else {
		x = writemsg (MSGSETUP);
		if (x != SCMOK)  return (x);
		if (protver >= 7) {
			x = writeint (xpatch);
			if (x != SCMOK)  return (x);
		}
		if (xpatch) {
			x = writestring (xuser);
			if (x != SCMOK)  return (x);
			return (writemend ());
		}
		if (x == SCMOK)  x = writestring (collname_g);
		if (x == SCMOK)  x = writeint ((int)lasttime);
		if (x == SCMOK)  x = writestring (basedir_g);
		if (x == SCMOK)  x = writeint (basedev);
		if (x == SCMOK)  x = writeint (baseino);
		if (x == SCMOK)  x = writeint (listonly);
		if (x == SCMOK)  x = writeint (newonly);
		if (x == SCMOK && protver >= 6)  x = writestring (release);
		if (x == SCMOK)  x = writemend ();
	}
	return (x);
}
Ejemplo n.º 10
0
int
main(int argc, const char **argv)
{
	unsigned char *m, h[crypto_hash_BYTES];
	size_t mlen, i;

	mlen = readmsg(&m);
	crypto_hash(h, m, mlen);
	for (i = 0; i < sizeof(h); i++)
		printf("%02x", h[i]);
	return 0;
}
Ejemplo n.º 11
0
int smtpfilter_ctlmsg()
{
	std::string cmd=getcmd();
	std::string msg(readmsg());

	std::string addr;

	{
		const char *address_cstr;

		if ((address_cstr=is_cmd(cmd.c_str(), "subscribe")) != 0)
		{
			addr=returnaddr(msg, address_cstr);
		}
		else if ((address_cstr=is_cmd(cmd.c_str(), "alias-subscribe"))
			 != 0)
		{
			addr=extract_alias_to_subscribe(msg);
		}
		else
		{
			std::cerr << "200 Ok" << std::endl;
			return 0;
		}
	}

	uaddrlower(addr);

	if (cmdget_s("UNICODE") != "1")
	{
		std::string::const_iterator b=addr.begin(), e=addr.end();

		while (b != e)
		{
			if (*b & 0x80)
			{
				std::cerr << "550 This mailing list does not "
					"accept Unicode E-mail addresses, yet."
					  << std::endl;
				return EX_SOFTWARE;
			}
			++b;
		}
	}

	std::cerr << "200 Ok" << std::endl;
	return 0;
}
Ejemplo n.º 12
0
int msglogack (void)
{
	int x;
	if (server) {
		x = writemsg (MSGLOGACK);
		if (x == SCMOK)  x = writeint (logack);
		if (x == SCMOK)  x = writestring (logerror);
		if (x == SCMOK)  x = writemend ();
	} else {
		x = readmsg (MSGLOGACK);
		if (x == SCMOK)  x = readint (&logack);
		if (x == SCMOK)  x = readstring (&logerror);
		if (x == SCMOK)  x = readmend ();
	}
	return (x);
}
Ejemplo n.º 13
0
void
serve(Chan *chan)
{
	int i, nin, p9, npid;
	uint8_t inbuf[1024];
	void (*s)(Chan*, uint8_t*, int);
	int *pid;
	Waitmsg *w;

	p9 = 0;
	if((nin = readmsg(chan, inbuf, sizeof inbuf, &p9)) < 0)
		return;

	switch(p9){
	default:
		print("unknown 9P type\n");
		return;
	case 1:
		s = serve9p1;
		break;
	case 2:
		s = serve9p2;
		break;
	}

	pid = malloc(sizeof(pid)*(conf.nserve-1));
	if(pid == nil)
		return;
	for(i=1; i<conf.nserve; i++)
		pid[i-1] = startserveproc(s, "srv", chan, nil, 0);

	(*s)(chan, inbuf, nin);

	/* wait till all other servers for this chan are done */
	for(npid = conf.nserve-1; npid > 0;){
		w = wait();
		if(w == 0)
			break;
		for(i = 0; i < conf.nserve-1; i++)
			if(pid[i] == w->pid)
				npid--;
		free(w);
	}
	free(pid);
}
Ejemplo n.º 14
0
int msglogin (void)
{
	int x;
	if (server) {
		x = readmsg (MSGLOGIN);
		if (x == SCMOK)  x = readstring (&logcrypt);
		if (x == SCMOK)  x = readstring (&loguser);
		if (x == SCMOK)  x = readstring (&logpswd);
		if (x == SCMOK)  x = readmend ();
	} else {
		x = writemsg (MSGLOGIN);
		if (x == SCMOK)  x = writestring (logcrypt);
		if (x == SCMOK)  x = writestring (loguser);
		if (x == SCMOK)  x = writestring (logpswd);
		if (x == SCMOK)  x = writemend ();
	}
	return (x);
}
Ejemplo n.º 15
0
char*
canon(Biobuf *bp, char *header, char *body, int *n)
{
    int hsize;
    char *raw;

    hsize = 0;
    *header = 0;
    *body = 0;
    raw = readmsg(bp, &hsize, n);
    if(raw) {
        if(convert(raw, raw+hsize, header, Hdrsize, 0))
            conv64(raw+hsize, raw+*n, body, Bodysize);	/* base64 */
        else
            convert(raw+hsize, raw+*n, body, Bodysize, 1);	/* text */
    }
    return raw;
}
Ejemplo n.º 16
0
int msgsignon (void)
{
	int x;

	if (server) {
		x = readmsg (MSGSIGNON);
		if (x == SCMOK)  x = readint (&protver);
		if (x == SCMOK)  x = readint (&pgmver);
		if (x == SCMOK)  x = readstring (&scmver);
		if (x == SCMOK)  x = readmend ();
	} else {
		x = writemsg (MSGSIGNON);
		if (x == SCMOK)  x = writeint (PROTOVERSION);
		if (x == SCMOK)  x = writeint (pgmversion);
		if (x == SCMOK)  x = writestring (scmversion);
		if (x == SCMOK)  x = writemend ();
	}
	return (x);
}
Ejemplo n.º 17
0
int msgsignonack ()
{
	register int x;

	if (server) {
		x = writemsg (MSGSIGNONACK);
		if (x == SCMOK)  x = writeint (PROTOVERSION);
		if (x == SCMOK)  x = writeint (pgmversion);
		if (x == SCMOK)  x = writestring (scmversion);
		if (x == SCMOK)  x = writeint (fspid);
		if (x == SCMOK)  x = writemend ();
	} else {
		x = readmsg (MSGSIGNONACK);
		if (x == SCMOK)  x = readint (&protver);
		if (x == SCMOK)  x = readint (&pgmver);
		if (x == SCMOK)  x = readstring (&scmver);
		if (x == SCMOK)  x = readint (&fspid);
		if (x == SCMOK)  x = readmend ();
	}
	return (x);
}
Ejemplo n.º 18
0
int msgdone (void)
{
	int x;

	if (protver < 6) {
		printf ("Error, msgdone should not have been called.");
		return (SCMERR);
	}
	if (server) {
		x = readmsg (MSGDONE);
		if (x == SCMOK)  x = readint (&doneack);
		if (x == SCMOK)  x = readstring (&donereason);
		if (x == SCMOK)  x = readmend ();
	} else {
		x = writemsg (MSGDONE);
		if (x == SCMOK)  x = writeint (doneack);
		if (x == SCMOK)  x = writestring (donereason);
		if (x == SCMOK)  x = writemend ();
	}
	return (x);
}
Ejemplo n.º 19
0
int msgdeny (void)
{
	int x;
	if (server) {
		x = writemsg (MSGDENY);
		if (x == SCMOK)  x = Tprocess (denyT,denyone);
		if (x == SCMOK)  x = writestring ((char *)NULL);
		if (x == SCMOK)  x = writemend ();
	} else {
		char *name;
		x = readmsg (MSGDENY);
		if (x == SCMOK)  x = readstring (&name);
		while (x == SCMOK) {
			if (name == NULL)  break;
			(void) Tinsert (&denyT,name,FALSE);
			free (name);
			x = readstring (&name);
		}
		if (x == SCMOK)  x = readmend ();
	}
	return (x);
}
Ejemplo n.º 20
0
int msgrefuse (void)
{
	int x;
	if (server) {
		char *name;
		x = readmsg (MSGREFUSE);
		if (x == SCMOK)  x = readstring (&name);
		while (x == SCMOK) {
			if (name == NULL)  break;
			(void) Tinsert (&refuseT,name,FALSE);
			free (name);
			x = readstring (&name);
		}
		if (x == SCMOK)  x = readmend ();
	} else {
		x = writemsg (MSGREFUSE);
		if (x == SCMOK)  x = Tprocess (refuseT,refuseone);
		if (x == SCMOK)  x = writestring ((char *)NULL);
		if (x == SCMOK)  x = writemend ();
	}
	return (x);
}
Ejemplo n.º 21
0
void judgement(int start, char* current_round_pokers, char* current_user_put_pokers, char* current_user_claim_pokers)
{
	int i;
	char buf[512], user_judge[512];
	for(i = 1; i < MAXUSERNUM; i++)
	{
		write(connecter_fd[(i+start)%MAXUSERNUM], "JUDGE", strlen("JUDGE"));
		msg = readmsg();
		strcpy(buf, msg.mtext);
		printf("LOG: %d-----%s\n", msg.mtype, msg.mtext);
		sscanf(buf, "%*s%s", user_judge);
		broadcast(connecter_fd[(i+start)%MAXUSERNUM], user_judge);
		if (!strcmp(user_judge, "FALSE"))
		{
			sprintf(buf, "%s %s ", "FORCE", current_round_pokers);	
			printf("%d\n", strcmp(current_user_put_pokers, current_user_claim_pokers));
			if(strcmp(current_user_put_pokers, current_user_claim_pokers) != 0)
				write(connecter_fd[start], buf, sizeof(buf));
			else
				write(connecter_fd[(i+start)%MAXUSERNUM], buf, sizeof(buf));
		}
	}
}
Ejemplo n.º 22
0
int
main(int argc, const char **argv)
{
	unsigned char *sk, *m, *sm;
	size_t mlen, n;
	long long unsigned int smlen;

	if (argc < 2) {
		puts("usage: csign PRIVATE_KEY");
		return 1;
	}
	if (strlen(argv[1]) != crypto_sign_SECRETKEYBYTES * 2)
		errx(1, "bad key length");
	sk = decodehex(argv[1]);
	mlen = readmsg(&m);
	if ((sm = calloc(mlen + crypto_sign_BYTES, 1)) == NULL)
		err(1, NULL);

	crypto_sign(sm, &smlen, m, mlen, sk);
	if ((n = fwrite(sm, 1, crypto_sign_BYTES, stdout)) != smlen)
		err(1, NULL);
	return 0;
}
Ejemplo n.º 23
0
/*
 * suppress an upstart, untrustworthy, self-appointed master
 */
void
suppress(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)strlcpy(tname, name, sizeof(tname));

	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);
}
Ejemplo n.º 24
0
void
main(int argc, char *argv[])
{
	int len, rcode;
	char tname[32];
	char *err, *ext = "";
	unsigned char buf[64*1024], callip[IPaddrlen];
	DNSmsg reqmsg, repmsg;
	Request req;

	alarm(2*60*1000);
	cfg.cachedb = 1;
	ARGBEGIN{
	case 'd':
		debug++;
		break;
	case 'f':
		dbfile = EARGF(usage());
		break;
	case 'r':
		cfg.resolver = 1;
		break;
	case 'R':
		norecursion = 1;
		break;
	case 'x':
		ext = EARGF(usage());
		break;
	default:
		usage();
		break;
	}ARGEND

	if(debug < 2)
		debug = 0;

	if(argc > 0)
		getcaller(argv[0]);

	cfg.inside = 1;
	dninit();

	snprint(mntpt, sizeof mntpt, "/net%s", ext);
	if(myipaddr(ipaddr, mntpt) < 0)
		sysfatal("can't read my ip address");
	dnslog("dnstcp call from %s to %I", caller, ipaddr);
	memset(callip, 0, sizeof callip);
	parseip(callip, caller);

	db2cache(1);

	memset(&req, 0, sizeof req);
	setjmp(req.mret);
	req.isslave = 0;
	procsetname("main loop");

	/* loop on requests */
	for(;; putactivity(0)){
		now = time(nil);
		memset(&repmsg, 0, sizeof repmsg);
		len = readmsg(0, buf, sizeof buf);
		if(len <= 0)
			break;

		getactivity(&req, 0);
		req.aborttime = timems() + S2MS(15*Min);
		rcode = 0;
		memset(&reqmsg, 0, sizeof reqmsg);
		err = convM2DNS(buf, len, &reqmsg, &rcode);
		if(err){
			dnslog("server: input error: %s from %s", err, caller);
			free(err);
			break;
		}
		if (rcode == 0) {
			if(reqmsg.qdcount < 1){
				dnslog("server: no questions from %s", caller);
				break;
			} else if(reqmsg.flags & Fresp){
				dnslog("server: reply not request from %s",
					caller);
				break;
			} else if((reqmsg.flags & Omask) != Oquery){
				dnslog("server: op %d from %s",
					reqmsg.flags & Omask, caller);
				break;
			}
		}
		if(debug)
			dnslog("[%d] %d: serve (%s) %d %s %s",
				getpid(), req.id, caller,
				reqmsg.id, reqmsg.qd->owner->name,
				rrname(reqmsg.qd->type, tname, sizeof tname));

		/* loop through each question */
		while(reqmsg.qd)
			if(reqmsg.qd->type == Taxfr)
				dnzone(&reqmsg, &repmsg, &req);
			else {
				dnserver(&reqmsg, &repmsg, &req, callip, rcode);
				reply(1, &repmsg, &req);
				rrfreelist(repmsg.qd);
				rrfreelist(repmsg.an);
				rrfreelist(repmsg.ns);
				rrfreelist(repmsg.ar);
			}
		rrfreelist(reqmsg.qd);		/* qd will be nil */
		rrfreelist(reqmsg.an);
		rrfreelist(reqmsg.ns);
		rrfreelist(reqmsg.ar);

		if(req.isslave){
			putactivity(0);
			_exits(0);
		}
	}
	refreshmain(mntpt);
}
Ejemplo n.º 25
0
int main(int argc, char **argv)
{

        int sl, sa, sc;
        struct sockaddr_in  saddr, clientaddr;
        struct sockaddr_can caddr;
        struct ifreq ifr;
        socklen_t sin_size = sizeof(clientaddr);

        char buf[100];

        struct {
                struct bcm_msg_head msg_head;
                struct can_frame frame;
        } msg;

        if((sl = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
                perror("inetsocket");
                exit(1);
        }

        saddr.sin_family = AF_INET;
        saddr.sin_addr.s_addr = htonl(INADDR_ANY);
        saddr.sin_port = htons(28600);

        while(bind(sl,(struct sockaddr*)&saddr, sizeof(saddr)) < 0) {
                printf(".");fflush(NULL);
                usleep(100000);
        }

        if (listen(sl,3) != 0) {
                perror("listen");
                exit(1);
        }

        while (1) { 
                sa = accept(sl,(struct sockaddr *)&clientaddr, &sin_size);
                if (sa > 0 ){

                        if (fork())
                                close(sa);
                        else
                                break;
                }
                else {
                        if (errno != EINTR) {
                                /*
                                 * If the cause for the error was NOT the signal from
                                 * a dying child, than give an error
                                 */
                                perror("accept");
                                exit(1);
                        }
                }
        }

        /* open BCM socket */

        if ((sc = socket(PF_CAN, SOCK_DGRAM, CAN_BCM)) < 0) {
                perror("bcmsocket");
                return 1;
        }

        caddr.can_family = PF_CAN;
        caddr.can_ifindex = 0; /* any device => need for sendto() */

        if (connect(sc, (struct sockaddr *)&caddr, sizeof(caddr)) < 0) {
                perror("connect");
                return 1;
        }

        /* prepare stable settings */
        msg.msg_head.nframes       = 1;
        msg.msg_head.count         = 0;
        msg.msg_head.ival1.tv_sec  = 0;
        msg.msg_head.ival1.tv_usec = 0;

        while (1) {

                char cmd;
                int items;

                readmsg(sa, buf, sizeof(buf));

                // printf("read '%s'\n", buf);

                items = sscanf(buf, "< %6s %c %lu %lu %x %hhu "
                               "%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx >",
                               ifr.ifr_name,
                               &cmd, 
                               &msg.msg_head.ival2.tv_sec,
                               &msg.msg_head.ival2.tv_usec,
                               &msg.msg_head.can_id,
                               &msg.frame.can_dlc,
                               &msg.frame.data[0],
                               &msg.frame.data[1],
                               &msg.frame.data[2],
                               &msg.frame.data[3],
                               &msg.frame.data[4],
                               &msg.frame.data[5],
                               &msg.frame.data[6],
                               &msg.frame.data[7]);

                if (items < 6)
                        break;
                if (msg.frame.can_dlc > 8)
                        break;
                if (items != 6 + msg.frame.can_dlc)
                        break;

                msg.frame.can_id = msg.msg_head.can_id;

                switch (cmd) {
                case 'S':
                        msg.msg_head.opcode = TX_SEND;
                        break;
                case 'A':
                        msg.msg_head.opcode = TX_SETUP;
                        msg.msg_head.flags |= SETTIMER|STARTTIMER;
                        break;
                case 'U':
                        msg.msg_head.opcode = TX_SETUP;
                        msg.msg_head.flags  = 0;
                        break;
                case 'D':
                        msg.msg_head.opcode = TX_DELETE;
                        break;

                default:
                        printf("unknown command '%c'.\n", cmd);
                        exit(1);
                }

                if (!ioctl(sc, SIOCGIFINDEX, &ifr)) {
                        caddr.can_ifindex = ifr.ifr_ifindex;
                        sendto(sc, &msg, sizeof(msg), 0,
                               (struct sockaddr*)&caddr, sizeof(caddr));
                }

        }

        close(sc);
        close(sa);

        return 0;
}
Ejemplo n.º 26
0
Archivo: slave.c Proyecto: npe9/sprite
slave()
{
	int length;
	int senddateack;
	long electiontime, refusetime, looktime;
	u_short seq;
	char candidate[MAXHOSTNAMELEN];
	struct tsp *msg, to, *readmsg();
	struct sockaddr_in saveaddr, msaveaddr;
	struct timeval wait;
	struct timeval time, otime;
	struct tsp *answer, *acksend();
	int timeout();
	char *date();
	long casual();
	int bytenetorder();
	char olddate[32];
	struct sockaddr_in server;
	register struct netinfo *ntp;
	int ind;
	struct tsp resp;
	extern int Mflag;
	extern int justquit;
#ifdef MEASURE
	extern FILE *fp;
#endif
	if (slavenet) {
		resp.tsp_type = TSP_SLAVEUP;
		resp.tsp_vers = TSPVERSION;
		(void)strcpy(resp.tsp_name, hostname);
		bytenetorder(&resp);
		if (sendto(sock, (char *)&resp, sizeof(struct tsp), 0,
		    &slavenet->dest_addr, sizeof(struct sockaddr_in)) < 0) {
			syslog(LOG_ERR, "sendto: %m");
			exit(1);
		}
	}

	if (status & MASTER) {
#ifdef MEASURE
		if (fp == NULL) {
			fp = fopen("/usr/adm/timed.masterlog", "w");
			setlinebuf(fp);
		}
#endif
		syslog(LOG_INFO, "THIS MACHINE IS A SUBMASTER");
		if (trace) {
			fprintf(fd, "THIS MACHINE IS A SUBMASTER\n");
		}
		for (ntp = nettab; ntp != NULL; ntp = ntp->next)
			if (ntp->status == MASTER)
				masterup(ntp);

	} else {
		syslog(LOG_INFO, "THIS MACHINE IS A SLAVE");
		if (trace) {
			fprintf(fd, "THIS MACHINE IS A SLAVE\n");
		}
	}

	seq = 0;
	senddateack = OFF;
	refusetime = 0;

	(void)gettimeofday(&time, (struct timezone *)0);
	electiontime = time.tv_sec + delay2;
	if (Mflag)
		if (justquit)
			looktime = time.tv_sec + delay2;
		else 
			looktime = 1;
	else
		looktime = 0;

loop:
	length = sizeof(struct sockaddr_in);
	(void)gettimeofday(&time, (struct timezone *)0);
	if (time.tv_sec > electiontime) {
		if (trace) 
			fprintf(fd, "election timer expired\n");
		longjmp(jmpenv, 1);
	}
	if (looktime && time.tv_sec > looktime) {
		if (trace) 
			fprintf(fd, "Looking for nets to master and loops\n");
		
		if (nignorednets > 0) {
			for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
				if (ntp->status == IGNORE) {
					lookformaster(ntp);
					if (ntp->status == MASTER)
						masterup(ntp);
					else
						ntp->status = IGNORE;
				}
			}
			setstatus();
#ifdef MEASURE
			/*
			 * Check to see if we just became master
			 * (file not open)
			 */
			if (fp == NULL) {
				fp = fopen("/usr/adm/timed.masterlog", "w");
				setlinebuf(fp);
			}
#endif
		}

		for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
		    if (ntp->status == MASTER) {
			to.tsp_type = TSP_LOOP;
			to.tsp_vers = TSPVERSION;
			to.tsp_seq = sequence++;
			to.tsp_hopcnt = 10;
			(void)strcpy(to.tsp_name, hostname);
			bytenetorder(&to);
			if (sendto(sock, (char *)&to, sizeof(struct tsp), 0,
			    &ntp->dest_addr, sizeof(struct sockaddr_in)) < 0) {
				syslog(LOG_ERR, "sendto: %m");
				exit(1);
			}
		    }
		}
		(void)gettimeofday(&time, (struct timezone *)0);
		looktime = time.tv_sec + delay2;
	}
	wait.tv_sec = electiontime - time.tv_sec + 10;
	wait.tv_usec = 0;
	msg = readmsg(TSP_ANY, (char *)ANYADDR, &wait, (struct netinfo *)NULL);
	if (msg != NULL) {
		switch (msg->tsp_type) {
		case TSP_SETDATE:
#ifdef TESTING
		case TSP_TEST:
#endif
		case TSP_MSITE:
		case TSP_TRACEOFF:
		case TSP_TRACEON:
			break;
		case TSP_MASTERUP:
			if (fromnet == NULL) {
				if (trace) {
					fprintf(fd, "slave ignored: ");
					print(msg, &from);
				}
				goto loop;
			}
			break;
		default:
			if (fromnet == NULL || fromnet->status == IGNORE) {
				if (trace) {
					fprintf(fd, "slave ignored: ");
					print(msg, &from);
				}
				goto loop;
			}
			break;
		}

		switch (msg->tsp_type) {

		case TSP_ADJTIME:
			if (fromnet->status != SLAVE)
				break;
			(void)gettimeofday(&time, (struct timezone *)0);
			electiontime = time.tv_sec + delay2;
			if (seq != msg->tsp_seq) {
				seq = msg->tsp_seq;
				if ((status & SUBMASTER) == SUBMASTER) {
					synch((msg->tsp_time.tv_sec * 1000) + 
					    (msg->tsp_time.tv_usec / 1000));
				} else {
					adjclock(&(msg->tsp_time));
				}
			}
			break;
		case TSP_SETTIME:
			if (fromnet->status != SLAVE)
				break;
			if (seq == msg->tsp_seq)
				break;

			seq = msg->tsp_seq;

			(void)strcpy(olddate, date());
			(void)gettimeofday(&otime, (struct timezone *)0);
			(void)settimeofday(&msg->tsp_time,
				(struct timezone *)0);
			syslog(LOG_NOTICE, "date changed by %s from: %s",
				msg->tsp_name, olddate);
			logwtmp(otime, msg->tsp_time);
			if ((status & SUBMASTER) == SUBMASTER)
				spreadtime();
			(void)gettimeofday(&time, (struct timezone *)0);
			electiontime = time.tv_sec + delay2;

			if (senddateack == ON) {
				senddateack = OFF;
				msg->tsp_type = TSP_DATEACK;
				(void)strcpy(msg->tsp_name, hostname);
				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_MASTERUP:
			if (slavenet && fromnet != slavenet)
				break;
			makeslave(fromnet);
			setstatus();
			msg->tsp_type = TSP_SLAVEUP;
			msg->tsp_vers = TSPVERSION;
			(void)strcpy(msg->tsp_name, hostname);
			bytenetorder(msg);
			answerdelay();
			length = sizeof(struct sockaddr_in);
			if (sendto(sock, (char *)msg, sizeof(struct tsp), 0, 
						&from, length) < 0) {
				syslog(LOG_ERR, "sendto: %m");
				exit(1);
			}
			backoff = 1;
			delay2 = casual((long)MINTOUT, (long)MAXTOUT);
			(void)gettimeofday(&time, (struct timezone *)0);
			electiontime = time.tv_sec + delay2;
			refusetime = 0;
			break;
		case TSP_MASTERREQ:
			if (fromnet->status != SLAVE)
				break;
			(void)gettimeofday(&time, (struct timezone *)0);
			electiontime = time.tv_sec + delay2;
			break;
		case TSP_SETDATE:
			saveaddr = from;
			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;
}
Ejemplo n.º 27
0
void
lookformaster(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 != NULL && !good_host_name(answer->tsp_name)) {
		suppress(&from, answer->tsp_name, ntp);
		ntp->status = NOMASTER;
		answer = NULL;
	}
	if (answer == NULL) {
		/*
		 * 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 != NULL) {
			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 != NULL) {
			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 != NULL) {
			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");
		}
	}
}
Ejemplo n.º 28
0
/*
 * The main function of `master' is to periodically compute the differences
 * (deltas) between its clock and the clocks of the slaves, to compute the
 * network average delta, and to send to the slaves the differences between
 * their individual deltas and the network delta.
 * While waiting, it receives messages from the slaves (i.e. requests for
 * master's name, remote requests to set the network time, ...), and
 * takes the appropriate action.
 */
int
master()
{
	struct hosttbl *htp;
	long pollingtime;
#define POLLRATE 4
	int polls;
	struct timeval wait, ntime;
	time_t tsp_time_sec;
	struct tsp *msg, *answer, to;
	char newdate[32];
	struct sockaddr_in taddr;
	char tname[MAXHOSTNAMELEN];
	struct netinfo *ntp;
	int i;

	syslog(LOG_NOTICE, "This machine is master");
	if (trace)
		fprintf(fd, "This machine is master\n");
	for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
		if (ntp->status == MASTER)
			masterup(ntp);
	}
	(void)gettimeofday(&ntime, 0);
	pollingtime = ntime.tv_sec+3;
	if (justquit)
		polls = 0;
	else
		polls = POLLRATE-1;

/* Process all outstanding messages before spending the long time necessary
 *	to update all timers.
 */
loop:
	(void)gettimeofday(&ntime, 0);
	wait.tv_sec = pollingtime - ntime.tv_sec;
	if (wait.tv_sec < 0)
		wait.tv_sec = 0;
	wait.tv_usec = 0;
	msg = readmsg(TSP_ANY, ANYADDR, &wait, 0);
	if (!msg) {
		(void)gettimeofday(&ntime, 0);
		if (ntime.tv_sec >= pollingtime) {
			pollingtime = ntime.tv_sec + SAMPLEINTVL;
			get_goodgroup(0);

/* If a bogus master told us to quit, we can have decided to ignore a
 * network.  Therefore, periodically try to take over everything.
 */
			polls = (polls + 1) % POLLRATE;
			if (0 == polls && nignorednets > 0) {
				trace_msg("Looking for nets to re-master\n");
				for (ntp = nettab; ntp; ntp = ntp->next) {
					if (ntp->status == IGNORE
					    || ntp->status == NOMASTER) {
						lookformaster(ntp);
						if (ntp->status == MASTER) {
							masterup(ntp);
							polls = POLLRATE-1;
						}
					}
					if (ntp->status == MASTER
					    && --ntp->quit_count < 0)
						ntp->quit_count = 0;
				}
				if (polls != 0)
					setstatus();
			}

			synch(0L);

			for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
				to.tsp_type = TSP_LOOP;
				to.tsp_vers = TSPVERSION;
				to.tsp_seq = sequence++;
				to.tsp_hopcnt = MAX_HOPCNT;
				(void)strcpy(to.tsp_name, hostname);
				bytenetorder(&to);
				if (sendto(sock, (char *)&to,
					   sizeof(struct tsp), 0,
					   (struct sockaddr*)&ntp->dest_addr,
					   sizeof(ntp->dest_addr)) < 0) {
				   trace_sendto_err(ntp->dest_addr.sin_addr);
				}
			}
		}


	} else {
		switch (msg->tsp_type) {

		case TSP_MASTERREQ:
			break;

		case TSP_SLAVEUP:
			newslave(msg);
			break;

		case TSP_SETDATE:
			/*
			 * XXX check to see it is from ourself
			 */
			tsp_time_sec = msg->tsp_time.tv_sec;
			(void)strcpy(newdate, ctime(&tsp_time_sec));
			if (!good_host_name(msg->tsp_name)) {
				syslog(LOG_NOTICE,
				       "attempted date change by %s to %s",
				       msg->tsp_name, newdate);
				spreadtime();
				break;
			}

			mchgdate(msg);
			(void)gettimeofday(&ntime, 0);
			pollingtime = ntime.tv_sec + SAMPLEINTVL;
			break;

		case TSP_SETDATEREQ:
			if (!fromnet || fromnet->status != MASTER)
				break;
			tsp_time_sec = msg->tsp_time.tv_sec;
			(void)strcpy(newdate, ctime(&tsp_time_sec));
			htp = findhost(msg->tsp_name);
			if (htp == 0) {
				syslog(LOG_ERR,
				       "attempted SET DATEREQ by uncontrolled %s to %s",
				       msg->tsp_name, newdate);
				break;
			}
			if (htp->seq == msg->tsp_seq)
				break;
			htp->seq = msg->tsp_seq;
			if (!htp->good) {
				syslog(LOG_NOTICE,
				"attempted SET DATEREQ by untrusted %s to %s",
				       msg->tsp_name, newdate);
				spreadtime();
				break;
			}

			mchgdate(msg);
			(void)gettimeofday(&ntime, 0);
			pollingtime = ntime.tv_sec + SAMPLEINTVL;
			break;

		case TSP_MSITE:
			xmit(TSP_ACK, msg->tsp_seq, &from);
			break;

		case TSP_MSITEREQ:
			break;

		case TSP_TRACEON:
			traceon();
			break;

		case TSP_TRACEOFF:
			traceoff("Tracing ended at %s\n");
			break;

		case TSP_ELECTION:
			if (!fromnet)
				break;
			if (fromnet->status == MASTER) {
				pollingtime = 0;
				(void)addmach(msg->tsp_name, &from,fromnet);
			}
			taddr = from;
			(void)strcpy(tname, msg->tsp_name);
			to.tsp_type = TSP_QUIT;
			(void)strcpy(to.tsp_name, hostname);
			answer = acksend(&to, &taddr, tname,
					 TSP_ACK, 0, 1);
			if (answer == NULL) {
				syslog(LOG_ERR, "election error by %s",
				       tname);
			}
			break;

		case TSP_CONFLICT:
			/*
			 * After a network partition, there can be
			 * more than one master: the first slave to
			 * come up will notify here the situation.
			 */
			if (!fromnet || fromnet->status != MASTER)
				break;
			(void)strcpy(to.tsp_name, hostname);

			/* The other master often gets into the same state,
			 * with boring results if we stay at it forever.
			 */
			ntp = fromnet;	/* (acksend() can leave fromnet=0 */
			for (i = 0; i < 3; i++) {
				to.tsp_type = TSP_RESOLVE;
				(void)strcpy(to.tsp_name, hostname);
				answer = acksend(&to, &ntp->dest_addr,
						 ANYADDR, TSP_MASTERACK,
						 ntp, 0);
				if (!answer)
					break;
				htp = addmach(answer->tsp_name,&from,ntp);
				to.tsp_type = TSP_QUIT;
				msg = acksend(&to, &htp->addr, htp->name,
					      TSP_ACK, 0, htp->noanswer);
				if (msg == NULL) {
					syslog(LOG_ERR,
				    "no response from %s to CONFLICT-QUIT",
					       htp->name);
				}
			}
			masterup(ntp);
			pollingtime = 0;
			break;

		case TSP_RESOLVE:
			if (!fromnet || fromnet->status != MASTER)
				break;
			/*
			 * do not want to call synch() while waiting
			 * to be killed!
			 */
			(void)gettimeofday(&ntime, (struct timezone *)0);
			pollingtime = ntime.tv_sec + SAMPLEINTVL;
			break;

		case TSP_QUIT:
			doquit(msg);		/* become a slave */
			break;

		case TSP_LOOP:
			if (!fromnet || fromnet->status != MASTER
			    || !strcmp(msg->tsp_name, hostname))
				break;
			/*
			 * We should not have received this from a net
			 * we are master on.  There must be two masters.
			 */
			htp = addmach(msg->tsp_name, &from,fromnet);
			to.tsp_type = TSP_QUIT;
			(void)strcpy(to.tsp_name, hostname);
			answer = acksend(&to, &htp->addr, htp->name,
					 TSP_ACK, 0, 1);
			if (!answer) {
				syslog(LOG_WARNING,
				"loop breakage: no reply from %s=%s to QUIT",
				    htp->name, inet_ntoa(htp->addr.sin_addr));
				(void)remmach(htp);
			}

		case TSP_TEST:
			if (trace) {
				fprintf(fd,
		"\tnets = %d, masters = %d, slaves = %d, ignored = %d\n",
		nnets, nmasternets, nslavenets, nignorednets);
				setstatus();
			}
			pollingtime = 0;
			polls = POLLRATE-1;
			break;

		default:
			if (trace) {
				fprintf(fd, "garbage message: ");
				print(msg, &from);
			}
			break;
		}
	}
	goto loop;
}
Ejemplo n.º 29
0
int
slave()
{
	int tries;
	long electiontime, refusetime, looktime, looptime, adjtime;
	u_short seq;
	long fastelection;
#define FASTTOUT 3
	struct in_addr cadr;
	struct timeval otime;
	struct sockaddr_in taddr;
	char tname[MAXHOSTNAMELEN];
	struct tsp *msg, to;
	struct timeval ntime, wait, tmptv;
	time_t tsp_time_sec;
	struct tsp *answer;
	int timeout();
	char olddate[32];
	char newdate[32];
	struct netinfo *ntp;
	struct hosttbl *htp;
	struct utmpx utx;


	old_slavenet = 0;
	seq = 0;
	refusetime = 0;
	adjtime = 0;

	(void)gettimeofday(&ntime, NULL);
	electiontime = ntime.tv_sec + delay2;
	fastelection = ntime.tv_sec + FASTTOUT;
	if (justquit)
		looktime = electiontime;
	else
		looktime = fastelection;
	looptime = fastelection;

	if (slavenet)
		xmit(TSP_SLAVEUP, 0, &slavenet->dest_addr);
	if (status & MASTER) {
		for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
			if (ntp->status == MASTER)
				masterup(ntp);
		}
	}

loop:
	get_goodgroup(0);
	(void)gettimeofday(&ntime, NULL);
	if (ntime.tv_sec > electiontime) {
		if (trace)
			fprintf(fd, "election timer expired\n");
		longjmp(jmpenv, 1);
	}

	if (ntime.tv_sec >= looktime) {
		if (trace)
			fprintf(fd, "Looking for nets to master\n");

		if (Mflag && nignorednets > 0) {
			for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
				if (ntp->status == IGNORE
				    || ntp->status == NOMASTER) {
					lookformaster(ntp);
					if (ntp->status == MASTER) {
						masterup(ntp);
					} else if (ntp->status == MASTER) {
						ntp->status = NOMASTER;
					}
				}
				if (ntp->status == MASTER
				    && --ntp->quit_count < 0)
					ntp->quit_count = 0;
			}
			makeslave(slavenet);	/* prune extras */
			setstatus();
		}
		(void)gettimeofday(&ntime, NULL);
		looktime = ntime.tv_sec + delay2;
	}
	if (ntime.tv_sec >= looptime) {
		if (trace)
			fprintf(fd, "Looking for loops\n");
		for (ntp = nettab; ntp != NULL; ntp = ntp->next) {
		    if (ntp->status == MASTER) {
			to.tsp_type = TSP_LOOP;
			to.tsp_vers = TSPVERSION;
			to.tsp_seq = sequence++;
			to.tsp_hopcnt = MAX_HOPCNT;
			(void)strcpy(to.tsp_name, hostname);
			bytenetorder(&to);
			if (sendto(sock, (char *)&to, sizeof(struct tsp), 0,
				   (struct sockaddr*)&ntp->dest_addr,
				   sizeof(ntp->dest_addr)) < 0) {
				trace_sendto_err(ntp->dest_addr.sin_addr);
			}
		    }
		}
		(void)gettimeofday(&ntime, NULL);
		looptime = ntime.tv_sec + delay2;
	}

	wait.tv_sec = min(electiontime,min(looktime,looptime)) - ntime.tv_sec;
	if (wait.tv_sec < 0)
		wait.tv_sec = 0;
	wait.tv_sec += FASTTOUT;
	wait.tv_usec = 0;
	msg = readmsg(TSP_ANY, ANYADDR, &wait, 0);

	if (msg != NULL) {
		/*
		 * filter stuff not for us
		 */
		switch (msg->tsp_type) {
		case TSP_SETDATE:
		case TSP_TRACEOFF:
		case TSP_TRACEON:
			/*
			 * XXX check to see they are from ourself
			 */
			break;

		case TSP_TEST:
		case TSP_MSITE:
			break;

		case TSP_MASTERUP:
			if (!fromnet) {
				if (trace) {
					fprintf(fd, "slave ignored: ");
					print(msg, &from);
				}
				goto loop;
			}
			break;

		default:
			if (!fromnet
			    || fromnet->status == IGNORE
			    || fromnet->status == NOMASTER) {
				if (trace) {
					fprintf(fd, "slave ignored: ");
					print(msg, &from);
				}
				goto loop;
			}
			break;
		}


		/*
		 * now process the message
		 */
		switch (msg->tsp_type) {

		case TSP_ADJTIME:
			if (fromnet != slavenet)
				break;
			if (!good_host_name(msg->tsp_name)) {
				syslog(LOG_NOTICE,
				   "attempted time adjustment by %s",
				       msg->tsp_name);
				suppress(&from, msg->tsp_name, fromnet);
				break;
			}
			/*
			 * Speed up loop detection in case we have a loop.
			 * Otherwise the clocks can race until the loop
			 * is found.
			 */
			(void)gettimeofday(&otime, NULL);
			if (adjtime < otime.tv_sec)
				looptime -= (looptime-otime.tv_sec)/2 + 1;

			setmaster(msg);
			if (seq != msg->tsp_seq) {
				seq = msg->tsp_seq;
				synch(tvtomsround(msg->tsp_time));
			}
			(void)gettimeofday(&ntime, NULL);
			electiontime = ntime.tv_sec + delay2;
			fastelection = ntime.tv_sec + FASTTOUT;
			adjtime = ntime.tv_sec + SAMPLEINTVL*2;
			break;

		case TSP_SETTIME:
			if (fromnet != slavenet)
				break;
			if (seq == msg->tsp_seq)
				break;
			seq = msg->tsp_seq;

			/* adjust time for residence on the queue */
			(void)gettimeofday(&otime, NULL);
			adj_msg_time(msg,&otime);
			/*
			 * the following line is necessary due to syslog
			 * calling ctime() which clobbers the static buffer
			 */
			(void)strcpy(olddate, date());
			tsp_time_sec = msg->tsp_time.tv_sec;
			(void)strcpy(newdate, ctime(&tsp_time_sec));

			if (!good_host_name(msg->tsp_name)) {
				syslog(LOG_NOTICE,
			    "attempted time setting by untrusted %s to %s",
				       msg->tsp_name, newdate);
				suppress(&from, msg->tsp_name, fromnet);
				break;
			}

			setmaster(msg);
 			tmptv.tv_sec = msg->tsp_time.tv_sec;
 			tmptv.tv_usec = msg->tsp_time.tv_usec;
			timevalsub(&ntime, &tmptv, &otime);
			if (ntime.tv_sec < MAXADJ && ntime.tv_sec > -MAXADJ) {
				/*
				 * do not change the clock if we can adjust it
				 */
				synch(tvtomsround(ntime));
			} else {
				utx.ut_type = OLD_TIME;
				gettimeofday(&utx.ut_tv, NULL);
				pututxline(&utx);
				(void)settimeofday(&tmptv, 0);
				utx.ut_type = NEW_TIME;
				gettimeofday(&utx.ut_tv, NULL);
				pututxline(&utx);
				syslog(LOG_NOTICE,
				       "date changed by %s from %s",
					msg->tsp_name, olddate);
				if (status & MASTER)
					spreadtime();
			}
			(void)gettimeofday(&ntime, NULL);
			electiontime = ntime.tv_sec + delay2;
			fastelection = ntime.tv_sec + FASTTOUT;

/* This patches a bad protocol bug.  Imagine a system with several networks,
 * where there are a pair of redundant gateways between a pair of networks,
 * each running timed.  Assume that we start with a third machine mastering
 * one of the networks, and one of the gateways mastering the other.
 * Imagine that the third machine goes away and the non-master gateway
 * decides to replace it.  If things are timed just 'right,' we will have
 * each gateway mastering one network for a little while.  If a SETTIME
 * message gets into the network at that time, perhaps from the newly
 * masterful gateway as it was taking control, the SETTIME will loop
 * forever.  Each time a gateway receives it on its slave side, it will
 * call spreadtime to forward it on its mastered network.  We are now in
 * a permanent loop, since the SETTIME msgs will keep any clock
 * in the network from advancing.  Normally, the 'LOOP' stuff will detect
 * and correct the situation.  However, with the clocks stopped, the
 * 'looptime' timer cannot expire.  While they are in this state, the
 * masters will try to saturate the network with SETTIME packets.
 */
			looptime = ntime.tv_sec + (looptime-otime.tv_sec)/2-1;
			break;

		case TSP_MASTERUP:
			if (slavenet && fromnet != slavenet)
				break;
			if (!good_host_name(msg->tsp_name)) {
				suppress(&from, msg->tsp_name, fromnet);
				if (electiontime > fastelection)
					electiontime = fastelection;
				break;
			}
			makeslave(fromnet);
			setmaster(msg);
			setstatus();
			answerdelay();
			xmit(TSP_SLAVEUP, 0, &from);
			(void)gettimeofday(&ntime, NULL);
			electiontime = ntime.tv_sec + delay2;
			fastelection = ntime.tv_sec + FASTTOUT;
			refusetime = 0;
			break;

		case TSP_MASTERREQ:
			if (fromnet->status != SLAVE)
				break;
			(void)gettimeofday(&ntime, NULL);
			electiontime = ntime.tv_sec + delay2;
			break;

		case TSP_SETDATE:
			tsp_time_sec = msg->tsp_time.tv_sec;
			(void)strcpy(newdate, ctime(&tsp_time_sec));
			schgdate(msg, newdate);
			break;

		case TSP_SETDATEREQ:
			if (fromnet->status != MASTER)
				break;
			tsp_time_sec = msg->tsp_time.tv_sec;
			(void)strcpy(newdate, ctime(&tsp_time_sec));
			htp = findhost(msg->tsp_name);
			if (0 == htp) {
				syslog(LOG_WARNING,
				       "DATEREQ from uncontrolled machine");
				break;
			}
			if (!htp->good) {
				syslog(LOG_WARNING,
				"attempted date change by untrusted %s to %s",
				       htp->name, newdate);
				spreadtime();
				break;
			}
			schgdate(msg, newdate);
			break;

		case TSP_TRACEON:
			traceon();
			break;

		case TSP_TRACEOFF:
			traceoff("Tracing ended at %s\n");
			break;

		case TSP_SLAVEUP:
			newslave(msg);
			break;

		case TSP_ELECTION:
			if (fromnet->status == SLAVE) {
				(void)gettimeofday(&ntime, NULL);
				electiontime = ntime.tv_sec + delay2;
				fastelection = ntime.tv_sec + FASTTOUT;
				seq = 0;
				if (!good_host_name(msg->tsp_name)) {
					syslog(LOG_NOTICE,
					       "suppress election of %s",
					       msg->tsp_name);
					to.tsp_type = TSP_QUIT;
					electiontime = fastelection;
				} else if (cadr.s_addr != from.sin_addr.s_addr
					   && ntime.tv_sec < refusetime) {
/* if the candidate has to repeat itself, the old code would refuse it
 * the second time.  That would prevent elections.
 */
					to.tsp_type = TSP_REFUSE;
				} else {
					cadr.s_addr = from.sin_addr.s_addr;
					to.tsp_type = TSP_ACCEPT;
					refusetime = ntime.tv_sec + 30;
				}
				taddr = from;
				(void)strcpy(tname, msg->tsp_name);
				(void)strcpy(to.tsp_name, hostname);
				answerdelay();
				if (!acksend(&to, &taddr, tname,
					     TSP_ACK, 0, 0))
					syslog(LOG_WARNING,
					     "no answer from candidate %s\n",
					       tname);

			} else {	/* fromnet->status == MASTER */
				htp = addmach(msg->tsp_name, &from,fromnet);
				to.tsp_type = TSP_QUIT;
				(void)strcpy(to.tsp_name, hostname);
				if (!acksend(&to, &htp->addr, htp->name,
					     TSP_ACK, 0, htp->noanswer)) {
					syslog(LOG_ERR,
					  "no reply from %s to ELECTION-QUIT",
					       htp->name);
					(void)remmach(htp);
				}
			}
			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);

			/* The other master often gets into the same state,
			 * with boring results.
			 */
			ntp = fromnet;	/* (acksend() can leave fromnet=0 */
			for (tries = 0; tries < 3; tries++) {
				to.tsp_type = TSP_RESOLVE;
				answer = acksend(&to, &ntp->dest_addr,
						 ANYADDR, TSP_MASTERACK,
						 ntp, 0);
				if (answer == NULL)
					break;
				htp = addmach(answer->tsp_name,&from,ntp);
				to.tsp_type = TSP_QUIT;
				answer = acksend(&to, &htp->addr, htp->name,
						 TSP_ACK, 0, htp->noanswer);
				if (!answer) {
					syslog(LOG_WARNING,
				  "conflict error: no reply from %s to QUIT",
						htp->name);
					(void)remmach(htp);
				}
			}
			masterup(ntp);
			break;

		case TSP_MSITE:
			if (!slavenet)
				break;
			taddr = from;
			to.tsp_type = TSP_MSITEREQ;
			to.tsp_vers = TSPVERSION;
			to.tsp_seq = 0;
			(void)strcpy(to.tsp_name, hostname);
			answer = acksend(&to, &slavenet->dest_addr,
					 ANYADDR, TSP_ACK,
					 slavenet, 0);
			if (answer != NULL
			    && good_host_name(answer->tsp_name)) {
				setmaster(answer);
				to.tsp_type = TSP_ACK;
				(void)strcpy(to.tsp_name, answer->tsp_name);
				bytenetorder(&to);
				if (sendto(sock, (char *)&to,
					   sizeof(struct tsp), 0,
					   (struct sockaddr*)&taddr,
					   sizeof(taddr)) < 0) {
					trace_sendto_err(taddr.sin_addr);
				}
			}
			break;

		case TSP_MSITEREQ:
			break;

		case TSP_ACCEPT:
		case TSP_REFUSE:
		case TSP_RESOLVE:
			break;

		case TSP_QUIT:
			doquit(msg);		/* become a slave */
			break;

		case TSP_TEST:
			electiontime = 0;
			break;

		case TSP_LOOP:
			/* looking for loops of masters */
			if (!(status & MASTER))
				break;
			if (fromnet->status == SLAVE) {
			    if (!strcmp(msg->tsp_name, hostname)) {
				/*
				 * Someone forwarded our message back to
				 * us.  There must be a loop.  Tell the
				 * master of this network to quit.
				 *
				 * The other master often gets into
				 * the same state, with boring results.
				 */
				ntp = fromnet;
				for (tries = 0; tries < 3; tries++) {
				    to.tsp_type = TSP_RESOLVE;
				    answer = acksend(&to, &ntp->dest_addr,
						     ANYADDR, TSP_MASTERACK,
						     ntp,0);
				    if (answer == NULL)
					break;
				    taddr = from;
				    (void)strcpy(tname, answer->tsp_name);
				    to.tsp_type = TSP_QUIT;
				    (void)strcpy(to.tsp_name, hostname);
				    if (!acksend(&to, &taddr, tname,
						 TSP_ACK, 0, 1)) {
					syslog(LOG_ERR,
					"no reply from %s to slave LOOP-QUIT",
						 tname);
				    } else {
					electiontime = 0;
				    }
				}
				(void)gettimeofday(&ntime, NULL);
				looptime = ntime.tv_sec + FASTTOUT;
			    } else {
				if (msg->tsp_hopcnt-- < 1)
				    break;
				bytenetorder(msg);
				for (ntp = nettab; ntp != 0; ntp = ntp->next) {
				    if (ntp->status == MASTER
					&& 0 > sendto(sock, (char *)msg,
						      sizeof(struct tsp), 0,
					      (struct sockaddr*)&ntp->dest_addr,
						      sizeof(ntp->dest_addr)))
				    trace_sendto_err(ntp->dest_addr.sin_addr);
				}
			    }
			} else {	/* fromnet->status == MASTER */
			    /*
			     * We should not have received this from a net
			     * we are master on.  There must be two masters,
			     * unless the packet was really from us.
			     */
			    if (from.sin_addr.s_addr
				== fromnet->my_addr.s_addr) {
				if (trace)
				    fprintf(fd,"discarding forwarded LOOP\n");
				break;
			    }

			    /*
			     * The other master often gets into the same
			     * state, with boring results.
			     */
			    ntp = fromnet;
			    for (tries = 0; tries < 3; tries++) {
				to.tsp_type = TSP_RESOLVE;
				answer = acksend(&to, &ntp->dest_addr,
						 ANYADDR, TSP_MASTERACK,
						ntp,0);
				if (!answer)
					break;
				htp = addmach(answer->tsp_name,
					      &from,ntp);
				to.tsp_type = TSP_QUIT;
				(void)strcpy(to.tsp_name, hostname);
				if (!acksend(&to,&htp->addr,htp->name,
					     TSP_ACK, 0, htp->noanswer)) {
					syslog(LOG_ERR,
				    "no reply from %s to master LOOP-QUIT",
					       htp->name);
					(void)remmach(htp);
				}
			    }
			    (void)gettimeofday(&ntime, NULL);
			    looptime = ntime.tv_sec + FASTTOUT;
			}
			break;
		default:
			if (trace) {
				fprintf(fd, "garbage message: ");
				print(msg, &from);
			}
			break;
		}
	}
	goto loop;
}
Ejemplo n.º 30
0
void multiplexer(int listener)
{
	fd_set readfds, masterfd;
	FD_ZERO(&readfds);
	FD_ZERO(&masterfd);
	FD_SET(listener, &masterfd);
	FD_SET(STDIN, &masterfd);
	int fdmax;

	socklen_t addrsize;
	struct sockaddr_storage their_addr;
	int inbytes,  new_fd, var;
	char outmsg[1024], inmsg[1024];
	char incoming_IP[INET6_ADDRSTRLEN]; //Extra size doesn't hurt
	fdmax = listener;
	
	while(1)
	{
		readfds = masterfd;
		if (select(fdmax+1, &readfds, NULL, NULL, NULL) == -1) 
		{
 			perror("select");
 			exit(4);
 		}
 		for(int i=0; i<=fdmax; i++)
		{	
			if(FD_ISSET(i, &readfds))
			{
				if(i==listener)
				{
					addrsize = sizeof their_addr;
					if((new_fd = accept(listener, (struct sockaddr *)&their_addr, &addrsize)) == -1) 
					{
						perror("server: accept error");
					}
					else
					{
						char c[1024];
						FD_SET(new_fd, &masterfd); // add to master set
						if (new_fd > fdmax) 
							fdmax = new_fd;
						inet_ntop(their_addr.ss_family, get_in_addr(&their_addr), incoming_IP, INET6_ADDRSTRLEN);
						printf("Server received a connection from %s on socket %d\n",incoming_IP, new_fd);
						getnick(new_fd, c);
						client_t *cli = (client_t *)malloc(sizeof(client_t));
						cli->connfd = new_fd;
						cli->uid = uid++;
						sprintf(cli->name, "%s", c);
						/* Add client to the queue */
						queue_add(cli);
						var = get_index(new_fd);
						sprintf(outmsg, "%s %s %s", "||| WELCOME",clients[var]->name, "|||\n");
						send_private(new_fd, outmsg);
						sprintf(outmsg, "%s joined the room\n",clients[var]->name);
						printf("%s", outmsg); //display on server
						broadcast_msg(new_fd, outmsg, &masterfd, fdmax, listener);
					}
				}
				else if(i == 0)
			    {
					if(fgets(outmsg, 1023, stdin)==NULL) 
						return ; 
					else
					{	
						char out[1024];
						sprintf(out, "%s %s","[Server] : ", outmsg);
						broadcast_msg(i, out, &masterfd, fdmax, listener);
					}
				}
				else //Only case left is that a client got some data
				{
					var = get_index(i);
					if(readmsg(i, 1023, inmsg))
					{
						printf("[%s] : %s", clients[var]->name, inmsg); //display on server
						sprintf(outmsg, "[%s] : %s",clients[var]->name, inmsg);
						broadcast_msg(i, outmsg, &masterfd, fdmax, listener);
					}
					else
					{
						printf("%s left the room\n", clients[var]->name); //display on server
						sprintf(outmsg, "%s %s",clients[var]->name, "left the room\n");
						broadcast_msg(i, outmsg, &masterfd, fdmax, listener);
						FD_CLR(i, &masterfd);
						close(i);
						queue_delete(i);
					}
				}
			}
		}		
	}
}