Пример #1
0
/* This is for register side. */
static void register_thread_listen(
	int* tcp, 
	int* exit_time)
{
	/*******/
	/* TCP */
	/*******/

	struct sockaddr_in server_addr;
	int on = 1;

	if ((*tcp = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
	{
/*		perror("Socket");*/
		return;
	}
	
	server_addr.sin_family = AF_INET;         
	server_addr.sin_port = htons(NL_REGISTER_PORT);
	server_addr.sin_addr.s_addr = INADDR_ANY; 
	memset(&(server_addr.sin_zero), 0, 8); 
	
	// Re-use socket if you can.
	setsockopt(tcp, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

	if(bind(*tcp, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)) < 0) 
	{
		LOG("Unable to bind. Make sure no other instance of register is running.");
		return;
	}

	if(listen(*tcp, 5) < 0)
	{
		/*perror("Listen");*/
		return;
	}

	do
	{
		socklen_t sin_size = sizeof(struct sockaddr_in);
		struct sockaddr_in s;
		long int socket = accept(*tcp, (struct sockaddr*)&s, &sin_size);
		char buffer[NL_BUFFER_SIZE+1];

		LOG("I got a connection from (%s, %d)", inet_ntoa(s.sin_addr), ntohs(s.sin_port));

		if(!nl_tcp_rcv(buffer, socket))
			break;
		
		if(buffer[0] == 'C') /* A clients wants to know who already registered. */
		{
			client* c = (client*)mmalloc(sizeof(client));
			int port; /* Client's UDP port */
			
			c->socket = socket;

			#warning Check for errors.
			sscanf(buffer + 2, "%d", &port); /* Client's UDP port */

			/*
			 * TODO: Shall we have a limit of peer that can connect? 
			 * 		 Let's say, 2000?
			 */

			/* This should be the UDP port we can connect on. */
			s.sin_port = htons(port);
			c->addr = s;
			
			LOG("Client's UDP port: %d.", port);
			
			lock_init(c);
			thread_detached(c->t, tcp_register_client_thread, (void*)c);
		}
		else if(buffer[0] == 'S') /* A server wants to register. */
		{
			char* remember;
			server_game* g = (server_game*)mmalloc(sizeof(server_game));
				
			/*
			 * Packet format:
			 * 
			 * port internal_address name
			 */
			#warning Check for errors.
			int port;

			sscanf(_strtok_r(buffer + 2, " ", &remember), "%d", &port); /* Server's TCP port */
			char* internal_ip = _strtok_r(NULL, " ", &remember);
			char* name = _strtok_r(NULL, "\n", &remember);  /* Server's name */
			
			g->socket = socket;
			
			/* This should be the TCP port we can connect on. */
			s.sin_port = htons(port);

			/*
			 * First: Check if we can connect to this address from
			 * 		  outside. If not, there's no need to continue:
			 * 		  nobody will be able to connect to it!
			 */

			if(!nl_test_connection(s))
			{
				LOG("Some server tried to connect, but I "
					   "cannot reach it from the other side.\nAborting.");
				
				nl_tcp_snd("I", socket); /* Impossible to connect. */
				mfree(g);
				continue;
			}
			
			/* Here, we check if the provided server name already exists
			* in the server list. If so, return Nack. */
			if(rGetByKey(&game_server_array, buffer, NULL) != NULL)
			{
				LOG("Game server with the same exists. Aborting.");
				nl_tcp_snd("N", socket);
				mfree(g);
				continue;
			}

			nl_tcp_snd("O", socket); /* It's okay. */
			
			LOG("Success: Server with TCP port %d added.", port);

			g->name = m_strdup(name);

			g->addr = s;
			g->internal_ip = m_strdup(internal_ip);
			
			lock_init(g);
			thread_detached(g->t, tcp_register_server_thread, (void*)g);
		}
		else if(buffer[0] == 'N') /* N is used when trying to quit. */
		{
			LOG("Exit message.");
		}
	}
	while(!(*exit_time));
	
	close(*tcp);
	LOG("Socket closed.");
}
Пример #2
0
/* open the text dict */
static xdict_t _xdict_open_txt(const char *fpath, int mode, unsigned char *ml)
{
	xdict_t xd;
	xtree_t xt;
	char buf[XDICT_PATH_MAX], tmpfile[XDICT_PATH_MAX];
	struct stat st1, st2;

	// check the input filepath
	_realpath(fpath, buf);
	if (stat(buf, &st1) < 0)
		return NULL;

	// check dest file & orginal file, compare there mtime
#ifdef WIN32
	{
		char *tmp_ptr;
		GetTempPath(sizeof(tmpfile) - 20, tmpfile);
		tmp_ptr = tmpfile + strlen(tmpfile);
		if (tmp_ptr[-1] == '\\') tmp_ptr--;
		sprintf(tmp_ptr, "\\scws-%08x.xdb", scws_crc32(buf));
	}
#else
	sprintf(tmpfile, "/tmp/scws-%08x.xdb", scws_crc32(buf));
#endif
	if (!stat(tmpfile, &st2) && st2.st_mtime > st1.st_mtime)
	{
		xdb_t x;
		if ((x = xdb_open(tmpfile, 'r')) != NULL)
		{
			xd = (xdict_t) malloc(sizeof(xdict_st));
			memset(xd, 0, sizeof(xdict_st));
			xd->ref = 1;

			if (mode & SCWS_XDICT_MEM)
			{
				/* convert the xdb(disk) -> xtree(memory) */
				if ((xt = xdb_to_xtree(x, NULL)) != NULL)
				{
					xdb_close(x);
					xd->xdict = (void *) xt;
					xd->xmode = SCWS_XDICT_MEM;
					return xd;
				}
			}
			xd->xmode = SCWS_XDICT_XDB;
			xd->xdict = (void *) x;
			return xd;
		}
	}

	// create xtree
	if ((xt = xtree_new(0, 0)) == NULL)
		return NULL;
	else
	{
		int cl, kl;
		FILE *fp;
		word_st word, *w;
		char *key, *part, *last, *delim = " \t\r\n";

		// re-build the xdb file from text file	
		if ((fp = fopen(buf, "r")) == NULL)
			return NULL;

		// parse every line
		word.attr[2] = '\0';
		while (fgets(buf, sizeof(buf) - 1, fp) != NULL)
		{
			// <word>[\t<tf>[\t<idf>[\t<attr>]]]		
			if (buf[0] == ';' || buf[0] == '#') continue;

			key = _strtok_r(buf, delim, &last);
			if (key == NULL) continue;
			kl = strlen(key);

			// init the word
			do
			{
				word.tf = word.idf = 1.0;
				word.flag = SCWS_WORD_FULL;
				word.attr[0] = '@';
				word.attr[1] = '\0';

				if (!(part = _strtok_r(NULL, delim, &last))) break;
				word.tf = (float) atof(part);

				if (!(part = _strtok_r(NULL, delim, &last))) break;
				word.idf = (float) atof(part);

				if ((part = _strtok_r(NULL, delim, &last)))
				{
					word.attr[0] = part[0];
					if (part[1]) word.attr[1] = part[1];
				}
			}
			while (0);

			// save into xtree
			if ((w = xtree_nget(xt, key, kl, NULL)) == NULL)
			{
				w = (word_st *) pmalloc(xt->p, sizeof(word_st));
				memcpy(w, &word, sizeof(word));
				xtree_nput(xt, w, sizeof(word), key, kl);
			}
			else
			{
				w->tf = word.tf;
				w->idf = word.idf;
				w->flag |= word.flag;
				strcpy(w->attr, word.attr);
			}

			// parse the part	
			cl = ml[(unsigned char) (key[0])];
			while (1)
			{
				cl += ml[(unsigned char) (key[cl])];
				if (cl >= kl) break;

				if ((w = xtree_nget(xt, key, cl, NULL)) != NULL)
					w->flag |= SCWS_WORD_PART;
				else
				{
					w = (word_st *) pmalloc_z(xt->p, sizeof(word_st));
					w->flag = SCWS_WORD_PART;
					xtree_nput(xt, w, sizeof(word), key, cl);
				}
			}
		}
		fclose(fp);

		// optimize the xtree & save to xdb
		xtree_optimize(xt);
		unlink(tmpfile);
		xtree_to_xdb(xt, tmpfile);
		chmod(tmpfile, 0777);

		// return xtree
		xd = (xdict_t) malloc(sizeof(xdict_st));
		memset(xd, 0, sizeof(xdict_st));
		xd->ref = 1;
		xd->xdict = (void *) xt;
		xd->xmode = SCWS_XDICT_MEM;
		return xd;
	}
}