Ejemplo n.º 1
0
/* Callback: "a message is received to a registered object path" */
static DBusHandlerResult message_received(DBusConnection* conn, DBusMessage* msg, void* data)
{
    const char* member = dbus_message_get_member(msg);
    VERB1 log("%s(method:'%s')", __func__, member);

    set_client_name(dbus_message_get_sender(msg));

    DBusMessage* reply = dbus_message_new_method_return(msg);
    int r = -1;
    if (strcmp(member, "DeleteDebugDump") == 0)
        r = handle_DeleteDebugDump(msg, reply);

// NB: C++ binding also handles "Introspect" method, which returns a string.
// It was sending "dummy" introspection answer whick looks like this:
// "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
// "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
// "<node>\n"
// "</node>\n"
// Apart from a warning from abrt-gui, just sending error back works as well.
// NB2: we may want to handle "Disconnected" here too.

    if (r < 0)
    {
        /* handle_XXX experienced an error (and did not send any reply) */
        dbus_message_unref(reply);
        if (dbus_message_get_type(msg) == DBUS_MESSAGE_TYPE_METHOD_CALL)
        {
            /* Create and send error reply */
            reply = dbus_message_new_error(msg, DBUS_ERROR_FAILED, "not supported");
            if (!reply)
                die_out_of_memory();
            send_flush_and_unref(reply);
        }
    }

    set_client_name(NULL);

    return DBUS_HANDLER_RESULT_HANDLED;
}
Ejemplo n.º 2
0
/* register new midi synth port */
int
snd_seq_midisynth_register_port(snd_seq_device_t *dev)
{
	seq_midisynth_client_t *client;
	seq_midisynth_t *msynth, *ms;
	snd_seq_port_info_t port;
	snd_rawmidi_info_t info;
	int newclient = 0;
	unsigned int p, ports;
	snd_seq_client_callback_t callbacks;
	snd_seq_port_callback_t pcallbacks;
	snd_card_t *card = dev->card;
	int device = dev->device;
	unsigned int input_count = 0, output_count = 0;

	snd_assert(card != NULL && device >= 0 && device < SNDRV_RAWMIDI_DEVICES, return -EINVAL);
	info.device = device;
	info.stream = SNDRV_RAWMIDI_STREAM_OUTPUT;
	info.subdevice = 0;
	if (snd_rawmidi_info_select(card, &info) >= 0)
		output_count = info.subdevices_count;
	info.stream = SNDRV_RAWMIDI_STREAM_INPUT;
	if (snd_rawmidi_info_select(card, &info) >= 0) {
		input_count = info.subdevices_count;
	}
	ports = output_count;
	if (ports < input_count)
		ports = input_count;
	if (ports == 0)
		return -ENODEV;
	if (ports > (256 / SNDRV_RAWMIDI_DEVICES))
		ports = 256 / SNDRV_RAWMIDI_DEVICES;

	down(&register_mutex);
	client = synths[card->number];
	if (client == NULL) {
		newclient = 1;
		client = kcalloc(1, sizeof(*client), GFP_KERNEL);
		if (client == NULL) {
			up(&register_mutex);
			return -ENOMEM;
		}
		memset(&callbacks, 0, sizeof(callbacks));
		callbacks.private_data = client;
		callbacks.allow_input = callbacks.allow_output = 1;
		client->seq_client = snd_seq_create_kernel_client(card, 0, &callbacks);
		if (client->seq_client < 0) {
			kfree(client);
			up(&register_mutex);
			return -ENOMEM;
		}
		set_client_name(client, card, &info);
	} else if (device == 0)
		set_client_name(client, card, &info); /* use the first device's name */

	msynth = kcalloc(ports, sizeof(seq_midisynth_t), GFP_KERNEL);
	if (msynth == NULL)
		goto __nomem;

	for (p = 0; p < ports; p++) {
		ms = &msynth[p];

		if (snd_seq_midisynth_new(ms, card, device, p) < 0)
			goto __nomem;

		/* declare port */
		memset(&port, 0, sizeof(port));
		port.addr.client = client->seq_client;
		port.addr.port = device * (256 / SNDRV_RAWMIDI_DEVICES) + p;
		port.flags = SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
		memset(&info, 0, sizeof(info));
		info.device = device;
		if (p < output_count)
			info.stream = SNDRV_RAWMIDI_STREAM_OUTPUT;
		else
			info.stream = SNDRV_RAWMIDI_STREAM_INPUT;
		info.subdevice = p;
		if (snd_rawmidi_info_select(card, &info) >= 0)
			strcpy(port.name, info.subname);
		if (! port.name[0]) {
			if (info.name[0]) {
				if (ports > 1)
					snprintf(port.name, sizeof(port.name), "%s-%d", info.name, p);
				else
					snprintf(port.name, sizeof(port.name), "%s", info.name);
			} else {
				/* last resort */
				if (ports > 1)
					sprintf(port.name, "MIDI %d-%d-%d", card->number, device, p);
				else
					sprintf(port.name, "MIDI %d-%d", card->number, device);
			}
		}
		if ((info.flags & SNDRV_RAWMIDI_INFO_OUTPUT) && p < output_count)
			port.capability |= SNDRV_SEQ_PORT_CAP_WRITE | SNDRV_SEQ_PORT_CAP_SYNC_WRITE | SNDRV_SEQ_PORT_CAP_SUBS_WRITE;
		if ((info.flags & SNDRV_RAWMIDI_INFO_INPUT) && p < input_count)
			port.capability |= SNDRV_SEQ_PORT_CAP_READ | SNDRV_SEQ_PORT_CAP_SYNC_READ | SNDRV_SEQ_PORT_CAP_SUBS_READ;
		if ((port.capability & (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ)) == (SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_READ) &&
		    info.flags & SNDRV_RAWMIDI_INFO_DUPLEX)
			port.capability |= SNDRV_SEQ_PORT_CAP_DUPLEX;
		port.type = SNDRV_SEQ_PORT_TYPE_MIDI_GENERIC;
		port.midi_channels = 16;
		memset(&pcallbacks, 0, sizeof(pcallbacks));
		pcallbacks.owner = THIS_MODULE;
		pcallbacks.private_data = ms;
		pcallbacks.subscribe = midisynth_subscribe;
		pcallbacks.unsubscribe = midisynth_unsubscribe;
		pcallbacks.use = midisynth_use;
		pcallbacks.unuse = midisynth_unuse;
		pcallbacks.event_input = event_process_midi;
		port.kernel = &pcallbacks;
		if (snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_CREATE_PORT, &port)<0)
			goto __nomem;
		ms->seq_client = client->seq_client;
		ms->seq_port = port.addr.port;
	}
	client->ports_per_device[device] = ports;
	client->ports[device] = msynth;
	client->num_ports++;
	if (newclient)
		synths[card->number] = client;
	up(&register_mutex);
	return 0;	/* success */

      __nomem:
	if (msynth != NULL) {
	      	for (p = 0; p < ports; p++)
	      		snd_seq_midisynth_delete(&msynth[p]);
		kfree(msynth);
	}
	if (newclient) {
		snd_seq_delete_kernel_client(client->seq_client);
		kfree(client);
	}
	up(&register_mutex);
	return -ENOMEM;
}
Ejemplo n.º 3
0
int exec_cmd_node(cmd_node_t* cmd_node, client_node_t* client) {

    int pipe_count = cmd_node->pipe_count;
    int pid = -1;
    int input_pipe_fd = -1;
    int output_pipe_fd = -1;

    if(strcmp(cmd_node->cmd, "printenv") == 0) {
        char* env_name = cmd_node->args[1];
        if(env_name != NULL) {
            char* env_val = getenv(env_name);
            printf("%s=%s\n", env_name, env_val);
            fflush(stdout);
        }
        decrease_all_pipe_node(client->pipe_list);
        return 0;
    } else if(strcmp(cmd_node->cmd, "setenv") == 0) {
        char* env_name = cmd_node->args[1];
        char* env_val = cmd_node->args[2];
        set_env_to_client_node(client, env_name, env_val);
        setenv(env_name, env_val, 1);
        decrease_all_pipe_node(client->pipe_list);
        return 0;
    } else if(strcmp(cmd_node->cmd, "exit") == 0) {
        char exit_msg[64];
        bzero(exit_msg, 64);
        sprintf(exit_msg, "*** User '%s' left. ***\n", client->name);
        broad_cast(client, exit_msg);
        // clean message queues
        mq_clean(client->id);
        // remove global pipes
        remove_global_pipe(client->id, client->id, 0);
        // remove client from client list
        remove_client_node(client);
        // return logout status
        return -4;
    } else if(strcmp(cmd_node->cmd, "who") == 0) {
        who(client);
        decrease_all_pipe_node(client->pipe_list);
        return 0;
    } else if(strcmp(cmd_node->cmd, "tell") == 0) {
        int r = tell(client, cmd_node->args[1], cmd_node->args[2]);
        if(r == -1) {
            printf("*** Error: user #%s does not exist yet. ***\n", cmd_node->args[1]);
            fflush(stdout);
        } else {
            decrease_all_pipe_node(client->pipe_list);
        }
        return 0;
    } else if(strcmp(cmd_node->cmd, "yell") == 0) {
        char message[11000];
        sprintf(message, "*** %s yelled ***: %s\n", client->name, cmd_node->args[1]);
        bzero(message, 11000);
        broad_cast(client, message);
        decrease_all_pipe_node(client->pipe_list);
        return 0;
    } else if(strcmp(cmd_node->cmd, "name") == 0) {
        char* name = cmd_node->args[1];
        if(check_name_exist(name) == 1) {
            printf("*** User '%s' already exists. ***\n", name);
            fflush(stdout);
        } else {
            set_client_name(client->id, name);
            strcpy(client->name, name);
            char msg[40];
            bzero(msg, 40);
            sprintf(msg, "*** User from %s/%d is named '%s'. ***\n", client->ip, client->port, client->name);
            broad_cast(client, msg);
            fflush(stdout);
        }
        decrease_all_pipe_node(client->pipe_list);
        return 0;
    }

    decrease_all_pipe_node(client->pipe_list);

    // get this process input source
    pipe_node_t* in_pipe_node = find_pipe_node_by_count(client->pipe_list, 0);
    if(in_pipe_node != NULL) {
        input_pipe_fd = in_pipe_node->in_fd;
        if(fcntl(in_pipe_node->out_fd, F_GETFD) != -1) {
            close(in_pipe_node->out_fd);
        }
        in_pipe_node->count--;
    }
    if(cmd_node->pipe_from_user == 1) {
        char data[2048];
        bzero(data, 2048);
        int r = pull_global_pipe_data(cmd_node->from_user_id, client->id, data);
        if(r == -1) {
            inscrease_all_pipe_node(client->pipe_list);
            return -2;
        }
        int g_pipe[2];
        pipe(g_pipe);
        write(g_pipe[1], r.msg, strlen(r.msg));
        close(g_pipe[1]);
        input_pipe_fd = g_pipe[0];
    }
    int tmp_global_pipe[2];

    // get this process output source
    pipe_node_t* out_pipe_node = find_pipe_node_by_count(client->pipe_list, pipe_count);
    if(out_pipe_node != NULL) {
        output_pipe_fd = out_pipe_node->out_fd;
    } else if(cmd_node->pipe_to_file == 1){
        output_pipe_fd = get_file_fd(cmd_node->filename);
    } else if(cmd_node->pipe_to_user == 1) {
        if(is_client_available(cmd_node->to_user_id) != 1) {
            printf("*** Error: user #%d does not exist yet. ***\n", cmd_node->to_user_id);
            fflush(stdout);
            close_unused_fd(client);
            return 0;
        } else if(is_global_pipe_exist(client->id, cmd_node->to_user_id) == 1) {
            close_unused_fd(client);
            return -3;
        }
        // global pipe
        // create global pipe node
        pipe(tmp_global_pipe);
        output_pipe_fd = tmp_global_pipe[1];

        // broad cast message
        // *** (name) (#<client id>) just piped '(command line)' to (receiver's name) (#<receiver's client_id>) ***
        char* msg_temp = "*** %s (#%d) just piped '%s' to %s (#%d) ***\n";
        char msg[128];
        bzero(msg, 128);
        char to_client_name[30];
        get_client_name(cmd_node->to_user_id, to_client_name);
        sprintf(msg, msg_temp, client->name, client->id, last_line, to_client_name, cmd_node->to_user_id);
        broad_cast(client, msg);
        fflush(stdout);
    } else if(cmd_node->pipe_count != 0) {
        int new_pipe_fd[2];
        pipe(new_pipe_fd);
        out_pipe_node = malloc(sizeof(pipe_node_t));
        out_pipe_node->count = cmd_node->pipe_count;
        out_pipe_node->in_fd = new_pipe_fd[0];
        out_pipe_node->out_fd = new_pipe_fd[1];
        out_pipe_node->next_node = NULL;
        insert_pipe_node(&(client->pipe_list), out_pipe_node);

        output_pipe_fd = new_pipe_fd[1];
    }


    pid = fork();
    if(pid == 0) {
        if(input_pipe_fd != -1) {
            // not use stdin
            close(0);
            dup(input_pipe_fd);
            close(input_pipe_fd);
        }

        // out
        if(out_pipe_node != NULL) {
            close(1);
            dup(out_pipe_node->out_fd);
            close(out_pipe_node->out_fd);
        } else if(cmd_node->pipe_to_file == 1) {
            close(1);
            dup(output_pipe_fd);
            close(output_pipe_fd);
        } else if(cmd_node->pipe_to_user == 1) {
            close(1);
            close(2);
            dup(output_pipe_fd);
            dup(output_pipe_fd);
            close(output_pipe_fd);
        } else {
            dup2(client->client_sc_fd, 1);
        }
        execvp(cmd_node->cmd, cmd_node->args);
        exit(-1);

    } else if(pipe_count != 0) {
        int status;
        wait(&status);
        // waitpid(pid, &status, 0);
        if(WEXITSTATUS(status) != 0){
            inscrease_all_pipe_node(client->pipe_list);
            return -1;
        } else {
            if(input_pipe_fd != -1) {
                close(input_pipe_fd);
            }
        }
    } else {
        int status;
        wait(&status);
        // waitpid(pid, &status, 0);
        if(WEXITSTATUS(status) != 0){
            inscrease_all_pipe_node(client->pipe_list);
            return -1;
        } else {
            if(in_pipe_node != NULL) {
                close(in_pipe_node->out_fd);
                in_pipe_node->count--;
            }
            if(cmd_node->pipe_to_user == 1) {
                if(fcntl(output_pipe_fd, F_GETFD) != -1) {
                    close(output_pipe_fd);
                }
                char buffer[2048];
                bzero(buffer, 2048);
                read(tmp_global_pipe[0], buffer, 2048);
                //printf("[DBG] Buffer:\n");
                //printf("%s\n", buffer);
                add_global_pipe(client->id, cmd_node->to_user_id, buffer);
                close(tmp_global_pipe[0]);
            }
            close_unused_fd(client);
        }
    }
    if(cmd_node->pipe_from_user == 1) {
        char* msg_tmp = "*** %s (#%d) just received from %s (#%d) by '%s' ***\n";
        char msg[100];
        bzero(msg, 100);
        char from_client_name[30];
        get_client_name(cmd_node->from_user_id, from_client_name);
        sprintf(msg, msg_tmp, client->name, client->id, from_client_name, cmd_node->from_user_id, last_line);
        broad_cast(client, msg);
        remove_global_pipe(cmd_node->from_user_id, client->id, 1);
    }
    return 0;
}