static void check_cygwin_console(void) { char *term = getenv("TERM"); HANDLE hWnd; if (term == NULL) term = DEFAULT_TERM; if (term && strncmp(term, "cygwin", 6) == 0) { isWinConsole = TERM_CYGWIN; } if (isWinConsole) { hWnd = GetConsoleHwnd(); if (hWnd != INVALID_HANDLE_VALUE) { if (IsWindowVisible(hWnd)) { isLocalConsole = 1; } } if (strncmp(getenv("LANG"), "ja", 2) == 0) { isWinConsole = TERM_CYGWIN_RESERVE_IME; } #ifdef SUPPORT_WIN9X_CONSOLE_MBCS check_win9x(); if (isWin95 && ttyslot() != -1) { isLocalConsole = 0; } #endif } #if CYGWIN_VERSION_DLL_MAJOR < 1005 && defined(USE_MOUSE) if (cygwin_version() <= 1003015) { /* cygwin DLL 1.3.15 or earler */ cygwin_mouse_btn_swapped = 1; } #endif }
void utmp_login(char *tty, const char *username, const char *hostname) { struct utmp utmp; int fd; prepare_utmp (&utmp, tty, username, hostname); #ifdef HAVE_SETUTENT utmpname(_PATH_UTMP); setutent(); pututline(&utmp); endutent(); #else #ifdef HAVE_TTYSLOT { int ttyno; ttyno = ttyslot(); if (ttyno > 0 && (fd = open(_PATH_UTMP, O_WRONLY, 0)) >= 0) { lseek(fd, (long)(ttyno * sizeof(struct utmp)), SEEK_SET); write(fd, &utmp, sizeof(struct utmp)); close(fd); } } #endif /* HAVE_TTYSLOT */ #endif /* HAVE_SETUTENT */ if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) { write(fd, &utmp, sizeof(struct utmp)); close(fd); } }
/* This is a slightly modification of code in OpenBSD's login.c */ static int utmp_write_direct(struct logininfo *li, struct utmp *ut) { return 1; #if 0 struct utmp old_ut; register int fd; int tty; /* FIXME: (ATL) ttyslot() needs local implementation */ #if defined(HAVE_GETTTYENT) register struct ttyent *ty; tty=0; setttyent(); while ((struct ttyent *)0 != (ty = getttyent())) { tty++; if (!strncmp(ty->ty_name, ut->ut_line, sizeof(ut->ut_line))) break; } endttyent(); if((struct ttyent *)0 == ty) { dropbear_log(LOG_WARNING, "utmp_write_entry: tty not found"); return(1); } #else /* FIXME */ tty = ttyslot(); /* seems only to work for /dev/ttyp? style names */ #endif /* HAVE_GETTTYENT */ if (tty > 0 && (fd = open(UTMP_FILE, O_RDWR|O_CREAT, 0644)) >= 0) { (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); /* * Prevent luser from zero'ing out ut_host. * If the new ut_line is empty but the old one is not * and ut_line and ut_name match, preserve the old ut_line. */ if (atomicio(read, fd, &old_ut, sizeof(old_ut)) == sizeof(old_ut) && (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') && (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) && (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) { (void)memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); } (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); if (atomicio(write, fd, ut, sizeof(*ut)) != sizeof(*ut)) dropbear_log(LOG_WARNING, "utmp_write_direct: error writing %s: %s", UTMP_FILE, strerror(errno)); (void)close(fd); return 1; } else { return 0; } #endif }
void login(struct utmp *utp) { struct utmp old_ut; register int fd; int tty; tty = ttyslot(); if (tty > 0 && (fd = open(_PATH_UTMP, O_RDWR|O_CREAT, 0644)) >= 0) { (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); /* * Prevent luser from zero'ing out ut_host. * If the new ut_line is empty but the old one is not * and ut_line and ut_name match, preserve the old ut_line. */ if (read(fd, &old_ut, sizeof(struct utmp)) == sizeof(struct utmp) && utp->ut_host[0] == '\0' && old_ut.ut_host[0] != '\0' && strncmp(old_ut.ut_line, utp->ut_line, UT_LINESIZE) == 0 && strncmp(old_ut.ut_name, utp->ut_name, UT_NAMESIZE) == 0) (void)memcpy(utp->ut_host, old_ut.ut_host, UT_HOSTSIZE); (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); (void)write(fd, utp, sizeof(struct utmp)); (void)close(fd); } if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) { (void)write(fd, utp, sizeof(struct utmp)); (void)close(fd); } }
/* * Common function */ static char * getl_r_common(char *answer, size_t namelen, size_t maxlen) { int uf; off64_t me; struct futmpx ubuf; if ((me = (off64_t)ttyslot()) < 0) return (NULL); if ((uf = open64(UTMPX_FILE, 0)) < 0) return (NULL); (void) lseek64(uf, me * sizeof (ubuf), SEEK_SET); if (read(uf, &ubuf, sizeof (ubuf)) != sizeof (ubuf)) { (void) close(uf); return (NULL); } (void) close(uf); if (ubuf.ut_user[0] == '\0') return (NULL); /* Insufficient buffer size */ if (namelen < strnlen(&ubuf.ut_user[0], maxlen)) { errno = ERANGE; return (NULL); } (void) strncpy(&answer[0], &ubuf.ut_user[0], maxlen); answer[maxlen] = '\0'; return (&answer[0]); }
static int s_shell_fd_init(t_sh *sh) { int fd; char *tty_name; fd = -1; if (sh->is_interactive == true) { if ((tty_name = ttyname(STDIN_FILENO)) == NULL) { log_error("ttyname() failed"); return (ST_TTYNAME); } if ((fd = open(tty_name, O_RDWR)) == -1) { log_error("open() failed"); return (ST_OPEN); } log_info("ttyname: %s, ttyslot: %d", tty_name, ttyslot()); } else fd = STDIN_FILENO; sh->fd = fd; log_info("is_interactive ? %s fd: %d", sh->is_interactive ? "true" : "false", fd); return (ST_OK); }
int main(int argc, char **argv) { FT_INIT(int, nb_loop, 0); int i; char *name; int is_term; struct termios *termios_p; i = ttyslot(); printf("fd shell =%d,\n", i); is_term = isatty(i); printf("is_term? =%d,\n", is_term); name = ttyname(i); printf("term_name =%s,\n", name); while (argv[nb_loop]) nb_loop++; return (0); }
static int open_tty(void) { int fd; if ((fd = ttyslot()) == -1) ft_error(TTYSLOT); if (isatty(fd) == 0) ft_error(NOTATTY); return (fd); }
int main(int argc, char **argv) { char *tmp= PATH_UTMP; FILE *f; struct utmp ut; struct tm *tm; int slot, wtmp= 0, once= 0; if (argc > 3) { fprintf(stderr, "Usage: who <account-file> | who am i\n"); exit(1); } if (argc == 2) { tmp= argv[1]; wtmp= 1; } if ((f= fopen(tmp, "r")) == nil) { fprintf(stderr, "who: can't open %s\n", tmp); exit(1); } if (argc == 3) { if ((slot= ttyslot()) < 0) { fprintf(stderr, "who: no access to terminal.\n"); exit(1); } fseek(f, (off_t) sizeof(ut) * slot, 0); once= 1; } while (fread((char *) &ut, sizeof(ut), 1, f) == 1) { if (!wtmp && ut.ut_name[0] == 0) continue; tm= localtime(&ut.ut_time); printf("%-9.8s %-9.8s %.3s %.3s %2d %02d:%02d", ut.ut_name, ut.ut_line, day + (3 * tm->tm_wday), month + (3 * tm->tm_mon), tm->tm_mday, tm->tm_hour, tm->tm_min ); if (ut.ut_host[0] != 0) printf(" (%.*s)", (int) sizeof(ut.ut_host), ut.ut_host); printf("\n"); if (once) break; } exit(0); }
char * getlogin() { register me, uf; register char *cp; if( !(me = ttyslot()) ) return(0); if( (uf = open( UTMP, 0 )) < 0 ) return(0); lseek( uf, (long)(me*sizeof(ubuf)), 0 ); if (read(uf, (char *)&ubuf, sizeof(ubuf)) != sizeof(ubuf)) return(0); close(uf); ubuf.ut_name[8] = ' '; for (cp=ubuf.ut_name; *cp++!=' ';) ; *--cp = '\0'; return( ubuf.ut_name ); }
/* * Write a utmp entry direct to the file * This is a slightly modification of code in OpenBSD's login.c */ static int utmp_write_direct(struct logininfo *li, struct utmp *ut) { struct utmp old_ut; register int fd; int tty; /* FIXME: (ATL) ttyslot() needs local implementation */ #if defined(HAVE_GETTTYENT) struct ttyent *ty; tty=0; setttyent(); while (NULL != (ty = getttyent())) { tty++; if (!strncmp(ty->ty_name, ut->ut_line, sizeof(ut->ut_line))) break; } endttyent(); if (NULL == ty) { logit("%s: tty not found", __func__); return (0); } #else /* FIXME */ tty = ttyslot(); /* seems only to work for /dev/ttyp? style names */ #endif /* HAVE_GETTTYENT */ if (tty > 0 && (fd = open(UTMP_FILE, O_RDWR|O_CREAT, 0644)) >= 0) { off_t pos, ret; pos = (off_t)tty * sizeof(struct utmp); if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { logit("%s: lseek: %s", __func__, strerror(errno)); return (0); } if (ret != pos) { logit("%s: Couldn't seek to tty %d slot in %s", __func__, tty, UTMP_FILE); return (0); } /* * Prevent luser from zero'ing out ut_host. * If the new ut_line is empty but the old one is not * and ut_line and ut_name match, preserve the old ut_line. */ if (atomicio(read, fd, &old_ut, sizeof(old_ut)) == sizeof(old_ut) && (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') && (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) && (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { logit("%s: lseek: %s", __func__, strerror(errno)); return (0); } if (ret != pos) { logit("%s: Couldn't seek to tty %d slot in %s", __func__, tty, UTMP_FILE); return (0); } if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) { logit("%s: error writing %s: %s", __func__, UTMP_FILE, strerror(errno)); } close(fd); return (1); } else { return (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 }
void setutmp(const char *name, const char *line) { struct utmp utmp; int fd; int found = 0; if ((fd = open(_UTMP_FILE, O_RDWR)) < 0) return; #if !defined(SUN) && !defined(BSD) && !defined(SUN4) /* XXX */ while (!found && read(fd, (char *)&utmp, sizeof utmp) == sizeof utmp) { if (! strncmp (line, utmp.ut_line, (int) sizeof utmp.ut_line)) found++; } #endif if (! found) { /* * This is a brand-new entry. Clear it out and fill it in * later. */ memzero(&utmp, sizeof utmp); strncpy(utmp.ut_line, line, (int) sizeof utmp.ut_line); } /* * Fill in the parts of the UTMP entry. BSD has just the name, * while System V has the name, PID and a type. */ strncpy(utmp.ut_user, name, sizeof utent.ut_user); #ifdef USER_PROCESS utmp.ut_type = USER_PROCESS; utmp.ut_pid = getpid (); #endif /* * Put in the current time (common to everyone) */ (void) time (&utmp.ut_time); #ifdef UT_HOST /* * Update the host name field for systems with networking support */ (void) strncpy (utmp.ut_host, utent.ut_host, (int) sizeof utmp.ut_host); #endif /* * Locate the correct position in the UTMP file for this * entry. */ #ifdef HAVE_TTYSLOT (void) lseek (fd, (off_t) (sizeof utmp) * ttyslot (), SEEK_SET); #else if (found) /* Back up a splot */ lseek (fd, (off_t) - sizeof utmp, SEEK_CUR); else /* Otherwise, go to the end of the file */ lseek (fd, (off_t) 0, SEEK_END); #endif /* * Scribble out the new entry and close the file. We're done * with UTMP, next we do WTMP (which is real easy, put it on * the end of the file. */ (void) write (fd, (char *) &utmp, sizeof utmp); (void) close (fd); updwtmp(_WTMP_FILE, &utmp); utent = utmp; }
int main(int argc, char **argv) { char *namep; int pflag = 0, hflag = 0, t, f, c; int invalid, quietlog; FILE *nlfd; char *ttyn, *tty; int ldisc = 0, zero = 0, i; char **envnew; #ifdef AFS_AIX32_ENV /* * The following signal action for AIX is necessary so that in case of a * crash (i.e. core is generated) we can include the user's data section * in the core dump. Unfortunately, by default, only a partial core is * generated which, in many cases, isn't too useful. */ struct sigaction nsa; sigemptyset(&nsa.sa_mask); nsa.sa_handler = SIG_DFL; nsa.sa_flags = SA_FULLDUMP; sigaction(SIGSEGV, &nsa, NULL); #endif signal(SIGALRM, timedout); alarm(timeout); signal(SIGQUIT, SIG_IGN); signal(SIGINT, SIG_IGN); setpriority(PRIO_PROCESS, 0, 0); quota(Q_SETUID, 0, 0, 0); /* create a dummy user */ memset(&nouser, 0, sizeof(nouser)); nouser.pw_name = ""; nouser.pw_passwd = "*"; nouser.pw_dir = nouser.pw_shell = ""; nouser.pw_uid = nouser.pw_gid = -1; /* * -p is used by getty to tell login not to destroy the environment * -r is used by rlogind to cause the autologin protocol; * -h is used by other servers to pass the name of the * remote host to login so that it may be placed in utmp and wtmp */ while (argc > 1) { if (strcmp(argv[1], "-r") == 0) { if (rflag || hflag) { printf("Only one of -r and -h allowed\n"); exit(1); } rflag = 1; usererr = doremotelogin(argv[2]); SCPYN(utmp.ut_host, argv[2]); argc -= 2; argv += 2; continue; } if (strcmp(argv[1], "-h") == 0 && getuid() == 0) { if (rflag || hflag) { printf("Only one of -r and -h allowed\n"); exit(1); } hflag = 1; SCPYN(utmp.ut_host, argv[2]); argc -= 2; argv += 2; continue; } if (strcmp(argv[1], "-p") == 0) { argc--; argv++; pflag = 1; continue; } break; } ioctl(0, TIOCLSET, &zero); ioctl(0, TIOCNXCL, 0); ioctl(0, FIONBIO, &zero); ioctl(0, FIOASYNC, &zero); ioctl(0, TIOCGETP, &ttyb); /* * If talking to an rlogin process, * propagate the terminal type and * baud rate across the network. */ if (rflag) doremoteterm(term, &ttyb); ttyb.sg_erase = CERASE; ttyb.sg_kill = CKILL; ioctl(0, TIOCSLTC, <c); ioctl(0, TIOCSETC, &tc); ioctl(0, TIOCSETP, &ttyb); for (t = getdtablesize(); t > 2; t--) close(t); ttyn = ttyname(0); if (ttyn == (char *)0 || *ttyn == '\0') ttyn = "/dev/tty??"; tty = strrchr(ttyn, '/'); if (tty == NULL) tty = ttyn; else tty++; openlog("login", LOG_ODELAY, LOG_AUTH); t = 0; invalid = FALSE; do { ldisc = 0; ioctl(0, TIOCSETD, &ldisc); SCPYN(utmp.ut_name, ""); /* * Name specified, take it. */ if (argc > 1) { SCPYN(utmp.ut_name, argv[1]); argc = 0; } /* * If remote login take given name, * otherwise prompt user for something. */ if (rflag && !invalid) SCPYN(utmp.ut_name, lusername); else getloginname(&utmp); invalid = FALSE; if (!strcmp(pwd->pw_shell, "/bin/csh")) { ldisc = NTTYDISC; ioctl(0, TIOCSETD, &ldisc); } /* * If no remote login authentication and * a password exists for this user, prompt * for one and verify it. */ if (usererr == -1 && *pwd->pw_passwd != '\0') { #ifdef KAUTH char password[BUFSIZ]; char *reason; if (ka_UserReadPassword ("Password:"******"Unable to login because %s,\n", reason); invalid = TRUE; } else if (ka_UserAuthenticate (pwd->pw_name, /*inst */ 0, /*realm */ 0, password, /*sepag */ 1, &reason)) { printf("Unable to authenticate to AFS because %s.\n", reason); printf(" proceeding with local authentication... \n"); /* try local login */ namep = crypt(password, pwd->pw_passwd); if (strcmp(namep, pwd->pw_passwd)) invalid = TRUE; } #else char *pp; setpriority(PRIO_PROCESS, 0, -4); pp = getpass("Password:"******"r")) != 0) { while ((c = getc(nlfd)) != EOF) putchar(c); fflush(stdout); sleep(5); exit(0); } /* * If valid so far and root is logging in, * see if root logins on this terminal are permitted. */ if (!invalid && pwd->pw_uid == 0 && !rootterm(tty)) { if (utmp.ut_host[0]) syslog(LOG_CRIT, "ROOT LOGIN REFUSED ON %s FROM %.*s", tty, HMAX, utmp.ut_host); else syslog(LOG_CRIT, "ROOT LOGIN REFUSED ON %s", tty); invalid = TRUE; } if (invalid) { printf("Login incorrect\n"); if (++t >= 5) { if (utmp.ut_host[0]) syslog(LOG_CRIT, "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s", tty, HMAX, utmp.ut_host, NMAX, utmp.ut_name); else syslog(LOG_CRIT, "REPEATED LOGIN FAILURES ON %s, %.*s", tty, NMAX, utmp.ut_name); ioctl(0, TIOCHPCL, NULL); close(0), close(1), close(2); sleep(10); exit(1); } } if (*pwd->pw_shell == '\0') pwd->pw_shell = "/bin/sh"; if (chdir(pwd->pw_dir) < 0 && !invalid) { if (chdir("/") < 0) { printf("No directory!\n"); invalid = TRUE; } else { printf("No directory! %s\n", "Logging in with home=/"); pwd->pw_dir = "/"; } } /* * Remote login invalid must have been because * of a restriction of some sort, no extra chances. */ if (!usererr && invalid) exit(1); } while (invalid); /* committed to login turn off timeout */ alarm(0); if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) { if (errno == EUSERS) printf("%s.\n%s.\n", "Too many users logged on already", "Try again later"); else if (errno == EPROCLIM) printf("You have too many processes running.\n"); else perror("quota (Q_SETUID)"); sleep(5); exit(0); } time(&utmp.ut_time); t = ttyslot(); if (t > 0 && (f = open("/etc/utmp", O_WRONLY)) >= 0) { lseek(f, (afs_int32) (t * sizeof(utmp)), 0); SCPYN(utmp.ut_line, tty); write(f, (char *)&utmp, sizeof(utmp)); close(f); } if ((f = open("/usr/adm/wtmp", O_WRONLY | O_APPEND)) >= 0) { write(f, (char *)&utmp, sizeof(utmp)); close(f); } quietlog = access(qlog, F_OK) == 0; if ((f = open(lastlog, O_RDWR)) >= 0) { struct lastlog ll; lseek(f, (afs_int32) pwd->pw_uid * sizeof(struct lastlog), 0); if (read(f, (char *)&ll, sizeof ll) == sizeof ll && ll.ll_time != 0 && !quietlog) { printf("Last login: %.*s ", 24 - 5, (char *)ctime(&ll.ll_time)); if (*ll.ll_host != '\0') printf("from %.*s\n", sizeof(ll.ll_host), ll.ll_host); else printf("on %.*s\n", sizeof(ll.ll_line), ll.ll_line); } lseek(f, (afs_int32) pwd->pw_uid * sizeof(struct lastlog), 0); time(&ll.ll_time); SCPYN(ll.ll_line, tty); SCPYN(ll.ll_host, utmp.ut_host); write(f, (char *)&ll, sizeof ll); close(f); } chown(ttyn, pwd->pw_uid, TTYGID(pwd->pw_gid)); if (!hflag && !rflag) /* XXX */ ioctl(0, TIOCSWINSZ, &win); chmod(ttyn, 0620); setgid(pwd->pw_gid); strncpy(name, utmp.ut_name, NMAX); name[NMAX] = '\0'; initgroups(name, pwd->pw_gid); quota(Q_DOWARN, pwd->pw_uid, (dev_t) - 1, 0); setuid(pwd->pw_uid); /* destroy environment unless user has asked to preserve it */ if (!pflag) environ = envinit; /* set up environment, this time without destruction */ /* copy the environment before setenving */ i = 0; while (environ[i] != NULL) i++; envnew = (char **)malloc(sizeof(char *) * (i + 1)); for (; i >= 0; i--) envnew[i] = environ[i]; environ = envnew; setenv("HOME=", pwd->pw_dir, 1); setenv("SHELL=", pwd->pw_shell, 1); if (term[0] == '\0') strncpy(term, stypeof(tty), sizeof(term)); setenv("TERM=", term, 0); setenv("USER="******"PATH=", ":/usr/ucb:/bin:/usr/bin", 0); if ((namep = strrchr(pwd->pw_shell, '/')) == NULL) namep = pwd->pw_shell; else namep++; strcat(minusnam, namep); if (tty[sizeof("tty") - 1] == 'd') syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name); if (pwd->pw_uid == 0) if (utmp.ut_host[0]) syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s", tty, HMAX, utmp.ut_host); else syslog(LOG_NOTICE, "ROOT LOGIN %s", tty); if (!quietlog) { struct stat st; showmotd(); strcat(maildir, pwd->pw_name); if (stat(maildir, &st) == 0 && st.st_size != 0) printf("You have %smail.\n", (st.st_mtime > st.st_atime) ? "new " : ""); } signal(SIGALRM, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGINT, SIG_DFL); signal(SIGTSTP, SIG_IGN); execlp(pwd->pw_shell, minusnam, 0); perror(pwd->pw_shell); printf("No shell\n"); exit(0); }
/*************************************************************************** * * Account * * update utmp/wtmp files. ***************************************************************************/ void Account( struct display *d, char *user, char *line, pid_t pid, #if NeedWidePrototypes int type, #else short type, #endif /* NeedWidePrototypes */ waitType exitcode ) { #if !defined(CSRG_BASED) /* we cannot do this on BSD ... */ struct utmp utmp; /* local struct for new entry */ struct utmp *u; /* pointer to entry in utmp file */ int fd; char buf[32]; char* user_str = user ? user : "******"; char* line_str = line ? line : "NULL"; #ifdef __PASSWD_ETC struct rtmp rtmp; struct rtmp *r; int tty_slot; int rtmp_fd; #endif if (d->utmpId == NULL) return; switch (type) { case INIT_PROCESS: strcpy(buf, "INIT_PROCESS"); break; case LOGIN_PROCESS: strcpy(buf, "LOGIN_PROCESS"); break; case USER_PROCESS: strcpy(buf, "USER_PROCESS"); break; case DEAD_PROCESS: strcpy(buf, "DEAD_PROCESS"); break; default: strcpy(buf, "UNKNOWN"); break; } Debug("Account: id=%s, user=%s, line=%s, pid=%d, type=%s\n", d->utmpId, user_str, line_str, pid, buf); #ifdef PAM PamAccounting("dtlogin", d->name, d->utmpId, user, line, pid, type, exitcode); #else # ifdef SUNAUTH solaris_accounting("dtlogin", d->name, d->utmpId, user, line, pid, type, exitcode); # endif #endif #ifdef sun return; #else bzero(&utmp, sizeof(struct utmp)); strncpy(utmp.ut_id, d->utmpId, sizeof(u->ut_id)); utmp.ut_type = LOGIN_PROCESS; setutent(); if ( (u = getutid(&utmp)) == NULL ) u = &utmp; /* * make sure process ID's match if this is DEAD_PROCESS... * don't update an already DEAD_PROCESS... */ if ((type == DEAD_PROCESS && pid != 0 && u->ut_pid != pid) || (type == DEAD_PROCESS && u->ut_type == DEAD_PROCESS) ) { endutent(); return; } /* * fill in required fields of utmp structure... * * Note: for USER_PRCESS the "e_exit" field is overloaded to contain * the method for counting this user. This is used later to * determine if restricted user licenses have been exceeded. * Currently, an unlimited number of foreign displays can log in. */ if (user) strncpy(u->ut_user, user, sizeof(u->ut_user)); if (line) { #ifdef _AIX /* For AIX the Init process writes the exact mapped device name for console to the utmp file (like hft/0), if a getty on /dev/console record exists in the Inittab file.Hitherto, we need to have a similar logic to make sure for having the correct entry in the utmp file in order for the correct operation of the GettyRunning function. It should be noted that by having the correct value in the d->gettyLine field, the utmp file eventuallly updated by the Account function in dm.c will have the right value. And thus the GettyRunning function returns the appropriate value. So, it is important that the following logic be included here for AIX platform only. Raghu Krovvidi 07.06.93 */ if (!strcmp(line,"console")) { char *ttynm; int fd=0; fd = open("/dev/console",O_RDONLY); ttynm = ttyname(fd); ttynm += 5; strcpy(u->ut_line,ttynm); close(fd); } else strncpy(u->ut_line, line, sizeof(u->ut_line)); #else strncpy(u->ut_line, line, sizeof(u->ut_line)); #endif } if (pid ) u->ut_pid = pid; if (type) { u->ut_type = type; if (type == DEAD_PROCESS) { u->ut_exit.e_termination = waitSig(exitcode); u->ut_exit.e_exit = waitCode(exitcode); #ifndef SVR4 (void) memset((char *) u->ut_host, '\0', sizeof(u->ut_host)); #endif } if (type == LOGIN_PROCESS && d->displayType.location != Local ) { #ifndef SVR4 strncpy(u->ut_host, d->name, sizeof(u->ut_host)); #endif #ifdef __hpux u->ut_addr = 0; #endif } if (type == USER_PROCESS) u->ut_exit.e_exit = (d->displayType.location == Local ? 1 : 0 ); } (void) time(&u->ut_time); /* * write to utmp... * * (Do not close utmp yet. If "u" points to the static structure, it is * cleared upon close. This does not bode well for the following write * to wtmp!) */ pututline(u); /* * write the same entry to wtmp... */ if ((fd = open(WTMP_FILE, O_WRONLY | O_APPEND)) >= 0) { write(fd, u, sizeof(utmp)); close(fd); } /* * close utmp... */ endutent(); #ifdef __PASSWD_ETC /* Now fill in the "rgy utmp" struct */ if (line) strncpy(rtmp.rt_line, u->ut_line, sizeof(u->ut_line)); bzero(rtmp.rt_host, sizeof(rtmp.rt_host)); rtmp.rt_time = u->ut_time; r = &rtmp; /* Write entry to rtmp */ tty_slot = ttyslot(); if (tty_slot > 0 && (rtmp_fd = open("/etc/rtmp", O_WRONLY|O_CREAT, 0644)) >= 0) { lseek(rtmp_fd, (long) (tty_slot * sizeof(struct rtmp)), 0); write(rtmp_fd, (char *) r, sizeof(struct rtmp)); close(rtmp_fd); } #endif #if defined(AIXV3) && !defined(_POWER) /* Log the lastlogin data .. RK 09.13.93 */ /** in AIX 4.1 this is taken care of during authentication **/ if(type == USER_PROCESS) { int loginType; char tempTtyName[128]; char *hostname; GetLoginInfo(d, &loginType, tempTtyName, &hostname); time(&last_login.stime); if(line) { Debug("tty_last_login is (line=%s)\n",line); last_login.stty = (char *)malloc(strlen(line) + 1); strcpy(last_login.stty,line); } else { last_login.stty = (char *)malloc(strlen(tempTtyName) + 1); strcpy(last_login.stty,tempTtyName); } last_login.shost = (char *) malloc (MAXHOSTNAMELEN); if (hostname == NULL) { gethostname (last_login.shost , MAXHOSTNAMELEN); } else { strncpy(last_login.shost, hostname, MAXHOSTNAMELEN); last_login.shost[MAXHOSTNAMELEN -1] = '\0'; } Debug("logging lastlogin entry (user=%s)\n",user); dt_lastlogin(user,&last_login); free(last_login.stty); free(last_login.shost); } #endif #endif /* !sun */ #endif /* !CSRG_BASED */ }
/* 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 }
/* Procure an open DS9 window for use with ScopeDesign, check status via XPA */ void *display_ds9_open(void *status){ /* Declare XPA-related variables */ int i,j,got; size_t lens[NXPA]; char *bufs[NXPA], *names[NXPA], *messages[NXPA]; // Needed by XPAGet() /* Declare local function variables */ int stop=0; int wombat=1; extern char *active_ports[NXPA]; extern char *ds9_port; char *extant_ports[NXPA]; char *token,*cp,*save; char command[100]; int nopen,good[NXPA]; bool verbose = true; char *ds9_filename,ds9_title[50]; /* Check for the existance of currently-open DS9 window */ /* Note: the XPAGet() routine searches ONLY for windows owned by the current username... it ignores windows owned by other users of the machine. */ got = XPAGet(NULL, "ds9", "file", NULL, bufs, lens, names, messages, NXPA); nopen = got; /* If active_ports DS9 windows found, get connection information */ if( nopen > 0 ) { printf("*** Found %d extant DS9 window(s) open on this system. ***\n", nopen); display_get_ports(names,nopen,true); // Place port info in active_ports for(i=0;i<nopen;i++){ extant_ports[i] = strdup(active_ports[i]); // Copy list of extant ports /* Free arrays from XPAGet(), otherwise memory fills... */ if( bufs[i] ) free(bufs[i]); if( names[i] ) free(names[i]); if( messages[i] ) free(messages[i]); } } else { /* If no open windows, we're going to need to FORCE_NEW */ *((int *)status) = DS9_FORCE_NEW; } /* =======================================================================*/ /* At this point, port information is in active_ports[k] and loaded */ /* filenames are in bufs[k] */ /* =======================================================================*/ /* Control Loop -- Use input status to determine how to proceed */ do switch(*((int *)status)){ case(DS9_FORCE_NEW): /****************************************************/ /* Open windows be damned, we're opening a new one! */ printf("Opening a new DS9 window for use with ScopeDesign...\n"); /* Create the system command and send forth! */ sprintf(ds9_title,"ScopeDesign_%d",ttyslot()); // Unique! sprintf(command,"%s -title %s -xpa yes &",DS9_PATH,ds9_title); system(command); // Execute the command /* Wait until the new window opens, then register its port information */ do{ usleep(500); // Cool your heels while waiting for new window to open /* Get the DS9 frame information for window with this title */ got = XPAGet(NULL, ds9_title, "frame", "frameno", bufs, lens, names, messages, NXPA); if(got == 1) // If a window appears with the proper title... break; }while(1); /* Extract port information for all open DS9 windows */ display_get_ports(names,got,false); /* Compare extant_ports and active_ports one by one; find the new one! */ for(i=0;i<got;i++){ // Loop through active_ports good[i] = 1; for(j=0;j<nopen;j++){ // Compare with extant_ports if( strcmp(active_ports[i],extant_ports[j]) == 0 ){ good[i] = 0; break; // If match found reset good[i], go on to next i } } /* Free arrays from XPAGet(), otherwise memory fills... */ if( bufs[i] ) free(bufs[i]); if( names[i] ) free(names[i]); if( messages[i] ) free(messages[i]); } /* Assign cannonical PORT value to the 'good' one */ for(i=0;i<got;i++){ if(good[i]) ds9_port = strdup(active_ports[i]); } printf("New DS9 window open with port: %s\n",ds9_port); wombat = 0; // Set wombat to break the do...while loop. break; case(DS9_CANIBALIZE): /******************************************************************/ /* I hope you saved what was in that DS9 window... it's mine now! */ /* Note: This will only canibalize windows owned by the current user */ /* First check for a blank DS9 window */ for(i=0;i<nopen;i++){ /* The filenames in bufs[i] contain a "\n" at the end */ if( strlen(bufs[i]) == 1 ){ // If blank (i.e. no open file), ds9_port = strdup(active_ports[i]); // set ds9_port, wombat = 0; // and break the loop. } } // If blank window, take it and move on... /* If no blank window, then take over the last one */ if(wombat !=0) ds9_port = strdup(active_ports[nopen-1]); printf("Using extant DS9 window with port: %s\n",ds9_port); wombat = 0; // Set wombat to break the do...while loop. break; case(DS9_WHATEVER): /**************************************************/ /* The ultimate case of "meh", if I ever saw one. */ /* Check to see if any of the extant DS9 windows are blank */ for(i=0;i<nopen;i++){ /* The filenames in bufs[i] contain a "\n" at the end */ if( strlen(bufs[i]) == 1 ){ // If blank (i.e. no open file), ds9_port = strdup(active_ports[i]); // set ds9_port, wombat = 0; // and break the loop. } } /* If no blank windows were found, set status = DS9_FORCE_NEW */ if(wombat != 0) *((int *)status) = DS9_FORCE_NEW; else printf("Using extant blank DS9 window with port: %s\n",ds9_port); break; default: /************************************************************/ /* If no proper input status, force WHATEVER and loop again */ *((int *)status) = DS9_WHATEVER; } // End of switch statement while(wombat); // do...while loop return status; }
int main(int argc, char **argv) { register char *namep; int t, f, c; char *ttyn; alarm(60); signal(SIGQUIT, SIG_IGN); signal(SIGINT, SIG_IGN); nice(-100); nice(20); nice(0); gtty(0, &ttyb); ttyb.sg_erase = '#'; ttyb.sg_kill = '@'; stty(0, &ttyb); for (t=3; t<20; t++) close(t); ttyn = ttyname(0); if (ttyn==0) ttyn = "/dev/tty??"; loop: SCPYN(utmp.ut_name, ""); if (argc>1) { SCPYN(utmp.ut_name, argv[1]); argc = 0; } while (utmp.ut_name[0] == '\0') { namep = utmp.ut_name; printf("login: "******"Password:"******"Login incorrect\n"); goto loop; } } if(chdir(pwd->pw_dir) < 0) { printf("No directory\n"); goto loop; } time(&utmp.ut_time); t = ttyslot(); if (t>0 && (f = open("/etc/utmp", 1)) >= 0) { lseek(f, (long)(t*sizeof(utmp)), 0); SCPYN(utmp.ut_line, strchr(ttyn+1, '/')+1); write(f, (char *)&utmp, sizeof(utmp)); close(f); } if (t>0 && (f = open("/usr/adm/wtmp", 1)) >= 0) { lseek(f, 0L, 2); write(f, (char *)&utmp, sizeof(utmp)); close(f); } chown(ttyn, pwd->pw_uid, pwd->pw_gid); setgid(pwd->pw_gid); setuid(pwd->pw_uid); if (*pwd->pw_shell == '\0') pwd->pw_shell = "/bin/sh"; environ = envinit; strncat(homedir, pwd->pw_dir, sizeof(homedir)-6); if ((namep = strrchr(pwd->pw_shell, '/')) == NULL) namep = pwd->pw_shell; else namep++; strcat(minusnam, namep); alarm(0); umask(02); showmotd(); strcat(maildir, pwd->pw_name); if(access(maildir,4)==0) { struct stat statb; stat(maildir, &statb); if (statb.st_size) printf("You have mail.\n"); } signal(SIGQUIT, SIG_DFL); signal(SIGINT, SIG_DFL); execlp(pwd->pw_shell, minusnam, 0); printf("No shell\n"); exit(0); return 0; }
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; }