コード例 #1
0
ファイル: server.c プロジェクト: dividuum/infon
void server_writeto(client_t *client, const void *data, size_t size) {
    if (size == 0) 
        return;
    traffic += size;

    // Fileclients werden direkt ueber write abgewickelt.
    if (client->is_file_writer) {
        write(client_num(client), data, size);
        return;
    }
    
    if (EVBUFFER_LENGTH(client->out_buf) > 1024*1024)
        return;
    
    if (client->compress) {
        char buf[1024];
        client->strm.next_in  = (void*)data; // not const?
        client->strm.avail_in = size;
        while (client->strm.avail_in > 0) {
            client->strm.next_out  = (unsigned char*)buf;
            client->strm.avail_out = sizeof(buf);
            int ret = deflate(&client->strm, 0);
            if (ret != Z_OK) {
                fprintf(stderr, "urgh. deflate didn't return Z_OK: %d\n", ret);
                // XXX: handle
            }
            evbuffer_add(client->out_buf, buf, sizeof(buf) - client->strm.avail_out);
        }
    } else {
        evbuffer_add(client->out_buf, (void*)data, size);
    }

    event_add(&client->wr_event, NULL);
}
コード例 #2
0
ファイル: main.c プロジェクト: mariogamer2/Cafiine
DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *handle, int error) {
    int my_ret = -1;
    error = 0xffffffff;
    if ((int)bss_ptr != 0x0a000000) {
        int client = client_num(pClient);
        if (client < MAX_CLIENT && client >= 0) {
            int ret;
            my_ret = cafiine_fopen(bss.socket_fsa[client], &ret, path, mode, handle);
            if (my_ret == 0) {
                // File exists in cafiine server, a new handle has been created
                return ret;
            }
            else if (my_ret >= 1) {
                // File has been requested from cafiine server,
                ret = real_FSOpenFile(pClient, pCmd, path, mode, handle, error);
                if (ret >= 0) {
                    int size = (my_ret == 1 ? DUMP_BLOCK_SIZE : DUMP_BLOCK_SIZE_SLOW);
                    cafiine_send_handle(bss.socket_fsa[client], client, path, *handle);
                    void* buffer = memalign(sizeof(char) * size, 0x40);
                    int ret2;
                    while ((ret2 = real_FSReadFile(pClient, pCmd, buffer, 1, size, *handle, 0, error)) > 0)
                        cafiine_send_file(bss.socket_fsa[client], buffer, ret2, *handle);
                    cafiine_fclose(bss.socket_fsa[client], &ret2, *handle);
                    real_FSSetPosFile(pClient, pCmd, *handle, 0, error);
                }
                return ret;
            }
        }
    }

    return real_FSOpenFile(pClient, pCmd, path, mode, handle, error);
}
コード例 #3
0
ファイル: fs.c プロジェクト: Joonie86/loadiine
static int GetCurClient(void *pClient) {
    if ((int)bss_ptr != 0x0a000000) {
        int client = client_num(pClient);
        if (client >= 0) {
            return client;
        }
    }
    return -1;
}
コード例 #4
0
ファイル: fs.c プロジェクト: Joonie86/loadiine
DECL(int, FSDelClient, void *pClient) {
    if ((int)bss_ptr != 0x0a000000) {
        int client = client_num(pClient);
        if (client >= 0) {
            fs_disconnect(bss.socket_fs[client]);
            client_num_free(client);
        }
    }

    return real_FSDelClient(pClient);
}
コード例 #5
0
ファイル: main.c プロジェクト: NWPlayer123/Cafiine-5.5.X
DECL(int, FSIsEof, void *pClient, void *pCmd, int fd, int error) {
	if ((int)bss_ptr != 0x0a000000 && ((fd & MASK_FD) == MASK_FD)) {
		int client = client_num(pClient);
		if (client < MAX_CLIENT && client >= 0) {
			int ret;
			if (cafiine_feof(bss.socket_fsa[client], &ret, fd) == 0) {
				return ret;
			}
		}
	}

	return real_FSIsEof(pClient, pCmd, fd, error);
}
コード例 #6
0
ファイル: main.c プロジェクト: NWPlayer123/Cafiine-5.5.X
DECL(int, FSGetStatFile, void *pClient, void *pCmd, int fd, void *buffer, int error) {
	if ((int)bss_ptr != 0x0a000000 && ((fd & MASK_FD) == MASK_FD)) {
		int client = client_num(pClient);
		if (client < MAX_CLIENT && client >= 0) {
			int ret;
			if (cafiine_fstat(bss.socket_fsa[client], &ret, fd, buffer) == 0) {
				return ret;
			}
		}
	}

	return real_FSGetStatFile(pClient, pCmd, fd, buffer, error);
}
コード例 #7
0
ファイル: main.c プロジェクト: NWPlayer123/Cafiine-5.5.X
DECL(int, FSGetPosFile, void *pClient, void *pCmd, int fd, int *pos, int error) {
	if ((int)bss_ptr != 0x0a000000 && ((fd & MASK_FD) == MASK_FD)) {
		int client = client_num(pClient);
		if (client < MAX_CLIENT && client >= 0) {
			int ret;
			if (cafiine_fgetpos(bss.socket_fsa[client], &ret, fd, pos) == 0) {
				return ret;
			}
		}
	}

	return real_FSGetPosFile(pClient, pCmd, fd, pos, error);
}
コード例 #8
0
ファイル: main.c プロジェクト: NWPlayer123/Cafiine-5.5.X
DECL(int, FSReadFile, void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int error) {
	if ((int)bss_ptr != 0x0a000000 && ((fd & MASK_FD) == MASK_FD)) {
		int client = client_num(pClient);
		if (client < MAX_CLIENT && client >= 0) {
			int ret;
			if (cafiine_fread(bss.socket_fsa[client], &ret, buffer, size, count, fd) == 0) {
				return ret;
			}
		}
	}

	return real_FSReadFile(pClient, pCmd, buffer, size, count, fd, flag, error);
}
コード例 #9
0
ファイル: main.c プロジェクト: NWPlayer123/Cafiine-5.5.X
DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *handle, int error) {
	if ((int)bss_ptr != 0x0a000000) {
		int client = client_num(pClient);
		if (client < MAX_CLIENT && client >= 0) {
			int ret;
			if (cafiine_fopen(bss.socket_fsa[client], &ret, path, mode, handle) == 0) {
				return ret;
			}
		}
	}

	return real_FSOpenFile(pClient, pCmd, path, mode, handle, error);
}
コード例 #10
0
ファイル: server.c プロジェクト: dividuum/infon
static int luaStartFileWriter(lua_State *L) {
    const char *file     = luaL_checkstring(L, 1);
    int         one_game = lua_isboolean(L, 2) ? lua_toboolean(L, 2) : 1;
    int    is_gui_client = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : 1;
    client_t *filewriter = server_start_file_writer(file);
    if (!filewriter) 
        luaL_error(L, "cannot start file %s", file);
    if (is_gui_client) 
        client_turn_into_gui_client(filewriter);
    if (one_game)      
        filewriter->kick_at_end_of_game = one_game;
    lua_pushnumber(L, client_num(filewriter));
    return 1;
}
コード例 #11
0
ファイル: server.c プロジェクト: dividuum/infon
static void server_readable(int fd, short event, void *arg) {
    client_t *client = (client_t*)arg;

    // Der Client wurde 'extern' gekickt, allerdings noch
    // nicht entfernt. Dann wird dieser Readcallback aufgerufen,
    // sollte allerdings nichts mehr machen.
    if (client->kill_me)
        return;

    int ret = evbuffer_read(client->in_buf, fd, 128);
    if (ret < 0) {
        server_destroy(client, strerror(errno));
    } else if (ret == 0) {
        server_destroy(client, "eof reached");
    } else if (EVBUFFER_LENGTH(client->in_buf) > 8192) {
        server_destroy(client, "line too long. go away.");
    } else {
        char *line;
        while ((line = evbuffer_readline(client->in_buf))) {
            lua_pushliteral(L, "on_client_input");   
            lua_rawget(L, LUA_GLOBALSINDEX);      
            lua_pushnumber(L, client_num(client));
            lua_pushstring(L, line);
            free(line);

            // Cycles fuer die Verarbeitung hochsetzen
            lua_set_cycles(L, 0xFFFFFF);
                
            // Input verarbeiten
            output_client = client;
            if (lua_pcall(L, 2, 0, 0) != 0) {
                fprintf(stderr, "error calling on_client_input: %s\n", lua_tostring(L, -1));
                server_writeto(client, lua_tostring(L, -1), lua_strlen(L, -1));
                lua_pop(L, 1);
            }
            output_client = NULL;

            // Kill Me Flag waehrend Aufruf von on_client_input 
            // gesetzt? Direkt rausschmeissen!
            if (client->kill_me) {
                server_destroy(client, client->kill_me);
                return;
            }
        }
    }
}
コード例 #12
0
ファイル: server.c プロジェクト: dividuum/infon
client_t *server_accept(int fd, const char *address) {
    client_t *client = clients;

    for (int i = 0; i < MAXCLIENTS; i++, client++) {
        if (!CLIENT_USED(client))
            goto found;
    }

    // write(fd, "no free slot\r\n", 14);
    fprintf(stderr, "cannot accept() new incoming connection: no free slot\n");
    return NULL;

found:
    memset(client, 0, sizeof(client_t));
    client->fd = fd;

    // File Writer wird leicht unterschiedlich behandelt
    client->is_file_writer = strstr(address, "special:file") == address;

    // Non Blocking setzen 
#ifdef WIN32
    DWORD notblock = 1;
    ioctlsocket(client->fd, FIONBIO, &notblock);
#else
    if (fcntl(client->fd, F_SETFL, O_NONBLOCK) < 0) {
        fprintf(stderr, "cannot set accept()ed socket nonblocking: %s\n", strerror(errno));
        return NULL;
    }
#endif

    // Soll Verbindung angenommen werden?
    lua_pushliteral(L, "on_new_client");
    lua_rawget(L, LUA_GLOBALSINDEX);
    lua_pushstring(L, address);

    if (lua_pcall(L, 1, 2, 0) != 0) {
        fprintf(stderr, "error calling on_new_client: %s\n", lua_tostring(L, -1));
        lua_pop(L, 1);
        return NULL;
    }

    if (!lua_toboolean(L, -2)) {
        size_t len; const char *msg = lua_tolstring(L, -1, &len);
        write(client->fd, msg, len);
        lua_pop(L, 2);
        return NULL;
    }

    lua_pop(L, 2);

    // Libevent aktivieren
    event_set(&client->rd_event, client->fd, EV_READ | EV_PERSIST, server_readable, client);
    event_set(&client->wr_event, client->fd, EV_WRITE            , server_writable, client);
    
    client->in_buf  = evbuffer_new();
    client->out_buf = evbuffer_new();

    client->compress = 0;

    client->kill_me = NULL;
    client->player  = NULL;

    client->next = NULL;
    client->prev = NULL;

    client->is_gui_client = 0;
    client->next_gui = NULL;
    client->prev_gui = NULL;

    num_clients++;

    // Annehmen
    lua_pushliteral(L, "on_client_accepted");
    lua_rawget(L, LUA_GLOBALSINDEX);
    lua_pushnumber(L, client_num(client));
    lua_pushstring(L, address);

    if (lua_pcall(L, 2, 0, 0) != 0) {
        fprintf(stderr, "error calling on_client_accepted: %s\n", lua_tostring(L, -1));
        lua_pop(L, 1);
    }

    if (!client->is_file_writer)
        event_add(&client->rd_event, NULL);

    return client;
}
コード例 #13
0
ファイル: server.c プロジェクト: dividuum/infon
void server_destroy(client_t *client, const char *reason) {
    lua_pushliteral(L, "on_client_close");
    lua_rawget(L, LUA_GLOBALSINDEX);
    lua_pushnumber(L, client_num(client));
    lua_pushstring(L, reason);
    if (lua_pcall(L, 2, 0, 0) != 0) {
        fprintf(stderr, "error calling on_client_close: %s\n", lua_tostring(L, -1));
        lua_pop(L, 1);
    }

    // Quitmeldung senden
    if (client->is_gui_client) {
        packet_t packet;
        packet_init(&packet, PACKET_QUIT_MSG);
        packet_writeXX(&packet, reason, strlen(reason));
        server_send_packet(&packet, client);
    } else {
        server_writeto(client, "connection terminated: ", 23);
        server_writeto(client, reason, strlen(reason));
        server_writeto(client, "\r\n", 2);
    }

    // Kompressionsrest flushen
    server_flush_compression(client);

    // Rest rausschreiben (hier keine Fehlerbehandlung mehr, da eh egal).
    // Bei Filewritern muss nichts geschrieben werden, da deren Daten
    // immer direkt rausgeschrieben werden.
    if (!client->is_file_writer) 
        evbuffer_write(client->out_buf, client->fd);

    evbuffer_free(client->in_buf);
    evbuffer_free(client->out_buf);

    free(client->kill_me);

    if (client->compress)
        deflateEnd(&client->strm);
    
    event_del(&client->rd_event);
    event_del(&client->wr_event);
    client->in_buf  = NULL;
    client->out_buf = NULL;

    if (client->player) 
        player_detach_client(client, client->player);

    assert(client->next == NULL);
    assert(client->prev == NULL);

    if (client->is_gui_client) {
        if (client->next_gui == client) {
            assert(client->prev_gui == client);
            guiclients = NULL;
        } else {
            client->next_gui->prev_gui = client->prev_gui;
            client->prev_gui->next_gui = client->next_gui;
            guiclients = client->next_gui;
        }
    }

    num_clients--;
    
#ifndef NO_CONSOLE_CLIENT    
    if (client->fd != STDIN_FILENO)
#endif
#ifdef WIN32
        if (client->is_file_writer) {
            close(client->fd);
        } else {
            closesocket(client->fd);
        }
#else
        close(client->fd);
#endif
}