Пример #1
0
/*
 * 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);
}
Пример #2
0
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);
}
Пример #3
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
}
Пример #4
0
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);
}
Пример #5
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;
}
Пример #6
0
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;
}
Пример #7
0
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;
	}
}
Пример #8
0
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);
}
Пример #9
0
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;
}
Пример #10
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));
}
Пример #11
0
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);
	}
}
Пример #12
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, "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;
}
Пример #13
0
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);
}
Пример #14
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;
  }
}
Пример #15
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);
	}
}
Пример #16
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;
  }
}