From be079e9054dbb44332734dba8307628ee48fd0dc Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Tue, 26 Apr 2016 21:15:20 -0400 Subject: [PATCH] Finished initial implementation of getty --- Makefile | 24 +++++------- include/util.h | 16 ++++++++ source/getty.c | 100 ++++++++++++++++++++++++------------------------- 3 files changed, 75 insertions(+), 65 deletions(-) diff --git a/Makefile b/Makefile index 5080417f..eebb6c62 100644 --- a/Makefile +++ b/Makefile @@ -8,20 +8,13 @@ CC = cc LIBS = INCS = -Iinclude CPPFLAGS = -CFLAGS = -O2 ${INCS} ${CPPFLAGS} -LDFLAGS = ${LIBS} -ECLEAN = +CFLAGS = -O2 $(INCS) $(CPPFLAGS) +LDFLAGS = $(LIBS) +BUILD = $(CC) $(CFLAGS) -o $@ $< #------------------------------------------------------------------------------ # Build-Specific Macros #------------------------------------------------------------------------------ -# Simple Single-file Binary Template -define make-bin = -$1: source/$1.c - $(CC) ${CFLAGS} -o $$@ $$< -ECLEAN += $1 -endef - BINS = init getty # load user-specific settings @@ -34,12 +27,15 @@ BINS = init getty all: $(BINS) -$(eval $(call make-bin,init)) -$(eval $(call make-bin,getty)) +init: source/init.c + $(BUILD) + +getty: source/getty.c + $(BUILD) clean: - $(RM) $(ECLEAN) + $(RM) $(BINS) # load dependency files --include ${DEPS} +-include $(DEPS) diff --git a/include/util.h b/include/util.h index cae12905..5427c1ea 100644 --- a/include/util.h +++ b/include/util.h @@ -114,6 +114,22 @@ static FILE* efopen(const char* filename, const char* mode) return file; } +size_t efread(void* ptr, size_t size, size_t nitems, FILE* stream) +{ + errno = 0; + size_t nbytes = fread(ptr, size, nitems, stream); + if (errno) die("fread error: %s", strerror(errno)); + return nbytes; +} + +size_t efwrite(const void* ptr, size_t size, size_t nitems, FILE* stream) +{ + errno = 0; + size_t nbytes = fwrite(ptr, size, nitems, stream); + if (errno) die("fwrite error: %s", strerror(errno)); + return nbytes; +} + static char* efreadline(FILE* input) { size_t size = 8; diff --git a/source/getty.c b/source/getty.c index f0d79323..1e1d2957 100644 --- a/source/getty.c +++ b/source/getty.c @@ -6,13 +6,19 @@ #include "util.h" #include #include +#include +#include #include +#include char* ARGV0; static char* TTY = "/dev/tty1"; static char* TERM = "linux"; +static char* UTMP = "/var/run/utmp"; +static char Hostname[256] = {0}; +static char Username[256] = {0}; -static void sigignore(int signal, int ignore) { +static void ignoresig(int signal, int ignore) { struct sigaction sigact; sigact.sa_handler = (ignore ? SIG_IGN : SIG_DFL); sigact.sa_flags = 0; @@ -37,33 +43,46 @@ static int opentty(void) { return fd; } -static int dologin(void) { - //if (gethostname(hostname, sizeof(hostname)) == 0) - // printf("%s ", hostname); - //printf("login: "); - //fflush(stdout); +static void clearutmp(void) { + struct utmp usr; + FILE* fp = efopen(UTMP, "r+"); + do { + int pos = ftell(fp); + efread(&usr, sizeof(usr), 1, fp); + if ((usr.ut_line[0] == '\0') || (strcmp(usr.ut_line, TTY) != 0)) + continue; + memset(&usr, 0, sizeof(usr)); + fseek(fp, pos, SEEK_SET); + efwrite(&usr, sizeof(usr), 1, fp); + } while (1); + if (ferror(fp)) + warn("%s: I/O error:", UTMP); + fclose(fp); +} - ///* Flush pending input */ - //ioctl(0, TCFLSH, (void *)0); - //memset(logname, 0, sizeof(logname)); - //while (1) { - // n = read(0, &c, 1); - // if (n < 0) - // eprintf("read:"); - // if (n == 0) - // return 1; - // if (i >= sizeof(logname) - 1) - // eprintf("login name too long\n"); - // if (c == '\n' || c == '\r') - // break; - // logname[i++] = c; - //} - //if (logname[0] == '-') - // eprintf("login name cannot start with '-'\n"); - //if (logname[0] == '\0') - // return 1; - //return execlp("/bin/login", "login", "-p", logname, NULL); - return 0; +static int dologin(void) { + int i = 0, c = 0; + /* Print the hostname */ + if (gethostname(Hostname, sizeof(Hostname)) == 0) + printf("%s ", Hostname); + printf("login: "); + fflush(stdout); + /* Read in the username */ + ioctl(0, TCFLSH, (void *)0); + while (1) { + if (0 == efread(&c, 1, 1, stdin)) + return 1; + if (i >= (sizeof(Username) - 1)) + die("login name too long\n"); + if (c == '\n' || c == '\r') + break; + Username[i++] = c; + } + /* Execute the login command */ + if ((Username[0] == '\0') || (Username[0] == '-')) + return 1; + else + return execlp("/bin/login", "login", "-p", Username, NULL); } int main(int argc, char *argv[]) { @@ -76,7 +95,7 @@ int main(int argc, char *argv[]) { if (argc > 0) TTY = argv[0]; if (argc > 1) TERM = argv[1]; /* setup the environment and session */ - sigignore(SIGHUP, 1); // ignore SIGHUP + ignoresig(SIGHUP, 1); // ignore SIGHUP setenv("TERM", TERM, 1); setsid(); /* Open the TTY for normal usage */ @@ -88,30 +107,9 @@ int main(int argc, char *argv[]) { warn("fchown %s:", TTY); if (fchmod(fd, 0600) < 0) warn("fchmod %s:", TTY); - if (fd > 2) - close(fd); - sigignore(SIGHUP, 0); // stop ignoring SIGHUP + ignoresig(SIGHUP, 0); // stop ignoring SIGHUP /* clear all utmp entries for this TTY */ -// /* Clear all utmp entries for this tty */ -// fp = fopen(UTMP_PATH, "r+"); -// if (fp) { -// do { -// pos = ftell(fp); -// if (fread(&usr, sizeof(usr), 1, fp) != 1) -// break; -// if (usr.ut_line[0] == '\0') -// continue; -// if (strcmp(usr.ut_line, tty) != 0) -// continue; -// memset(&usr, 0, sizeof(usr)); -// fseek(fp, pos, SEEK_SET); -// if (fwrite(&usr, sizeof(usr), 1, fp) != 1) -// break; -// } while (1); -// if (ferror(fp)) -// weprintf("%s: I/O error:", UTMP_PATH); -// fclose(fp); -// } + clearutmp(); /* Start the command or login prompt */ if (argc > 2) return execvp(argv[2], &(argv[2])); -- 2.54.0