static double get_create_time(pid_t pid) { FILE *fp = NULL; char procfile[50]; char s_pid[10]; char *tmp; double ct_jiffies; double ct_seconds; double clock_ticks = sysconf(_SC_CLK_TCK); long boot_time = get_boot_time(); sprintf(s_pid, "%d", pid); sprintf(procfile, "/proc/%d/stat", pid); fp = fopen(procfile, "r"); check(fp, "Couldn't open process stat file"); tmp = grep_awk(fp, s_pid, 21, " "); ct_jiffies = atof(tmp); free(tmp); fclose(fp); ct_seconds = boot_time + (ct_jiffies / clock_ticks); return ct_seconds; error: if (fp) fclose(fp); return -1; }
static int lock_file_1 (char *lfname, int force) { int err; int symlink_errno; USE_SAFE_ALLOCA; /* Call this first because it can GC. */ printmax_t boot = get_boot_time (); Lisp_Object luser_name = Fuser_login_name (Qnil); char const *user_name = STRINGP (luser_name) ? SSDATA (luser_name) : ""; Lisp_Object lhost_name = Fsystem_name (); char const *host_name = STRINGP (lhost_name) ? SSDATA (lhost_name) : ""; ptrdiff_t lock_info_size = (strlen (user_name) + strlen (host_name) + 2 * INT_STRLEN_BOUND (printmax_t) + sizeof "@.:"); char *lock_info_str = SAFE_ALLOCA (lock_info_size); printmax_t pid = getpid (); esprintf (lock_info_str, boot ? "%s@%s.%"pMd":%"pMd : "%s@%s.%"pMd, user_name, host_name, pid, boot); err = symlink (lock_info_str, lfname); if (errno == EEXIST && force) { unlink (lfname); err = symlink (lock_info_str, lfname); } symlink_errno = errno; SAFE_FREE (); errno = symlink_errno; return err == 0; }
/* Returns the number of milliseconds from boot time: this should be monotonic */ guint32 mono_msec_ticks (void) { static gint64 boot_time = 0; gint64 now; if (!boot_time) boot_time = get_boot_time (); now = mono_100ns_ticks (); /*printf ("now: %llu (boot: %llu) ticks: %llu\n", (gint64)now, (gint64)boot_time, (gint64)(now - boot_time));*/ return (now - boot_time)/10000; }
int init_process_iterator(struct process_iterator *it, struct process_filter *filter) { if (!check_proc()) { fprintf(stderr, "procfs is not mounted!\nAborting\n"); exit(-2); } //open a directory stream to /proc directory if ((it->dip = opendir("/proc")) == NULL) { perror("opendir"); return -1; } it->filter = filter; it->boot_time = get_boot_time(); return 0; }
static int lock_file_1 (char *lfname, int force) { register int err; time_t boot; const char *user_name; const char *host_name; char *lock_info_str; /* Call this first because it can GC. */ boot = get_boot_time (); if (STRINGP (Fuser_login_name (Qnil))) user_name = SSDATA (Fuser_login_name (Qnil)); else user_name = ""; if (STRINGP (Fsystem_name ())) host_name = SSDATA (Fsystem_name ()); else host_name = ""; lock_info_str = (char *)alloca (strlen (user_name) + strlen (host_name) + LOCK_PID_MAX + 30); if (boot) sprintf (lock_info_str, "%s@%s.%lu:%lu", user_name, host_name, (unsigned long) getpid (), (unsigned long) boot); else sprintf (lock_info_str, "%s@%s.%lu", user_name, host_name, (unsigned long) getpid ()); err = symlink (lock_info_str, lfname); if (errno == EEXIST && force) { unlink (lfname); err = symlink (lock_info_str, lfname); } return err == 0; }
int main (int argc, char **argv) { struct timeval tv; #ifdef HAVE_LIBKVM if (kvm_init()) can_use_kvm = 1; #endif #ifdef DEBUG if (!(debug_file = fopen("debug", "w"))) { printf("file debug open error\n"); exit(0); } #endif get_boot_time(); get_rows_cols(&screen_rows, &screen_cols); buf_size = screen_cols + screen_cols/2; line_buf = malloc(buf_size); if (!line_buf) errx(1, "Cannot allocate memory for buffer."); curses_init(); current = &users_list; users_init(); procwin_init(); subwin_init(); menu_init(); signal(SIGINT, int_handler); signal(SIGWINCH, winch_handler); // signal(SIGSEGV, segv_handler); print_help(); update_load(); current->redraw(); wnoutrefresh(main_win); wnoutrefresh(info_win.wd); wnoutrefresh(help_win.wd); doupdate(); tv.tv_sec = TIMEOUT; tv.tv_usec = 0; for(;;) { /* main loop */ #ifndef RETURN_TV_IN_SELECT struct timeval before; struct timeval after; #endif fd_set rfds; int retval; FD_ZERO(&rfds); FD_SET(STDIN_FILENO,&rfds); #ifdef RETURN_TV_IN_SELECT retval = select(1, &rfds, 0, 0, &tv); if(retval > 0) { int key = read_key(); key_action(key); } if (!tv.tv_sec && !tv.tv_usec){ ticks++; periodic(); tv.tv_sec = TIMEOUT; } #else gettimeofday(&before, 0); retval = select(1, &rfds, 0, 0, &tv); gettimeofday(&after, 0); tv.tv_sec -= (after.tv_sec - before.tv_sec); if(retval > 0) { int key = read_key(); key_action(key); } if(tv.tv_sec <= 0) { ticks++; periodic(); tv.tv_sec = TIMEOUT; } #endif if (size_changed) resize(); } }
static int read_process(SEXP_t *cmd_ent, probe_ctx *ctx) { int err = 1; DIR *d; struct dirent *ent; d = opendir("/proc"); if (d == NULL) return err; // Get the time tick hertz ticks = (unsigned long)sysconf(_SC_CLK_TCK); get_boot_time(); // Scan the directories while (( ent = readdir(d) )) { int fd, len; char buf[256]; char *tmp, cmd[16], state, tty_dev[128]; int pid, ppid, pgrp, session, tty_nr, tpgid; unsigned flags, sched_policy; unsigned long minflt, cminflt, majflt, cmajflt, uutime, ustime; long cutime, cstime, priority, cnice, nthreads, itrealvalue; unsigned long long start; SEXP_t *cmd_sexp; // Skip non-process dir entries if(*ent->d_name<'0' || *ent->d_name>'9') continue; errno = 0; pid = strtol(ent->d_name, NULL, 10); if (errno || pid == 2) // skip err & kthreads continue; // Parse up the stat file for the proc snprintf(buf, 32, "/proc/%d/stat", pid); fd = open(buf, O_RDONLY, 0); if (fd < 0) continue; len = read(fd, buf, sizeof buf - 1); close(fd); if (len < 40) continue; buf[len] = 0; tmp = strrchr(buf, ')'); if (tmp) *tmp = 0; else continue; memset(cmd, 0, sizeof(cmd)); sscanf(buf, "%d (%15c", &ppid, cmd); sscanf(tmp+2, "%c %d %d %d %d %d " "%u %lu %lu %lu %lu " "%lu %lu %lu %ld %ld " "%ld %ld %ld %llu", &state, &ppid, &pgrp, &session, &tty_nr, &tpgid, &flags, &minflt, &cminflt, &majflt, &cmajflt, &uutime, &ustime, &cutime, &cstime, &priority, &cnice, &nthreads, &itrealvalue, &start ); // Skip kthreads if (ppid == 2) continue; err = 0; // If we get this far, no permission problems dI("Have command: %s\n", cmd); cmd_sexp = SEXP_string_newf("%s", cmd); if (probe_entobj_cmp(cmd_ent, cmd_sexp) == OVAL_RESULT_TRUE) { struct result_info r; unsigned long t = uutime/ticks + ustime/ticks; char tbuf[32], sbuf[32]; int tday,tyear; time_t s_time; struct tm *proc, *now; const char *fmt; // Now get scheduler policy sched_policy = sched_getscheduler(pid); switch (sched_policy) { case SCHED_OTHER: r.scheduling_class = "TS"; break; case SCHED_BATCH: r.scheduling_class = "B"; break; #ifdef SCHED_IDLE case SCHED_IDLE: r.scheduling_class = "#5"; break; #endif case SCHED_FIFO: r.scheduling_class = "FF"; break; case SCHED_RR: r.scheduling_class = "RR"; break; default: r.scheduling_class = "?"; break; } // Calculate the start time s_time = time(NULL); now = localtime(&s_time); tyear = now->tm_year; tday = now->tm_yday; s_time = boot + (start / ticks); proc = localtime(&s_time); // Select format based on how long we've been running // // FROM THE SPEC: // "This is the time of day the process started formatted in HH:MM:SS if // the same day the process started or formatted as MMM_DD (Ex.: Feb_5) // if process started the previous day or further in the past." // if (tday != proc->tm_yday || tyear != proc->tm_year) fmt = "%b_%d"; else fmt = "%H:%M:%S"; strftime(sbuf, sizeof(sbuf), fmt, proc); r.command = cmd; r.exec_time = convert_time(t, tbuf, sizeof(tbuf)); r.pid = pid; r.ppid = ppid; r.priority = priority; r.start_time = sbuf; dev_to_tty(tty_dev, sizeof(tty_dev), (dev_t) tty_nr, pid, ABBREV_DEV); r.tty = tty_dev; get_uids(pid, &r); report_finding(&r, ctx); } SEXP_free(cmd_sexp); } closedir(d); return err; }
int sys_get_boot_time( time_t* _time ) { *_time = get_boot_time(); return 0; }
static int read_process(SEXP_t *cmd_ent, SEXP_t *pid_ent, probe_ctx *ctx) { int err = 1, max_cap_id; DIR *d; struct dirent *ent; oval_version_t oval_version; d = opendir("/proc"); if (d == NULL) return err; // Get the time tick hertz ticks = (unsigned long)sysconf(_SC_CLK_TCK); get_boot_time(); oval_version = probe_obj_get_schema_version(probe_ctx_getobject(ctx)); if (oval_version_cmp(oval_version, OVAL_VERSION(5.11)) < 0) { max_cap_id = OVAL_5_8_MAX_CAP_ID; } else { max_cap_id = OVAL_5_11_MAX_CAP_ID; } struct oscap_buffer *cmdline_buffer = oscap_buffer_new(); char cmd_buffer[1 + 15 + 11 + 1]; // Format:" [ cmd:15 ] <defunc>" cmd_buffer[0] = '['; // Scan the directories while (( ent = readdir(d) )) { int fd, len; char buf[256]; char *tmp, state, tty_dev[128]; int pid, ppid, pgrp, session, tty_nr, tpgid; unsigned flags, sched_policy; unsigned long minflt, cminflt, majflt, cmajflt, uutime, ustime; long cutime, cstime, priority, cnice, nthreads, itrealvalue; unsigned long long start; SEXP_t *cmd_sexp = NULL, *pid_sexp = NULL; // Skip non-process58 dir entries if(*ent->d_name<'0' || *ent->d_name>'9') continue; errno = 0; pid = strtol(ent->d_name, NULL, 10); if (errno || pid == 2) // skip err & kthreads continue; // Parse up the stat file for the proc snprintf(buf, 32, "/proc/%d/stat", pid); fd = open(buf, O_RDONLY, 0); if (fd < 0) continue; len = read(fd, buf, sizeof buf - 1); close(fd); if (len < 40) continue; buf[len] = 0; tmp = strrchr(buf, ')'); if (tmp) *tmp = 0; else continue; memset(cmd_buffer + 1, 0, sizeof(cmd_buffer)-1); // clear cmd after starting '[' sscanf(buf, "%d (%15c", &ppid, cmd_buffer + 1); sscanf(tmp+2, "%c %d %d %d %d %d " "%u %lu %lu %lu %lu " "%lu %lu %lu %ld %ld " "%ld %ld %ld %llu", &state, &ppid, &pgrp, &session, &tty_nr, &tpgid, &flags, &minflt, &cminflt, &majflt, &cmajflt, &uutime, &ustime, &cutime, &cstime, &priority, &cnice, &nthreads, &itrealvalue, &start ); // Skip kthreads if (ppid == 2) continue; const char* cmd; if (state == 'Z') { // zombie cmd = make_defunc_str(cmd_buffer); } else { snprintf(buf, 32, "/proc/%d/cmdline", pid); if (get_process_cmdline(buf, cmdline_buffer)) { cmd = oscap_buffer_get_raw(cmdline_buffer); // use full cmdline } else { cmd = cmd_buffer + 1; } } err = 0; // If we get this far, no permission problems dI("Have command: %s\n", cmd); cmd_sexp = SEXP_string_newf("%s", cmd); pid_sexp = SEXP_number_newu_32(pid); if ((cmd_sexp == NULL || probe_entobj_cmp(cmd_ent, cmd_sexp) == OVAL_RESULT_TRUE) && (pid_sexp == NULL || probe_entobj_cmp(pid_ent, pid_sexp) == OVAL_RESULT_TRUE) ) { struct result_info r; unsigned long t = uutime/ticks + ustime/ticks; char tbuf[32], sbuf[32], *selinux_domain_label, **posix_capabilities; int tday,tyear; time_t s_time; struct tm *proc, *now; const char *fmt; // Now get scheduler policy sched_policy = sched_getscheduler(pid); switch (sched_policy) { case SCHED_OTHER: r.scheduling_class = "TS"; break; case SCHED_BATCH: r.scheduling_class = "B"; break; #ifdef SCHED_IDLE case SCHED_IDLE: r.scheduling_class = "#5"; break; #endif case SCHED_FIFO: r.scheduling_class = "FF"; break; case SCHED_RR: r.scheduling_class = "RR"; break; default: r.scheduling_class = "?"; break; } // Calculate the start time s_time = time(NULL); now = localtime(&s_time); tyear = now->tm_year; tday = now->tm_yday; s_time = boot + (start / ticks); proc = localtime(&s_time); // Select format based on how long we've been running // // FROM THE SPEC: // "This is the time of day the process started formatted in HH:MM:SS if // the same day the process started or formatted as MMM_DD (Ex.: Feb_5) // if process started the previous day or further in the past." // if (tday != proc->tm_yday || tyear != proc->tm_year) fmt = "%b_%d"; else fmt = "%H:%M:%S"; strftime(sbuf, sizeof(sbuf), fmt, proc); r.command_line = cmd; r.exec_time = convert_time(t, tbuf, sizeof(tbuf)); r.pid = pid; r.ppid = ppid; r.priority = priority; r.start_time = sbuf; dev_to_tty(tty_dev, sizeof(tty_dev), (dev_t) tty_nr, pid, ABBREV_DEV); r.tty = tty_dev; r.exec_shield = (get_exec_shield_status(pid) > 0); selinux_domain_label = get_selinux_label(pid); r.selinux_domain_label = selinux_domain_label; posix_capabilities = get_posix_capability(pid, max_cap_id); r.posix_capability = posix_capabilities; r.session_id = session; get_uids(pid, &r); report_finding(&r, ctx); if (selinux_domain_label != NULL) free(selinux_domain_label); if (posix_capabilities != NULL) { char **posix_capabilities_p = posix_capabilities; while (*posix_capabilities_p) free(*posix_capabilities_p++); free(posix_capabilities); } } SEXP_free(cmd_sexp); SEXP_free(pid_sexp); } closedir(d); oscap_buffer_free(cmdline_buffer); return err; }
static int current_lock_owner (lock_info_type *owner, char *lfname) { int ret; ptrdiff_t len; lock_info_type local_owner; intmax_t n; char *at, *dot, *colon; char readlink_buf[READLINK_BUFSIZE]; char *lfinfo = emacs_readlink (lfname, readlink_buf); /* If nonexistent lock file, all is well; otherwise, got strange error. */ if (!lfinfo) return errno == ENOENT ? 0 : -1; /* Even if the caller doesn't want the owner info, we still have to read it to determine return value. */ if (!owner) owner = &local_owner; /* Parse [email protected]:BOOT_TIME. If can't parse, return -1. */ /* The USER is everything before the last @. */ at = strrchr (lfinfo, '@'); dot = strrchr (lfinfo, '.'); if (!at || !dot) { if (lfinfo != readlink_buf) xfree (lfinfo); return -1; } len = at - lfinfo; owner->user = xmalloc (len + 1); memcpy (owner->user, lfinfo, len); owner->user[len] = 0; /* The PID is everything from the last `.' to the `:'. */ errno = 0; n = strtoimax (dot + 1, NULL, 10); owner->pid = ((0 <= n && n <= TYPE_MAXIMUM (pid_t) && (TYPE_MAXIMUM (pid_t) < INTMAX_MAX || errno != ERANGE)) ? n : 0); colon = strchr (dot + 1, ':'); /* After the `:', if there is one, comes the boot time. */ n = 0; if (colon) { errno = 0; n = strtoimax (colon + 1, NULL, 10); } owner->boot_time = ((0 <= n && n <= TYPE_MAXIMUM (time_t) && (TYPE_MAXIMUM (time_t) < INTMAX_MAX || errno != ERANGE)) ? n : 0); /* The host is everything in between. */ len = dot - at - 1; owner->host = xmalloc (len + 1); memcpy (owner->host, at + 1, len); owner->host[len] = 0; /* We're done looking at the link info. */ if (lfinfo != readlink_buf) xfree (lfinfo); /* On current host? */ if (STRINGP (Fsystem_name ()) && strcmp (owner->host, SSDATA (Fsystem_name ())) == 0) { if (owner->pid == getpid ()) ret = 2; /* We own it. */ else if (owner->pid > 0 && (kill (owner->pid, 0) >= 0 || errno == EPERM) && (owner->boot_time == 0 || within_one_second (owner->boot_time, get_boot_time ()))) ret = 1; /* An existing process on this machine owns it. */ /* The owner process is dead or has a strange pid (<=0), so try to zap the lockfile. */ else if (unlink (lfname) < 0) ret = -1; else ret = 0; } else { /* If we wanted to support the check for stale locks on remote machines, here's where we'd do it. */ ret = 1; } /* Avoid garbage. */ if (owner == &local_owner || ret <= 0) { FREE_LOCK_INFO (*owner); } return ret; }
static int current_lock_owner (lock_info_type *owner, char *lfname) { int len, ret; int local_owner = 0; char *at, *dot, *colon; char *lfinfo = 0; int bufsize = 50; /* Read arbitrarily-long contents of symlink. Similar code in file-symlink-p in fileio.c. */ do { bufsize *= 2; lfinfo = (char *) xrealloc (lfinfo, bufsize); errno = 0; len = readlink (lfname, lfinfo, bufsize); #ifdef ERANGE /* HP-UX reports ERANGE if the buffer is too small. */ if (len == -1 && errno == ERANGE) len = bufsize; #endif } while (len >= bufsize); /* If nonexistent lock file, all is well; otherwise, got strange error. */ if (len == -1) { xfree (lfinfo); return errno == ENOENT ? 0 : -1; } /* Link info exists, so `len' is its length. Null terminate. */ lfinfo[len] = 0; /* Even if the caller doesn't want the owner info, we still have to read it to determine return value, so allocate it. */ if (!owner) { owner = (lock_info_type *) alloca (sizeof (lock_info_type)); local_owner = 1; } /* Parse [email protected]:BOOT_TIME. If can't parse, return -1. */ /* The USER is everything before the last @. */ at = strrchr (lfinfo, '@'); dot = strrchr (lfinfo, '.'); if (!at || !dot) { xfree (lfinfo); return -1; } len = at - lfinfo; owner->user = (char *) xmalloc (len + 1); strncpy (owner->user, lfinfo, len); owner->user[len] = 0; /* The PID is everything from the last `.' to the `:'. */ owner->pid = atoi (dot + 1); colon = dot; while (*colon && *colon != ':') colon++; /* After the `:', if there is one, comes the boot time. */ if (*colon == ':') owner->boot_time = atoi (colon + 1); else owner->boot_time = 0; /* The host is everything in between. */ len = dot - at - 1; owner->host = (char *) xmalloc (len + 1); strncpy (owner->host, at + 1, len); owner->host[len] = 0; /* We're done looking at the link info. */ xfree (lfinfo); /* On current host? */ if (STRINGP (Fsystem_name ()) && strcmp (owner->host, SSDATA (Fsystem_name ())) == 0) { if (owner->pid == getpid ()) ret = 2; /* We own it. */ else if (owner->pid > 0 && (kill (owner->pid, 0) >= 0 || errno == EPERM) && (owner->boot_time == 0 || within_one_second (owner->boot_time, get_boot_time ()))) ret = 1; /* An existing process on this machine owns it. */ /* The owner process is dead or has a strange pid (<=0), so try to zap the lockfile. */ else if (unlink (lfname) < 0) ret = -1; else ret = 0; } else { /* If we wanted to support the check for stale locks on remote machines, here's where we'd do it. */ ret = 1; } /* Avoid garbage. */ if (local_owner || ret <= 0) { FREE_LOCK_INFO (*owner); } return ret; }