Example #1
0
File: client.c Project: azuwis/mpd
static void client_close(struct client *client)
{
    assert(num_clients > 0);
    assert(clients != NULL);

    clients = g_list_remove(clients, client);
    --num_clients;

    client_set_expired(client);

    if (client->cmd_list) {
        free_cmd_list(client->cmd_list);
        client->cmd_list = NULL;
    }

    g_queue_foreach(client->deferred_send, deferred_buffer_free, NULL);
    g_queue_free(client->deferred_send);

    g_log(G_LOG_DOMAIN, LOG_LEVEL_SECURE,
          "[%u] closed", client->num);
    g_free(client);
}
Example #2
0
void
client_close(struct client *client)
{
	client_list_remove(client);

	client_set_expired(client);

	g_timer_destroy(client->last_activity);

	if (client->cmd_list) {
		free_cmd_list(client->cmd_list);
		client->cmd_list = NULL;
	}

	g_queue_foreach(client->deferred_send, deferred_buffer_free, NULL);
	g_queue_free(client->deferred_send);

	fifo_buffer_free(client->input);

	g_log(G_LOG_DOMAIN, LOG_LEVEL_SECURE,
	      "[%u] closed", client->num);
	g_free(client);
}
Example #3
0
enum command_return
client_process_line(struct client *client, char *line)
{
    enum command_return ret;

    if (strcmp(line, "noidle") == 0) {
        if (client->idle_waiting) {
            /* send empty idle response and leave idle mode */
            client->idle_waiting = false;
            command_success(client);
            client_write_output(client);
        }

        /* do nothing if the client wasn't idling: the client
           has already received the full idle response from
           client_idle_notify(), which he can now evaluate */

        return COMMAND_RETURN_OK;
    } else if (client->idle_waiting) {
        /* during idle mode, clients must not send anything
           except "noidle" */
        g_warning("[%u] command \"%s\" during idle",
                  client->num, line);
        return COMMAND_RETURN_CLOSE;
    }

    if (client->cmd_list_OK >= 0) {
        if (strcmp(line, CLIENT_LIST_MODE_END) == 0) {
            g_debug("[%u] process command list",
                    client->num);

            /* for scalability reasons, we have prepended
               each new command; now we have to reverse it
               to restore the correct order */
            client->cmd_list = g_slist_reverse(client->cmd_list);

            ret = client_process_command_list(client,
                                              client->cmd_list_OK,
                                              client->cmd_list);
            g_debug("[%u] process command "
                    "list returned %i", client->num, ret);

            if (ret == COMMAND_RETURN_CLOSE ||
                    client_is_expired(client))
                return COMMAND_RETURN_CLOSE;

            if (ret == COMMAND_RETURN_OK)
                command_success(client);

            client_write_output(client);
            free_cmd_list(client->cmd_list);
            client->cmd_list = NULL;
            client->cmd_list_OK = -1;
        } else {
            size_t len = strlen(line) + 1;
            client->cmd_list_size += len;
            if (client->cmd_list_size >
                    client_max_command_list_size) {
                g_warning("[%u] command list size (%lu) "
                          "is larger than the max (%lu)",
                          client->num,
                          (unsigned long)client->cmd_list_size,
                          (unsigned long)client_max_command_list_size);
                return COMMAND_RETURN_CLOSE;
            }

            new_cmd_list_ptr(client, line);
            ret = COMMAND_RETURN_OK;
        }
    } else {
        if (strcmp(line, CLIENT_LIST_MODE_BEGIN) == 0) {
            client->cmd_list_OK = 0;
            ret = COMMAND_RETURN_OK;
        } else if (strcmp(line, CLIENT_LIST_OK_MODE_BEGIN) == 0) {
            client->cmd_list_OK = 1;
            ret = COMMAND_RETURN_OK;
        } else {
            g_debug("[%u] process command \"%s\"",
            client->num, line);
            ret = command_process(client, 0, line);
            g_debug("[%u] command returned %i",
            client->num, ret);

            if (ret == COMMAND_RETURN_CLOSE ||
            client_is_expired(client))
                return COMMAND_RETURN_CLOSE;

            if (ret == COMMAND_RETURN_OK)
                command_success(client);

            client_write_output(client);
        }
    }

    return ret;
}
Example #4
0
int serve(client_node_t* client) {

    client->pid = getpid();
    client_id = client->id;
    signal(SIGUSR1, signal_handle);

    int c;
    // replace stdin, stdout, stderr to client fd
    for(c=0; c<3; c++){
        dup2(client->client_sc_fd, c);
    }

    for(c=0; c<client->num_env; c++) {
        setenv(client->env[c], client->env_val[c], 1);
    }

    printf("%s\n", welcome_message);
    fflush(stdout);
    char broad_msg[1024];
    bzero(broad_msg, 1024);
    sprintf(broad_msg, "*** User '(no name)' entered from %s/%d. ***\n", client->ip, client->port);
    broad_cast(client, broad_msg);
    printf("%% ");
    fflush(stdout);

    while(1){
        cmd_node_t* cmd_node_list = NULL;
        parse_tokens(&cmd_node_list);
        int state;

        if(cmd_node_list != NULL) {

            // handle_from_user_node(&cmd_node_list);
            // process commands
            // despatch node to right palce
            while(cmd_node_list != NULL) {
                cmd_node_t* node_to_exec = pull_cmd_node(&cmd_node_list);
                if(node_to_exec->pipe_count == -1) {
                    break;
                }
                int errnum = exec_cmd_node(node_to_exec, client);
                if(errnum == -1) {
                    // command not found
                    printf("Unknown command: [%s].\n", node_to_exec->cmd);
                    fflush(stdout);
                    free_cmd_list(&cmd_node_list);
                } else if(errnum == -2) {
                    // pipe to me not exist
                    printf("*** Error: the pipe #%d->#%d does not exist yet. ***\n", node_to_exec->from_user_id, client->id);
                    fflush(stdout);
                    free_cmd_list(&cmd_node_list);
                } else if(errnum == -3) {
                    // pipe to other exist
                    printf("*** Error: the pipe #%d->#%d already exists. ***\n", client->id, node_to_exec->to_user_id);
                    fflush(stdout);
                } else if(errnum == -4) {
                    // logout
                    return -1;
                }
            }
        }
        printf("%% ");
        fflush(stdout);
    }
    return 0;
}