Logo Search packages:      
Sourcecode: mailleds version File versions  Download package

tty.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <paths.h>
#include <utmp.h>
#include <time.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <linux/tty.h>
#include "config.h"
#include "mailleds.h"

extern int ct[MAX_CONSOLES];
extern int uid;
extern char *username;
extern char opt_t;

char **tty_filenames;


void detach_from_tty(void)
{
      int fd;
      fd = open(_PATH_TTY, O_RDONLY);

      /* are we started from a non-terminal? */
      if (fd == -1)
            return;
      if (ioctl(fd, TIOCNOTTY, 0)) {
            perror("mailleds");
            exit_fatal("Cannot detach from tty");
      }
      close(fd);
}

void check_ttys(ttyfiles)
char **ttyfiles;
{
      int x;
      struct stat stat_buf;
      for (x = 0; ttyfiles[x] != (char *) NULL; x++) {
            if (stat(ttyfiles[x], &stat_buf))
                  stat_error(ttyfiles[x]);
            if (!S_ISCHR(stat_buf.st_mode)) {
                  fprintf(stderr, "mailleds: %s is not a tty\n", ttyfiles[x]);
                  exit(-1);
            }
      }
}

/* Looking at permissions, ownership, this determines a list of ttys to 
   flash from the specified list. */
void make_tty_array()
{
      int x, i, j, fd;
      struct utmp *utmp_info;
      static time_t utmp_lastmod;
      static struct stat stat_buf;

      int consoles = 0;

      if (stat(_PATH_UTMP, &stat_buf))
            stat_error(_PATH_UTMP);
      if (utmp_lastmod == stat_buf.st_mtime)
            return;
      utmp_lastmod = stat_buf.st_mtime;

      if (tty_filenames) {    /* Don't free first time around */
            for (x = 0; tty_filenames[x]; x++)
                  free(tty_filenames[x]);
            free(tty_filenames);
      }
      /* now we wait our turn to read utmp, grab it and go.
         This should also prevent others from logging in while we're on the fly */
      fd = open(_PATH_UTMP, O_RDONLY);
#ifndef DEBUG
      flock(fd, LOCK_EX);
#endif

      setutent();
      tty_filenames = xmalloc(sizeof(char *) * MAX_CONSOLES);
      while ((utmp_info = getutent()) != (struct utmp *) NULL) {
#ifdef DEBUG
            if (utmp_info->ut_id)
                  fprintf(stderr, "utmp[%s] = %-.*s\n", utmp_info->ut_id, UT_NAMESIZE, utmp_info->ut_user);
#endif
            if (strncmp(utmp_info->ut_user, username, UT_NAMESIZE) == 0
                && isdigit(utmp_info->ut_id[0])) {    /* makes sure is a console */
                  tty_filenames[consoles] = xmalloc(strlen(_PATH_DEV) + strlen(utmp_info->ut_line) + 1);
                  sprintf(tty_filenames[consoles++], "%s%s", _PATH_DEV, utmp_info->ut_line);
            }
      }
      tty_filenames[consoles] = (char *) NULL;

      for (x = 0; x < MAX_CONSOLES && ct[x] != -1; x++)
            close(ct[x]);

      for (i = 0, j = 0; i < consoles; i++) {
            if (stat(tty_filenames[i], &stat_buf))
                  stat_error(tty_filenames[i]);

            /* If we grabbed the tty from utmp, we should be ok.  However, 
               a getty may be logging in the terminal, and it might be owned by
               root still.  Give it 1/4 of a second to complete its operation. */
            if (stat_buf.st_uid != uid)
                  usleep(250000);
            ct[j++] = open(tty_filenames[i], O_RDONLY);
      }
      ct[j] = -1;
/* finally, let the others log in */
      flock(fd, LOCK_UN);
      close(fd);
}

Generated by  Doxygen 1.6.0   Back to index