/* * Change all /etc/ttys entries' flags. */ static int change_all(void) { struct ttyent *tep; int rval; rval = 0; for (tep = getttyent(); tep != NULL; tep = getttyent()) if (change_ttyflags(tep)) rval = 1; return (rval); }
int ttyslot() { register struct ttyent *ttyp; register int slot; register char *p; int cnt; char *name; setttyent(); for (cnt = 0; cnt < 3; ++cnt) if ((name = ttyname(cnt))) { if ((p = strrchr(name, '/'))) ++p; else p = name; for (slot = 1; (ttyp = getttyent()); ++slot) if (!strcmp(ttyp->ty_name, p)) { endttyent(); return(slot); } break; } endttyent(); return(0); }
/* 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 }
int ttyslot() { register struct ttyent *ttyp; register int slot; register char *p; int cnt; size_t buflen = __sysconf (_SC_TTY_NAME_MAX) + 1; char *name; if (buflen == 0) /* This should be enough if no fixed value is given. */ buflen = 32; name = __alloca (buflen); setttyent(); for (cnt = 0; cnt < 3; ++cnt) if (__ttyname_r (cnt, name, buflen) == 0) { if ((p = rindex(name, '/'))) ++p; else p = name; for (slot = 1; (ttyp = getttyent()); ++slot) if (!strcmp(ttyp->ty_name, p)) { endttyent(); return(slot); } break; } endttyent(); return(0); }
gboolean ck_get_max_num_consoles (guint *num) { int max_consoles; int res; gboolean ret; struct ttyent *t; ret = FALSE; max_consoles = 0; res = setttyent (); if (res == 0) { goto done; } while ((t = getttyent ()) != NULL) { if (t->ty_status & TTY_ON && strncmp (t->ty_name, "ttyE", 4) == 0) max_consoles++; } ret = TRUE; endttyent (); done: if (num != NULL) { *num = max_consoles; } return ret; }
struct ttyent *getttynam(const char *name) /* Return the ttytab file entry for a given tty. */ { struct ttyent *tty; endttyent(); while ((tty= getttyent()) != nil && strcmp(tty->ty_name, name) != 0) {} endttyent(); return tty; }
static void read_ttytab () { tablist0 = (struct ttytablist *)malloc (sizeof (struct ttytablist)); if (!tablist0) { printf ("Malloc failed in init\n\r"); _exit (0); } tablist0->next = (struct ttytablist *)0; tablist = tablist0; ent = getttyent (); if (!ent) { printf ("Getttyent failed in init, check /etc/ttytab\n\r"); /* should probably enter single-user mode */ _exit (0); } /* assume first entry is on, if it's off, waste some memory */ tablist->pid = 0; for (;;) { tablist->next = (struct ttytablist *)0; tablist->dev = (char *)malloc (5 + strlen (ent->ty_name)); strcpy (tablist->dev, "/dev/"); strcat (tablist->dev, ent->ty_name); tablist->getty = (char *)malloc (strlen (ent->ty_getty)); strcpy (tablist->getty, ent->ty_getty); if (ent->ty_status & TTY_ON) tablist->pid = -1; else tablist->pid = 0; /* don't waste memory to store off entries */ do { ent = getttyent (); if (!ent) { endttyent (); break; } } while (ent->ty_status & TTY_ON); if (!ent) break; tablist->next = (struct ttytablist *)malloc (sizeof (struct ttytablist)); tablist = tablist->next; } }
struct ttyent * getttynam(const char *tty) { struct ttyent *t; if (strncmp(tty, "/dev/", 5) == 0) tty += 5; setttyent(); while ( (t = getttyent()) ) if (!strcmp(tty, t->ty_name)) break; endttyent(); return (t); }
int ttyslot(void) { struct ttyent *ttyp; int slot = 0, ispty = 0; char *p; int cnt; char *name; #ifndef __minix struct ptmget ptm; #endif setttyent(); for (cnt = 0; cnt < 3; ++cnt) { #ifndef __minix if (ioctl(cnt, TIOCPTSNAME, &ptm) != -1) { ispty = 1; name = ptm.sn; } else if ((name = ttyname(cnt)) != NULL) { #else if ((name = ttyname(cnt)) != NULL) { #endif ispty = 0; } else continue; if ((p = strstr(name, "/pts/")) != NULL) ++p; else if ((p = strrchr(name, '/')) != NULL) ++p; else p = name; for (slot = 1; (ttyp = getttyent()) != NULL; ++slot) if (!strcmp(ttyp->ty_name, p)) { endttyent(); return slot; } break; } endttyent(); if (ispty) { struct stat st; if (fstat(cnt, &st) == -1) return 0; return slot + (int)minor(st.st_rdev) + 1; } return 0; }
void ftpd_login(struct utmp *ut) { struct utmp ubuf; /* * First, loop through /etc/ttys, if needed, to initialize the * top of the tty slots, since ftpd has no tty. */ if (topslot < 0) { topslot = 0; while (getttyent() != (struct ttyent *)NULL) topslot++; } if ((topslot < 0) || ((fd < 0) && (fd = open(_PATH_UTMP, O_RDWR|O_CREAT, 0644)) < 0)) return; /* * Now find a slot that's not in use... */ (void)lseek(fd, (off_t)(topslot * sizeof(struct utmp)), SEEK_SET); while (1) { if (read(fd, &ubuf, sizeof(struct utmp)) == sizeof(struct utmp)) { if (!ubuf.ut_name[0]) { (void)lseek(fd, -(off_t)sizeof(struct utmp), SEEK_CUR); break; } topslot++; } else { (void)lseek(fd, (off_t)(topslot * sizeof(struct utmp)), SEEK_SET); break; } } (void)write(fd, ut, sizeof(struct utmp)); }
void login(struct utmp *ut) { struct ttyent *ty; int fd; int tty; setttyent(); for (tty = 1; (ty = getttyent()) != NULL; ++tty) if (strcmp(ty->ty_name, ut->ut_line) == 0) break; endttyent(); if (tty > 0 && (fd = open(_PATH_UTMP, O_WRONLY|O_CREAT, 0644)) >= 0) { (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), L_SET); (void)write(fd, ut, sizeof(struct utmp)); (void)close(fd); } if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) { (void)write(fd, ut, sizeof(struct utmp)); (void)close(fd); } }
gboolean ck_get_max_num_consoles (guint *num) { int max_consoles; int res; gboolean ret; struct ttyent *t; ret = FALSE; max_consoles = 0; res = setttyent (); if (res == 0) { goto done; } while ((t = getttyent ()) != NULL) { if (t->ty_status & TTY_ON && strncmp (t->ty_name, "ttyC", 4) == 0) max_consoles++; } /* Increment one more so that all consoles are properly counted * this is arguable a bug in vt_add_watches(). */ max_consoles++; ret = TRUE; endttyent (); done: if (num != NULL) { *num = max_consoles; } return ret; }
int ttyslot() { struct ttyent *ttyp; int slot; int cnt; char *name; setttyent(); for (cnt = 0; cnt < 3; ++cnt) if ( (name = ttyname(cnt)) ) { if (strncmp(name, _PATH_DEV, sizeof _PATH_DEV - 1) != 0) break; name += sizeof _PATH_DEV - 1; for (slot = 1; (ttyp = getttyent()); ++slot) if (!strcmp(ttyp->ty_name, name)) { endttyent(); return(slot); } break; } endttyent(); return(0); }
int main(void) { pid_t pid; /* pid of child process */ int fd; /* generally useful */ int linenr; /* loop variable */ int check; /* check if a new process must be spawned */ int sn; /* signal number */ struct slotent *slotp; /* slots[] pointer */ struct ttyent *ttyp; /* ttytab entry */ struct sigaction sa; struct stat stb; #define OPENFDS \ if (fstat(0, &stb) < 0) { \ /* Open standard input, output & error. */ \ (void) open("/dev/null", O_RDONLY); \ (void) open("/dev/log", O_WRONLY); \ dup(1); \ } sigemptyset(&sa.sa_mask); sa.sa_flags = 0; /* Default: Ignore every signal (except those that follow). */ sa.sa_handler = SIG_IGN; for (sn = 1; sn < _NSIG; sn++) { sigaction(sn, &sa, NULL); } /* Hangup: Reexamine /etc/ttytab for newly enabled terminal lines. */ sa.sa_handler = onhup; sigaction(SIGHUP, &sa, NULL); /* Terminate: Stop spawning login processes, shutdown is near. */ sa.sa_handler = onterm; sigaction(SIGTERM, &sa, NULL); /* Abort: Sent by the kernel on CTRL-ALT-DEL; shut the system down. */ sa.sa_handler = onabrt; sigaction(SIGABRT, &sa, NULL); /* Execute the /etc/rc file. */ if ((pid = fork()) != 0) { /* Parent just waits. */ while (wait(NULL) != pid) { if (gotabrt) reboot(RBT_HALT); } } else { #if ! SYS_GETKENV struct sysgetenv sysgetenv; #endif char bootopts[16]; static char *rc_command[] = { "sh", "/etc/rc", NULL, NULL, NULL }; char **rcp = rc_command + 2; /* Get the boot options from the boot environment. */ sysgetenv.key = "bootopts"; sysgetenv.keylen = 8+1; sysgetenv.val = bootopts; sysgetenv.vallen = sizeof(bootopts); if (svrctl(PMGETPARAM, &sysgetenv) == 0) *rcp++ = bootopts; *rcp = "start"; execute(rc_command); report(2, "sh /etc/rc"); _exit(1); /* impossible, we hope */ } OPENFDS; /* Clear /etc/utmp if it exists. */ if ((fd = open(PATH_UTMP, O_WRONLY | O_TRUNC)) >= 0) close(fd); /* Log system reboot. */ wtmp(BOOT_TIME, 0, NULL, 0); /* Main loop. If login processes have already been started up, wait for one * to terminate, or for a HUP signal to arrive. Start up new login processes * for all ttys which don't have them. Note that wait() also returns when * somebody's orphan dies, in which case ignore it. If the TERM signal is * sent then stop spawning processes, shutdown time is near. */ check = 1; while (1) { while ((pid = waitpid(-1, NULL, check ? WNOHANG : 0)) > 0) { /* Search to see which line terminated. */ for (linenr = 0; linenr < PIDSLOTS; linenr++) { slotp = &slots[linenr]; if (slotp->pid == pid) { /* Record process exiting. */ wtmp(DEAD_PROCESS, linenr, NULL, pid); slotp->pid = NO_PID; check = 1; } } } /* If a signal 1 (SIGHUP) is received, simply reset error counts. */ if (gothup) { gothup = 0; for (linenr = 0; linenr < PIDSLOTS; linenr++) { slots[linenr].errct = 0; } check = 1; } /* Shut down on signal 6 (SIGABRT). */ if (gotabrt) { gotabrt = 0; startup(0, &TT_REBOOT); } if (spawn && check) { /* See which lines need a login process started up. */ for (linenr = 0; linenr < PIDSLOTS; linenr++) { slotp = &slots[linenr]; if ((ttyp = getttyent()) == NULL) break; if (ttyp->ty_getty != NULL /* ty_getty is a string, and TTY_ON is * the way to check for enabled ternimanls. */ && (ttyp->ty_status & TTY_ON) && slotp->pid == NO_PID && slotp->errct < ERRCT_DISABLE) { startup(linenr, ttyp); } } endttyent(); } check = 0; } }
/* * 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); } }
int main(void) { pid_t pid; /* pid of child process */ int fd; /* generally useful */ int linenr; /* loop variable */ int check; /* check if a new process must be spawned */ struct slotent *slotp; /* slots[] pointer */ struct ttyent *ttyp; /* ttytab entry */ struct sigaction sa; struct stat stb; if (fstat(0, &stb) < 0) { /* Open standard input, output & error. */ (void) open("/dev/null", O_RDONLY); (void) open("/dev/log", O_WRONLY); dup(1); } sigemptyset(&sa.sa_mask); sa.sa_flags = 0; /* Hangup: Reexamine /etc/ttytab for newly enabled terminal lines. */ sa.sa_handler = onhup; sigaction(SIGHUP, &sa, NULL); /* Terminate: Stop spawning login processes, shutdown is near. */ sa.sa_handler = onterm; sigaction(SIGTERM, &sa, NULL); /* Abort: Sent by the kernel on CTRL-ALT-DEL; shut the system down. */ sa.sa_handler = onabrt; sigaction(SIGABRT, &sa, NULL); /* Execute the /etc/rc file. */ if ((pid = fork()) != 0) { /* Parent just waits. */ while (wait(NULL) != pid) { if (gotabrt) reboot(RBT_HALT); } } else { static char *rc_command[] = { "sh", "/etc/rc", NULL, NULL }; #if __minix_vmd /* Minix-vmd: Get the boot options from the boot environment. */ rc_command[2] = getenv("bootopts"); #else /* Minix: Input from the console. */ close(0); (void) open("/dev/console", O_RDONLY); #endif execute(rc_command); report(2, "sh /etc/rc"); _exit(1); /* impossible, we hope */ } /* Clear /etc/utmp if it exists. */ if ((fd = open(PATH_UTMP, O_WRONLY | O_TRUNC)) >= 0) close(fd); /* Log system reboot. */ wtmp(BOOT_TIME, 0, NULL, 0); /* Main loop. If login processes have already been started up, wait for one * to terminate, or for a HUP signal to arrive. Start up new login processes * for all ttys which don't have them. Note that wait() also returns when * somebody's orphan dies, in which case ignore it. If the TERM signal is * sent then stop spawning processes, shutdown time is near. */ check = 1; while (1) { while ((pid = waitpid(-1, NULL, check ? WNOHANG : 0)) > 0) { /* Search to see which line terminated. */ for (linenr = 0; linenr < PIDSLOTS; linenr++) { slotp = &slots[linenr]; if (slotp->pid == pid) { /* Record process exiting. */ wtmp(DEAD_PROCESS, linenr, NULL, pid); slotp->pid = NO_PID; check = 1; } } } /* If a signal 1 (SIGHUP) is received, simply reset error counts. */ if (gothup) { gothup = 0; for (linenr = 0; linenr < PIDSLOTS; linenr++) { slots[linenr].errct = 0; } check = 1; } /* Shut down on signal 6 (SIGABRT). */ if (gotabrt) { gotabrt = 0; startup(0, &TT_REBOOT); } if (spawn && check) { /* See which lines need a login process started up. */ for (linenr = 0; linenr < PIDSLOTS; linenr++) { slotp = &slots[linenr]; if ((ttyp = getttyent()) == NULL) break; if (ttyp->ty_getty != NULL && ttyp->ty_getty[0] != NULL && slotp->pid == NO_PID && slotp->errct < ERRCT_DISABLE) { startup(linenr, ttyp); } } endttyent(); } check = 0; } }