Пример #1
0
// Send message to a player
void send_to_player(player p, char * buffer) {
    int j;

    // Not in a game
    if(!p->game) {
        senderror(p->fd, CMD_SEND_TO_PLAYER, ERR_NOT_IN_GAME);
        return;
    }

    // get the name of the receiver
    char * pointer = strchr(buffer+4, '#');
    if(strlen(buffer+4) < 3 || !pointer) {
        senderror(p->fd, NULL, ERR_NOT_RECOGNIZED);
        return;
    }
    *pointer = 0;

    for(j=0; j<p->game->nb_players; j++)
        if(strcmp(p->game->players[j]->name, buffer+4) == 0) {
            char * msg = malloc((strlen(pointer+1)+strlen(p->name)+7)*sizeof(char));
            sprintf(msg, "%s#%s#%s\n", CMD_SEND_TO_PLAYER, p->name, pointer+1);
            sendline(p->game->players[j]->fd, msg);
            free(msg);
            return;
        }

    senderror(p->fd, CMD_SEND_TO_PLAYER, ERR_NO_SUCH_PLAYER);
}
Пример #2
0
// bind to a game
void bindToGame(player p, char * buffer) {
    int j;
    buffer[9] = 0;

    // already in a game
    if(p->game) {
        senderror(p->fd, NULL, ERR_ALREADY_IN_GAME);
        return;
    }

    // id of the game
    int id = atoi(buffer+4);

    // search for the game
    game g = NULL;
    for(j=0; j<nb_game; j++)
        if(games[j]->id == id) {
            g = games[j];
            break;
        }

    // if it doesn't exist, 
    if(!g) {
        senderror(p->fd, CMD_BIND, ERR_GAME_DOESNT_EXIST);
        return;
    }

    // update the name of the player
    strncpy(p->name, buffer+10, MAX_NAME_SIZE);

    // if game is already full
    if(g->nb_players >= MAX_PLAYER_GAME) {
        printf("\rToo many players in this game !\n");
        senderror(p->fd, CMD_BIND, ERR_TOO_MANY_PLAYERS_IN_GAME);
        return;
    }

    // check if the name is already used
    for(j=0; j<g->nb_players; j++)
        if(strcmp(g->players[j]->name, p->name) == 0) {
            printf("\rName already used !\n");
            senderror(p->fd, CMD_BIND, ERR_NAME_USED);
            return;
        }

    // send notification to players in the game
    char * msg = malloc(sizeof(char)*(6+strlen(p->name)));
    sprintf(msg, "%s#%s\n", CMD_CONNECTED, p->name);
    for(j=0;j<g->nb_players; j++)
        if(g->players[j] != p)
            sendline(g->players[j]->fd, msg);
    free(msg);

    // update player, game and table of games
    p->game = g;
    g->players[g->nb_players] = p;
    g->nb_players++;
    sendack(p->fd, CMD_BIND, buffer+4);
}
Пример #3
0
// Parse the answers of the child processes transferring files
void parseFileProcessesRequest(int i, char * buffer) {
    // if the fd closed
    if(readline(fileprocesses[i]->in, buffer, MAXBUF-1) == 0) {
        printf("\rChild process MIA...\n");
        senderror(fileprocesses[i]->sender->fd, CMD_FILE, ERR_INTERNAL);
        removeChildProcess(i);
        return;
    }

    if(buffer[3] != '#') {
        printf("\rChild process is sending strange commands... Better check that, bro.\n");
        senderror(fileprocesses[i]->sender->fd, CMD_FILE, ERR_INTERNAL);
        removeChildProcess(i);
        return;
    }

    buffer[3] = 0;
    if(strcmp(buffer, CMD_ERR) == 0) {
        printf("\rChild process failed with error: %s\n", buffer+4);
        senderror(fileprocesses[i]->sender->fd, CMD_FILE, ERR_INTERNAL);
        removeChildProcess(i);
        return;
    }

    if(strcmp(buffer, CMD_PORT) == 0 && buffer[9] == '#') {
        char * msg = malloc(sizeof(char)*(6+strlen(buffer+4)));
        buffer[9] = 0;
        printf("\rChild process waiting on port %s\n", buffer+4);
        sprintf(msg, "%s#%s#%s\n", CMD_PORT, buffer+4, buffer+10);
        sendline(fileprocesses[i]->sender->fd, msg);
        free(msg);
        return;
    }

    if(strcmp(buffer, CMD_READY) == 0) {
        printf("\rFile successfully uploaded !\n");
        int j;
        char * msg = malloc(sizeof(char)*(6+strlen(buffer+4)));
        sprintf(msg, "%s#%s\n", CMD_FILE, buffer+4);
        for(j=0; j<fileprocesses[i]->sender->game->nb_players; j++)
            if(fileprocesses[i]->sender->game->players[j] != fileprocesses[i]->sender)
                sendline(fileprocesses[i]->sender->game->players[j]->fd, msg);
        sprintf(msg, "%05d", fileprocesses[i]->sender->game->nb_players);
        sendack(fileprocesses[i]->out, NULL, msg);
        free(msg);
        return;
    }

    if(strcmp(buffer, CMD_ACK) == 0) {
        printf("\rFile successfully broadcasted !\n");
        sendack(fileprocesses[i]->sender->fd, CMD_FILE, buffer+4);
        removeChildProcess(i);
        return;
    }
}
Пример #4
0
// Register as a game master
void register_game_master(player p) {
    // Not in a game
    if(!p->game) {
        senderror(p->fd, CMD_REGISTER_GM, ERR_NOT_IN_GAME);
        return;
    }

    // can't register as Game Master if there is already one
    if(p->game->game_master) {
        senderror(p->fd, CMD_REGISTER_GM, ERR_ALREADY_A_GM);
        return;
    }

    p->game->game_master = p;
}
Пример #5
0
// accept a new incoming socket
void acceptNewSocket(int sock_serv) {
    struct 	  sockaddr_in csin;
    socklen_t recsize = sizeof(csin);

    // accept new socket
    int new_socket = accept(sock_serv, (struct sockaddr *) &csin, &recsize);

    if(nb_client < MAX_PLAYER) {

        if(new_socket < 0) {
            perror("accept");
            exit(EXIT_FAILURE);
        }

        players[nb_client]=malloc(sizeof(struct _player));
        if(players[nb_client] < 0) {
            perror("malloc");
            exit(EXIT_FAILURE);
        }

        players[nb_client]->fd = new_socket;
        players[nb_client]->game = NULL;
        nb_client ++;
        printf("\rNew connection, socket n° : %d (total : %d)\n", new_socket, nb_client);
    }
    else {
        senderror(new_socket, NULL, ERR_TOO_MANY_PLAYERS);
        close(new_socket);
        printf("\rA client has been rejected !\n");
    }
}
Пример #6
0
static int
rrofs(SunMsg *m)
{
	uchar buf[512];	/* clumsy hack*/

	memset(buf, 0, sizeof buf);
	return senderror(m, (SunCall*)buf, Nfs3ErrRoFs);
}
Пример #7
0
// Send a message to the game master
void send_to_game_master(player p, char * buffer) {
    // Not in a game
    if(!p->game) {
        senderror(p->fd, CMD_SEND_GM, ERR_NOT_IN_GAME);
        return;
    }

    // No game master in this game
    if(!p->game->game_master) {
        senderror(p->fd, CMD_SEND_GM, ERR_NO_GM);
        return;
    }

    char * msg = malloc((strlen(buffer+4)+strlen(p->name)+7)*sizeof(char));
    sprintf(msg, "%s#%s#%s\n", CMD_SEND_GM, p->name, buffer+4);
    sendline(p->game->game_master->fd, msg);
    free(msg);
}
Пример #8
0
// create a game and bind to it
void createGame(player p, char * buffer) {
    int j;
    buffer[9] = 0;

    // already in a game
    if(p->game) {
        senderror(p->fd, NULL, ERR_ALREADY_IN_GAME);
        return;
    }

    // id of the game
    int id = atoi(buffer+4);

    // search for the game
    game g = NULL;
    for(j=0; j<nb_game; j++)
        if(games[j]->id == id) {
            g = games[j];
            break;
        }

    // if it exists, 
    if(g) {
        senderror(p->fd, CMD_CREATE_GAME, ERR_GAME_ALREADY_EXIST);
        return;
    }

    // Too many games
    if(nb_game >= MAX_GAME) {
        printf("\rThere are so many games boy...\n");
        senderror(p->fd, CMD_CREATE_GAME, ERR_TOO_MANY_GAMES);
        return;
    }

    // Create a new game
    printf("\rNew game created by %s (total : %d)\n", buffer+10, nb_game+1);
    games[nb_game] = g = malloc(sizeof(struct _game));
    g->nb_players = 0;
    g->id = id;
    g->game_master = p;
    nb_game++;

    bindToGame(p, buffer);
}
Пример #9
0
// broadcast a message
void broadcastMessage(player p, char * buffer) {
    int j;

    if(!p->game) {
        senderror(p->fd, buffer, ERR_NOT_IN_GAME);
        return;
    }

    char * msg = malloc((strlen(buffer+4)+strlen(p->name)+7)*sizeof(char));
    sprintf(msg, "%s#%s#%s\n", buffer, p->name, buffer+4);
    for(j=0; j < p->game->nb_players; j++)
        if ( p->game->players[j] != p )
            sendline(p->game->players[j]->fd, msg);
    free(msg);
}
Пример #10
0
int
doit(int sockfd, uint16_t num_trackers, in_addr_t *trackers, uint16_t maxpeers,
	uint16_t num_pkg_servers, in_addr_t *pkg_servers, CURL *curlhandle)
{
	struct timeval		start_time;
#ifdef	TIMEIT
#endif
	struct timeval		end_time;
	unsigned long long	s, e;
	char			*forminfo;
	char			*range;
	char			filename[PATH_MAX];

	gettimeofday(&start_time, NULL);

	bzero(filename, sizeof(filename));

	if ((forminfo = getenv("QUERY_STRING")) == NULL) {
		senderror(500, "No QUERY_STRING", errno);
		return(0);
	}

	if ((range = getenv("HTTP_RANGE")) != NULL) {
		char	*ptr;

		if ((ptr = strchr(range, '=')) != NULL) {
			range = ptr + 1;
		}
	}

	if (getargs(forminfo, filename) != 0) {
		senderror(500, "getargs():failed", errno);
		return(0);
	}

	/*
	 * the time is 'epoch' time
	 */
	logmsg("%d : doit:file %s\n", start_time.tv_sec, basename(filename));
#ifdef	DEBUG
	logmsg("doit:getting file (%s)\n", filename);
#endif

	/*
	 * if the file is local, just read it off the disk, otherwise, ask
	 * the tracker where the file is
	 */
	if (getlocal(filename, range) != 0) {
		if (trackfile(sockfd, filename, range, num_trackers, trackers,
				maxpeers, num_pkg_servers, pkg_servers,
				curlhandle) != 0) {
			senderror(404, "File not found", 0);
		}
	}

#ifdef	DEBUG
	logmsg("doit:done:file (%s)\n\n", filename);
#endif

#ifdef	TIMEIT
#endif
	gettimeofday(&end_time, NULL);
	s = (start_time.tv_sec * 1000000) + start_time.tv_usec;
	e = (end_time.tv_sec * 1000000) + end_time.tv_usec;
	logmsg("doit:svc time: %lld usec file %s from %s\n\n",
		(e - s) - curltime, basename(filename), fromip);

	return(0);
}
Пример #11
0
// get request from client socket
void parseClientRequest(player p, char * buffer) {

    // socket closed
    if(readline(p->fd, buffer, MAXBUF-1) == 0)
        removeClient(p);

    else if(strlen(buffer) > 3 && buffer[3] == '#') { // new message
#ifdef DEBUG
        printf("\r[DEBUG] : %s\n", buffer);
#endif
        buffer[3] = 0;

        // broadcast message
        if(strcmp(buffer, CMD_MESSAGE) == 0)
            broadcastMessage(p, buffer);

        // broadcast action
        else if(strcmp(buffer, CMD_ACTION) == 0)
            broadcastMessage(p, buffer);

        // bind to a game
        else if(strlen(buffer+4) > 6 && buffer[9] == '#' && strcmp(buffer, CMD_BIND) == 0)
            bindToGame(p, buffer);

        // create a game
        else if(strlen(buffer+4) > 6 && buffer[9] == '#' && strcmp(buffer, CMD_CREATE_GAME) == 0)
            createGame(p, buffer);

        // list existing games
        else if(strcmp(buffer, CMD_LIST) == 0)
            listGames(p);

        // Get available id to creage a game
        else if(strcmp(buffer, CMD_CREATE) == 0)
            getAvailableId(p);

        // Create new socket to send a file
        else if(strlen(buffer+4) > 7 && buffer[10] == '#' && strcmp(buffer, CMD_FILE) == 0)
            transfer_file(p, buffer);

        // Register as a Game Master
        else if(strcmp(buffer, CMD_REGISTER_GM) == 0)
            register_game_master(p);

        // Send a message to game master
        else if(strcmp(buffer, CMD_SEND_GM) == 0)
            send_to_game_master(p, buffer);

        // Send a message to a specific player
        else if(strcmp(buffer, CMD_SEND_TO_PLAYER) == 0)
            send_to_player(p, buffer);

        else
            senderror(p->fd, NULL, ERR_NOT_RECOGNIZED);
    }
    else {
#ifdef DEBUG
        printf("\r[DEBUG] : %s\n", buffer);
#endif
        senderror(p->fd, NULL, ERR_NOT_RECOGNIZED);
    }
}
Пример #12
0
// transfer a file
// for the son, never return
void transfer_file(player p, char * buffer) {
    int out[2], in[2];
    int childpid;
    int size;
    char * filepath;
    buffer[10] = 0;

    // if in a game
    if(!p->game) {
        senderror(p->fd, CMD_FILE, ERR_NOT_IN_GAME);
        return;
    }

    // if there is no game master or if the player is not game master
    if(p->game->game_master != p) {
        senderror(p->fd, CMD_FILE, ERR_ONLY_GM);
        return;
    }

    // check for file size
    if((size = atoi(buffer+4)) > MAX_FILE_SIZE) {
        senderror(p->fd, CMD_FILE, ERR_FILE_TOO_BIG);
        return;
    }

    // path of the file is specified
    if(strlen(buffer+11) == 0) {
        senderror(p->fd, NULL, ERR_NOT_RECOGNIZED);
        return;
    }

    filepath = malloc(sizeof(char)*(strlen(buffer+11)+1));
    strcpy(filepath, buffer+11);
    printf("\rPlayer %s is trying to broadcast the file : %s (%dB)\n", p->name, filepath, size);

    // The file can be transmitted
    if(nb_file_processes >= MAX_FILE_TRANSFER) {
        printf("\rToo many ongoing file transfers !\n");
        senderror(p->fd, CMD_FILE, ERR_TOO_MANY_FILE_TRANSFERS);
        return;
    }

    // create a pipe to communicate between the two processes
    pipe(in);
    pipe(out);

    // fork
    if((childpid = fork()) == -1) {
        printf("\rServer failed to fork !\n");
        senderror(p->fd, CMD_FILE, ERR_INTERNAL);
        return;
    }

    // for the child
    if(childpid == 0) {
        // close the input part of one pipe and the output part of the other one
        close(out[0]);
        close(in[1]);

        // create the listening socket
        int filelistener = socket(AF_INET, SOCK_STREAM, 0);
        if(filelistener == -1) {
            senderror(out[1], NULL, "Could not open socket");
            exit(EXIT_FAILURE);
        }
        // enable to reuse addr right after we stopped the server
        int optval = 1;
        setsockopt(filelistener, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

        struct    sockaddr_in servaddr;  // socket address struct 
        memset(&servaddr, 0, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port = htons(0);

        // bind socket
        if(bind(filelistener, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
            senderror(out[1], NULL, "Error when trying to bind !");
            exit(EXIT_FAILURE);
        }

        // get port
        socklen_t length = sizeof(servaddr);
        getsockname(filelistener, (struct sockaddr *)&servaddr, &length);
        int port = ntohs(servaddr.sin_port);

        // Listen on the port
        if(listen(filelistener, MAX_PLAYER_GAME+2) == -1) {
            senderror(out[1], NULL, "Error when trying to listen !");
            exit(EXIT_FAILURE);
        }

        // send port to parent
        char * msg = malloc(sizeof(char)*(12+strlen(filepath)));
        sprintf(msg, "%s#%05d#%s\n", CMD_PORT, port, filepath);
        sendline(out[1], msg);
        free(msg);

        // wait for the connection of the sender
        fd_set rfds;
        FD_ZERO(&rfds);
        FD_SET(filelistener, &rfds);
        int fd_max;
        fd_max = filelistener;
        struct timeval to = {TIMEOUT_FILE, 0};
        if(select(fd_max+1, &rfds, NULL, NULL, &to) < 0) {
            senderror(out[1], NULL, "Error when trying to select !");
            exit(EXIT_FAILURE);
        }

        int sender_socket;
        if(FD_ISSET(filelistener, &rfds)) {
            struct 	  sockaddr_in csin;
            socklen_t recsize = sizeof(csin);
            sender_socket = accept(filelistener, (struct sockaddr *) &csin, &recsize);
        }
        else {
            senderror(out[1], NULL, "Timeout before sender tries to connect !");
            exit(EXIT_FAILURE);
        }

        // get the file from the sender
        char filename[12+MAX_NAME_SIZE];
        sprintf(filename, "/tmp/%05d_%s", p->game->id, p->name);
        int serverfile = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
        int sent = 0;
        while(sent < size) {

            // prepare the set
            fd_set rfds;
            FD_ZERO(&rfds);
            FD_SET(sender_socket, &rfds);
            fd_max = sender_socket;
            to.tv_sec = TIMEOUT_FILE;
            to.tv_usec = 0;

            if(select(fd_max+1, &rfds, NULL, NULL, &to) < 0) {
                senderror(out[1], NULL, "Error when trying to select !");
                close(serverfile);
                unlink(filename);
                exit(EXIT_FAILURE);
            }

            if(FD_ISSET(sender_socket, &rfds)) {
                int rc = read(sender_socket, buffer, MAXBUF);
                if(write(serverfile, buffer, rc) < 0) {
                    senderror(out[1], NULL, "Error when writing to tmp file !");
                    close(serverfile);
                    unlink(filename);
                    exit(EXIT_FAILURE);
                }
                sent += rc;
            }
            else {
                senderror(out[1], NULL, "Timeout when sender was sending data");
                close(serverfile);
                unlink(filename);
                exit(EXIT_FAILURE);
            }
        }
        close(serverfile);
        close(sender_socket);

        // send notification to the parent that we are ready to broadcast
        msg = malloc(sizeof(char)*(19+strlen(filepath)));
        sprintf(msg, "%s#%05d#%06d#%s\n", CMD_READY, port, size, filepath);
        sendline(out[1], msg);
        readline(in[0], buffer, MAXBUF);
        if(buffer[3] != '#') {
            senderror(out[1], NULL, "Who are you ?");
            unlink(filename);
            exit(EXIT_FAILURE);
        }
        buffer[3] = 0;
        if(strcmp(buffer, CMD_ACK) != 0) {
            senderror(out[1], NULL, "Who are you ?");
            unlink(filename);
            exit(EXIT_FAILURE);
        }
        int nb_players = atoi(buffer+4);

        // send the file to the other players
        int connected_clients = 0, served_clients = 0;
        int * sock_client = malloc(sizeof(int)*nb_players);
        int * fd_client = malloc(sizeof(int)*nb_players);
        int * byte_written = malloc(sizeof(int)*nb_players);

        while(served_clients < nb_players-1) {
            fd_set rfds;
            fd_set rfds_write;
            FD_ZERO(&rfds);
            FD_ZERO(&rfds_write);
            FD_SET(filelistener, &rfds);
            fd_max = filelistener;
            int j;
            for(j=0; j<connected_clients; j++) {
                FD_SET(sock_client[j], &rfds_write);
                if(sock_client[j] > fd_max)
                    fd_max = sock_client[j];
            }
            to.tv_sec = TIMEOUT_FILE;
            to.tv_usec = 0;
            int return_value;

            if((return_value = select(fd_max+1, &rfds, &rfds_write, NULL, &to)) < 0) {
                senderror(out[1], NULL, "Error when trying to select !");
                unlink(filename);
                exit(EXIT_FAILURE);
            }
            if(return_value == 0) {
                senderror(out[1], NULL, "Timeout clients");
                unlink(filename);
                exit(EXIT_FAILURE);
            }

            if(FD_ISSET(filelistener, &rfds)) {
                struct 	  sockaddr_in csin;
                socklen_t recsize = sizeof(csin);
                int s = accept(filelistener, (struct sockaddr *) &csin, &recsize);
                if(connected_clients < nb_players) {
                    sock_client[connected_clients] = s;
                    fd_client[connected_clients] = open(filename, O_RDONLY);
                    byte_written[connected_clients] = 0;
                    connected_clients ++;
                }
                else
                    close(s);
            }

            for(j=0; j<connected_clients; j++)
                if(FD_ISSET(sock_client[j], &rfds_write)) {
                    int b_read = read(fd_client[j], buffer, size-byte_written[j] < MAXBUF ? size-byte_written[j] : MAXBUF);
                    int b_written = write(sock_client[j], buffer, b_read);
                    if(b_written == 0) {
                        close(sock_client[j]);
                        close(fd_client[j]);
                        int k;
                        for(k=j; k<connected_clients-1; k++) {
                            fd_client[k] = fd_client[k+1];
                            sock_client[k] = sock_client[k+1];
                            byte_written[k] = byte_written[k+1];
                        }
                    }
                    lseek(sock_client[j], b_written-b_read, SEEK_CUR);
                    byte_written[j] += b_written;
                    if(byte_written[j] == size) {
                        close(sock_client[j]);
                        close(fd_client[j]);
                        int k;
                        for(k=j; k<connected_clients-1; k++) {
                            fd_client[k] = fd_client[k+1];
                            sock_client[k] = sock_client[k+1];
                            byte_written[k] = byte_written[k+1];
                        }
                        served_clients++;
                        connected_clients--;
                        j--;
                    }

                }
        }
        sendack(out[1], NULL, filepath);
        unlink(filename);
        exit(0);
    }
    // for the parent
    else {
        // close output part of the pipe and input part of the other
        close(out[1]);
        close(in[0]);

        // create a new entry in the child processes table
        fileprocesses[nb_file_processes] = malloc(sizeof(struct _fproc));
        fileprocesses[nb_file_processes]->in = out[0];
        fileprocesses[nb_file_processes]->out = in[1];
        fileprocesses[nb_file_processes]->sender = p;
        fileprocesses[nb_file_processes]->pid = childpid;
        nb_file_processes++;
        free(filepath);

        return;
    }
}