int get_boottime(struct timeval *tv) { struct utmpx *ut, key; memset(&key, 0, sizeof(key)); key.ut_type = BOOT_TIME; if ((ut = getutxid(&key)) != NULL) { tv->tv_sec = ut->ut_tv.tv_sec; tv->tv_usec = ut->ut_tv.tv_usec; endutxent(); } return ut != NULL; }
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; }
bool get_boottime(struct timespec *ts) { struct utmpx *ut, key; debug_decl(get_boottime, SUDOERS_DEBUG_UTIL) memset(&key, 0, sizeof(key)); key.ut_type = BOOT_TIME; setutxent(); if ((ut = getutxid(&key)) != NULL) { sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO, "BOOT_TIME: %lld, %ld", (long long)ut->ut_tv.tv_sec, (long)ut->ut_tv.tv_usec); TIMEVAL_TO_TIMESPEC(&ut->ut_tv, ts); } endutxent(); debug_return_bool(ut != NULL); }
static int get_run_level(void) { #if defined(HAVE_UTMPX_H) && defined(RUN_LVL) int res=0; struct utmpx *ut,tmp; setutxent(); tmp.ut_type=RUN_LVL; ut=getutxid(&tmp); if(!ut) { endutxent(); return 5; } res=ut->ut_pid & 0xff; endutxent(); //g_message("runlevel %c\n",res); return res; #else return 5; #endif }
char platform_get_runlevel() { char runlevel; struct utmpx ut, *utp = NULL; MUTEX_LOCK(utmp_lock); memset(&ut, 0, sizeof(ut)); ut.ut_type = RUN_LVL; setutxent(); utp = getutxid(&ut); if (utp->ut_type == RUN_LVL && sscanf(utp->ut_line, "run-level %c", &runlevel) != 1) runlevel = 'u'; endutxent(); MUTEX_UNLOCK(utmp_lock); return runlevel; }
struct utmpx *pututxline(struct utmpx *ut) { struct utmpx *tmp, ut_copy, *retval = 0, *result; int e; ssize_t bytes_written; sigset_t oldset, *savedset; /* It's kosher to call this function with a pointer to our own static * utmp structure, so work with a copy of "ut" */ memcpy (&ut_copy, ut, sizeof (struct utmpx)); savedset = __utmp_block_signals (&oldset); /* Seek to the current record before searching. */ lseek (fd, utmp_current, SEEK_SET); if ((tmp = getutxid(&ut_copy))) { lseek(fd, - (off_t)sizeof(struct utmpx), SEEK_CUR); result = __utmp_io (fd, &ut_copy, sizeof(struct utmpx), &utmp_current, F_WRLCK); e = errno; } else { utmp_current = lseek(fd, 0, SEEK_END); result = __utmp_io (fd, &ut_copy, sizeof(struct utmpx), &utmp_current, F_WRLCK); e = errno; } if (savedset) sigprocmask (SIG_SETMASK, savedset, 0); if (result) { retval = ut; } memcpy (ut, &ut_copy, sizeof (struct utmpx)); errno = e; return retval; }
/* EXTPROTO */ void rxvt_cleanutent(rxvt_t *r) { #ifdef UTEMPTER_SUPPORT utempter_remove_record (PVTS(r)->cmd_fd); #else /* UTEMPTER_SUPPORT */ #ifdef HAVE_STRUCT_UTMP struct utmp *ut = &(PVTS(r)->ut); #endif #if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) struct utmpx *tmputx, *utx = &(PVTS(r)->utx); #endif #ifdef HAVE_STRUCT_UTMP # ifdef HAVE_UTMP_PID MEMSET(ut, 0, sizeof(struct utmp)); setutent(); STRNCPY(ut->ut_id, PVTS(r)->ut_id, sizeof(ut->ut_id)); ut->ut_type = USER_PROCESS; { struct utmp *tmput = getutid(ut); if (tmput) /* position to entry in utmp file */ ut = tmput; } ut->ut_type = DEAD_PROCESS; # else MEMSET(ut->ut_name, 0, sizeof(ut->ut_name)); # ifdef HAVE_UTMP_HOST MEMSET(ut->ut_host, 0, sizeof(ut->ut_host)); # endif # endif ut->ut_time = time(NULL); #endif #if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) MEMSET(utx, 0, sizeof(struct utmpx)); setutxent(); STRNCPY(utx->ut_id, PVTS(r)->ut_id, sizeof(utx->ut_id)); utx->ut_type = USER_PROCESS; if ((tmputx = getutxid(utx))) /* position to entry in utmp file */ utx = tmputx; utx->ut_type = DEAD_PROCESS; # ifdef HAVE_UTMPX_SESSION utx->ut_session = getsid(0); # endif utx->ut_tv.tv_sec = time(NULL); utx->ut_tv.tv_usec = 0; #endif /* * Write ending wtmp entry */ #ifdef WTMP_SUPPORT # ifdef WTMP_ONLY_ON_LOGIN if (ISSET_OPTION(r, Opt_loginShell)) # endif { # ifdef HAVE_STRUCT_UTMP # ifdef HAVE_UPDWTMP updwtmp(RXVT_WTMP_FILE, ut); # else rxvt_update_wtmp(RXVT_WTMP_FILE, ut); # endif # endif # if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) # ifdef HAVE_UPDWTMPX updwtmpx(RXVT_WTMPX_FILE, utx); # else pututxline (utx); # endif # endif } #endif /* * Write utmp entry */ #ifdef HAVE_STRUCT_UTMP # ifdef HAVE_UTMP_PID if (ut->ut_pid == PVTS(r)->cmd_pid) pututline(ut); endutent(); # else MEMSET(ut, 0, sizeof(struct utmp)); rxvt_write_bsd_utmp(PVTS(r)->utmp_pos, ut); # endif #endif #if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) if (utx->ut_pid == PVTS(r)->cmd_pid) pututxline(utx); endutxent(); #endif #endif /* UTEMPTER_SUPPORT */ }
/* * remove utmp and wtmp entries */ void ptytty_unix::logout () { if (!cmd_pid) return; #ifdef HAVE_STRUCT_UTMP struct utmp *tmput, *ut = &this->ut; #endif #ifdef HAVE_STRUCT_UTMPX struct utmpx *tmputx, *utx = &this->utx; #endif #ifdef HAVE_STRUCT_UTMP # ifdef HAVE_UTMP_PID memset (ut, 0, sizeof (struct utmp)); setutent (); strncpy (ut->ut_id, this->ut_id, sizeof (ut->ut_id)); ut->ut_type = USER_PROCESS; if ((tmput = getutid (ut))) /* position to entry in utmp file */ ut = tmput; ut->ut_type = DEAD_PROCESS; # else memset (ut->ut_name, 0, sizeof (ut->ut_name)); # ifdef HAVE_UTMP_HOST memset (ut->ut_host, 0, sizeof (ut->ut_host)); # endif # endif ut->ut_time = time (NULL); #endif #ifdef HAVE_STRUCT_UTMPX memset (utx, 0, sizeof (struct utmpx)); setutxent (); strncpy (utx->ut_id, this->ut_id, sizeof (utx->ut_id)); utx->ut_type = USER_PROCESS; if ((tmputx = getutxid (utx))) /* position to entry in utmp file */ utx = tmputx; utx->ut_type = DEAD_PROCESS; # if HAVE_UTMPX_SESSION utx->ut_session = getsid (0); # endif utx->ut_tv.tv_sec = time (NULL); utx->ut_tv.tv_usec = 0; #endif /* * Write ending wtmp entry */ #ifdef WTMP_SUPPORT #ifdef LOG_ONLY_ON_LOGIN if (login_shell) #endif { # ifdef HAVE_STRUCT_UTMP # ifdef HAVE_UPDWTMP updwtmp (WTMP_FILE, ut); # else update_wtmp (WTMP_FILE, ut); # endif # endif # if defined(HAVE_STRUCT_UTMPX) && defined(HAVE_UPDWTMPX) updwtmpx (WTMPX_FILE, utx); # endif } #endif /* * Write utmp entry */ #ifdef HAVE_STRUCT_UTMP # ifdef HAVE_UTMP_PID if (ut->ut_pid == cmd_pid) pututline (ut); endutent (); # else memset (ut, 0, sizeof (struct utmp)); write_bsd_utmp (utmp_pos, ut); # endif #endif #ifdef HAVE_STRUCT_UTMPX if (utx->ut_pid == cmd_pid) pututxline (utx); endutxent (); #endif cmd_pid = 0; }
/* * make and write utmp and wtmp entries */ void ptytty_unix::login (int cmd_pid, bool login_shell, const char *hostname) { const char *pty = name; if (!pty || !*pty) return; this->cmd_pid = cmd_pid; this->login_shell = login_shell; #ifdef HAVE_STRUCT_UTMP struct utmp *ut = &this->ut; #endif #ifdef HAVE_STRUCT_UTMPX struct utmpx *utx = &this->utx; #endif int i; struct passwd *pwent = getpwuid (getuid ()); const char *name = (pwent && pwent->pw_name) ? pwent->pw_name : "?"; if (!strncmp (pty, "/dev/", 5)) pty += 5; /* skip /dev/ prefix */ #if defined(HAVE_UTMP_PID) || defined(HAVE_STRUCT_UTMPX) if (!strncmp (pty, "pty", 3) || !strncmp (pty, "tty", 3)) strncpy (ut_id, pty + 3, sizeof (ut_id)); else if (sscanf (pty, "pts/%d", &i) == 1) sprintf (ut_id, "vt%02x", (i & 0xff)); /* sysv naming */ else { ptytty_warn ("can't parse tty name \"%s\", not adding utmp entry.\n", pty); return; } #endif #ifdef HAVE_STRUCT_UTMP memset (ut, 0, sizeof (struct utmp)); # ifdef HAVE_UTMP_PID setutent (); strncpy (ut->ut_id, ut_id, sizeof (ut->ut_id)); ut->ut_type = DEAD_PROCESS; getutid (ut); /* position to entry in utmp file */ # endif #endif #ifdef HAVE_STRUCT_UTMPX memset (utx, 0, sizeof (struct utmpx)); setutxent (); strncpy (utx->ut_id, ut_id, sizeof (utx->ut_id)); utx->ut_type = DEAD_PROCESS; getutxid (utx); /* position to entry in utmp file */ #endif #ifdef HAVE_STRUCT_UTMP strncpy (ut->ut_line, pty, sizeof (ut->ut_line)); # ifdef HAVE_UTMP_HOST strncpy (ut->ut_host, hostname, sizeof (ut->ut_host)); # endif ut->ut_time = time (NULL); # ifdef HAVE_UTMP_PID strncpy (ut->ut_user, name, sizeof (ut->ut_user)); strncpy (ut->ut_id, ut_id, sizeof (ut->ut_id)); ut->ut_pid = cmd_pid; ut->ut_type = USER_PROCESS; pututline (ut); endutent (); /* close the file */ utmp_pos = 0; # else strncpy (ut->ut_name, name, sizeof (ut->ut_name)); # endif #endif #ifdef HAVE_STRUCT_UTMPX strncpy (utx->ut_line, pty, sizeof (utx->ut_line)); strncpy (utx->ut_user, name, sizeof (utx->ut_user)); strncpy (utx->ut_id, ut_id, sizeof (utx->ut_id)); # if HAVE_UTMPX_SESSION utx->ut_session = getsid (0); # endif utx->ut_tv.tv_sec = time (NULL); utx->ut_tv.tv_usec = 0; utx->ut_pid = cmd_pid; # ifdef HAVE_UTMPX_HOST strncpy (utx->ut_host, hostname, sizeof (utx->ut_host)); # if 0 { char *colon; if ((colon = strrchr (ut->ut_host, ':')) != NULL) *colon = '\0'; } # endif # endif utx->ut_type = USER_PROCESS; pututxline (utx); endutxent (); /* close the file */ utmp_pos = 0; #endif #if defined(HAVE_STRUCT_UTMP) && !defined(HAVE_UTMP_PID) { # if 1 int fdstdin = dup (STDIN_FILENO); dup2 (tty, STDIN_FILENO); i = ttyslot (); if (write_bsd_utmp (i, ut)) utmp_pos = i; dup2 (fdstdin, STDIN_FILENO); close (fdstdin); # endif } #endif #ifdef WTMP_SUPPORT #ifdef LOG_ONLY_ON_LOGIN if (login_shell) #endif { # ifdef HAVE_STRUCT_UTMP # ifdef HAVE_UPDWTMP updwtmp (WTMP_FILE, ut); # else update_wtmp (WTMP_FILE, ut); # endif # endif # if defined(HAVE_STRUCT_UTMPX) && defined(HAVE_UPDWTMPX) updwtmpx (WTMPX_FILE, utx); # endif } #endif #if defined(LASTLOG_SUPPORT) && defined(LASTLOG_FILE) #ifdef LOG_ONLY_ON_LOGIN if (login_shell) #endif update_lastlog (LASTLOG_FILE, pty, hostname); #endif }
struct utmpx * pututxline(const struct utmpx *utx) { struct passwd *pw; struct lastlogx ll; struct utmpx temp, *u = NULL; int gotlock = 0; _DIAGASSERT(utx != NULL); if (utx == NULL) return NULL; if (utx->ut_type == USER_PROCESS) { ll.ll_tv = utx->ut_tv; strcpy(ll.ll_host, utx->ut_host); strcpy(ll.ll_line, utx->ut_line); pw = getpwnam(utx->ut_name); if (pw != NULL) updlastlogx(_PATH_LASTLOGX, pw->pw_uid, &ll); } if (strcmp(_PATH_UTMPX, utfile) == 0) if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0)) return utmp_update(utx); (void)memcpy(&temp, utx, sizeof(temp)); if (fp == NULL) { (void)getutxent(); if (fp == NULL || readonly) return NULL; } if (getutxid(&temp) == NULL) { setutxent(); if (getutxid(&temp) == NULL) { if (lockf(fileno(fp), F_LOCK, (off_t)0) == -1) return NULL; gotlock++; if (fseeko(fp, (off_t)0, SEEK_END) == -1) goto fail; } } if (!gotlock) { /* we are not appending */ if (fseeko(fp, -(off_t)sizeof(ut), SEEK_CUR) == -1) return NULL; } if (fwrite(&temp, sizeof (temp), 1, fp) != 1) goto fail; if (fflush(fp) == -1) goto fail; u = memcpy(&ut, &temp, sizeof(ut)); fail: if (gotlock) { if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1) return NULL; } return u; }
struct utmpx * pututxline(const struct utmpx *utx) { struct utmpx temp, *u = NULL; int gotlock = 0; _DIAGASSERT(utx != NULL); if (utx == NULL) return NULL; if (strcmp(_PATH_UTMPX, utfile) == 0) { if (geteuid() == 0) { if (fp != NULL && readonly) endutxent(); } else { if (fp == NULL || readonly) return utmp_update(utx); } } (void)memcpy(&temp, utx, sizeof(temp)); if (fp == NULL) { (void)getutxent(); if (fp == NULL || readonly) return NULL; } if (getutxid(&temp) == NULL) { setutxent(); if (getutxid(&temp) == NULL) { if (lockf(fileno(fp), F_LOCK, (off_t)0) == -1) return NULL; gotlock++; if (fseeko(fp, (off_t)0, SEEK_END) == -1) goto fail; } } if (!gotlock) { /* we are not appending */ if (fseeko(fp, -(off_t)sizeof(ut), SEEK_CUR) == -1) return NULL; } if (version == 1) new2old(&temp); if (fwrite(&temp, sizeof (temp), 1, fp) != 1) goto fail; if (fflush(fp) == -1) goto fail; u = memcpy(&ut, &temp, sizeof(ut)); fail: if (gotlock) { if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1) return NULL; } return u; }
void ptytty_unix::log_session (bool login, const char *hostname) { struct passwd *pwent = getpwuid (getuid ()); const char *user = (pwent && pwent->pw_name) ? pwent->pw_name : "?"; const char *pty = name; if (!strncmp (pty, "/dev/", 5)) pty += 5; /* skip /dev/ prefix */ #ifdef HAVE_STRUCT_UTMP struct utmp *tmput; struct utmp ut; fill_utmp (&ut, login, cmd_pid, pty, user, hostname); #endif #ifdef HAVE_STRUCT_UTMPX struct utmpx *tmputx; struct utmpx utx; fill_utmpx (&utx, login, cmd_pid, pty, user, hostname); #endif #ifdef HAVE_STRUCT_UTMP # ifdef HAVE_UTMP_PID setutent (); if (login || ((tmput = getutid (&ut)) && tmput->ut_pid == cmd_pid)) pututline (&ut); endutent (); # else write_bsd_utmp (utmp_pos, &ut); # endif #endif #ifdef HAVE_STRUCT_UTMPX setutxent (); if (login || ((tmputx = getutxid (&utx)) && tmputx->ut_pid == cmd_pid)) pututxline (&utx); endutxent (); #endif #ifdef WTMP_SUPPORT if (login_shell) { # ifdef HAVE_STRUCT_UTMP # ifdef HAVE_UPDWTMP updwtmp (WTMP_FILE, &ut); # else update_wtmp (WTMP_FILE, &ut); # endif # endif # if defined(HAVE_STRUCT_UTMPX) && defined(HAVE_UPDWTMPX) updwtmpx (WTMPX_FILE, &utx); # endif } #endif #ifdef LASTLOG_SUPPORT if (login_shell) if (login) { if (pwent) update_lastlog (pty, hostname); else PTYTTY_WARN ("no entry in password file, not updating lastlog.\n"); } #endif }
/* EXTPROTO */ void rxvt_makeutent(rxvt_t *r, const char *pty, const char *hostname) { #ifdef UTEMPTER_SUPPORT utempter_add_record (PVTS(r)->cmd_fd, hostname); #else /* UTEMPTER_SUPPORT */ #ifdef HAVE_STRUCT_UTMP struct utmp *ut = &(PVTS(r)->ut); #endif #if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) struct utmpx *utx = &(PVTS(r)->utx); #endif #ifdef HAVE_UTMP_PID int i; #endif char ut_id[5]; struct passwd *pwent = getpwuid(getuid()); if (!STRNCMP(pty, "/dev/", 5)) pty += 5; /* skip /dev/ prefix */ if (!STRNCMP(pty, "pty", 3) || !STRNCMP(pty, "tty", 3)) { STRNCPY(ut_id, (pty + 3), sizeof(ut_id)); } #ifdef HAVE_UTMP_PID else if (sscanf(pty, "pts/%d", &i) == 1) sprintf(ut_id, "vt%02x", (i & 0xff)); /* sysv naming */ #endif else if (STRNCMP(pty, "pty", 3) && STRNCMP(pty, "tty", 3)) { rxvt_msg (DBG_ERROR, DBG_LOGGING, "can't parse tty name \"%s\"", pty); return; } #ifdef HAVE_STRUCT_UTMP MEMSET(ut, 0, sizeof(struct utmp)); # ifdef HAVE_UTMP_PID setutent(); STRNCPY(ut->ut_id, ut_id, sizeof(ut->ut_id)); ut->ut_type = DEAD_PROCESS; getutid(ut); /* position to entry in utmp file */ STRNCPY(PVTS(r)->ut_id, ut_id, sizeof(PVTS(r)->ut_id)); # endif #endif #if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) MEMSET(utx, 0, sizeof(struct utmpx)); setutxent(); STRNCPY(utx->ut_id, ut_id, sizeof(utx->ut_id)); utx->ut_type = DEAD_PROCESS; getutxid(utx); /* position to entry in utmp file */ STRNCPY(PVTS(r)->ut_id, ut_id, sizeof(PVTS(r)->ut_id)); #endif #ifdef HAVE_STRUCT_UTMP STRNCPY(ut->ut_line, pty, sizeof(ut->ut_line)); ut->ut_time = time(NULL); # ifdef HAVE_UTMP_PID STRNCPY(ut->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?", sizeof(ut->ut_user)); STRNCPY(ut->ut_id, ut_id, sizeof(ut->ut_id)); ut->ut_time = time(NULL); ut->ut_pid = PVTS(r)->cmd_pid; # ifdef HAVE_UTMP_HOST STRNCPY(ut->ut_host, hostname, sizeof(ut->ut_host)); # endif ut->ut_type = USER_PROCESS; pututline(ut); endutent(); /* close the file */ PVTS(r)->utmp_pos = 0; # else STRNCPY(ut->ut_name, (pwent && pwent->pw_name) ? pwent->pw_name : "?", sizeof(ut->ut_name)); # ifdef HAVE_UTMP_HOST STRNCPY(ut->ut_host, hostname, sizeof(ut->ut_host)); # endif # endif #endif #if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) STRNCPY(utx->ut_line, pty, sizeof(utx->ut_line)); STRNCPY(utx->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?", sizeof(utx->ut_user)); STRNCPY(utx->ut_id, ut_id, sizeof(utx->ut_id)); # ifdef HAVE_UTMPX_SESSION utx->ut_session = getsid(0); # endif utx->ut_tv.tv_sec = time(NULL); utx->ut_tv.tv_usec = 0; utx->ut_pid = PVTS(r)->cmd_pid; # ifdef HAVE_UTMPX_HOST STRNCPY(utx->ut_host, hostname, sizeof(utx->ut_host)); # endif utx->ut_type = USER_PROCESS; pututxline(utx); endutxent(); /* close the file */ PVTS(r)->utmp_pos = 0; #endif #if defined(HAVE_STRUCT_UTMP) && !defined(HAVE_UTMP_PID) { int i; # ifdef HAVE_TTYSLOT i = ttyslot(); if (rxvt_write_bsd_utmp(i, ut)) PVTS(r)->utmp_pos = i; # else FILE *fd0; if (NOT_NULL(fd0 = fopen(TTYTAB_FILENAME, "r"))) { char buf[256], name[256]; buf[sizeof(buf) - 1] = '\0'; for (i = 1; NOT_NULL(fgets(buf, sizeof(buf) - 1, fd0)); ) { if (*buf == '#' || sscanf(buf, "%s", name) != 1) continue; if (!STRCMP(ut->ut_line, name)) { if (!rxvt_write_bsd_utmp(i, ut)) i = 0; PVTS(r)->utmp_pos = i; fclose(fd0); break; } i++; } fclose(fd0); } # endif } #endif #ifdef WTMP_SUPPORT # ifdef WTMP_ONLY_ON_LOGIN if (ISSET_OPTION(r, Opt_loginShell)) # endif { # ifdef HAVE_STRUCT_UTMP # ifdef HAVE_UPDWTMP updwtmp(RXVT_WTMP_FILE, ut); # else rxvt_update_wtmp(RXVT_WTMP_FILE, ut); # endif # endif # if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP) # ifdef HAVE_UPDWTMPX updwtmpx(RXVT_WTMPX_FILE, utx); # else pututxline (utx); # endif # endif } #endif #endif /* UTEMPTER_SUPPORT */ #if defined(LASTLOG_SUPPORT) && defined(RXVT_LASTLOG_FILE) if (ISSET_OPTION(r, Opt_loginShell)) rxvt_update_lastlog(RXVT_LASTLOG_FILE, pty, hostname); #endif }
void utmpx_set_runlevel(char runlevel, char oldrl, boolean_t do_bump) { struct utmpx u; struct utmpx *oup; size_t tmplen; int i; if (runlevel == 's') runlevel = 'S'; if (oldrl == 's') oldrl = 'S'; 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_type = RUN_LVL; (void) time(&u.ut_tv.tv_sec); MUTEX_LOCK(&utmpx_lock); setutxent(); if ((oup = getutxid(&u)) != NULL) { bcopy(oup->ut_host, u.ut_host, sizeof (u.ut_host)); bcopy(oup->ut_line, u.ut_line, sizeof (u.ut_line)); bcopy(oup->ut_user, u.ut_user, sizeof (u.ut_user)); tmplen = strlen(u.ut_host); if (tmplen) u.ut_syslen = min(tmplen + 1, sizeof (u.ut_host)); else u.ut_syslen = 0; } if (oldrl != '\0') u.ut_exit.e_exit = oldrl; else if (oup != NULL) u.ut_exit.e_exit = oup->ut_exit.e_termination; else u.ut_exit.e_exit = '0'; u.ut_exit.e_termination = runlevel; for (i = 0; rlevels[i] != '\0'; ++i) { if (rlevels[i] == runlevel) break; } u.ut_pid = n_prev[i]; if (do_bump) { for (i = 0; rlevels[i] != '\0'; ++i) { if (rlevels[i] == u.ut_exit.e_exit) break; } ++n_prev[i]; } (void) sprintf(u.ut_line, RUNLVL_MSG, runlevel); if (pututxline(&u) == NULL) { endutxent(); MUTEX_UNLOCK(&utmpx_lock); return; } updwtmpx(WTMPX_FILE, &u); endutxent(); MUTEX_UNLOCK(&utmpx_lock); utmpx_check(); }
/* * Update wtmp and utmp logs. */ static void log_utmp(struct login_context *cxt) { struct utmpx ut; struct utmpx *utp; struct timeval tv; utmpxname(_PATH_UTMP); setutxent(); /* Find pid in utmp. * * login sometimes overwrites the runlevel entry in /var/run/utmp, * confusing sysvinit. I added a test for the entry type, and the * problem was gone. (In a runlevel entry, st_pid is not really a pid * but some number calculated from the previous and current runlevel.) * -- Michael Riepe <*****@*****.**> */ while ((utp = getutxent())) if (utp->ut_pid == cxt->pid && utp->ut_type >= INIT_PROCESS && utp->ut_type <= DEAD_PROCESS) break; /* If we can't find a pre-existing entry by pid, try by line. * BSD network daemons may rely on this. */ if (utp == NULL && cxt->tty_name) { setutxent(); ut.ut_type = LOGIN_PROCESS; str2memcpy(ut.ut_line, cxt->tty_name, sizeof(ut.ut_line)); utp = getutxline(&ut); } /* If we can't find a pre-existing entry by pid and line, try it by id. * Very stupid telnetd daemons don't set up utmp at all. (kzak) */ if (utp == NULL && cxt->tty_number) { setutxent(); ut.ut_type = DEAD_PROCESS; str2memcpy(ut.ut_id, cxt->tty_number, sizeof(ut.ut_id)); utp = getutxid(&ut); } if (utp) memcpy(&ut, utp, sizeof(ut)); else /* some gettys/telnetds don't initialize utmp... */ memset(&ut, 0, sizeof(ut)); if (cxt->tty_number && ut.ut_id[0] == 0) str2memcpy(ut.ut_id, cxt->tty_number, sizeof(ut.ut_id)); if (cxt->username) str2memcpy(ut.ut_user, cxt->username, sizeof(ut.ut_user)); if (cxt->tty_name) str2memcpy(ut.ut_line, cxt->tty_name, sizeof(ut.ut_line)); gettimeofday(&tv, NULL); ut.ut_tv.tv_sec = tv.tv_sec; ut.ut_tv.tv_usec = tv.tv_usec; ut.ut_type = USER_PROCESS; ut.ut_pid = cxt->pid; if (cxt->hostname) { str2memcpy(ut.ut_host, cxt->hostname, sizeof(ut.ut_host)); if (*cxt->hostaddress) memcpy(&ut.ut_addr_v6, cxt->hostaddress, sizeof(ut.ut_addr_v6)); } pututxline(&ut); endutxent(); updwtmpx(_PATH_WTMP, &ut); }
int utmpx_mark_init(pid_t pid, char *prefix) { struct utmpx ut, *oldu; int tmplen; int ret; while (st->st_initial && !utmpx_truncated) (void) usleep(200 * USEC_PER_MSEC); /* * Clean out any preexisting records for this PID, as they must be * inaccurate. */ utmpx_mark_dead(pid, 0, B_TRUE); /* * Construct a new record with the appropriate prefix. */ (void) memset(&ut, 0, sizeof (ut)); (void) strncpy(ut.ut_user, ".startd", sizeof (ut.ut_user)); ut.ut_pid = pid; ut.ut_id[0] = ut.ut_id[1] = ut.ut_id[2] = ut.ut_id[3] = (char)SC_WILDC; for (ret = 0; ret < strlen(prefix); ret++) ut.ut_id[ret] = prefix[ret]; ut.ut_type = INIT_PROCESS; (void) time(&ut.ut_tv.tv_sec); for (;;) { MUTEX_LOCK(&utmpx_lock); setutxent(); if ((oldu = getutxid(&ut)) != NULL) { /* * Copy in the old "line" and "host" fields. */ bcopy(oldu->ut_line, ut.ut_line, sizeof (ut.ut_line)); bcopy(oldu->ut_host, ut.ut_host, sizeof (ut.ut_host)); ut.ut_syslen = (tmplen = strlen(ut.ut_host)) ? min(tmplen + 1, sizeof (ut.ut_host)) : 0; } if (makeutx(&ut) != NULL) break; if (errno != EROFS) log_framework(LOG_WARNING, "makeutx failed, retrying: %s\n", strerror(errno)); MUTEX_UNLOCK(&utmpx_lock); (void) sleep(1); } updwtmpx(WTMPX_FILE, &ut); endutxent(); MUTEX_UNLOCK(&utmpx_lock); return (ret); }
uint64 System_Uptime(void) { uint64 uptime = -1; #ifdef USERWORLD { VmkuserStatus_Code status; uint64 sysUptime; status = VmkuserUptime_GetUptime(&sysUptime); if (VmkuserStatus_IsOK(status)) { uptime = sysUptime / 10000; } } #elif defined(__linux__) { FILE *procStream; char *buf = NULL; size_t bufSize; uint64 sec; unsigned int csec; if (((procStream = Posix_Fopen("/proc/uptime", "r")) != NULL) && (StdIO_ReadNextLine(procStream, &buf, 80, &bufSize) == StdIO_Success) && (sscanf(buf, "%"FMT64"u.%2u", &sec, &csec) == 2)) { uptime = sec * 100 + csec; } else { Warning("%s: Unable to parse /proc/uptime.\n", __func__); } free(buf); if (procStream) { fclose(procStream); } } #elif defined sun || defined __APPLE__ { struct utmpx *boot, tmp; tmp.ut_type = BOOT_TIME; if ((boot = getutxid(&tmp)) != NULL) { struct timeval now; struct timeval *boottime = &boot->ut_tv; gettimeofday(&now, NULL); uptime = (now.tv_sec * 100 + now.tv_usec / 10000) - (boottime->tv_sec * 100 + boottime->tv_usec / 10000); } else { Warning("%s: Unable to determine boot time.\n", __func__); } endutxent(); } #else // FreeBSD { /* * FreeBSD: src/usr.bin/w/w.c rev 1.59: * "Obtain true uptime through clock_gettime(CLOCK_MONOTONIC, * struct *timespec) instead of subtracting 'bootime' from 'now'." */ struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts) != -1) { uptime = ts.tv_sec * 100 + ts.tv_nsec / 10000000; } else { Warning("%s: clock_gettime: %d\n", __func__, errno); } } #endif return uptime; }
int SYSTEM_BOOTTIME(AGENT_REQUEST *request, AGENT_RESULT *result) { int ret = SYSINFO_RET_FAIL; #ifdef HAVE_ZONE_H if (GLOBAL_ZONEID == getzoneid()) { #endif kstat_ctl_t *kc; kstat_t *kp; kstat_named_t *kn; if (NULL == (kc = kstat_open())) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot open kernel statistics facility: %s", zbx_strerror(errno))); return ret; } if (NULL == (kp = kstat_lookup(kc, "unix", 0, "system_misc"))) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot look up in kernel statistics facility: %s", zbx_strerror(errno))); goto clean; } if (-1 == kstat_read(kc, kp, 0)) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot read from kernel statistics facility: %s", zbx_strerror(errno))); goto clean; } if (NULL == (kn = (kstat_named_t *)kstat_data_lookup(kp, "boot_time"))) { SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot look up data in kernel statistics facility:" " %s", zbx_strerror(errno))); goto clean; } SET_UI64_RESULT(result, get_kstat_numeric_value(kn)); ret = SYSINFO_RET_OK; clean: kstat_close(kc); #ifdef HAVE_ZONE_H } else { struct utmpx utmpx_local, *utmpx; utmpx_local.ut_type = BOOT_TIME; setutxent(); if (NULL != (utmpx = getutxid(&utmpx_local))) { SET_UI64_RESULT(result, utmpx->ut_xtime); ret = SYSINFO_RET_OK; } else SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain system boot time.")); endutxent(); } #endif return ret; }
int rckrunlevel(void) { struct utmpx utmpx; struct utmpx *putmpx; char ans[MAX_INPUT]; char *pt; char *rstates; int n; char *uxstate; if (ADM(runlevel, "nocheck")) { return (0); } pt = getenv("RSTATES"); if (pt == NULL) { return (0); } utmpx.ut_type = RUN_LVL; putmpx = getutxid(&utmpx); if (putmpx == NULL) { progerr(ERR_RUNSTATE); return (99); } uxstate = strtok(&putmpx->ut_line[10], " \t\n"); rstates = qstrdup(pt); if ((pt = strtok(pt, " \t\n, ")) == NULL) return (0); /* no list is no list */ do { if (strcmp(pt, uxstate) == 0) { free(rstates); return (0); } } while (pt = strtok(NULL, " \t\n, ")); if (preremoveCheck == B_FALSE) { msgtext = MSG_PKGREMOVE_RUNLEVEL; ptext(stderr, msgtext, uxstate); } else { (void) fprintf(stdout, "runlevel=%s", uxstate); } pt = strtok(rstates, " \t\n, "); do { if (preremoveCheck == B_FALSE) { ptext(stderr, "\\t%s", pt); } else { (void) fprintf(stdout, ":%s", pt); } } while (pt = strtok(NULL, " \t\n, ")); if (preremoveCheck == B_TRUE) { (void) fprintf(stdout, "\n"); } free(rstates); if (ADM(runlevel, "quit")) { return (4); } if (echoGetFlag() == B_FALSE) { return (5); } msgtext = NULL; n = ckyorn(ans, NULL, NULL, HLP_PKGREMOVE_RUNLEVEL, ASK_PKGREMOVE_CONTINUE); if (n != 0) { return (n); } if (strchr("yY", *ans) == NULL) { return (3); } return (0); }
/* EXTPROTO */ void rxvt_cleanutent(rxvt_t *r) { #ifdef HAVE_STRUCT_UTMP struct utmp *tmput, *ut = &(r->h->ut); #endif #ifdef HAVE_STRUCT_UTMPX struct utmpx *tmputx, *utx = &(r->h->utx); #endif #ifdef HAVE_STRUCT_UTMP # ifdef RXVT_UTMP_PID MEMSET(ut, 0, sizeof(struct utmp)); setutent(); STRNCPY(ut->ut_id, r->h->ut_id, sizeof(ut->ut_id)); ut->ut_type = USER_PROCESS; if ((tmput = getutid(ut))) /* position to entry in utmp file */ ut = tmput; ut->ut_type = DEAD_PROCESS; # else MEMSET(ut->ut_name, 0, sizeof(ut->ut_name)); MEMSET(ut->ut_host, 0, sizeof(ut->ut_host)); # endif ut->ut_time = time(NULL); #endif #ifdef HAVE_STRUCT_UTMPX MEMSET(utx, 0, sizeof(struct utmpx)); setutxent(); STRNCPY(utx->ut_id, r->h->ut_id, sizeof(utx->ut_id)); utx->ut_type = USER_PROCESS; if ((tmputx = getutxid(utx))) /* position to entry in utmp file */ utx = tmputx; utx->ut_type = DEAD_PROCESS; utx->ut_session = getsid(0); utx->ut_tv.tv_sec = time(NULL); utx->ut_tv.tv_usec = 0; #endif /* * Write ending wtmp entry */ #ifdef WTMP_SUPPORT # ifdef WTMP_ONLY_ON_LOGIN if (r->Options & Opt_loginShell) # endif { # ifdef HAVE_STRUCT_UTMP # ifdef HAVE_UPDWTMP updwtmp(RXVT_WTMP_FILE, ut); # else rxvt_update_wtmp(RXVT_WTMP_FILE, ut); # endif # endif # ifdef HAVE_STRUCT_UTMPX updwtmpx(RXVT_WTMPX_FILE, utx); # endif #endif } /* * Write utmp entry */ #ifdef HAVE_STRUCT_UTMP # ifdef RXVT_UTMP_PID if (ut->ut_pid == r->h->cmd_pid) pututline(ut); endutent(); # else if (r->h->utmp_pos > 0) { MEMSET(ut, 0, sizeof(struct utmp)); rxvt_write_bsd_utmp(r->h->utmp_pos, ut); } # endif #endif #ifdef HAVE_STRUCT_UTMPX if (utx->ut_pid == r->h->cmd_pid) pututxline(utx); endutxent(); #endif }
int main (int argc, char **argv) { #if defined(USE_UTMP) && !defined(HAVE_PUTUTLINE) int utmp; #endif #ifndef USE_UTMPX int wtmp; #endif time_t current_time; #ifdef USE_UTMP struct utmp utmp_entry; #endif #ifdef USE_UTMPX struct utmpx utmpx_entry; #endif char * line = NULL; program_name = argv[0]; while (*++argv && **argv == '-') { switch (*++*argv) { case 'w': wtmp_file = getstring (&argv, &wflag); if (!strcmp (wtmp_file, "none")) wtmp_none = 1; #if defined(USE_UTMPX) && defined(HAVE_UPDWTMPX) else wtmpx_file = wtmp_file; #endif break; case 'u': utmp_file = getstring (&argv, &uflag); if (!strcmp (utmp_file, "none")) utmp_none = 1; #if defined(USE_UTMPX) && defined(HAVE_UTMPXNAME) else utmpx_file = utmp_file; #endif break; #ifdef USE_LASTLOG case 'L': llog_file = getstring (&argv, &Lflag); if (!strcmp (llog_file, "none")) llog_none = 1; break; #endif case 't': ttys_file = getstring (&argv, &tflag); break; case 'l': line = getstring (&argv, &lflag); break; case 'h': host_name = getstring (&argv, &hflag); break; case 's': #if defined(USE_UTMP) && !defined(HAVE_PUTUTLINE) slot_number = atoi (getstring (&argv, &sflag)); #endif break; case 'x': xservers_file = getstring (&argv, &xflag); break; case 'a': aflag++; break; case 'd': dflag++; break; case 'V': printf("%s\n", PACKAGE_STRING); exit (0); default: fprintf (stderr, "%s: unrecognized option '%s'\n", program_name, argv[0]); usage (1); } } user_name = *argv++; if (user_name == NULL) { fprintf (stderr, "%s: missing required user-name argument\n", program_name); usage (1); } if (*argv != NULL) { fprintf (stderr, "%s: unrecognized argument '%s'\n", program_name, argv[0]); usage (1); } /* * complain if neither aflag nor dflag are set, * or if both are set. */ if (!(aflag ^ dflag)) { fprintf (stderr, "%s: must specify exactly one of -a or -d\n", program_name); usage (1); } if (xflag && !lflag) { fprintf (stderr, "%s: must specify -l when -x is used\n", program_name); usage (1); } /* set up default file names */ if (!wflag) { wtmp_file = WTMP_FILE; #if defined(USE_UTMPX) && defined(HAVE_UPDWTMPX) wtmpx_file = WTMPX_FILE; #endif } if (!uflag) { utmp_file = UTMP_FILE; #if defined(USE_UTMPX) && defined(HAVE_UTMPXNAME) utmpx_file = UTMPX_FILE; #endif } #ifdef USE_LASTLOG if (!Lflag) llog_file = LLOG_FILE; #endif #if defined(USE_UTMP) && !defined(HAVE_PUTUTLINE) if (!tflag) ttys_file = TTYS_FILE; if (!sflag && !utmp_none) { if (xflag) sysnerr (slot_number = Xslot (ttys_file, xservers_file, line, host_name, aflag), "Xslot"); else sysnerr (slot_number = ttyslot (), "ttyslot"); } #endif if (!lflag) { sysnerr ((line = ttyname (0)) != NULL, "ttyname"); if (strncmp(line, "/dev/", 5) == 0) line += 5; } time (¤t_time); #ifdef USE_UTMP set_utmp (&utmp_entry, line, user_name, host_name, current_time, aflag); #endif #ifdef USE_UTMPX /* need to set utmpxname() before calling set_utmpx() for UtmpxIdOpen to work */ # ifdef HAVE_UTMPXNAME if (utmpx_file != NULL) { utmpxname (utmpx_file); } # endif set_utmpx (&utmpx_entry, line, user_name, host_name, current_time, aflag); #endif if (!utmp_none) { #ifdef USE_UTMPX # ifdef HAVE_UTMPXNAME if (utmpx_file != NULL) # endif { setutxent (); (void) getutxid (&utmpx_entry); pututxline (&utmpx_entry); endutxent (); } #endif #ifdef USE_UTMP # ifdef HAVE_PUTUTLINE utmpname (utmp_file); setutent (); (void) getutid (&utmp_entry); pututline (&utmp_entry); endutent (); # else utmp = open (utmp_file, O_RDWR); if (utmp != -1) { syserr ((int) lseek (utmp, (long) slot_number * sizeof (struct utmp), 0), "lseek"); sysnerr (write (utmp, (char *) &utmp_entry, sizeof (utmp_entry)) == sizeof (utmp_entry), "write utmp entry"); close (utmp); } # endif #endif /* USE_UTMP */ } if (!wtmp_none) { #ifdef USE_UTMPX # ifdef HAVE_UPDWTMPX if (wtmpx_file != NULL) { updwtmpx(wtmpx_file, &utmpx_entry); } # endif #else wtmp = open (wtmp_file, O_WRONLY|O_APPEND); if (wtmp != -1) { sysnerr (write (wtmp, (char *) &utmp_entry, sizeof (utmp_entry)) == sizeof (utmp_entry), "write wtmp entry"); close (wtmp); } #endif } #ifdef USE_LASTLOG if (aflag && !llog_none) { int llog; struct passwd *pwd = getpwnam(user_name); sysnerr( pwd != NULL, "get user id"); llog = open (llog_file, O_RDWR); if (llog != -1) { struct lastlog ll; sysnerr (lseek(llog, (long) (pwd->pw_uid*sizeof(ll)), 0) != -1, "seeking lastlog entry"); memset(&ll, 0, sizeof(ll)); ll.ll_time = current_time; if (line) (void) strncpy (ll.ll_line, line, sizeof (ll.ll_line)); if (host_name) (void) strncpy (ll.ll_host, host_name, sizeof (ll.ll_host)); sysnerr (write (llog, (char *) &ll, sizeof (ll)) == sizeof (ll), "write lastlog entry"); close (llog); } } #endif return 0; }