static char *client_ext_dump(struct pa_client *client, char *buf, int len)
{
    const char  *name;
    const char  *id;
    pid_t        pid;
    uid_t        uid;
    const char  *exe;
    const char  *args, *arg0;

    if (client == NULL)
        *buf = '\0';
    else {
        name = pa_client_ext_name(client);
        id   = pa_client_ext_id(client);
        pid  = pa_client_ext_pid(client);
        uid  = pa_client_ext_uid(client);
        exe  = pa_client_ext_exe(client);
        args = pa_client_ext_args(client);
        arg0 = pa_client_ext_arg0(client);

        if (!name)  name = "<noname>";
        if ( !id )  id   = "<noid>";
        if (!exe )  exe  = "<noexe>";
        if (!args)  args = "<noargs>";
        if (!arg0)  arg0 = "<noarg>";

        snprintf(buf, len,
                 "(%s|%s|%d|%d|%s|%s|%s)", name,id, pid, uid, exe,arg0,args);
    }
    
    return buf;
}
Exemplo n.º 2
0
static const char *find_group_for_client(struct userdata  *u,
                                         struct pa_client *client,
                                         pa_proplist      *proplist,
                                         uint32_t         *flags_ret)
{
    struct pa_classify *classify;
    struct pa_classify_pid_hash **hash;
    struct pa_classify_stream_def **defs;
    pid_t       pid   = 0;          /* client processs PID */
    const char *clnam = "";         /* client's name in PA */
    uid_t       uid   = (uid_t) -1; /* client process user ID */
    const char *exe   = "";         /* client's binary path */
    const char *group = NULL;
    uint32_t  flags = 0;

    assert(u);
    pa_assert_se((classify = u->classify));

    hash = classify->streams.pid_hash;
    defs = &classify->streams.defs;

    if (client == NULL)
        group = streams_get_group(defs, proplist, clnam, uid, exe, &flags);
    else {
        pid = pa_client_ext_pid(client);

        if ((group = pid_hash_get_group(hash, pid, proplist)) == NULL) {
            clnam = pa_client_ext_name(client);
            uid   = pa_client_ext_uid(client);
            exe   = pa_client_ext_exe(client);

            group = streams_get_group(defs, proplist, clnam, uid, exe, &flags);
        }
    }

    if (group == NULL)
        group = PA_POLICY_DEFAULT_GROUP_NAME;

    pa_log_debug("%s (%s|%d|%d|%s) => %s,0x%x", __FUNCTION__,
                 clnam?clnam:"<null>", pid, uid, exe?exe:"<null>",
                 group?group:"<null>", flags);

    if (flags_ret != NULL)
        *flags_ret = flags;

    return group;
}
static void client_ext_set_arg0(struct pa_client *client)
{
    char  path[256], arg0[1024];
    int   fd, len;
    pid_t pid;

    if (!(pid = pa_client_ext_pid(client))) {
        /*
          application.process.id property is set not for all kinds
          of pulseaudio clients, and not right after a client creation
        */
        pa_log_debug("no pid property for client %u, skip it", client->index);
        return;
    }

    snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
    if ((fd = open(path, O_RDONLY)) < 0) {
        pa_log("can't obtain command line");
        return;
    }

    for (;;) {
        if ((len = read(fd, arg0, sizeof(arg0)-1)) < 0) {
            if (errno == EINTR)
                continue;
            else {
                arg0[0] = '\0';
                break;
            }
        }
        
        arg0[len] = '\0';
        break;
    }

    close(fd);

    pa_proplist_sets(client->proplist, PA_PROP_APPLICATION_PROCESS_ARG0, arg0);
}