int check_utmp (int total_unused) { /* replace total_unused with the minimum of * total_unused and the shortest utmp idle time. */ typedef struct utmp utmp_t; utmp_t *u; int min_idle=2*max_unused; utmpname(UTMP_FILE); setutent(); while ((u=getutent())) { if (u->ut_type == USER_PROCESS) { /* get tty. From w.c in procps by Charles Blake. */ char tty[5 + sizeof u->ut_line + 1] = "/dev/"; int i; for (i=0; i < sizeof u->ut_line; i++) { /* clean up tty if garbled */ if (isalnum(u->ut_line[i]) || (u->ut_line[i]=='/')) { tty[i+5] = u->ut_line[i]; } else { tty[i+5] = '\0'; } } int cur_idle=idletime(tty); min_idle = (cur_idle < min_idle) ? cur_idle : min_idle; } } /* The shortest idle time is the real idle time */ total_unused = (min_idle < total_unused) ? min_idle : total_unused; if (debug && total_unused == min_idle) printf("sleepd: activity: utmp %d seconds\n", min_idle); return total_unused; }
static void user_busy(const char *name, uid_t uid) { struct utmp *utent; /* * We see if the user is logged in by looking for the user name * in the utmp file. */ setutent (); while ((utent = getutent ())) { #ifdef USER_PROCESS if (utent->ut_type != USER_PROCESS) continue; #else if (utent->ut_user[0] == '\0') continue; #endif if (strncmp(utent->ut_user, name, sizeof utent->ut_user)) continue; fprintf(stderr, _("%s: user %s is currently logged in\n"), Prog, name); exit(E_USER_BUSY); } }
static int do_check (void) { struct utmp *ut; int n; setutent (); n = 0; while ((ut = getutent ())) { if (n < num_entries && memcmp (ut, &entry[n], sizeof (struct utmp))) { printf ("UTMP entry does not match"); ++errors; return 1; } n++; } if (n != num_entries) { printf ("number of UTMP entries is incorrect"); ++errors; return 1; } endutent (); return 0; }
/* * Notify all available ttys about device insertion. * * Return the number of ttys notified. */ static int notify_all_ttys(const char *manufacturer, const char *product, const char *devnode) { struct utmp *ut = NULL; int ttys_notified = 0; setutent(); /* Don't free ut, it is statically allocated. */ while ((ut = getutent()) != NULL) { /* Skip invalid entries. */ if (ut->ut_type != USER_PROCESS) continue; if (notify_tty(ut->ut_line, manufacturer, product, devnode) == -1) { log_fn("Could not notify %s (@%s) about device %s (%s %s).", ut->ut_user, ut->ut_line, devnode, manufacturer, product); } else { log_fn("Notified %s (@%s) about device %s (%s %s).", ut->ut_user, ut->ut_line, devnode, manufacturer, product); ttys_notified++; } } endutent(); return ttys_notified; }
int uv_uptime(double* uptime) { struct utmp *utmp_buf; size_t entries = 0; time_t boot_time; boot_time = 0; utmpname(UTMP_FILE); setutent(); while ((utmp_buf = getutent()) != NULL) { if (utmp_buf->ut_user[0] && utmp_buf->ut_type == USER_PROCESS) ++entries; if (utmp_buf->ut_type == BOOT_TIME) boot_time = utmp_buf->ut_time; } endutent(); if (boot_time == 0) return UV_ENOSYS; *uptime = time(NULL) - boot_time; return 0; }
/* * get_current_utmp - return the most probable utmp entry for the current * session * * The utmp file is scanned for an entry with the same process ID. * The line enterred by the *getty / telnetd, etc. should also match * the current terminal. * * When an entry is returned by get_current_utmp, and if the utmp * structure has a ut_id field, this field should be used to update * the entry information. * * Return NULL if no entries exist in utmp for the current process. */ /*@null@*/ /*@only@*/struct utmp *get_current_utmp (void) { struct utmp *ut; struct utmp *ret = NULL; setutent (); /* First, try to find a valid utmp entry for this process. */ while ((ut = getutent ()) != NULL) { if ( (ut->ut_pid == getpid ()) #ifdef HAVE_STRUCT_UTMP_UT_ID && ('\0' != ut->ut_id[0]) #endif #ifdef HAVE_STRUCT_UTMP_UT_TYPE && ( (LOGIN_PROCESS == ut->ut_type) || (USER_PROCESS == ut->ut_type)) #endif /* A process may have failed to close an entry * Check if this entry refers to the current tty */ && is_my_tty (ut->ut_line)) { break; } } if (NULL != ut) { ret = (struct utmp *) xmalloc (sizeof (*ret)); memcpy (ret, ut, sizeof (*ret)); } endutent (); return ret; }
int who_main(int argc, char **argv) { char str6[6]; struct utmp *ut; struct stat st; char *name; if (argc > 1) { bb_show_usage(); } setutent(); printf("USER TTY IDLE TIME HOST\n"); while ((ut = getutent()) != NULL) { if (ut->ut_user[0] && ut->ut_type == USER_PROCESS) { time_t thyme = ut->ut_tv.tv_sec; /* ut->ut_line is device name of tty - "/dev/" */ name = concat_path_file("/dev", ut->ut_line); str6[0] = '?'; str6[1] = '\0'; if (stat(name, &st) == 0) idle_string(str6, st.st_atime); printf("%-10s %-8s %-9s %-14.14s %s\n", ut->ut_user, ut->ut_line, str6, ctime(&thyme) + 4, ut->ut_host); if (ENABLE_FEATURE_CLEAN_UP) free(name); } } if (ENABLE_FEATURE_CLEAN_UP) endutent(); return 0; }
/* * Return currently connected users as a list of tuples. */ static PyObject* get_system_users(PyObject* self, PyObject* args) { PyObject *ret_list = PyList_New(0); PyObject *tuple = NULL; PyObject *user_proc = NULL; struct utmp *ut; setutent(); while (NULL != (ut = getutent())) { if (ut->ut_type == USER_PROCESS) user_proc = Py_True; else user_proc = Py_False; tuple = Py_BuildValue("(sssfO)", ut->ut_user, // username ut->ut_line, // tty ut->ut_host, // hostname (float)ut->ut_tv.tv_sec, // tstamp user_proc // (bool) user process ); PyList_Append(ret_list, tuple); Py_DECREF(tuple); } endutent(); return ret_list; }
static int count_users(void) { int total = 0; #if HAVE_UTMPX_H #define setutent setutxent #define pututline pututxline #define getutent getutxent #define endutent endutxent struct utmpx *utmp_p; #else struct utmp *utmp_p; #endif setutent(); while ((utmp_p = getutent()) != NULL) { #ifndef UTMP_HAS_NO_TYPE if (utmp_p->ut_type != USER_PROCESS) continue; #endif #ifndef UTMP_HAS_NO_PID /* This block of code fixes zombie user PIDs in the utmp/utmpx file that would otherwise be counted as a current user */ if (kill(utmp_p->ut_pid, 0) == -1 && errno == ESRCH) { utmp_p->ut_type = DEAD_PROCESS; pututline(utmp_p); continue; } #endif ++total; } endutent(); return total; }
int runlevel_main(int argc UNUSED_PARAM, char **argv) { struct utmp *ut; char prev; if (argv[1]) utmpname(argv[1]); setutent(); while ((ut = getutent()) != NULL) { if (ut->ut_type == RUN_LVL) { prev = ut->ut_pid / 256; if (prev == 0) prev = 'N'; printf("%c %c\n", prev, ut->ut_pid % 256); if (ENABLE_FEATURE_CLEAN_UP) endutent(); return 0; } } puts("unknown"); if (ENABLE_FEATURE_CLEAN_UP) endutent(); return 1; }
static int getUptime(void) { struct sysinfo s_info; error = sysinfo(&s_info); int days, hours, minutes; long int upmind, upminh, uptimes; uptimes = s_info.uptime; /* returned in seconds */ days = uptimes / ONEDAY; upmind = uptimes - (days * ONEDAY); hours = upmind / ONEHOUR; upminh = upmind - hours * ONEHOUR; minutes = upminh / ONEMINUTE; float av1, av2, av3; av1 = s_info.loads[0] / LOADS_SCALE; av2 = s_info.loads[1] / LOADS_SCALE; av3 = s_info.loads[2] / LOADS_SCALE; /* This next block is stolen fron GNU uptime */ struct utmp *utmpstruct; int numuser = 0; setutent(); while ((utmpstruct = getutent())) { if ((utmpstruct->ut_type == USER_PROCESS) && (utmpstruct->ut_name[0] != '\0')) numuser++; } endutent(); printf(" up %i day%s, %02i:%02i, %i user%s, load average: %2.2f, %2.2f, %2.2f\n", days, (days != 1) ? "s" : "", hours, minutes, numuser, (numuser != 1) ? "s" : "", av1, av2, av3); return error; }
int main(int argc, char **argv) { struct utmp *ut; const char *user, *host; printf("%8s %8s %16s %8s %4s\n", "NAME", "LINE", "HOST", "TIME", "PID"); setutent(); while (NULL != (ut = getutent())) { host = strlen(ut->ut_host) ? ut->ut_host : localhost; user = ut->ut_user; switch (ut->ut_type) { case USER_PROCESS: break; case LOGIN_PROCESS: user = login; break; case DEAD_PROCESS: default: continue; } printf("%8s %8s %16s %8s %4d\n", user, ut->ut_line, host, "", ut->ut_pid); } return 0; }
/* * See if we were started directly from init. * Get the runlevel from /var/run/utmp or the environment. */ int get_runlevel(void) { struct utmp *ut; char *r; /* * First see if we were started directly from init. */ if (getenv("INIT_VERSION") && (r = getenv("RUNLEVEL")) != NULL) return *r; /* * Find runlevel in utmp. */ setutent(); while ((ut = getutent()) != NULL) { if (ut->ut_type == RUN_LVL) return (ut->ut_pid & 255); } endutent(); /* This should not happen but warn the user! */ fprintf(stderr, "WARNING: could not determine runlevel" " - doing soft %s\n", progname); fprintf(stderr, " (it's better to use shutdown instead of %s" " from the command line)\n", progname); return -1; }
static int check_login_time(const char *ruser, time_t timestamp) { struct utmp utbuf, *ut; time_t oldest_login = 0; setutent(); while( #ifdef HAVE_GETUTENT_R !getutent_r(&utbuf, &ut) #else (ut = getutent()) != NULL #endif ) { if (ut->ut_type != USER_PROCESS) { continue; } if (strncmp(ruser, ut->ut_user, sizeof(ut->ut_user) != 0)) { continue; } if (oldest_login == 0 || oldest_login > ut->ut_tv.tv_sec) { oldest_login = ut->ut_tv.tv_sec; } } endutent(); if(oldest_login == 0 || timestamp < oldest_login) { return PAM_AUTH_ERR; } return PAM_SUCCESS; }
/* count the number of users */ static int get_unique ( void ) { apr_pool_t *subpool; apr_hash_t *hashuser; char *name; void *user; unsigned int numunique = 0; struct utmp *utmpstruct; apr_pool_create(&subpool, pool); hashuser = apr_hash_make(subpool); apr_thread_mutex_lock(mutex); setutent(); while ((utmpstruct = getutent())) { if ((utmpstruct->ut_type == USER_PROCESS) && (utmpstruct->ut_name[0] != '\0')) { name = apr_pstrndup(subpool, utmpstruct->ut_name, UT_NAMESIZE); user = name; /* use key for value, not interested in it anyway */ apr_hash_set(hashuser, name, APR_HASH_KEY_STRING, user); } } endutent(); apr_thread_mutex_unlock(mutex); numunique = apr_hash_count(hashuser); apr_pool_destroy(subpool); return numunique; }
static int user_busy_utmp (const char *name) { #ifdef USE_UTMPX struct utmpx *utent; setutxent (); while ((utent = getutxent ()) != NULL) #else /* !USE_UTMPX */ struct utmp *utent; setutent (); while ((utent = getutent ()) != NULL) #endif /* !USE_UTMPX */ { if (utent->ut_type != USER_PROCESS) { continue; } if (strncmp (utent->ut_user, name, sizeof utent->ut_user) != 0) { continue; } if (kill (utent->ut_pid, 0) != 0) { continue; } fprintf (stderr, _("%s: user %s is currently logged in\n"), Prog, name); return 1; } return 0; }
int who_main(int argc UNUSED_PARAM, char **argv) { struct utmp *ut; unsigned opt; int do_users = (ENABLE_USERS && (!ENABLE_WHO || applet_name[0] == 'u')); const char *fmt = "%s"; opt_complementary = "=0"; opt = getopt32(argv, do_users ? "" : "aH"); if (opt & 2) // -H printf("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST\n"); setutent(); while ((ut = getutent()) != NULL) { if (ut->ut_user[0] && ((opt & 1) || ut->ut_type == USER_PROCESS) ) { if (!do_users) { char str6[6]; char name[sizeof("/dev/") + sizeof(ut->ut_line) + 1]; struct stat st; time_t seconds; str6[0] = '?'; str6[1] = '\0'; strcpy(name, "/dev/"); safe_strncpy(ut->ut_line[0] == '/' ? name : name + sizeof("/dev/")-1, ut->ut_line, sizeof(ut->ut_line)+1 ); if (stat(name, &st) == 0) idle_string(str6, st.st_atime); /* manpages say ut_tv.tv_sec *is* time_t, * but some systems have it wrong */ seconds = ut->ut_tv.tv_sec; /* How wide time field can be? * "Nov 10 19:33:20": 15 chars * "2010-11-10 19:33": 16 chars */ printf("%-15.*s %-15.*s %-7s %-16.16s %.*s\n", (int)sizeof(ut->ut_user), ut->ut_user, (int)sizeof(ut->ut_line), ut->ut_line, str6, ctime(&seconds) + 4, (int)sizeof(ut->ut_host), ut->ut_host ); } else { printf(fmt, ut->ut_user); fmt = " %s"; } } } if (do_users) bb_putchar('\n'); if (ENABLE_FEATURE_CLEAN_UP) endutent(); return EXIT_SUCCESS; }
int main(int argc, char **argv) { extern int optind; int ch; struct iovec iov; struct utmp *utmpptr; char *p; char line[sizeof(utmpptr->ut_line) + 1]; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); while ((ch = getopt(argc, argv, "n")) != -1) { switch (ch) { case 'n': if (geteuid() == 0) nobanner = 1; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc > 1) usage(); makemsg(*argv); setutent(); iov.iov_base = mbuf; iov.iov_len = mbufsize; while((utmpptr = getutent())) { if (!utmpptr->ut_name[0] || !strncmp(utmpptr->ut_name, IGNOREUSER, sizeof(utmpptr->ut_name))) continue; #ifdef USER_PROCESS if (utmpptr->ut_type != USER_PROCESS) continue; #endif /* Joey Hess reports that use-sessreg in /etc/X11/wdm/ produces ut_line entries like :0, and a write to /dev/:0 fails. */ if (utmpptr->ut_line[0] == ':') continue; xstrncpy(line, utmpptr->ut_line, sizeof(utmpptr->ut_line)); if ((p = ttymsg(&iov, 1, line, 60*5)) != NULL) warnx("%s", p); } endutent(); exit(EXIT_SUCCESS); }
//********************************************************************** int get_number_of_users(void) { int user_count = 0; struct utmp *usr; setutent(); while ((usr=getutent())) { if (usr->ut_type == USER_PROCESS) user_count++; } return user_count; }
struct utmp * getutline(struct utmp *line) { do { if (strcmp(ut.ut_line, line->ut_line) == 0) { return(&ut); } } while (getutent() != (struct utmp *)NULL); return((struct utmp *)NULL); }
char *sprint_uptime(void) { struct utmp *utmpstruct; int upminutes, uphours, updays; int pos; struct tm *realtime; time_t realseconds; int numuser; double uptime_secs, idle_secs; /* first get the current time */ time(&realseconds); realtime = localtime(&realseconds); pos = sprintf(buf, " %02d:%02d:%02d ", realtime->tm_hour, realtime->tm_min, realtime->tm_sec); /* read and calculate the amount of uptime */ uptime(&uptime_secs, &idle_secs); updays = (int) uptime_secs / (60*60*24); strcat (buf, "up "); pos += 3; if (updays) pos += sprintf(buf + pos, "%d day%s, ", updays, (updays != 1) ? "s" : ""); upminutes = (int) uptime_secs / 60; uphours = upminutes / 60; uphours = uphours % 24; upminutes = upminutes % 60; if (uphours) pos += sprintf(buf + pos, "%2d:%02d, ", uphours, upminutes); else pos += sprintf(buf + pos, "%d min, ", upminutes); /* count the number of users */ numuser = 0; setutent(); while ((utmpstruct = getutent())) { if ((utmpstruct->ut_type == USER_PROCESS) && (utmpstruct->ut_name[0] != '\0')) numuser++; } endutent(); pos += sprintf(buf + pos, "%2d user%s, ", numuser, numuser == 1 ? "" : "s"); loadavg(&av[0], &av[1], &av[2]); pos += sprintf(buf + pos, " load average: %.2f, %.2f, %.2f", av[0], av[1], av[2]); return buf; }
static int count_users(void) { int ct = 0; struct utmp *entry; setutent(); while(entry = getutent()) if (entry->ut_type == USER_PROCESS) ct++; endutent(); return ct; }
static int users_read (void) { #if HAVE_GETUTXENT unsigned int users = 0; struct utmpx *entry = NULL; /* according to the *utent(3) man page none of the functions sets errno in case of an error, so we cannot do any error-checking here */ setutxent(); while (NULL != (entry = getutxent())) { if (USER_PROCESS == entry->ut_type) { ++users; } } endutxent(); users_submit (users); /* #endif HAVE_GETUTXENT */ #elif HAVE_GETUTENT unsigned int users = 0; struct utmp *entry = NULL; /* according to the *utent(3) man page none of the functions sets errno in case of an error, so we cannot do any error-checking here */ setutent(); while (NULL != (entry = getutent())) { if (USER_PROCESS == entry->ut_type) { ++users; } } endutent(); users_submit (users); /* #endif HAVE_GETUTENT */ #elif HAVE_LIBSTATGRAB sg_user_stats *us; us = sg_get_user_stats (); if (us == NULL) return (-1); users_submit ((gauge_t) us->num_entries); /* #endif HAVE_LIBSTATGRAB */ #else # error "No applicable input method." #endif return (0); } /* int users_read */
void fs_var_utmp(void) { struct stat s; // extract utmp group id gid_t utmp_group = 0; if (stat("/var/run/utmp", &s) == 0) utmp_group = s.st_gid; else { fprintf(stderr, "Warning: cannot find /var/run/utmp\n"); return; } // create /tmp/firejail/mnt directory fs_build_mnt_dir(); // create a new utmp file if (arg_debug) printf("Create the new utmp file\n"); char *utmp; if (asprintf(&utmp, "%s/utmp", MNT_DIR) == -1) errExit("asprintf"); FILE *fp = fopen(utmp, "w"); if (!fp) errExit("fopen"); // read current utmp struct utmp *u; struct utmp u_boot; setutent(); while ((u = getutent()) != NULL) { if (u->ut_type == BOOT_TIME) { memcpy(&u_boot, u, sizeof(u_boot)); u_boot.ut_tv.tv_sec = (unsigned) time(NULL); } } endutent(); // save new utmp file fwrite(&u_boot, sizeof(u_boot), 1, fp); fclose(fp); if (chown(utmp, 0, utmp_group) < 0) errExit("chown"); if (chmod(utmp, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH ) < 0) errExit("chmod"); // mount the new utmp file if (arg_debug) printf("Mount the new utmp file\n"); if (mount(utmp, "/var/run/utmp", NULL, MS_BIND|MS_REC, NULL) < 0) errExit("mount bind utmp"); }
UsersInfo * get_users () { int nusers = 100; UsersInfo *ret = (UsersInfo *)calloc(1, sizeof(UsersInfo)); Users *users = (Users *)calloc(nusers, sizeof(Users)); Users *u = users; struct utmp *ut; check_mem(ret); check_mem(users); ret->nitems = 0; ret->users = users; while (NULL != (ut = getutent())) { if (ut->ut_type != USER_PROCESS) continue; u->username = strdup(ut->ut_user); check_mem(u->username); u->tty = strdup(ut->ut_line); check_mem(u->username); u->hostname = strdup(ut->ut_host); check_mem(u->hostname); u->tstamp = ut->ut_tv.tv_sec; ret->nitems++; u++; if (ret->nitems == nusers) { /* More users than we've allocated space for. */ nusers *= 2; users = realloc(users, sizeof(Users) * nusers); check_mem(users); ret->users = users; u = ret->users + ret->nitems; /* Move the cursor to the correct value in case the realloc moved the memory */ } } endutent(); return ret; error: free_users_info(ret); return NULL; }
void wall(void) { /* write to all users, that the system is going down. */ struct utmp *ut; utmpname(_PATH_UTMP); setutent(); while((ut = getutent())) { if(ut->ut_type == USER_PROCESS) write_user(ut); } endutent(); }
main() { struct utmp *ut; utmpname(_PATH_UTMP); setutent(); printf("User TTY Login-time\n"); while(ut = getutent()) { if(ut->ut_type == USER_PROCESS) printf("%-8s %-2s %s", ut->ut_user, ut->ut_id, ctime(&ut->ut_time)); } endutent(); }
int runlevel_get(void) { int lvl = '?'; /* Non-existing runlevel */ struct utmp *utent; setutent(); while ((utent = getutent())) { if (utent->ut_type == RUN_LVL) { lvl = utent->ut_pid & 0xFF; break; } } endutent(); return lvl - '0'; }
struct utmp * get_next_line(char *id, char *line) { struct utmp request; if (!id && !line) return getutent(); memset(&request, 0, sizeof(request)); if (line) { strncpy(&request.ut_line[0], line, UT_LINESIZE); return getutline(&request); } request.ut_type = INIT_PROCESS; strncpy(&request.ut_id[0], id, 4); return getutid(&request); }
int main (int argc, char *argv[]) { struct utmp *up; if (argc > 1) utmpname (argv[1]); setutent (); while ((up = getutent ())) print_entry (up); endutent (); return EXIT_SUCCESS; }