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; }
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 void sendmes_tozone(zoneid_t zid, int aflag) { int i = 0; char zonename[ZONENAME_MAX], root[MAXPATHLEN]; struct utmpx *p; if (zid != getzoneid()) { root[0] = '\0'; (void) getzonenamebyid(zid, zonename, ZONENAME_MAX); (void) zone_get_rootpath(zonename, root, sizeof (root)); (void) strlcat(root, UTMPX_FILE, sizeof (root)); if (!utmpxname(root)) { (void) fprintf(stderr, "Cannot open %s\n", root); return; } } else { (void) utmpxname(UTMPX_FILE); } setutxent(); while ((p = getutxent()) != NULL) { if (p->ut_type != USER_PROCESS) continue; /* * if (-a option OR NOT pty window login), send the message */ if (aflag || !nonuserx(*p)) sendmes(p, zid); } endutxent(); (void) alarm(60); do { i = (int)wait((int *)0); } while (i != -1 || errno != ECHILD); }
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) { struct utmpx *p; if (argc < 3) (void) fprintf(stderr, "Usage: %s reason wtmpx_file\n", argv[0]), exit(1); (void) strncpy(wb.ut_line, argv[1], sizeof (wb.ut_line)); wb.ut_line[11] = NULL; wb.ut_type = ACCOUNTING; time(&wb.ut_xtime); utmpxname(argv[2]); setutxent(); if (pututxline(&wb) == NULL) printf("acctwtmp - pututxline failed\n"); endutxent(); exit(0); }
int main(int argc, char *argv[]) { struct utmpx *ut; if (argc > 1 && strcmp(argv[1], "--help") == 0) { fprintf(stderr, "usage: %s [utmp-pathname]\n", argv[0]); exit(EXIT_FAILURE); } /* Use alternate file if supplied */ if (argc > 1) { if (utmpxname(argv[1]) == -1) { perror("utmpxname"); } } setutxent(); printf("user type PID line id host date/time\n"); /* Sequential scan to EOF */ while ((ut = getutxent()) != NULL) { 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("%5ld %-6.6s %-3.5s %-9.9s ", (long) ut->ut_pid, ut->ut_line, ut->ut_id, ut->ut_host); printf("%s", ctime(&(ut->ut_tv.tv_sec))); } endutxent(); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { struct utmpx *ut; struct utmpx *utmpbegin; struct utmpx *utmpend; struct utmpx *utp; struct uproc *up, *parent, *pgrp; struct psinfo info; struct sigaction actinfo[ACTSIZE]; struct pstatus statinfo; size_t size; struct stat sbuf; DIR *dirp; struct dirent *dp; char pname[64]; char *fname; int procfd; char *cp; int i; int days, hrs, mins; int entries; double loadavg[3]; /* * This program needs the proc_owner privilege */ (void) __init_suid_priv(PU_CLEARLIMITSET, PRIV_PROC_OWNER, (char *)NULL); (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif (void) textdomain(TEXT_DOMAIN); login = (argv[0][0] == '-'); cp = strrchr(argv[0], '/'); firstchar = login ? argv[0][1] : (cp == 0) ? argv[0][0] : cp[1]; prog = argv[0]; while (argc > 1) { if (argv[1][0] == '-') { for (i = 1; argv[1][i]; i++) { switch (argv[1][i]) { case 'h': header = 0; break; case 'l': lflag++; break; case 's': lflag = 0; break; case 'u': case 'w': firstchar = argv[1][i]; break; default: (void) fprintf(stderr, gettext( "%s: bad flag %s\n"), prog, argv[1]); exit(1); } } } else { if (!isalnum(argv[1][0]) || argc > 2) { (void) fprintf(stderr, gettext( "usage: %s [ -hlsuw ] [ user ]\n"), prog); exit(1); } else sel_user = argv[1]; } argc--; argv++; } /* * read the UTMPX_FILE (contains information about each logged in user) */ if (stat(UTMPX_FILE, &sbuf) == ERR) { (void) fprintf(stderr, gettext("%s: stat error of %s: %s\n"), prog, UTMPX_FILE, strerror(errno)); exit(1); } entries = sbuf.st_size / sizeof (struct futmpx); size = sizeof (struct utmpx) * entries; if ((ut = malloc(size)) == NULL) { (void) fprintf(stderr, gettext("%s: malloc error of %s: %s\n"), prog, UTMPX_FILE, strerror(errno)); exit(1); } (void) utmpxname(UTMPX_FILE); utmpbegin = ut; utmpend = (struct utmpx *)((char *)utmpbegin + size); setutxent(); while ((ut < utmpend) && ((utp = getutxent()) != NULL)) (void) memcpy(ut++, utp, sizeof (*ut)); endutxent(); (void) time(&now); /* get current time */ if (header) { /* print a header */ prtat(&now); for (ut = utmpbegin; ut < utmpend; ut++) { if (ut->ut_type == USER_PROCESS) { if (!nonuserx(*ut)) nusers++; } else if (ut->ut_type == BOOT_TIME) { uptime = now - ut->ut_xtime; uptime += 30; days = uptime / (60*60*24); uptime %= (60*60*24); hrs = uptime / (60*60); uptime %= (60*60); mins = uptime / 60; PRINTF((gettext("up"))); if (days > 0) PRINTF((gettext( " %d day(s),"), days)); if (hrs > 0 && mins > 0) { PRINTF((" %2d:%02d,", hrs, mins)); } else { if (hrs > 0) PRINTF((gettext( " %d hr(s),"), hrs)); if (mins > 0) PRINTF((gettext( " %d min(s),"), mins)); } } } ut = utmpbegin; /* rewind utmp data */ PRINTF((((nusers == 1) ? gettext(" %d user") : gettext(" %d users")), nusers)); /* * Print 1, 5, and 15 minute load averages. */ (void) getloadavg(loadavg, 3); PRINTF((gettext(", load average: %.2f, %.2f, %.2f\n"), loadavg[LOADAVG_1MIN], loadavg[LOADAVG_5MIN], loadavg[LOADAVG_15MIN])); if (firstchar == 'u') /* uptime command */ exit(0); if (lflag) { PRINTF((dcgettext(NULL, "User tty " "login@ idle JCPU PCPU what\n", LC_TIME))); } else { PRINTF((dcgettext(NULL, "User tty idle what\n", LC_TIME))); } if (fflush(stdout) == EOF) { perror((gettext("%s: fflush failed\n"), prog)); exit(1); } } /* * loop through /proc, reading info about each process * and build the parent/child tree */ if (!(dirp = opendir(PROCDIR))) { (void) fprintf(stderr, gettext("%s: could not open %s: %s\n"), prog, PROCDIR, strerror(errno)); exit(1); } while ((dp = readdir(dirp)) != NULL) { if (dp->d_name[0] == '.') continue; retry: (void) sprintf(pname, "%s/%s/", PROCDIR, dp->d_name); fname = pname + strlen(pname); (void) strcpy(fname, "psinfo"); if ((procfd = open(pname, O_RDONLY)) < 0) continue; if (read(procfd, &info, sizeof (info)) != sizeof (info)) { int err = errno; (void) close(procfd); if (err == EAGAIN) goto retry; if (err != ENOENT) (void) fprintf(stderr, gettext( "%s: read() failed on %s: %s \n"), prog, pname, strerror(err)); continue; } (void) close(procfd); up = findhash(info.pr_pid); up->p_ttyd = info.pr_ttydev; up->p_state = (info.pr_nlwp == 0? ZOMBIE : RUNNING); up->p_time = 0; up->p_ctime = 0; up->p_igintr = 0; (void) strncpy(up->p_comm, info.pr_fname, sizeof (info.pr_fname)); up->p_args[0] = 0; if (up->p_state != NONE && up->p_state != ZOMBIE) { (void) strcpy(fname, "status"); /* now we need the proc_owner privilege */ (void) __priv_bracket(PRIV_ON); procfd = open(pname, O_RDONLY); /* drop proc_owner privilege after open */ (void) __priv_bracket(PRIV_OFF); if (procfd < 0) continue; if (read(procfd, &statinfo, sizeof (statinfo)) != sizeof (statinfo)) { int err = errno; (void) close(procfd); if (err == EAGAIN) goto retry; if (err != ENOENT) (void) fprintf(stderr, gettext( "%s: read() failed on %s: %s \n"), prog, pname, strerror(err)); continue; } (void) close(procfd); up->p_time = statinfo.pr_utime.tv_sec + statinfo.pr_stime.tv_sec; /* seconds */ up->p_ctime = statinfo.pr_cutime.tv_sec + statinfo.pr_cstime.tv_sec; (void) strcpy(fname, "sigact"); /* now we need the proc_owner privilege */ (void) __priv_bracket(PRIV_ON); procfd = open(pname, O_RDONLY); /* drop proc_owner privilege after open */ (void) __priv_bracket(PRIV_OFF); if (procfd < 0) continue; if (read(procfd, actinfo, sizeof (actinfo)) != sizeof (actinfo)) { int err = errno; (void) close(procfd); if (err == EAGAIN) goto retry; if (err != ENOENT) (void) fprintf(stderr, gettext( "%s: read() failed on %s: %s \n"), prog, pname, strerror(err)); continue; } (void) close(procfd); up->p_igintr = actinfo[SIGINT-1].sa_handler == SIG_IGN && actinfo[SIGQUIT-1].sa_handler == SIG_IGN; /* * Process args. */ up->p_args[0] = 0; clnarglist(info.pr_psargs); (void) strcat(up->p_args, info.pr_psargs); if (up->p_args[0] == 0 || up->p_args[0] == '-' && up->p_args[1] <= ' ' || up->p_args[0] == '?') { (void) strcat(up->p_args, " ("); (void) strcat(up->p_args, up->p_comm); (void) strcat(up->p_args, ")"); } } /* * link pgrp together in case parents go away * Pgrp chain is a single linked list originating * from the pgrp leader to its group member. */ if (info.pr_pgid != info.pr_pid) { /* not pgrp leader */ pgrp = findhash(info.pr_pgid); up->p_pgrpl = pgrp->p_pgrpl; pgrp->p_pgrpl = up; } parent = findhash(info.pr_ppid); /* if this is the new member, link it in */ if (parent->p_upid != INITPROCESS) { if (parent->p_child) { up->p_sibling = parent->p_child; up->p_child = 0; } parent->p_child = up; } } /* revert to non-privileged user after opening */ (void) __priv_relinquish(); (void) closedir(dirp); (void) time(&now); /* get current time */ /* * loop through utmpx file, printing process info * about each logged in user */ for (ut = utmpbegin; ut < utmpend; ut++) { if (ut->ut_type != USER_PROCESS) continue; if (sel_user && strncmp(ut->ut_name, sel_user, NMAX) != 0) continue; /* we're looking for somebody else */ /* print login name of the user */ PRINTF(("%-*.*s ", LOGIN_WIDTH, NMAX, ut->ut_name)); /* print tty user is on */ if (lflag) { PRINTF(("%-*.*s ", LINE_WIDTH, LMAX, ut->ut_line)); } else { if (ut->ut_line[0] == 'p' && ut->ut_line[1] == 't' && ut->ut_line[2] == 's' && ut->ut_line[3] == '/') { PRINTF(("%-*.*s ", LINE_WIDTH, LMAX, &ut->ut_line[4])); } else { PRINTF(("%-*.*s ", LINE_WIDTH, LMAX, ut->ut_line)); } } /* print when the user logged in */ if (lflag) { time_t tim = ut->ut_xtime; prtat(&tim); } /* print idle time */ idle = findidle(ut->ut_line); prttime(idle, 8); showtotals(findhash(ut->ut_pid)); } if (fclose(stdout) == EOF) { perror((gettext("%s: fclose failed"), prog)); exit(1); } return (0); }
static void updateXtmp_unix (TimeInternal oldTime, TimeInternal newTime) { /* Add the old time entry to utmp/wtmp */ /* About as long as the ntpd implementation, but not any less ugly */ #ifdef HAVE_UTMPX_H struct utmpx utx; memset(&utx, 0, sizeof(utx)); strncpy(utx.ut_user, "date", sizeof(utx.ut_user)); #ifndef OTIME_MSG strncpy(utx.ut_line, "|", sizeof(utx.ut_line)); #else strncpy(utx.ut_line, OTIME_MSG, sizeof(utx.ut_line)); #endif /* OTIME_MSG */ #ifdef OLD_TIME utx.ut_tv.tv_sec = oldTime.seconds; utx.ut_tv.tv_usec = oldTime.nanoseconds / 1000; utx.ut_type = OLD_TIME; #else /* no ut_type */ utx.ut_time = oldTime.seconds; #endif /* OLD_TIME */ /* ======== BEGIN OLD TIME EVENT - UTMPX / WTMPX =========== */ #ifdef HAVE_UTMPXNAME utmpxname("/var/log/utmp"); #endif /* HAVE_UTMPXNAME */ setutxent(); pututxline(&utx); endutxent(); #ifdef HAVE_UPDWTMPX updwtmpx("/var/log/wtmp", &utx); #endif /* HAVE_IPDWTMPX */ /* ======== END OLD TIME EVENT - UTMPX / WTMPX =========== */ #else /* NO UTMPX_H */ #ifdef HAVE_UTMP_H struct utmp ut; memset(&ut, 0, sizeof(ut)); strncpy(ut.ut_name, "date", sizeof(ut.ut_name)); #ifndef OTIME_MSG strncpy(ut.ut_line, "|", sizeof(ut.ut_line)); #else strncpy(ut.ut_line, OTIME_MSG, sizeof(ut.ut_line)); #endif /* OTIME_MSG */ #ifdef OLD_TIME #ifdef HAVE_STRUCT_UTMP_UT_TIME ut.ut_time = oldTime.seconds; #else ut.ut_tv.tv_sec = oldTime.seconds; ut.ut_tv.tv_usec = oldTime.nanoseconds / 1000; #endif /* HAVE_STRUCT_UTMP_UT_TIME */ ut.ut_type = OLD_TIME; #else /* no ut_type */ ut.ut_time = oldTime.seconds; #endif /* OLD_TIME */ /* ======== BEGIN OLD TIME EVENT - UTMP / WTMP =========== */ #ifdef HAVE_UTMPNAME utmpname(UTMP_FILE); #endif /* HAVE_UTMPNAME */ #ifdef HAVE_SETUTENT setutent(); #endif /* HAVE_SETUTENT */ #ifdef HAVE_PUTUTLINE pututline(&ut); #endif /* HAVE_PUTUTLINE */ #ifdef HAVE_ENDUTENT endutent(); #endif /* HAVE_ENDUTENT */ #ifdef HAVE_UTMPNAME utmpname(WTMP_FILE); #endif /* HAVE_UTMPNAME */ #ifdef HAVE_SETUTENT setutent(); #endif /* HAVE_SETUTENT */ #ifdef HAVE_PUTUTLINE pututline(&ut); #endif /* HAVE_PUTUTLINE */ #ifdef HAVE_ENDUTENT endutent(); #endif /* HAVE_ENDUTENT */ /* ======== END OLD TIME EVENT - UTMP / WTMP =========== */ #endif /* HAVE_UTMP_H */ #endif /* HAVE_UTMPX_H */ /* Add the new time entry to utmp/wtmp */ #ifdef HAVE_UTMPX_H memset(&utx, 0, sizeof(utx)); strncpy(utx.ut_user, "date", sizeof(utx.ut_user)); #ifndef NTIME_MSG strncpy(utx.ut_line, "{", sizeof(utx.ut_line)); #else strncpy(utx.ut_line, NTIME_MSG, sizeof(utx.ut_line)); #endif /* NTIME_MSG */ #ifdef NEW_TIME utx.ut_tv.tv_sec = newTime.seconds; utx.ut_tv.tv_usec = newTime.nanoseconds / 1000; utx.ut_type = NEW_TIME; #else /* no ut_type */ utx.ut_time = newTime.seconds; #endif /* NEW_TIME */ /* ======== BEGIN NEW TIME EVENT - UTMPX / WTMPX =========== */ #ifdef HAVE_UTMPXNAME utmpxname("/var/log/utmp"); #endif /* HAVE_UTMPXNAME */ setutxent(); pututxline(&utx); endutxent(); #ifdef HAVE_UPDWTMPX updwtmpx("/var/log/wtmp", &utx); #endif /* HAVE_UPDWTMPX */ /* ======== END NEW TIME EVENT - UTMPX / WTMPX =========== */ #else /* NO UTMPX_H */ #ifdef HAVE_UTMP_H memset(&ut, 0, sizeof(ut)); strncpy(ut.ut_name, "date", sizeof(ut.ut_name)); #ifndef NTIME_MSG strncpy(ut.ut_line, "{", sizeof(ut.ut_line)); #else strncpy(ut.ut_line, NTIME_MSG, sizeof(ut.ut_line)); #endif /* NTIME_MSG */ #ifdef NEW_TIME #ifdef HAVE_STRUCT_UTMP_UT_TIME ut.ut_time = newTime.seconds; #else ut.ut_tv.tv_sec = newTime.seconds; ut.ut_tv.tv_usec = newTime.nanoseconds / 1000; #endif /* HAVE_STRUCT_UTMP_UT_TIME */ ut.ut_type = NEW_TIME; #else /* no ut_type */ ut.ut_time = newTime.seconds; #endif /* NEW_TIME */ /* ======== BEGIN NEW TIME EVENT - UTMP / WTMP =========== */ #ifdef HAVE_UTMPNAME utmpname(UTMP_FILE); #endif /* HAVE_UTMPNAME */ #ifdef HAVE_SETUTENT setutent(); #endif /* HAVE_SETUTENT */ #ifdef HAVE_PUTUTLINE pututline(&ut); #endif /* HAVE_PUTUTLINE */ #ifdef HAVE_ENDUTENT endutent(); #endif /* HAVE_ENDUTENT */ #ifdef HAVE_UTMPNAME utmpname(WTMP_FILE); #endif /* HAVE_UTMPNAME */ #ifdef HAVE_SETUTENT setutent(); #endif /* HAVE_SETUTENT */ #ifdef HAVE_PUTUTLINE pututline(&ut); #endif /* HAVE_PUTUTLINE */ #ifdef HAVE_ENDUTENT endutent(); #endif /* HAVE_ENDUTENT */ /* ======== END NEW TIME EVENT - UTMP / WTMP =========== */ #endif /* HAVE_UTMP_H */ #endif /* HAVE_UTMPX_H */ }
int main(int argc, char **argv) { int goerr = 0; /* non-zero indicates cmd error */ int i; int optsw; /* switch for while of getopt() */ (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ #endif (void) textdomain(TEXT_DOMAIN); validtype[USER_PROCESS] = 1; validtype[EMPTY] = 0; stbufp = &stbuf; /* * Strip off path name of this command */ for (i = strlen(argv[0]); i >= 0 && argv[0][i] != '/'; --i); if (i >= 0) argv[0] += i+1; program = argv[0]; /* * Buffer stdout for speed */ setbuf(stdout, outbuf); /* * Retrieve options specified on command line * XCU4 - add -m option */ while ((optsw = getopt(argc, argv, "abdHlmn:pqrstTu")) != EOF) { optcnt++; switch (optsw) { case 'a': optcnt += 7; validtype[BOOT_TIME] = 1; validtype[DEAD_PROCESS] = 1; validtype[LOGIN_PROCESS] = 1; validtype[INIT_PROCESS] = 1; validtype[RUN_LVL] = 1; validtype[OLD_TIME] = 1; validtype[NEW_TIME] = 1; validtype[USER_PROCESS] = 1; #ifdef XPG4 aopt = 1; #endif /* XPG4 */ uopt = 1; Topt = 1; if (!sopt) terse = 0; break; case 'b': validtype[BOOT_TIME] = 1; if (!uopt) validtype[USER_PROCESS] = 0; break; case 'd': validtype[DEAD_PROCESS] = 1; if (!uopt) validtype[USER_PROCESS] = 0; #ifdef XPG4 dopt = 1; #endif /* XPG4 */ break; case 'H': optcnt--; /* Don't count Header */ Hopt = 1; break; case 'l': validtype[LOGIN_PROCESS] = 1; if (!uopt) validtype[USER_PROCESS] = 0; terse = 0; break; case 'm': /* New XCU4 option */ justme = 1; break; case 'n': errno = 0; number = strtol(optarg, &end, 10); if (errno != 0 || *end != '\0') { (void) fprintf(stderr, gettext( "%s: Invalid numeric argument\n"), program); exit(1); } if (number < 1) { (void) fprintf(stderr, gettext( "%s: Number of users per line must " "be at least 1\n"), program); exit(1); } break; case 'p': validtype[INIT_PROCESS] = 1; if (!uopt) validtype[USER_PROCESS] = 0; break; case 'q': qopt = 1; break; case 'r': validtype[RUN_LVL] = 1; terse = 0; if (!uopt) validtype[USER_PROCESS] = 0; break; case 's': sopt = 1; terse = 1; break; case 't': validtype[OLD_TIME] = 1; validtype[NEW_TIME] = 1; if (!uopt) validtype[USER_PROCESS] = 0; break; case 'T': Topt = 1; #ifdef XPG4 terse = 1; /* XPG4 requires -T */ #else /* XPG4 */ terse = 0; #endif /* XPG4 */ break; case 'u': uopt = 1; validtype[USER_PROCESS] = 1; if (!sopt) terse = 0; break; case '?': goerr++; break; default: break; } } #ifdef XPG4 /* * XCU4 changes - check for illegal sopt, Topt & aopt combination */ if (sopt == 1) { terse = 1; if (Topt == 1 || aopt == 1) goerr++; } #endif /* XPG4 */ if (goerr > 0) { #ifdef XPG4 /* * XCU4 - slightly different usage with -s -a & -T */ (void) fprintf(stderr, gettext("\nUsage:\t%s"), program); (void) fprintf(stderr, gettext(" -s [-bdHlmpqrtu] [utmpx_like_file]\n")); (void) fprintf(stderr, gettext( "\t%s [-abdHlmpqrtTu] [utmpx_like_file]\n"), program); #else /* XPG4 */ (void) fprintf(stderr, gettext( "\nUsage:\t%s [-abdHlmpqrstTu] [utmpx_like_file]\n"), program); #endif /* XPG4 */ (void) fprintf(stderr, gettext("\t%s -q [-n x] [utmpx_like_file]\n"), program); (void) fprintf(stderr, gettext("\t%s [am i]\n"), program); /* * XCU4 changes - be explicit with "am i" options */ (void) fprintf(stderr, gettext("\t%s [am I]\n"), program); (void) fprintf(stderr, gettext( "a\tall (bdlprtu options)\n")); (void) fprintf(stderr, gettext("b\tboot time\n")); (void) fprintf(stderr, gettext("d\tdead processes\n")); (void) fprintf(stderr, gettext("H\tprint header\n")); (void) fprintf(stderr, gettext("l\tlogin processes\n")); (void) fprintf(stderr, gettext( "n #\tspecify number of users per line for -q\n")); (void) fprintf(stderr, gettext("p\tprocesses other than getty or users\n")); (void) fprintf(stderr, gettext("q\tquick %s\n"), program); (void) fprintf(stderr, gettext("r\trun level\n")); (void) fprintf(stderr, gettext( "s\tshort form of %s (no time since last output or pid)\n"), program); (void) fprintf(stderr, gettext("t\ttime changes\n")); (void) fprintf(stderr, gettext( "T\tstatus of tty (+ writable, - not writable, " "? hung)\n")); (void) fprintf(stderr, gettext("u\tuseful information\n")); (void) fprintf(stderr, gettext("m\tinformation only about current terminal\n")); (void) fprintf(stderr, gettext( "am i\tinformation about current terminal " "(same as -m)\n")); (void) fprintf(stderr, gettext( "am I\tinformation about current terminal " "(same as -m)\n")); exit(1); } /* * XCU4: If -q option ignore all other options */ if (qopt == 1) { Hopt = 0; sopt = 0; Topt = 0; uopt = 0; justme = 0; validtype[ACCOUNTING] = 0; validtype[BOOT_TIME] = 0; validtype[DEAD_PROCESS] = 0; validtype[LOGIN_PROCESS] = 0; validtype[INIT_PROCESS] = 0; validtype[RUN_LVL] = 0; validtype[OLD_TIME] = 0; validtype[NEW_TIME] = 0; validtype[USER_PROCESS] = 1; } if (argc == optind + 1) { optcnt++; ck_file(argv[optind]); (void) utmpxname(argv[optind]); } /* * Test for 'who am i' or 'who am I' * XCU4 - check if justme was already set by -m option */ if (justme == 1 || (argc == 3 && strcmp(argv[1], "am") == 0 && ((argv[2][0] == 'i' || argv[2][0] == 'I') && argv[2][1] == '\0'))) { justme = 1; myname = nameval; (void) cuserid(myname); if ((mytty = ttyname(fileno(stdin))) == NULL && (mytty = ttyname(fileno(stdout))) == NULL && (mytty = ttyname(fileno(stderr))) == NULL) { (void) fprintf(stderr, gettext( "Must be attached to terminal for 'am I' option\n")); (void) fflush(stderr); exit(1); } else mytty += 5; /* bump past "/dev/" */ } if (!terse) { if (Hopt) (void) printf(gettext( "NAME LINE TIME IDLE PID COMMENTS\n")); timnow = time(0); if ((fildes = open("/etc/inittab", O_NONBLOCK|O_RDONLY)) == -1) { (void) snprintf(errmsg, sizeof (errmsg), gettext("%s: Cannot open /etc/inittab"), program); perror(errmsg); exit(errno); } if (fstat(fildes, stbufp) == -1) { (void) snprintf(errmsg, sizeof (errmsg), gettext("%s: Cannot stat /etc/inittab"), program); perror(errmsg); exit(errno); } if ((inittab = malloc(stbufp->st_size + 1)) == NULL) { (void) snprintf(errmsg, sizeof (errmsg), gettext("%s: Cannot allocate %ld bytes"), program, stbufp->st_size); perror(errmsg); exit(errno); } if (read(fildes, inittab, stbufp->st_size) != stbufp->st_size) { (void) snprintf(errmsg, sizeof (errmsg), gettext("%s: Error reading /etc/inittab"), program); perror(errmsg); exit(errno); } inittab[stbufp->st_size] = '\0'; iinit = inittab; } else { if (Hopt) { #ifdef XPG4 if (dopt) { (void) printf(gettext( "NAME LINE TIME COMMENTS\n")); } else { (void) printf( gettext("NAME LINE TIME\n")); } #else /* XPG4 */ (void) printf( gettext("NAME LINE TIME\n")); #endif /* XPG4 */ } } process(); /* * 'who -q' requires EOL upon exit, * followed by total line */ if (qopt) (void) printf(gettext("\n# users=%d\n"), totlusrs); return (0); }
void KPty::logout() { #ifdef HAVE_UTEMPTER Q_D(KPty); removeLineFromUtmp(d->ttyName, d->masterFd); #else Q_D(KPty); const char *str_ptr = d->ttyName.data(); if (!memcmp(str_ptr, "/dev/", 5)) { str_ptr += 5; } # ifdef __GLIBC__ else { const char * sl_ptr = strrchr(str_ptr, '/'); if (sl_ptr) { str_ptr = sl_ptr + 1; } } # endif # ifdef HAVE_LOGIN # ifdef HAVE_LOGINX ::logoutx(str_ptr, 0, DEAD_PROCESS); # else ::logout(str_ptr); # endif # else # ifdef HAVE_UTMPX struct utmpx l_struct, *ut; # else struct utmp l_struct, *ut; # endif memset(&l_struct, 0, sizeof(l_struct)); strncpy(l_struct.ut_line, str_ptr, sizeof(l_struct.ut_line)); # ifdef HAVE_UTMPX utmpxname(_PATH_UTMPX); setutxent(); if ((ut = getutxline(&l_struct))) { # else utmpname(_PATH_UTMP); setutent(); if ((ut = getutline(&l_struct))) { # endif memset(ut->ut_name, 0, sizeof(*ut->ut_name)); memset(ut->ut_host, 0, sizeof(*ut->ut_host)); # ifdef HAVE_STRUCT_UTMP_UT_SYSLEN ut->ut_syslen = 0; # endif # ifdef HAVE_STRUCT_UTMP_UT_TYPE ut->ut_type = DEAD_PROCESS; # endif # ifdef HAVE_UTMPX gettimeofday(&ut->ut_tv, 0); pututxline(ut); } endutxent(); # else ut->ut_time = time(0); pututline(ut); } endutent(); # endif # endif #endif }
void KPty::login(const char * user, const char * remotehost) { #ifdef HAVE_UTEMPTER Q_D(KPty); addToUtmp(d->ttyName, remotehost, d->masterFd); Q_UNUSED(user); #else # ifdef HAVE_UTMPX struct utmpx l_struct; # else struct utmp l_struct; # endif memset(&l_struct, 0, sizeof(l_struct)); // note: strncpy without terminators _is_ correct here. man 4 utmp if (user) { strncpy(l_struct.ut_name, user, sizeof(l_struct.ut_name)); } if (remotehost) { strncpy(l_struct.ut_host, remotehost, sizeof(l_struct.ut_host)); # ifdef HAVE_STRUCT_UTMP_UT_SYSLEN l_struct.ut_syslen = qMin(strlen(remotehost), sizeof(l_struct.ut_host)); # endif } # ifndef __GLIBC__ Q_D(KPty); const char * str_ptr = d->ttyName.data(); if (!memcmp(str_ptr, "/dev/", 5)) { str_ptr += 5; } strncpy(l_struct.ut_line, str_ptr, sizeof(l_struct.ut_line)); # ifdef HAVE_STRUCT_UTMP_UT_ID strncpy(l_struct.ut_id, str_ptr + strlen(str_ptr) - sizeof(l_struct.ut_id), sizeof(l_struct.ut_id)); # endif # endif # ifdef HAVE_UTMPX gettimeofday(&l_struct.ut_tv, 0); # else l_struct.ut_time = time(0); # endif # ifdef HAVE_LOGIN # ifdef HAVE_LOGINX ::loginx(&l_struct); # else ::login(&l_struct); # endif # else # ifdef HAVE_STRUCT_UTMP_UT_TYPE l_struct.ut_type = USER_PROCESS; # endif # ifdef HAVE_STRUCT_UTMP_UT_PID l_struct.ut_pid = getpid(); # ifdef HAVE_STRUCT_UTMP_UT_SESSION l_struct.ut_session = getsid(0); # endif # endif # ifdef HAVE_UTMPX utmpxname(_PATH_UTMPX); setutxent(); pututxline(&l_struct); endutxent(); # ifdef HAVE_UPDWTMPX updwtmpx(_PATH_WTMPX, &l_struct); # endif # else utmpname(_PATH_UTMP); setutent(); pututline(&l_struct); endutent(); updwtmp(_PATH_WTMP, &l_struct); # endif # endif #endif }
void servo_perform_clock_step(RunTimeOpts * rtOpts, PtpClock * ptpClock) { if(rtOpts->noAdjust){ WARNING("Could not step clock - clock adjustment disabled\n"); return; } TimeInternal oldTime, newTime; /*No need to reset the frequency offset: if we're far off, it will quickly get back to a high value */ getTime(&oldTime); subTime(&newTime, &oldTime, &ptpClock->offsetFromMaster); setTime(&newTime); #ifdef HAVE_LINUX_RTC_H if(rtOpts->setRtc) { setRtc(&newTime); } #endif /* HAVE_LINUX_RTC_H */ initClock(rtOpts, ptpClock); #ifdef HAVE_SYS_TIMEX_H if(ptpClock->clockQuality.clockClass > 127) restoreDrift(ptpClock, rtOpts, TRUE); #endif /* HAVE_SYS_TIMEX_H */ ptpClock->servo.runningMaxOutput = FALSE; toState(PTP_FAULTY, rtOpts, ptpClock); /* make a full protocol reset */ /* Major time change - need to inform utmp / wtmp */ if(oldTime.seconds != newTime.seconds) { /* Add the old time entry to utmp/wtmp */ /* About as long as the ntpd implementation, but not any less ugly */ #ifdef HAVE_UTMPX_H struct utmpx utx; memset(&utx, 0, sizeof(utx)); strncpy(utx.ut_user, "date", sizeof(utx.ut_user)); #ifndef OTIME_MSG strncpy(utx.ut_line, "|", sizeof(utx.ut_line)); #else strncpy(utx.ut_line, OTIME_MSG, sizeof(utx.ut_line)); #endif /* OTIME_MSG */ #ifdef OLD_TIME utx.ut_tv.tv_sec = oldTime.seconds; utx.ut_tv.tv_usec = oldTime.nanoseconds / 1000; utx.ut_type = OLD_TIME; #else /* no ut_type */ utx.ut_time = oldTime.seconds; #endif /* OLD_TIME */ /* ======== BEGIN OLD TIME EVENT - UTMPX / WTMPX =========== */ #ifdef HAVE_UTMPXNAME utmpxname("/var/log/utmp"); #endif /* HAVE_UTMPXNAME */ setutxent(); pututxline(&utx); endutxent(); #ifdef HAVE_UPDWTMPX updwtmpx("/var/log/wtmp", &utx); #endif /* HAVE_IPDWTMPX */ /* ======== END OLD TIME EVENT - UTMPX / WTMPX =========== */ #else /* NO UTMPX_H */ #ifdef HAVE_UTMP_H struct utmp ut; memset(&ut, 0, sizeof(ut)); strncpy(ut.ut_name, "date", sizeof(ut.ut_name)); #ifndef OTIME_MSG strncpy(ut.ut_line, "|", sizeof(ut.ut_line)); #else strncpy(ut.ut_line, OTIME_MSG, sizeof(ut.ut_line)); #endif /* OTIME_MSG */ #ifdef OLD_TIME ut.ut_tv.tv_sec = oldTime.seconds; ut.ut_tv.tv_usec = oldTime.nanoseconds / 1000; ut.ut_type = OLD_TIME; #else /* no ut_type */ ut.ut_time = oldTime.seconds; #endif /* OLD_TIME */ /* ======== BEGIN OLD TIME EVENT - UTMP / WTMP =========== */ #ifdef HAVE_UTMPNAME utmpname(UTMP_FILE); #endif /* HAVE_UTMPNAME */ #ifdef HAVE_SETUTENT setutent(); #endif /* HAVE_SETUTENT */ #ifdef HAVE_PUTUTLINE pututline(&ut); #endif /* HAVE_PUTUTLINE */ #ifdef HAVE_ENDUTENT endutent(); #endif /* HAVE_ENDUTENT */ #ifdef HAVE_UTMPNAME utmpname(WTMP_FILE); #endif /* HAVE_UTMPNAME */ #ifdef HAVE_SETUTENT setutent(); #endif /* HAVE_SETUTENT */ #ifdef HAVE_PUTUTLINE pututline(&ut); #endif /* HAVE_PUTUTLINE */ #ifdef HAVE_ENDUTENT endutent(); #endif /* HAVE_ENDUTENT */ /* ======== END OLD TIME EVENT - UTMP / WTMP =========== */ #endif /* HAVE_UTMP_H */ #endif /* HAVE_UTMPX_H */ /* Add the new time entry to utmp/wtmp */ #ifdef HAVE_UTMPX_H memset(&utx, 0, sizeof(utx)); strncpy(utx.ut_user, "date", sizeof(utx.ut_user)); #ifndef NTIME_MSG strncpy(utx.ut_line, "}", sizeof(utx.ut_line)); #else strncpy(utx.ut_line, NTIME_MSG, sizeof(utx.ut_line)); #endif /* NTIME_MSG */ #ifdef NEW_TIME utx.ut_tv.tv_sec = newTime.seconds; utx.ut_tv.tv_usec = newTime.nanoseconds / 1000; utx.ut_type = NEW_TIME; #else /* no ut_type */ utx.ut_time = newTime.seconds; #endif /* NEW_TIME */ /* ======== BEGIN NEW TIME EVENT - UTMPX / WTMPX =========== */ #ifdef HAVE_UTMPXNAME utmpxname("/var/log/utmp"); #endif /* HAVE_UTMPXNAME */ setutxent(); pututxline(&utx); endutxent(); #ifdef HAVE_UPDWTMPX updwtmpx("/var/log/wtmp", &utx); #endif /* HAVE_UPDWTMPX */ /* ======== END NEW TIME EVENT - UTMPX / WTMPX =========== */ #else /* NO UTMPX_H */ #ifdef HAVE_UTMP_H memset(&ut, 0, sizeof(ut)); strncpy(ut.ut_name, "date", sizeof(ut.ut_name)); #ifndef NTIME_MSG strncpy(ut.ut_line, "}", sizeof(ut.ut_line)); #else strncpy(ut.ut_line, NTIME_MSG, sizeof(ut.ut_line)); #endif /* NTIME_MSG */ #ifdef NEW_TIME ut.ut_tv.tv_sec = newTime.seconds; ut.ut_tv.tv_usec = newTime.nanoseconds / 1000; ut.ut_type = NEW_TIME; #else /* no ut_type */ ut.ut_time = newTime.seconds; #endif /* NEW_TIME */ /* ======== BEGIN NEW TIME EVENT - UTMP / WTMP =========== */ #ifdef HAVE_UTMPNAME utmpname(UTMP_FILE); #endif /* HAVE_UTMPNAME */ #ifdef HAVE_SETUTENT setutent(); #endif /* HAVE_SETUTENT */ #ifdef HAVE_PUTUTLINE pututline(&ut); #endif /* HAVE_PUTUTLINE */ #ifdef HAVE_ENDUTENT endutent(); #endif /* HAVE_ENDUTENT */ #ifdef HAVE_UTMPNAME utmpname(WTMP_FILE); #endif /* HAVE_UTMPNAME */ #ifdef HAVE_SETUTENT setutent(); #endif /* HAVE_SETUTENT */ #ifdef HAVE_PUTUTLINE pututline(&ut); #endif /* HAVE_PUTUTLINE */ #ifdef HAVE_ENDUTENT endutent(); #endif /* HAVE_ENDUTENT */ /* ======== END NEW TIME EVENT - UTMP / WTMP =========== */ #endif /* HAVE_UTMP_H */ #endif /* HAVE_UTMPX_H */ } }
int main(int argc, char **argv) { int c; int all, is_utmpx, do_getut; int f; char *fn; size_t recsize; size_t nread; union { struct utmp ut; #ifdef UTMPX struct utmpx utx; #endif } u; all = is_utmpx = do_getut = 0; recsize = sizeof(struct utmp); while ((c = getopt(argc, argv, OPTS)) != EOF) { switch (c) { case 'a': all = 1; break; #ifdef UTMPX case 'x': is_utmpx = 1; recsize = sizeof(struct utmpx); break; #endif #ifdef UTN case 'g': do_getut = 1; break; #endif default: usage(argv[0]); } } if (argc <= optind) usage(argv[0]); fn = argv[optind]; if (!do_getut) { f = open(fn, O_RDONLY); if (f == -1) { perror(fn); exit(1); } while ((nread = read(f, &u, recsize)) > 0) { if (nread < recsize) { fprintf(stderr, "short read"); close(f); exit(1); } if (is_utmpx) { #ifdef UTMPX print_utx(all, &u.utx); #else abort(); #endif } else { print_ut(all, &u.ut); } } if (nread == -1) { perror("read"); exit(1); } close(f); } else { if (is_utmpx) { #ifdef UTMPX #ifdef HAVE_UTMPXNAME struct utmpx *utxp; utmpxname(fn); setutxent(); while ((utxp = getutxent()) != NULL) print_utx(all, utxp); #else fprintf(stderr, "no utmpxname(); can't use getutxent()\n"); exit(1); #endif #else abort(); #endif } else { #ifdef HAVE_UTMPNAME struct utmp *utp; utmpname(fn); setutxent(); while ((utp = getutent()) != NULL) print_ut(all, utp); #else fprintf(stderr, "no utmpname(); can't use getutent()\n"); exit(1); #endif } } exit(0); }
/* * 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 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; }