int main(int argc, char **argv) { struct utmpx u; const char file[256] = "/home/flueg/workspace/utmp/ftmpx"; memset(&u, 0, sizeof(struct utmpx)); if (utmpxname(file) == -1) perror("failed to set ftmpx file"); strcpy(u.ut_user, getpwuid(getuid())->pw_name); printf("ttyname is: %s\n", ttyname(0)+strlen("/dev/")); strcpy(u.ut_id, ttyname(0) + strlen("/dev/tty")); strcpy(u.ut_line, ttyname(0) + strlen("/dev/")); u.ut_pid = getpid(); u.ut_type = LOGIN_PROCESS; setutxent(); if (pututxline(&u) == NULL) perror("failed to pututxline.\n"); sleep(2); u.ut_type = DEAD_PROCESS; time((time_t *) &u.ut_tv.tv_sec); setutxent(); if (pututxline(&u) == NULL) perror("failed to pututxline.\n"); endutxent(); exit(0); }
static int getfutxent(struct futx *fu) { if (uf == NULL) setutxent(); if (uf == NULL) return (-1); if (udb == UTXDB_LOG) { uint16_t len; if (fread(&len, sizeof(len), 1, uf) != 1) return (-1); len = be16toh(len); if (len > sizeof *fu) { /* Forward compatibility. */ if (fread(fu, sizeof(*fu), 1, uf) != 1) return (-1); fseek(uf, len - sizeof(*fu), SEEK_CUR); } else { /* Partial record. */ memset(fu, 0, sizeof(*fu)); if (fread(fu, len, 1, uf) != 1) return (-1); } } else { if (fread(fu, sizeof(*fu), 1, uf) != 1) return (-1); } return (0); }
/* Show utmp information via getutxent(3) @function utmp @return information (TABLE) */ static int Futmp(lua_State *L) { struct utmpx *utx = {0}; setutxent(); lua_createtable(L, 0, 7); while ((utx = getutxent())) { lua_pushstring(L, utx->ut_user); lua_setfield(L, -2, "user"); lua_pushstring(L, utx->ut_line); lua_setfield(L, -2, "tty"); lua_pushstring(L, utx->ut_host); lua_setfield(L, -2, "hostname"); lua_pushnumber(L, (float)utx->ut_tv.tv_sec); lua_setfield(L, -2, "timestamp"); lua_pushboolean(L, utx->ut_type & USER_PROCESS); lua_setfield(L, -2, "user_process"); lua_pushboolean(L, utx->ut_type & INIT_PROCESS); lua_setfield(L, -2, "init_process"); lua_pushboolean(L, utx->ut_type & LOGIN_PROCESS); lua_setfield(L, -2, "login_process"); } endutxent(); return 1; }
int wall_main(int argc UNUSED_PARAM, char **argv) { struct utmpx *ut; char *msg; int fd; fd = STDIN_FILENO; if (argv[1]) { /* The applet is setuid. * Access to the file must be under user's uid/gid. */ fd = xopen_as_uid_gid(argv[1], O_RDONLY, getuid(), getgid()); } msg = xmalloc_read(fd, NULL); if (ENABLE_FEATURE_CLEAN_UP && argv[1]) close(fd); setutxent(); while ((ut = getutxent()) != NULL) { char *line; if (ut->ut_type != USER_PROCESS) continue; line = concat_path_file("/dev", ut->ut_line); xopen_xwrite_close(line, msg); free(line); } if (ENABLE_FEATURE_CLEAN_UP) { endutxent(); free(msg); } return EXIT_SUCCESS; }
static void cleanup_utmp(void) { struct timeval tv; if (!pty_stamped_utmp) return; utmp_entry.ut_type = DEAD_PROCESS; memset(utmp_entry.ut_user, 0, lenof(utmp_entry.ut_user)); gettimeofday(&tv, NULL); utmp_entry.ut_tv.tv_sec = tv.tv_sec; utmp_entry.ut_tv.tv_usec = tv.tv_usec; updwtmpx(WTMPX_FILE, &utmp_entry); memset(utmp_entry.ut_line, 0, lenof(utmp_entry.ut_line)); utmp_entry.ut_tv.tv_sec = 0; utmp_entry.ut_tv.tv_usec = 0; setutxent(); pututxline(&utmp_entry); endutxent(); pty_stamped_utmp = 0; /* ensure we never double-cleanup */ }
static void remove_utmp_entry(main_server_st *s, struct proc_st* proc) { #ifdef HAVE_LIBUTIL struct utmpx entry; struct timespec tv; if (s->config->use_utmp == 0) return; memset(&entry, 0, sizeof(entry)); entry.ut_type = DEAD_PROCESS; if (proc->tun_lease.name[0] != 0) snprintf(entry.ut_line, sizeof(entry.ut_line), "%s", proc->tun_lease.name); entry.ut_pid = proc->pid; setutxent(); pututxline(&entry); endutxent(); #if defined(WTMPX_FILE) gettime(&tv); entry.ut_tv.tv_sec = tv.tv_sec; entry.ut_tv.tv_usec = tv.tv_nsec / 1000; updwtmpx(WTMPX_FILE, &entry); #endif return; #endif }
static void _add_utmp(TE_Pty* pty, int spid) { memset(&pty->ut_entry, 0, sizeof(pty->ut_entry) ); #if 0 pty->ut_entry.ut_type = USER_PROCESS; pty->ut_entry.ut_pid = spid; // strcpy(pty->ut_entry.ut_line, pty->ptyname+5); // printf("ut name \"%s\" (%d)\n", pty->ut_entry.ut_user, getuid()); #ifdef __APPLE__ // strcpy(pty->ut_entry.ut_id, pty->ptyname+8); strcpy(pty->ut_entry.ut_user, getpwuid(getuid())->pw_name); gettimeofday(&pty->ut_entry.ut_tv, NULL); setutxent(); pututxline(&pty->ut_entry); endutxent(); #else strcpy(pty->ut_entry.ut_host, getenv("DISPLAY")); time_t tt; time(&tt); pty->ut_entry.ut_time = tt; pty->ut_entry.ut_addr = 0; setutent(); pututline(&pty->ut_entry); endutent(); #endif #endif }
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 main(int argc, char *argv[]) { struct utmpx *ut; setutxent(); while ((ut = getutxent()) != NULL) { printf("%-10s ", ut->ut_user); printf("%-10s ", (ut->ut_type == EMPTY) ? "EMPTY" : (ut->ut_type == RUN_LVL) ? "RUN_LVL" : (ut->ut_type == BOOT_TIME) ? "BOOT_TIME": (ut->ut_type == NEW_TIME) ? "NEW_TIME" : (ut->ut_type == OLD_TIME) ? "OLD_TIME" : (ut->ut_type == INIT_PROCESS) ? "INIT_PR" : (ut->ut_type == LOGIN_PROCESS) ? "LOGIN_PR" : (ut->ut_type == USER_PROCESS) ? "USER_PR" : (ut->ut_type == DEAD_PROCESS) ? "DEAD_PR" : "?"); printf("%-7ld %-6s %-5s %-10s ", (long) ut->ut_pid, ut->ut_line, ut->ut_id, ut->ut_host); printf("%s", ctime((time_t *) &(ut->ut_tv.tv_sec))); } endutxent(); exit(EXIT_SUCCESS); }
void utmpx_mark_dead(pid_t pid, int status, boolean_t blocking) { struct utmpx *up; int logged = 0; for (;;) { int found = 0; MUTEX_LOCK(&utmpx_lock); setutxent(); while (up = getutxent()) { if (up->ut_pid == pid) { found = 1; if (up->ut_type == DEAD_PROCESS) { /* * Cleaned up elsewhere. */ endutxent(); MUTEX_UNLOCK(&utmpx_lock); return; } up->ut_type = DEAD_PROCESS; up->ut_exit.e_termination = WTERMSIG(status); up->ut_exit.e_exit = WEXITSTATUS(status); (void) time(&up->ut_tv.tv_sec); if (pututxline(up) != NULL) { /* * Now attempt to add to the end of the * wtmp and wtmpx files. Do not create * if they don't already exist. */ updwtmpx(WTMPX_FILE, up); endutxent(); MUTEX_UNLOCK(&utmpx_lock); return; } } } endutxent(); MUTEX_UNLOCK(&utmpx_lock); if (!found || !blocking) return; if (!logged) { log_framework(LOG_INFO, "retrying utmpx_dead on PID " "%ld\n", pid); logged++; } (void) sleep(1); } }
/* * Return users currently connected on the system. */ static PyObject * psutil_users(PyObject *self, PyObject *args) { struct utmpx *ut; PyObject *py_tuple = NULL; PyObject *py_username = NULL; PyObject *py_tty = NULL; PyObject *py_hostname = NULL; PyObject *py_user_proc = NULL; PyObject *py_retlist = PyList_New(0); if (py_retlist == NULL) return NULL; setutxent(); while (NULL != (ut = getutxent())) { if (ut->ut_type == USER_PROCESS) py_user_proc = Py_True; else py_user_proc = Py_False; py_username = PyUnicode_DecodeFSDefault(ut->ut_user); if (! py_username) goto error; py_tty = PyUnicode_DecodeFSDefault(ut->ut_line); if (! py_tty) goto error; py_hostname = PyUnicode_DecodeFSDefault(ut->ut_host); if (! py_hostname) goto error; py_tuple = Py_BuildValue( "(OOOfOi)", py_username, // username py_tty, // tty py_hostname, // hostname (float)ut->ut_tv.tv_sec, // tstamp py_user_proc, // (bool) user process ut->ut_pid // process id ); if (py_tuple == NULL) goto error; if (PyList_Append(py_retlist, py_tuple)) goto error; Py_DECREF(py_username); Py_DECREF(py_tty); Py_DECREF(py_hostname); Py_DECREF(py_tuple); } endutxent(); return py_retlist; error: Py_XDECREF(py_username); Py_XDECREF(py_tty); Py_XDECREF(py_hostname); Py_XDECREF(py_tuple); Py_DECREF(py_retlist); endutxent(); return NULL; }
int who_main(int argc UNUSED_PARAM, char **argv) { struct utmpx *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 puts("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST"); setutxent(); while ((ut = getutxent()) != 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) endutxent(); return EXIT_SUCCESS; }
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 */
static int utmpx_write_library(struct logininfo *li, struct utmpx *utx) { setutxent(); pututxline(utx); # ifdef HAVE_ENDUTXENT endutxent(); # endif return 1; }
void login(struct utmp *ut) { struct utmpx ux; getutmpx(ut, &ux); /* ut_id will automatically be calculated in the call to pututxline() */ ux.ut_type |= UTMPX_AUTOFILL_MASK; setutxent(); pututxline(&ux); endutxent(); }
int main (int argc, char **argv) { int users = -1; int result = STATE_UNKNOWN; char *perf; struct utmpx *putmpx; setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); perf = strdup (""); /* Parse extra opts if any */ argv = np_extra_opts (&argc, argv, progname); if (process_arguments (argc, argv) == ERROR) usage4 (_("Could not parse arguments")); users = 0; /* get currently logged users from utmpx */ setutxent (); while ((putmpx = getutxent ()) != NULL) if (putmpx->ut_type == USER_PROCESS) users++; endutxent (); /* check the user count against warning and critical thresholds */ if (users > cusers) result = STATE_CRITICAL; else if (users > wusers) result = STATE_WARNING; else if (users >= 0) result = STATE_OK; if (result == STATE_UNKNOWN) printf ("%s\n", _("Unable to read output")); else { asprintf (&perf, "%s", perfdata ("users", users, "", TRUE, wusers, TRUE, cusers, TRUE, 0, FALSE, 0)); printf (_("USERS %s - %d users currently logged in |%s\n"), state_text (result), users, perf); } return result; }
static char * _getlogin() { /* find name of the controlling terminal of the calling process */ char *tty; /* if the controlling terminal name cannot be determined, return a NULL pointer. * `errno` will have been appropriately set by `ttyname(3)`. */ if ((tty = ttyname(STDIN_FILENO)) == NULL) return NULL; /* the static data structure used for all calls to this function */ static char login[GETLOGIN_LOGIN_MAX]; utmpname(GETLOGIN_UTMP_FILE); /* search for an entry in the utmp file where the ut_line field matches * that of the controlling terminal name */ errno = 0; setutxent(); if (errno != 0) return NULL; struct utmpx *entry, criteria; char *line; /* drop the leading slash, if any */ if (tty[0] == '/') ++tty; /* remove the `dev/` prefix from the ttyname, if existent */ if ((line = strchr(tty, '/')) == NULL) line = tty; else /* dev/pts/0 becomes pts/0 */ ++line; strncpy(criteria.ut_line, line, __UT_LINESIZE); if ((entry = getutxline(&criteria)) == NULL) return NULL; strncpy(login, entry->ut_user, GETLOGIN_LOGIN_MAX); /* finish the reading of the utmp file */ errno = 0; endutxent(); if (errno != 0) return NULL; return login; }
char* test_getlogin() { struct utmpx *ut; char *tty = ttyname(STDIN_FILENO); setutxent(); while ((ut = getutxent()) != NULL) { if (strcmp(ut->ut_line, tty + 5) == 0) { strncpy(user, ut->ut_user, 255); user[255] = '\0'; break; } } endutxent(); return user; }
/* calculate number of users on the system */ static int ucount(void) { int nusers = 0; struct utmpx *ut; setutxent(); while ((ut = getutxent()) != NULL) if (ut->ut_type == USER_PROCESS) nusers++; endutxent(); return (nusers); }
static int utmp_get_runlevel(struct lxc_utmp *utmp_data) { #if HAVE_UTMPX_H struct utmpx *utmpx; #else struct utmp *utmpx; #endif char path[MAXPATHLEN]; struct lxc_handler *handler = utmp_data->handler; if (snprintf(path, MAXPATHLEN, "/proc/%d/root/run/utmp", handler->pid) > MAXPATHLEN) { ERROR("path is too long"); return -1; } if (!access(path, F_OK) && !utmpxname(path)) goto utmp_ok; if (snprintf(path, MAXPATHLEN, "/proc/%d/root/var/run/utmp", handler->pid) > MAXPATHLEN) { ERROR("path is too long"); return -1; } if (utmpxname(path)) { SYSERROR("failed to 'utmpxname'"); return -1; } utmp_ok: setutxent(); while ((utmpx = getutxent())) { if (utmpx->ut_type == RUN_LVL) { utmp_data->prev_runlevel = utmpx->ut_pid / 256; utmp_data->curr_runlevel = utmpx->ut_pid % 256; DEBUG("utmp handler - run level is %c/%c", utmp_data->prev_runlevel, utmp_data->curr_runlevel); } } endutxent(); return 0; }
/** * Get number of current users which are logged in */ static int OS_getSystemNumUsers(uint32_t *nu) { struct utmpx *utmp; setutxent(); *nu = 0; while ((utmp = getutxent()) != NULL) { if (utmp->ut_type == USER_PROCESS) (*nu)++; } endutxent(); return (SNMP_ERR_NOERROR); }
static void logout(const char *line) { #ifdef HAVE_GETUTXENT struct utmpx utx, *putx; pid_t pid; strcpy(utx.ut_line, line); setutxent(); putx = getutxline(&utx); if (putx != NULL) { gettimeofday(&utx.ut_tv, NULL); strncpy(utx.ut_line, putx->ut_line, sizeof(utx.ut_line)); strncpy(utx.ut_user, putx->ut_name, sizeof(utx.ut_name)); pid = getpid(); utx.ut_pid = pid; strncpy(utx.ut_id, putx->ut_id, sizeof(utx.ut_id)); utx.ut_type = DEAD_PROCESS; pututxline(&utx); updwtmpx(WTFILE, &utx); } endutxent(); #else /* HAVE_GETUTXENT */ struct utmp utmp; struct utmp *putmp; pid_t pid; strcpy(utmp.ut_line, line); setutent(); putmp = getutline(&utmp); if (putmp != NULL) { time(&utmp.ut_time); strncpy(utmp.ut_line, putmp->ut_line, sizeof(utmp.ut_line)); strncpy(utmp.ut_user, putmp->ut_name, sizeof(utmp.ut_name)); pid = getpid(); utmp.ut_pid = pid; strncpy(utmp.ut_id, putmp->ut_id, sizeof(utmp.ut_id)); utmp.ut_type = DEAD_PROCESS; pututline(&utmp); updwtmp(WTFILE, &utmp); } endutent(); #endif /* HAVE_GETUTXENT */ }
static void utmpx_write_entry(short type, const char *msg, time_t tstamp) { struct utmpx u; struct utmpx *oup; size_t tmplen; bzero(&u, sizeof (struct utmpx)); u.ut_id[0] = u.ut_id[1] = u.ut_id[2] = u.ut_id[3] = '\0'; u.ut_pid = 0; u.ut_exit.e_termination = WTERMSIG(0); u.ut_exit.e_exit = WEXITSTATUS(0); u.ut_type = type; u.ut_tv.tv_sec = tstamp; MUTEX_LOCK(&utmpx_lock); setutxent(); if ((oup = getutxid(&u)) != NULL) { bcopy(oup->ut_user, u.ut_user, sizeof (u.ut_user)); bcopy(oup->ut_line, u.ut_line, sizeof (u.ut_line)); bcopy(oup->ut_host, u.ut_host, sizeof (u.ut_host)); tmplen = strlen(u.ut_host); if (tmplen) u.ut_syslen = min(tmplen + 1, sizeof (u.ut_host)); else u.ut_syslen = 0; } (void) sprintf(u.ut_line, "%.12s", msg); if (pututxline(&u) == NULL) { endutxent(); MUTEX_UNLOCK(&utmpx_lock); return; } updwtmpx(WTMPX_FILE, &u); endutxent(); MUTEX_UNLOCK(&utmpx_lock); utmpx_check(); }
/* * Get the system uptime and return it in the boottime parameter. Returns 0 * on success and -1 on failure. */ int kernel_getboottime(time_t *boottime) { struct utmpx query, *result; query.ut_type = BOOT_TIME; setutxent(); result = getutxid(&query); endutxent(); if (result == NULL) { syswarn("getutxid failed to find BOOT_TIME"); return -1; } *boottime = result->ut_tv.tv_sec; return 0; }
int main(int argc, char **argv) { struct utmpx *utmpx; setutxent(); while ((utmpx = getutxent()) != NULL) { if (utmpx->ut_type == USER_PROCESS) { utmpx->ut_type = DEAD_PROCESS; time(&utmpx->ut_xtime); (void) updwtmpx(WTMPX_FILE, utmpx); } } endutxent(); return (0); }
/* * setutmpx - the UTMPX version for setutmp */ int setutmpx (struct utmpx *utx) { int err = 0; assert (NULL != utx); setutxent (); if (pututxline (utx) == NULL) { err = 1; } endutxent (); updwtmpx (_WTMP_FILE "x", utx); return err; }
void w_main(void) { struct utmpx *x; xprintf("USER TTY LOGIN@ FROM"); setutxent(); while ((x=getutxent()) != NULL) { if (x->ut_type==7) { time_t tt = x->ut_tv.tv_sec; xprintf("\n%-9.8s%-9.8s %-4.24s (%-1.12s)", x->ut_user, x->ut_line, ctime(&tt), x->ut_host); } } xputc('\n'); }
static void setup_utmp(char *ttyname, char *location) { #ifdef HAVE_LASTLOG struct lastlog lastlog_entry; FILE *lastlog; #endif struct passwd *pw; struct timeval tv; pw = getpwuid(getuid()); memset(&utmp_entry, 0, sizeof(utmp_entry)); utmp_entry.ut_type = USER_PROCESS; utmp_entry.ut_pid = getpid(); strncpy(utmp_entry.ut_line, ttyname+5, lenof(utmp_entry.ut_line)); strncpy(utmp_entry.ut_id, ttyname+8, lenof(utmp_entry.ut_id)); strncpy(utmp_entry.ut_user, pw->pw_name, lenof(utmp_entry.ut_user)); strncpy(utmp_entry.ut_host, location, lenof(utmp_entry.ut_host)); /* * Apparently there are some architectures where (struct * utmpx).ut_tv is not essentially struct timeval (e.g. Linux * amd64). Hence the temporary. */ gettimeofday(&tv, NULL); utmp_entry.ut_tv.tv_sec = tv.tv_sec; utmp_entry.ut_tv.tv_usec = tv.tv_usec; setutxent(); pututxline(&utmp_entry); endutxent(); updwtmpx(WTMPX_FILE, &utmp_entry); #ifdef HAVE_LASTLOG memset(&lastlog_entry, 0, sizeof(lastlog_entry)); strncpy(lastlog_entry.ll_line, ttyname+5, lenof(lastlog_entry.ll_line)); strncpy(lastlog_entry.ll_host, location, lenof(lastlog_entry.ll_host)); time(&lastlog_entry.ll_time); if ((lastlog = fopen(LASTLOG_FILE, "r+")) != NULL) { fseek(lastlog, sizeof(lastlog_entry) * getuid(), SEEK_SET); fwrite(&lastlog_entry, 1, sizeof(lastlog_entry), lastlog); fclose(lastlog); } #endif pty_stamped_utmp = 1; }
int main(int argc, char *argv[]) { struct utmpx *ut; struct in_addr in; if (argc > 1 && strcmp(argv[1], "--help") == 0) usageErr("%s [utmp-pathname]\n", argv[0]); if (argc > 1) /* Use alternate file if supplied */ if (utmpxname(argv[1]) == -1) errExit("utmpxname"); setutxent(); printf("user type PID line id host "); printf("term exit session address date/time\n"); while ((ut = getutxent()) != NULL) { /* Sequential scan to EOF */ printf("%-8s ", ut->ut_user); printf("%-9.9s ", (ut->ut_type == EMPTY) ? "EMPTY" : (ut->ut_type == RUN_LVL) ? "RUN_LVL" : (ut->ut_type == BOOT_TIME) ? "BOOT_TIME" : (ut->ut_type == NEW_TIME) ? "NEW_TIME" : (ut->ut_type == OLD_TIME) ? "OLD_TIME" : (ut->ut_type == INIT_PROCESS) ? "INIT_PR" : (ut->ut_type == LOGIN_PROCESS) ? "LOGIN_PR" : (ut->ut_type == USER_PROCESS) ? "USER_PR" : (ut->ut_type == DEAD_PROCESS) ? "DEAD_PR" : "???"); printf("(%1d) ", ut->ut_type); printf("%5ld %-6.6s %-3.5s %-9.9s ", (long) ut->ut_pid, ut->ut_line, ut->ut_id, ut->ut_host); printf("%3d %3d ", ut->ut_exit.e_termination, ut->ut_exit.e_exit); printf("%8ld ", (long) ut->ut_session); /* Display IPv4 address */ in.s_addr = ut->ut_addr_v6[0]; printf(" %-15.15s ", inet_ntoa(in)); printf("%s", ctime((time_t *) &(ut->ut_tv.tv_sec))); } endutxent(); exit(EXIT_SUCCESS); }
int main(int argc, char **argv) { namebuf *names = NULL; int ncnt = 0; int nmax = 0; int cnt; struct utmpx *ut; int ch; while ((ch = getopt(argc, argv, "")) != -1) switch(ch) { case '?': default: usage(); } argc -= optind; argv += optind; setutxent(); while ((ut = getutxent()) != NULL) { if (ut->ut_type != USER_PROCESS) continue; if (ncnt >= nmax) { nmax += 32; names = realloc(names, sizeof(*names) * nmax); if (!names) { errx(1, "realloc"); /* NOTREACHED */ } } (void)strlcpy(names[ncnt], ut->ut_user, sizeof(*names)); ++ncnt; } endutxent(); if (ncnt > 0) { qsort(names, ncnt, sizeof(namebuf), scmp); (void)printf("%s", names[0]); for (cnt = 1; cnt < ncnt; ++cnt) if (strcmp(names[cnt], names[cnt - 1]) != 0) (void)printf(" %s", names[cnt]); (void)printf("\n"); } exit(0); }