//----< get message content>-----------------------------------------
///////////////////////////////////////////////////////////////////////////////////////////////
////readMsg's function is very similar with readline
std::string Socket::readMsg()
{	std::string temp1;
	char block[1];
	size_t pos=0;
	size_t count=0;
	size_t record[2];
	record[0] = 0;
	int contentsize=0;	
	while (true)
	{	if (!recvAll(block, 1))
			return "";
		if (block[0] != '\n' && block[0] != '\r')
		{	temp1 += block[0];
			if (block[0] == ',')
			{	if (count == 2)
					record[0] = pos;
				if (count == 3)
				{	record[1] = pos;
					std::string test;
					test = temp1.substr(record[0] + 1, pos - record[0] - 1);
					contentsize = atoi(test.c_str());
				}
				if (count == 4)
				{	for (int i = 0; i < contentsize; i++)
					{
						bool temp2 = recvAll(block, 1);
						temp1 += block[0];
					}
				}
				count++;
			}
			pos++;
		}
		else
		{	temp1 += '\n';
			if (bytesLeft() > 0)
			{	char last = block[0];				
				::recv(s_, block, 1, MSG_PEEK);// remove remaining newline or carriage return if next in buffer
				if (last == '\n' && block[0] == '\r')
					recv(block, 1);
				else if (last == '\r' && block[0] == '\n')
					recv(block, 1);
			}
			return temp1;
		}
	}
	return temp1;
}
/*
 * - removes ending newline if present, else reads to end of buffer
 * - returns empty string if not successful
 *
 */
std::string Socket::readLine()
{
  std::string temp;
  char block[1];
  //while(bytesLeft() > 0)  // don't block
  while(true)
  {
    if(!recvAll(block,1))
      return "";
    // save all chars that are not newlines or carriage returns
    if(block[0] != '\n' && block[0] != '\r')
      temp += block[0];
    else
    {
      temp += '\n';
      if(bytesLeft() > 0)
      {
        char last = block[0];
        // remove remaining newline or carriage return if next in buffer
        ::recv(s_,block,1,MSG_PEEK);
        if(last == '\n' && block[0] == '\r')
          recv(block,1);
        else if(last == '\r' && block[0] == '\n')
          recv(block, 1);
      }
      return temp;
    }
  }
  return temp;
}
void *solicitar_solicitar_bytes(int socket_umv, uint32_t base, uint32_t offset, int tamanio, uint32_t id_programa, char origen, t_log *logger)
{
	uint32_t bEnv = 0;
	char *orden = codificar_solicitar_bytes(base,offset,tamanio,id_programa);
	void *valorRetorno = NULL;

	t_paquete_programa paq_saliente;
		paq_saliente.id = origen;
		paq_saliente.mensaje = orden;
		log_info(logger, "[INTERFAZ_UMV] [ORDEN] [%c] - %s", origen, orden);
		paq_saliente.sizeMensaje = strlen(orden);
	
	char *paqueteSaliente = serializar_paquete(&paq_saliente, logger);

	bEnv = paq_saliente.tamanio_total;
	if(sendAll(socket_umv, paqueteSaliente, &bEnv)){
		log_error(logger, "[INTERFAZ_UMV] Error en la solicitud de solicitar_bytes. Motivo: %s", strerror(errno));
		free(paqueteSaliente);
		free(orden);
		return 0;
	}

	free(paqueteSaliente);
	free(orden);

	uint32_t bRec = 0;
	t_paquete_programa respuesta;
	log_info(logger, "[INTERFAZ_UMV] Esperando la respuesta de la UMV al comando solicitar_bytes.");
	bRec = recvAll(&respuesta, socket_umv);
	log_info(logger, "[INTERFAZ_UMV] La UMV respondió %s", respuesta.mensaje);

	valorRetorno = (void *) respuesta.mensaje;

	return valorRetorno;
}
Beispiel #4
0
Message Next(int sock){
	char buf[8];
	recvAll(sock,buf,8);
	Message result;
	result.type=*(Type*)buf;
	result.size=*(uint8_t*)(buf+4);

	//DBG("Just recved type=%d size=%u\n",result.type,result.size);

	if(result.size>MAX_BODY_SIZE){
		throw std::runtime_error("Received message body too large");
	}

	result.body.resize(result.size);
	recvAll(sock,&result.body[0],result.size);
	//DBG("Finished a msg");
	return result;
}
void *atencionConexiones(void *config)
{
	t_log *logger = (t_log *) (((t_config_conexion *) config)->logger);
	int *sock = (int *) (((t_config_conexion *) config)->socket);
	t_param_memoria *parametros_memoria = (t_param_memoria *) (((t_config_conexion *) config)->parametros_memoria);
	pthread_t *punteroAEsteHilo = (pthread_t *) (((t_config_conexion *) config)->hilo);
	t_paquete_programa paq;
	int bytesRecibidos = 0;
	int atendiendoSolicitud = 1;

	pthread_mutex_init(&op_atomica, NULL);
	
	while(atendiendoSolicitud){
		bytesRecibidos = recvAll(&paq, *sock);
		log_info(logger, "[ATENCION_CONN] Recibí una solicitud de %d bytes.", bytesRecibidos);
		
		if(bytesRecibidos == 0){ //independientemente que haya sido una cpu o el plp, este hilo ya no tiene nada que hacer.
			log_info(logger, "[ATENCION_CONN] Se desconectó una CPU (lo más probable). Este hilo de atención finalizará ahora.");
			goto liberarRecursos;
		}	

		switch(paq.id){
			case 'P':
				;
				int resp = 0;
				handler_plp(*sock, &resp, paq.mensaje, parametros_memoria, logger);

				break;
			case 'C':
				;
				void *resp_buf = NULL;
				handler_cpu(*sock, resp_buf, paq.mensaje, parametros_memoria, logger);

				break;
			case 'H':
				log_info(logger, "[ATENCION_CONN] Recibí un handshake del Kernel");
				log_info(logger, "[ATENCION_CONN] El mensaje del handshake es: %s\n", paq.mensaje);
				break;
			case 'F':
			default:
				log_info(logger, "[ATENCION_CONN] No puedo identificar el tipo de conexión");
				//close(*sock);
				atendiendoSolicitud = 0;
		}

		free(paq.mensaje);
		bytesRecibidos = 0;
	}

	liberarRecursos:
		free(sock);
		free(parametros_memoria);
		free(punteroAEsteHilo);
		free(config);
		pthread_exit(NULL);
}
Beispiel #6
0
char *solicitarInstruccion(t_intructions instruccion)
{
	int mensaje[5];
	mensaje[0] = LEER;
	mensaje[1] = instruccion.start / tamanio_pagina;//Pagina en la que esta el codigo
	mensaje[2] = instruccion.start % tamanio_pagina;//Offset de la pagina
	mensaje[3] = instruccion.offset;				//Size de la instruccion
	mensaje[4] = pcb_actual.pid;					//pid

	printf("Start instruccion: %d, offset: %d.\n",instruccion.start,instruccion.offset);
	printf("msj %d, pag %d, offset %d, size %d, pid %d.\n", mensaje[0],mensaje[1],mensaje[2],mensaje[3],mensaje[4]);

	send(socket_umc, &mensaje, 5*sizeof(int), 0);

	//Recibo la respuesta si hay stack_overflow
	recv(socket_umc,&mensaje[0],sizeof(int),0);
	if(mensaje[0] == OVERFLOW)
	{
		printf("Error al solicitar instruccion: STACK_OVERFLOW\n");
		return NULL;
	}

	char *resultado = malloc(instruccion.offset + 1);

	printf("Espero el resultado...\n");
	if( recvAll(socket_umc,resultado,instruccion.offset,MSG_WAITALL) <= 0)
	{
		perror("Error al recibir instruccion");
	}

	//Le agrego un \0 al resultado
	resultado[instruccion.offset] = '\0';

	printf("Pude recibir la instruccion:\n\n");
	fwrite(resultado,sizeof(char),instruccion.offset,stdout);
	printf("\n\n");

	return resultado;
}
uint32_t solicitar_enviar_bytes(int socket_umv, uint32_t base, uint32_t offset, int tamanio, void *buffer, uint32_t id_programa, char origen, t_log *logger)
{
	uint32_t bEnv = 0;
	uint32_t tamanio_de_la_orden_completa = 0;
	char *orden = codificar_enviar_bytes(base,offset,tamanio,buffer,id_programa,&tamanio_de_la_orden_completa);
	uint32_t valorRetorno = 0;

	t_paquete_programa paq_saliente;
		paq_saliente.id = origen;
		paq_saliente.mensaje = orden;
		log_info(logger, "[INTERFAZ_UMV] [ORDEN] [%c] - %s", origen, orden);
		paq_saliente.sizeMensaje = tamanio_de_la_orden_completa;
	
	char *paqueteSaliente = serializar_paquete(&paq_saliente, logger);

	bEnv = paq_saliente.tamanio_total;
	if(sendAll(socket_umv, paqueteSaliente, &bEnv)){
		log_error(logger, "[INTERFAZ_UMV] Error en la solicitud de enviar bytes para el segmento de código. Motivo: %s", strerror(errno));
		free(paqueteSaliente);
		free(orden);
		return 0;
	}

	free(paqueteSaliente);
	free(orden);

	uint32_t bRec = 0;
	t_paquete_programa respuesta;
	log_info(logger, "[INTERFAZ_UMV] Esperando la respuesta de la UMV al comando enviar_bytes.");
	bRec = recvAll(&respuesta, socket_umv);
	log_info(logger, "[INTERFAZ_UMV] La UMV respondió %s", respuesta.mensaje);

	valorRetorno = atoi(respuesta.mensaje);
	free(respuesta.mensaje);

	return valorRetorno;
}
Beispiel #8
0
/** Receive a raw string (not encoded by msgpack).
 * This IO call blocks.
 * We pass the lua_State to avoid mixing thread contexts.
 */
LuaStackSize lk::Socket::recv(lua_State *L) {
  if (lua_isnumber(L, 3)) {
    setRecvTimeout(lua_tonumber(L, 3));
  }

  if (lua_isnumber(L, 2)) {
    // <self> <num_bytes> [<timeout>]
    return recvBytes(L, lua_tonumber(L, 2));
  } else if (lua_isstring(L, 2)) {
    // <self> <mode> [<timeout>]
    const char *mode = lua_tostring(L, 2);
    if (mode[0] == '*' && mode[1] == 'a') {
      return recvAll(L);
    } else if (mode[0] == '*' && mode[1] == 'l') {
      return recvLine(L);
    } else {
      throw dub::Exception("Bad mode to recv (should be '*a' or '*l' but found '%s')", mode);
    }
  } 
  // receive a single line (not returning \r or \n).
  return recvLine(L);

  return 1;
}
uint32_t solicitar_crear_segmento(int socket_umv, uint32_t id_programa, uint32_t tamanio_segmento, char origen, t_log *logger)
{
	uint32_t bEnv = 0;
	char *orden = codificar_crear_segmento(id_programa, tamanio_segmento);
	uint32_t valorRetorno = 0;

	t_paquete_programa paq_saliente;
		paq_saliente.id = origen;
		paq_saliente.mensaje = orden;
		log_info(logger, "[INTERFAZ_UMV] [ORDEN] [%c] - %s", origen, orden);
		paq_saliente.sizeMensaje = strlen(orden);
	
	char *paqueteSaliente = serializar_paquete(&paq_saliente, logger);
	
	bEnv = paq_saliente.tamanio_total;
	if(sendAll(socket_umv, paqueteSaliente, &bEnv)){
		log_error(logger, "[INTERFAZ_UMV] Error en la solicitud de creación de segmento. Motivo: %s", strerror(errno));
		free(paqueteSaliente);
		free(orden);
		return 0;
	}

	free(paqueteSaliente);
	free(orden);

	uint32_t bRec = 0;
	t_paquete_programa respuesta;
	log_info(logger, "[INTERFAZ_UMV] Esperando la respuesta de la UMV al comando crear_segmento.");
	bRec = recvAll(&respuesta, socket_umv);
	log_info(logger, "[INTERFAZ_UMV] La UMV respondió %s", respuesta.mensaje);

	valorRetorno = atoi(respuesta.mensaje);
	free(respuesta.mensaje);

	return valorRetorno;
}
Beispiel #10
0
int ClientSocket::recvNr()
{
    int ret = 0;
    recvAll(&ret, 4);
    return ret;
}
Beispiel #11
0
float ClientSocket::recvFloat32()
{
    float ret = 0;
    recvAll(&ret, sizeof(float));
    return ret;
}
Beispiel #12
0
int32_t ClientSocket::recvInt32()
{
    int32_t ret = -1;
    recvAll(&ret, sizeof(int32_t));
    return ret;
}
Beispiel #13
0
//check for the incoming file after waiting for a connection
int receiveFile(int port, 
	        char** inputFile, long* fileLength){
    int receiveSocket, acceptedSocket;
    int err, portStrlen;
    char *portStr;
    struct addrinfo *res, *curr;
    struct addrinfo hints;
    struct sockaddr incomingAddr;
    socklen_t incomingAddrSize = sizeof(incomingAddr);

    memset(&hints, 0, sizeof(hints));

    hints.ai_family = AF_INET; 
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    
    portStrlen = ceil(log10((float)(port))) + 1;
    portStr = (char *)(malloc(portStrlen * sizeof(char)));
    sprintf(portStr, "%d", port);

    err = getaddrinfo(NULL,portStr, &hints, &res);
    if(err){return GETADDR_ERROR;}

    err = -1;
    curr = res;
    while(NULL != curr){
	receiveSocket = socket((*curr).ai_family, (*curr).ai_socktype,
			    (*curr).ai_protocol);
	if(-1 != receiveSocket){
	    err = bind(receiveSocket, (*curr).ai_addr, (*curr).ai_addrlen);
	}
	if(-1 != err){
	    break;
	}

	close(receiveSocket);
	curr = (*curr).ai_next;
    }


    if(NULL == curr){
	return SOCKET_ABSENT_ERROR;
    }
    freeaddrinfo(res);
//start off the connection listening interface and wait for connections
    long amtReceived = 0;
    printf("Waiting for connections.\n");
    err = listen(receiveSocket, 1);
    if(err) {return ERROR;}
    acceptedSocket = accept(receiveSocket, &incomingAddr, &incomingAddrSize);
    if(-1 == acceptedSocket){return ERROR;}

    printf("Inbound file.\n");

    char * buff = (char*)(malloc(1 * sizeof(uint32_t)));
    recvAll(acceptedSocket, buff, 1*sizeof(uint32_t));
    *fileLength = ntohl(  *((long*)(buff)));
    *inputFile = (char*)(malloc( *fileLength *sizeof(char)));
    recvAll(acceptedSocket, *inputFile, *fileLength);

    return NONE;
}
Beispiel #14
0
int main(int argc, char *argv[])
{
	int errorArgumentos = 0;
	int errorLogger = 0;
	int errorConfig = 0;
	int errorConexion = 0;
	int errorEnvio = 0;
	int statusRecepcion = 0;

	//Variables para el script
	FILE *script = NULL;
	
	//Variables para el logger
	t_log *logger = NULL;
	
	//Variables para el socket
	int unSocket = -1;
	struct sockaddr_in socketInfo;

	//Variables para la carga de la configuración
	t_config *config = NULL;

	errorArgumentos = checkArgs(argc);
	errorLogger = crearLogger(&logger);
	errorConfig = cargarConfig(&config);

	if(errorArgumentos || errorLogger || errorConfig) {
		goto liberarRecursos;
		return EXIT_FAILURE;
	}

	int puerto = config_get_int_value(config, "Puerto");
	char *ip_kernel = config_get_string_value(config, "IP");

	if ((script = fopen(argv[1],"r")) != NULL) {
		//Pudimos abrir el archivo correctamente
		//Entonces creamos la conexión
		log_info(logger, "Conectando a %s:%d ...", ip_kernel, puerto);

		errorConexion = crear_conexion_saliente(&unSocket, &socketInfo, ip_kernel, puerto, logger, "PROGRAMA");
		if (errorConexion) {
			log_error(logger, "Error al conectar con el Kernel.");
			goto liberarRecursos;
			return EXIT_FAILURE;
		}

		log_info(logger, "Conexión establecida.");
		log_info(logger, "Comenzando a enviar el script AnSISOP.");

		errorEnvio = enviarDatos(script, unSocket, logger);
		if (errorEnvio) {
			goto liberarRecursos;
			return EXIT_FAILURE;
		} else {
			finalizarEnvio(&unSocket);
			log_info(logger, "Transmisión finalizada.");	
		}			

		//acá se abre la guarda para el modo debug
		t_paquete_programa paq;
		while(1){
			statusRecepcion = recvAll(&paq, unSocket);
			if(statusRecepcion == 0){
				log_error(logger, "Hubo un error al recibir un mensaje del Kernel.");
			} else {
				if(ejecutarMensajeKernel(paq.mensaje)){		//Si es 0 era porque era un imprimir/imprimirTexto. Si es 1, hay que terminar.
					log_info(logger, "Finalizó la ejecución del programa.");
					free(paq.mensaje);
					goto liberarRecursos;
					break;
				}
			}
		}
		//acá se cierra la guarda para el modo debug

	} else {
		log_error(logger,"No se pudo abrir el script AnSISOP. Motivo: %s", strerror(errno));
		goto liberarRecursos;
		return EXIT_FAILURE;
	}

	goto liberarRecursos;
	return EXIT_SUCCESS;

liberarRecursos:
	if(unSocket != -1) 
		close(unSocket);

	if(script)
		fclose(script);
	
	if(logger)
		log_destroy(logger);

	if(config)
		config_destroy(config);
}
Beispiel #15
0
static void* x11connThreadWriteProc(void* dataPtr)
{
	X11ConnData* data = (X11ConnData*)dataPtr;

	unsigned char *buf = NULL;
	size_t bufLen = 0;

	{
		xConnSetupPrefix header;
		if (!recvAll(data->server, &header, sz_xConnSetupPrefix)) goto done;
		if (!sendAll(data->client, &header, sz_xConnSetupPrefix)) goto done;

		log_debug("Server connection setup reply: %d\n", header.success);

		size_t dataLength = header.length * 4;
		bufSize(&buf, &bufLen, dataLength);
		if (!recvAll(data->server, buf, dataLength)) goto done;
		if (!sendAll(data->client, buf, dataLength)) goto done;
	}

	bufSize(&buf, &bufLen, sz_xReply);
	while (!data->exiting)
	{
		if (!recvAll(data->server, buf, sz_xReply)) goto done;
		size_t ofs = sz_xReply;
		const xReply* reply = (xReply*)buf;

		if (reply->generic.type == X_Reply || reply->generic.type == GenericEvent)
		{
			size_t dataLength = reply->generic.length * 4;
			bufSize(&buf, &bufLen, ofs + dataLength);
			reply = (xReply*)buf; // in case bufSize moved buf
			if (!recvAll(data->server, buf+ofs, dataLength)) goto done;
			ofs += dataLength;
		}
		log_debug2(" [%d]Response: %d sequenceNumber=%d length=%d\n", data->index, reply->generic.type, reply->generic.sequenceNumber, ofs);

		if (reply->generic.type == X_Reply)
		{
			switch (data->notes[reply->generic.sequenceNumber])
			{
				case Note_X_GetGeometry:
				{
					xGetGeometryReply* reply = (xGetGeometryReply*)buf;
					log_debug2("  XGetGeometry(%d,%d,%d,%d)\n", reply->x, reply->y, reply->width, reply->height);
					fixCoords(&reply->x, &reply->y, &reply->width, &reply->height);
					log_debug2("  ->          (%d,%d,%d,%d)\n", reply->x, reply->y, reply->width, reply->height);
					break;
				}

				case Note_X_InternAtom_Other:
				{
					xInternAtomReply* reply = (xInternAtomReply*)buf;
					log_debug2("  X_InternAtom: atom=%d\n", reply->atom);
					break;
				}

				case Note_X_QueryExtension_XFree86_VidModeExtension:
				{
					xQueryExtensionReply* reply = (xQueryExtensionReply*)buf;
					log_debug2("  X_QueryExtension (XFree86-VidModeExtension): present=%d major_opcode=%d first_event=%d first_error=%d\n",
						reply->present, reply->major_opcode, reply->first_event, reply->first_error);
					if (reply->present)
						data->opcode_XFree86_VidModeExtension = reply->major_opcode;
					break;
				}

				case Note_X_QueryExtension_RANDR:
				{
					xQueryExtensionReply* reply = (xQueryExtensionReply*)buf;
					log_debug2("  X_QueryExtension (RANDR): present=%d major_opcode=%d first_event=%d first_error=%d\n",
						reply->present, reply->major_opcode, reply->first_event, reply->first_error);
					if (reply->present)
						data->opcode_RANDR = reply->major_opcode;
					break;
				}

				case Note_X_QueryExtension_Xinerama:
				{
					xQueryExtensionReply* reply = (xQueryExtensionReply*)buf;
					log_debug2("  X_QueryExtension (XINERAMA): present=%d major_opcode=%d first_event=%d first_error=%d\n",
						reply->present, reply->major_opcode, reply->first_event, reply->first_error);
					if (reply->present)
						data->opcode_Xinerama = reply->major_opcode;
					break;
				}

				case Note_X_QueryExtension_NV_GLX:
				{
					xQueryExtensionReply* reply = (xQueryExtensionReply*)buf;
					log_debug2("  X_QueryExtension (NV-GLX): present=%d major_opcode=%d first_event=%d first_error=%d\n",
						reply->present, reply->major_opcode, reply->first_event, reply->first_error);
					if (reply->present)
						data->opcode_NV_GLX = reply->major_opcode;
					break;
				}

				case Note_X_QueryExtension_Other:
				{
					xQueryExtensionReply* reply = (xQueryExtensionReply*)buf;
					log_debug2("  X_QueryExtension: present=%d major_opcode=%d first_event=%d first_error=%d\n",
						reply->present, reply->major_opcode, reply->first_event, reply->first_error);
					break;
				}

				case Note_X_XF86VidModeGetModeLine:
				{
					xXF86VidModeGetModeLineReply* reply = (xXF86VidModeGetModeLineReply*)buf;
					log_debug2("  X_XF86VidModeGetModeLine(%d x %d)\n", reply->hdisplay, reply->vdisplay);
					fixSize(&reply->hdisplay, &reply->vdisplay);
					log_debug2("  ->                      (%d x %d)\n", reply->hdisplay, reply->vdisplay);
					break;
				}

				case Note_X_XF86VidModeGetAllModeLines:
				{
					xXF86VidModeGetAllModeLinesReply* reply = (xXF86VidModeGetAllModeLinesReply*)buf;
					xXF86VidModeModeInfo* modeInfos = (xXF86VidModeModeInfo*)(buf + sz_xXF86VidModeGetAllModeLinesReply);
					for (size_t i=0; i<reply->modecount; i++)
					{
						xXF86VidModeModeInfo* modeInfo = modeInfos + i;
						log_debug2("  X_XF86VidModeGetAllModeLines[%d] = %d x %d\n", i, modeInfo->hdisplay, modeInfo->vdisplay);
						fixSize(&modeInfo->hdisplay, &modeInfo->vdisplay);
						log_debug2("  ->                                %d x %d\n",    modeInfo->hdisplay, modeInfo->vdisplay);
					}
					break;
				}

				case Note_X_RRGetScreenInfo:
				{
					xRRGetScreenInfoReply* reply = (xRRGetScreenInfoReply*)buf;
					xScreenSizes* sizes = (xScreenSizes*)(buf+sz_xRRGetScreenInfoReply);
					for (size_t i=0; i<reply->nSizes; i++)
					{
						xScreenSizes* size = sizes+i;
						log_debug2("  X_RRGetScreenInfo[%d] = %d x %d\n", i, size->widthInPixels, size->heightInPixels);
						fixSize(&size->widthInPixels, &size->heightInPixels);
						log_debug2("  ->                      %d x %d\n",    size->widthInPixels, size->heightInPixels);
					}
					break;
				}

				case Note_X_RRGetScreenResources:
				{
					xRRGetScreenResourcesReply* reply = (xRRGetScreenResourcesReply*)buf;
					void* ptr = buf+sz_xRRGetScreenResourcesReply;
					ptr += reply->nCrtcs * sizeof(CARD32);
					ptr += reply->nOutputs * sizeof(CARD32);
					for (size_t i=0; i<reply->nModes; i++)
					{
						xRRModeInfo* modeInfo = (xRRModeInfo*)ptr;
						log_debug2("  X_RRGetScreenResources[%d] = %d x %d\n", i, modeInfo->width, modeInfo->height);
						fixSize(&modeInfo->width, &modeInfo->height);
						log_debug2("  ->                           %d x %d\n",    modeInfo->width, modeInfo->height);
						ptr += sz_xRRModeInfo;
					}
					break;
				}

				case Note_X_RRGetCrtcInfo:
				{
					xRRGetCrtcInfoReply* reply = (xRRGetCrtcInfoReply*)buf;
					log_debug2("  X_RRGetCrtcInfo = %dx%d @ %dx%d\n", reply->width, reply->height, reply->x, reply->y);
					if (reply->mode != None)
					{
						fixMonitor(&reply->x, &reply->y, &reply->width, &reply->height);
						if (!reply->width || !reply->height)
						{
							reply->x = reply->y = reply->width = reply->height = 0;
							reply->mode = None;
							reply->rotation = reply->rotations = RR_Rotate_0;
							reply->nOutput = reply->nPossibleOutput = 0;
						}
					}
					log_debug2("  ->                %dx%d @ %dx%d\n", reply->width, reply->height, reply->x, reply->y);
					break;
				}

				case Note_X_XineramaQueryScreens:
				{
					xXineramaQueryScreensReply* reply = (xXineramaQueryScreensReply*)buf;
					xXineramaScreenInfo* screens = (xXineramaScreenInfo*)(buf+sz_XineramaQueryScreensReply);
					for (size_t i=0; i<reply->number; i++)
					{
						xXineramaScreenInfo* screen = screens+i;
						log_debug2("  X_XineramaQueryScreens[%d] = %dx%d @ %dx%d\n", i, screen->width, screen->height, screen->x_org, screen->y_org);
						fixCoords(&screen->x_org, &screen->y_org, &screen->width, &screen->height);
						log_debug2("  ->                           %dx%d @ %dx%d\n",    screen->width, screen->height, screen->x_org, screen->y_org);
					}
					break;
				}

				case Note_NV_GLX:
				{
#if 0
					char fn[256];
					static int counter = 0;
					sprintf(fn, "/tmp/hax11-NV-%d-rsp-%d", reply->generic.sequenceNumber, counter++);
					FILE* f = fopen(fn, "wb");
					fwrite(buf, 1, ofs, f);
					fclose(f);
#endif
					break;
				}
			}
		}

		if (config.debug >= 2 && config.actualX && config.actualY && memmem(buf, ofs, &config.actualX, 2) && memmem(buf, ofs, &config.actualY, 2))
			log_debug2("   Found actualW/H in output! ----------------------------------------------------------------------------------------------\n");

		if (!sendAll(data->client, buf, ofs)) goto done;
	}
done:
	log_debug("Exiting write thread.\n");
	data->exiting = 1;
	close(data->client);
	close(data->server);
	return NULL;
}
Beispiel #16
0
static void* x11connThreadReadProc(void* dataPtr)
{
	X11ConnData* data = (X11ConnData*)dataPtr;
	unsigned char *buf = NULL;
	size_t bufLen = 0;
	bufSize(&buf, &bufLen, 1<<16);

	xConnClientPrefix header;
	if (!recvAll(data->client, &header, sizeof(header))) goto done;
	if (header.byteOrder != 'l')
	{
		log_debug("Unsupported byte order %c!\n", header.byteOrder);
		goto done;
	}
	if (!sendAll(data->server, &header, sz_xConnClientPrefix)) goto done;

	if (!recvAll(data->client, buf, pad(header.nbytesAuthProto))) goto done;
	if (!sendAll(data->server, buf, pad(header.nbytesAuthProto))) goto done;
	if (!recvAll(data->client, buf, pad(header.nbytesAuthString))) goto done;
	if (!sendAll(data->server, buf, pad(header.nbytesAuthString))) goto done;

	unsigned short sequenceNumber = 0;

	while (!data->exiting)
	{
		sequenceNumber++;

		size_t ofs = 0;
		if (!recvAll(data->client, buf+ofs, sz_xReq)) goto done;
		ofs += sz_xReq;

		const xReq* req = (xReq*)buf;
		uint requestLength = req->length * 4;
		if (requestLength == 0) // Big Requests Extension
		{
			recvAll(data->client, buf+ofs, 4);
			requestLength = *(uint*)(buf+ofs) * 4;
			ofs += 4;
		}
		log_debug2("[%d][%d] Request %d (%s) with data %d, length %d\n", data->index, sequenceNumber, req->reqType, requestNames[req->reqType], req->data, requestLength);
		bufSize(&buf, &bufLen, requestLength);
		req = (xReq*)buf; // in case bufSize moved buf

		if (!recvAll(data->client, buf+ofs, requestLength - ofs)) goto done;

		data->notes[sequenceNumber] = Note_None;
		switch (req->reqType)
		{
			// Fix for games that create the window of the wrong size or on the wrong monitor.
			case X_CreateWindow:
			{
				xCreateWindowReq* req = (xCreateWindowReq*)buf;
				log_debug2(" XCreateWindow(%dx%d @ %dx%d)\n", req->width, req->height, req->x, req->y);
				fixCoords(&req->x, &req->y, &req->width, &req->height);
				log_debug2(" ->           (%dx%d @ %dx%d)\n", req->width, req->height, req->x, req->y);
				break;
			}

			case X_ConfigureWindow:
			{
				xConfigureWindowReq* req = (xConfigureWindowReq*)buf;

				INT16 dummyXY = 0;
				CARD16 dummyW = config.mainW;
				CARD16 dummyH = config.mainH;
				INT16 *x = &dummyXY, *y = &dummyXY;
				CARD16 *w = &dummyW, *h = &dummyH;

				int* ptr = (int*)(buf + sz_xConfigureWindowReq);
				if (req->mask & 0x0001) // x
				{
					x = (INT16*)ptr;
					ptr++;
				}
				if (req->mask & 0x0002) // y
				{
					y = (INT16*)ptr;
					ptr++;
				}
				if (req->mask & 0x0004) // width
				{
					w = (CARD16*)ptr;
					ptr++;
				}
				if (req->mask & 0x0008) // height
				{
					h = (CARD16*)ptr;
					ptr++;
				}

				log_debug2(" XConfigureWindow(%dx%d @ %dx%d)\n", *w, *h, *x, *y);
				fixCoords(x, y, w, h);
				log_debug2(" ->              (%dx%d @ %dx%d)\n", *w, *h, *x, *y);
				break;
			}

			// Fix for games setting their window size based on the X root window size
			// (which can encompass multiple physical monitors).
			case X_GetGeometry:
			{
				data->notes[sequenceNumber] = Note_X_GetGeometry;
				break;
			}

			case X_InternAtom:
			{
				xInternAtomReq* req = (xInternAtomReq*)buf;
				const char* name = (const char*)(buf + sz_xInternAtomReq);
				log_debug2(" XInternAtom: %.*s\n", req->nbytes, name);
				data->notes[sequenceNumber] = Note_X_InternAtom_Other;
				break;
			}

			case X_ChangeProperty:
			{
				xChangePropertyReq* req = (xChangePropertyReq*)buf;
				log_debug2(" XChangeProperty: property=%d type=%d format=%d)\n", req->property, req->type, req->format);
				if (req->type == XA_WM_SIZE_HINTS)
				{
					XSizeHints* data = (XSizeHints*)(buf + sz_xChangePropertyReq);
					fixCoords((INT16*)&data->x, (INT16*)&data->y, (CARD16*)&data->width, (CARD16*)&data->height);
					fixSize((CARD16*)&data->max_width, (CARD16*)&data->max_height);
					fixSize((CARD16*)&data->base_width, (CARD16*)&data->base_height);
				}
				break;
			}

			case X_QueryExtension:
			{
				xQueryExtensionReq* req = (xQueryExtensionReq*)buf;
				const char* name = (const char*)(buf + sz_xQueryExtensionReq);
				log_debug2(" XQueryExtension(%.*s)\n", req->nbytes, name);

				if (!strmemcmp("XFree86-VidModeExtension", name, req->nbytes))
					data->notes[sequenceNumber] = Note_X_QueryExtension_XFree86_VidModeExtension;
				else
				if (!strmemcmp("RANDR", name, req->nbytes))
					data->notes[sequenceNumber] = Note_X_QueryExtension_RANDR;
				else
				if (!strmemcmp("XINERAMA", name, req->nbytes))
					data->notes[sequenceNumber] = Note_X_QueryExtension_Xinerama;
				else
				if (!strmemcmp("NV-GLX", name, req->nbytes))
					data->notes[sequenceNumber] = Note_X_QueryExtension_NV_GLX;
				else
					data->notes[sequenceNumber] = Note_X_QueryExtension_Other;
			}

			case 0:
				break;

			default:
			{
				if (req->reqType == data->opcode_XFree86_VidModeExtension)
				{
					xXF86VidModeGetModeLineReq* req = (xXF86VidModeGetModeLineReq*)buf;
					log_debug2(" XFree86_VidModeExtension - %d\n", req->xf86vidmodeReqType);
					switch (req->xf86vidmodeReqType)
					{
						case X_XF86VidModeGetModeLine:
							data->notes[sequenceNumber] = Note_X_XF86VidModeGetModeLine;
							break;
						case X_XF86VidModeGetAllModeLines:
							data->notes[sequenceNumber] = Note_X_XF86VidModeGetAllModeLines;
							break;
					}
				}
				else
				if (req->reqType == data->opcode_RANDR)
				{
					log_debug2(" RANDR - %d\n", req->data);
					switch (req->data)
					{
						case X_RRGetScreenInfo:
							data->notes[sequenceNumber] = Note_X_RRGetScreenInfo;
							break;
						case X_RRGetScreenResources:
							data->notes[sequenceNumber] = Note_X_RRGetScreenResources;
							break;
						case X_RRGetCrtcInfo:
							data->notes[sequenceNumber] = Note_X_RRGetCrtcInfo;
							break;
					}
				}
				else
				if (req->reqType == data->opcode_Xinerama)
				{
					log_debug2(" Xinerama - %d\n", req->data);
					switch (req->data)
					{
						case X_XineramaQueryScreens:
							data->notes[sequenceNumber] = Note_X_XineramaQueryScreens;
							break;
					}
				}
				else
				if (req->reqType == data->opcode_NV_GLX)
				{
#if 0
					char fn[256];
					sprintf(fn, "/tmp/hax11-NV-%d-req", sequenceNumber);
					FILE* f = fopen(fn, "wb");
					fwrite(buf, 1, requestLength, f);
					fclose(f);
#endif
					data->notes[sequenceNumber] = Note_NV_GLX;
				}
				break;
			}
		}

		if (config.debug >= 2 && config.actualX && config.actualY && memmem(buf, requestLength, &config.actualX, 2) && memmem(buf, requestLength, &config.actualY, 2))
			log_debug2("   Found actualW/H in input! ----------------------------------------------------------------------------------------------\n");

		if (!sendAll(data->server, buf, requestLength)) goto done;
	}
done:
	log_debug("Exiting read thread.\n");
	data->exiting = 1;
	close(data->client);
	close(data->server);
	return NULL;
}