GPtrArray* search_user_env(uid_t uid, const char *name, int update) { GPtrArray* rv = g_ptr_array_new_with_free_func(g_free); u_proc *proc = NULL; GHashTableIter iter; char *val; int i, found; gpointer ikey, value; g_hash_table_iter_init (&iter, processes); while (g_hash_table_iter_next (&iter, &ikey, &value)) { proc = (u_proc *)value; if(proc->proc->euid != uid) continue; if (!u_proc_ensure (proc, ENVIRONMENT, update ? UPDATE_NOW : UPDATE_DEFAULT)) continue; val = g_hash_table_lookup(proc->environ, name); if(val) { found = FALSE; for(i = 0; i < rv->len; i++) { if(g_strcmp0((char *)g_ptr_array_index(rv, i), val) == 0) { found = TRUE; break; } } if(!found) g_ptr_array_add(rv, g_strdup(val)); } } return rv; }
static int nl_handle_msg(struct cn_msg *cn_hdr) { /* The event to consider */ struct proc_event *ev; /* Return codes */ int ret = 0; /* Get the event data. We only care about two event types. */ ev = (struct proc_event*)cn_hdr->data; switch (ev->what) { case PROC_EVENT_NONE: g_debug("netlink: successfully subscribed for listening to proc events"); netlink_proc_listening = TRUE; break; // quite seldom events on old processes changing important parameters case PROC_EVENT_UID: // skip threads if(ev->event_data.id.process_tgid != ev->event_data.id.process_pid) break; u_trace("UID Event: PID = %d, tGID = %d, rUID = %d," " eUID = %d", ev->event_data.id.process_pid, ev->event_data.id.process_tgid, ev->event_data.id.r.ruid, ev->event_data.id.e.euid); process_new(ev->event_data.id.process_pid, FALSE); break; case PROC_EVENT_GID: // skip threads if(ev->event_data.id.process_tgid != ev->event_data.id.process_pid) break; u_trace("GID Event: PID = %d, tGID = %d, rGID = %d," " eGID = %d", ev->event_data.id.process_pid, ev->event_data.id.process_tgid, ev->event_data.id.r.rgid, ev->event_data.id.e.egid); process_new(ev->event_data.id.process_pid, FALSE); break; case PROC_EVENT_EXIT: // skip threads if(ev->event_data.exit.process_tgid != ev->event_data.exit.process_pid) break; u_trace("EXIT Event: PID = %d", ev->event_data.exit.process_pid); //g_ptr_array_foreach(stack, remove_pid_from_stack, &pid); // if the pid was found in the new stack, pid is set to 0 to indicate // the removal process_remove_by_pid(ev->event_data.exit.process_pid); break; case PROC_EVENT_EXEC: // skip threads if(ev->event_data.exec.process_tgid != ev->event_data.exec.process_pid) break; u_trace("EXEC Event: PID = %d, tGID = %d", ev->event_data.exec.process_pid, ev->event_data.exec.process_tgid); process_new_delay(ev->event_data.exec.process_tgid, 0); break; case PROC_EVENT_FORK: // we skip new threads for now // FIXME need filter block to get those events if(ev->event_data.fork.parent_tgid != ev->event_data.fork.child_pid) break; u_trace("FORK Event: PARENT = %d PID = %d tGID = %d", ev->event_data.fork.parent_tgid, ev->event_data.fork.child_pid, ev->event_data.fork.child_tgid); // parent does not mean the parent of the new proc, but the parent of // the forking process. so we lookup the parent of the forking process // first u_proc *rparent = proc_by_pid(ev->event_data.fork.parent_tgid); if(rparent) { u_proc_ensure(rparent, BASIC, NOUPDATE); process_new_delay(ev->event_data.fork.child_tgid, rparent->proc->ppid); //ev->event_data.fork.parent_pid); } else process_new_delay(ev->event_data.fork.child_tgid, 0); break; default: return 0; } return ret; }