All pastes #622273 Raw Edit

Anonymous

public c v1 · immutable
·published 2007-07-16 19:31 UTC
rendered paste body
//returns true if the pending proxy should be unlinked//truth does not imply that it should be freed/released, just unlinked.qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend){	char tempbuf[512];	char *s;	char *e;	char *colon;	float clientversion = 0;	int len;	int headersize;	qboolean raw;	sv_t *qtv;	if (pend->drop)	{		if (pend->srcfile)			fclose(pend->srcfile);		closesocket(pend->sock);		free(pend);		cluster->numproxies--;		return true;	}#define QTVSVHEADER "QTVSV 1.1\n"	Net_TryFlushProxyBuffer(cluster, pend);	if (pend->flushing)	{		if (pend->bufferpos == pend->buffersize)		{			if (pend->srcfile)			{				char buffer[4096];				len = fread(buffer, 1, sizeof(buffer), pend->srcfile);				if (!len)				{					fclose(pend->srcfile);					pend->srcfile = NULL;				}				Net_ProxySend(cluster, pend, buffer, len);				return false;	//don't try reading anything yet			}			else			{				pend->drop = true;				return false;			}		}		else			return false;	}	if (pend->droptime < cluster->curtime)	{		pend->drop = true;		return false;	}	len = sizeof(pend->inbuffer) - pend->inbuffersize - 1;	len = recv(pend->sock, pend->inbuffer+pend->inbuffersize, len, 0);	if (len == 0)	{		pend->drop = true;		return false;	}	if (len < 0)		return false;	pend->inbuffersize += len;	pend->inbuffer[pend->inbuffersize] = '\0';	if (pend->inbuffersize >= 4)	{		if (strncmp(pend->inbuffer, "QTV\r", 4) && strncmp(pend->inbuffer, "QTV\n", 4) && strncmp(pend->inbuffer, "GET ", 4) && strncmp(pend->inbuffer, "POST ", 5))		{	//I have no idea what the smeg you are.			pend->drop = true;			return false;		}	}	//make sure there's a double \n somewhere	for (s = pend->inbuffer; *s; s++)	{		if (s[0] == '\n' && (s[1] == '\n' || (s[1] == '\r' && s[2] == '\n')))			break;	}	if (!*s)		return false;	//don't have enough yet	s+=3;	headersize = s - pend->inbuffer - 1;	if (!strncmp(pend->inbuffer, "POST ", 5))	{		HTTPSV_PostMethod(cluster, pend, s);		return false;	//not keen on this..	}	else if (!strncmp(pend->inbuffer, "GET ", 4))	{		HTTPSV_GetMethod(cluster, pend);		pend->flushing = true;		return false;	}	raw = false;	qtv = pend->defaultstream;	e = pend->inbuffer;	s = e;	while(*e)	{		if (*e == '\n' || *e == '\r')		{			*e = '\0';			colon = strchr(s, ':');			if (*s)			{				if (!colon)				{					if (!strcmp(s, "QTV"))					{						//just a qtv request (as in, not http or some other protocol)					}					else if (!strcmp(s, "SOURCELIST"))					{	//lists sources that are currently playing						s = QTVSVHEADER;							Net_ProxySend(cluster, pend, s, strlen(s));						if (!cluster->servers)						{							s = "PERROR: No sources currently available\n";								Net_ProxySend(cluster, pend, s, strlen(s));						}						else						{							for (qtv = cluster->servers; qtv; qtv = qtv->next)							{								s = tempbuf;								if (clientversion > 1)								{									int plyrs = 0;									int i;									for (i = 0; i < MAX_CLIENTS; i++)									{										if (*qtv->players[i].userinfo)											plyrs++;									}									sprintf(tempbuf, "SRCSRV: %s\n", qtv->server);									Net_ProxySend(cluster, pend, s, strlen(s));									sprintf(tempbuf, "SRCHOST: %s\n", qtv->hostname);									Net_ProxySend(cluster, pend, s, strlen(s));									sprintf(tempbuf, "SRCPLYRS: %i\n", plyrs);									Net_ProxySend(cluster, pend, s, strlen(s));									sprintf(tempbuf, "SRCVIEWS: %i\n", qtv->numviewers);									Net_ProxySend(cluster, pend, s, strlen(s));									sprintf(tempbuf, "SRCID: %i\n", qtv->streamid);	//final part of each source									Net_ProxySend(cluster, pend, s, strlen(s));								}								else								{									sprintf(tempbuf, "ASOURCE: %i: %15s: %15s\n", qtv->streamid, qtv->server, qtv->hostname);									Net_ProxySend(cluster, pend, s, strlen(s));								}							}							qtv = NULL;						}						s = "\n";							Net_ProxySend(cluster, pend, s, strlen(s));						pend->flushing = true;					}					else if (!strcmp(s, "REVERSE"))					{	//this is actually a server trying to connect to us						//start up a new stream						//FIXME: does this work?#if 1	//left disabled until properly tested						qtv = QTV_NewServerConnection(cluster, "reverse"/*server*/, "", true, 2, false, 0);						s = QTVSVHEADER;		Net_ProxySend(cluster, pend, s, strlen(s));						s = "REVERSED\n";		Net_ProxySend(cluster, pend, s, strlen(s));						s = "VERSION: 1\n";		Net_ProxySend(cluster, pend, s, strlen(s));						s = "\n";				Net_ProxySend(cluster, pend, s, strlen(s));						//switch over the socket to the actual source connection rather than the pending						Net_TryFlushProxyBuffer(cluster, pend); //flush anything... this isn't ideal, but should be small enough						qtv->sourcesock = pend->sock;						pend->sock = 0;						memcpy(qtv->buffer, pend->inbuffer + headersize, pend->inbuffersize - headersize);						qtv->parsingqtvheader = true;						return false;#endif					}					else if (!strcmp(s, "RECEIVE"))					{	//a client connection request without a source						if (cluster->numservers == 1)						{	//only one stream anyway							qtv = cluster->servers;						}						else						{	//try and hunt down an explicit stream (rather than a user-recorded one)							int numfound = 0;							sv_t *suitable;							for (qtv = cluster->servers; qtv; qtv = qtv->next)							{								if (!qtv->disconnectwhennooneiswatching)								{									suitable = qtv;									numfound++;								}							}							if (numfound == 1)								qtv = suitable;						}						if (!qtv)						{							s = QTVSVHEADER;								Net_ProxySend(cluster, pend, s, strlen(s));							s = "PERROR: Multiple streams are currently playing\n";								Net_ProxySend(cluster, pend, s, strlen(s));							s = "\n";								Net_ProxySend(cluster, pend, s, strlen(s));							pend->flushing = true;						}					}					else if (!strcmp(s, "DEMOLIST"))					{	//lists sources that are currently playing						int i;						Cluster_BuildAvailableDemoList(cluster);						s = QTVSVHEADER;							Net_ProxySend(cluster, pend, s, strlen(s));						if (!cluster->availdemoscount)						{							s = "PERROR: No demos currently available\n";								Net_ProxySend(cluster, pend, s, strlen(s));						}						else						{							for (i = 0; i < cluster->availdemoscount; i++)							{								sprintf(tempbuf, "ADEMO: %i: %15s\n", cluster->availdemos[i].size, cluster->availdemos[i].name);								s = tempbuf;								Net_ProxySend(cluster, pend, s, strlen(s));							}							qtv = NULL;						}						s = "\n";							Net_ProxySend(cluster, pend, s, strlen(s));						pend->flushing = true;					}					else if (!strcmp(s, "AUTH"))					{	//lists the demos available on this proxy						//part of the connection process, can be ignored if there's no password					}					else						printf("Unrecognised token in QTV connection request (%s)\n", s);				}				else				{					*colon++ = '\0';					if (!strcmp(s, "VERSION"))					{						clientversion = atof(colon);					}					else if (!strcmp(s, "RAW"))						raw = atoi(colon);					/*else if (!strcmp(s, "ROUTE"))					{	//pure rewroute...						//is this safe? probably not.						s = "QTVSV 1\n"							"PERROR: ROUTE command not yet implemented\n"							"\n";						Net_ProxySend(cluster, pend, s, strlen(s));						pend->flushing = true;					}					*/					else if (!strcmp(s, "SOURCE"))					{	//connects, creating a new source						while (*colon == ' ')							colon++;						for (s = colon; *s; s++)							if (*s < '0' || *s > '9')								break;						if (*s)							qtv = QTV_NewServerConnection(cluster, colon, "", false, true, true, false);						else						{							//numerical source, use a stream id.							for (qtv = cluster->servers; qtv; qtv = qtv->next)								if (qtv->streamid == atoi(colon))									break;						}					}					else if (!strcmp(s, "DEMO"))					{	//starts a demo off the server... source does the same thing though...						char buf[256];							snprintf(buf, sizeof(buf), "demo:%s", colon);						qtv = QTV_NewServerConnection(cluster, buf, "", false, true, true, false);						if (!qtv)						{							s = QTVSVHEADER								"PERROR: couldn't open demo\n"								"\n";							Net_ProxySend(cluster, pend, s, strlen(s));							pend->flushing = true;						}					}					else if (!strcmp(s, "AUTH"))					{	//lists the demos available on this proxy						//part of the connection process, can be ignored if there's no password					}					else						printf("Unrecognised token in QTV connection request (%s)\n", s);				}			}			s = e+1;		}		e++;	}	if (!pend->flushing)	{		if (clientversion < 1)		{			s = QTVSVHEADER				"PERROR: Requested protocol version not supported\n"				"\n";			Net_ProxySend(cluster, pend, s, strlen(s));			pend->flushing = true;		}		if (!qtv)		{			s = QTVSVHEADER				"PERROR: No stream selected\n"				"\n";			Net_ProxySend(cluster, pend, s, strlen(s));			pend->flushing = true;		}	}	if (pend->flushing)		return false;	if (qtv->usequkeworldprotocols)	{		s = QTVSVHEADER			"PERROR: This version of QTV is unable to convert QuakeWorld to QTV protocols\n"			"\n";		Net_ProxySend(cluster, pend, s, strlen(s));		pend->flushing = true;		return false;	}	if (cluster->maxproxies>=0 && cluster->numproxies >= cluster->maxproxies)	{		s = QTVSVHEADER			"TERROR: This QTV has reached it's connection limit\n"			"\n";		Net_ProxySend(cluster, pend, s, strlen(s));		pend->flushing = true;		return false;	}	pend->next = qtv->proxies;	qtv->proxies = pend;	if (!raw)	{		s = QTVSVHEADER;		Net_ProxySend(cluster, pend, s, strlen(s));		s = "BEGIN: ";		Net_ProxySend(cluster, pend, s, strlen(s));		s = qtv->server;		Net_ProxySend(cluster, pend, s, strlen(s));		s = "\n\n";		Net_ProxySend(cluster, pend, s, strlen(s));	}//	else if (passwordprotected)	//raw mode doesn't support passwords, so reject them//	{//		pend->flushing = true;//		return;//	}	Net_SendConnectionMVD(qtv, pend);	return true;}