--- plugh-orig/Makefile	2002-09-30 20:27:56.000000000 +0200
+++ plugh/Makefile	2005-12-21 15:28:59.000402459 +0100
@@ -1,8 +1,9 @@
+PREFIX=/opt/plugh
 OBJS=gettydefs.o
 CFLAGS+=-O2
 LFLAGS=$(CFLAGS) #-s
 LIBES=-ltermcap
-CC=gcc -baout
+CC=gcc
 
 all: plugh
 
@@ -15,5 +16,12 @@
 plugh: plugh.o gettydefs.o
 	$(CC) $(LFLAGS) -o plugh plugh.o gettydefs.o $(LIBES)
 
+install:
+	install -D -d -o root -g root -m 0755 $(DESTDIR)${PREFIX}
+	install -D -d -o root -g root -m 0755 $(DESTDIR)${PREFIX}/bin
+	install -D -d -o root -g root -m 0755 $(DESTDIR)${PREFIX}/etc
+	install -D -o root -g root -m 0700 plugh $(DESTDIR)${PREFIX}/bin/plugh
+	install -D -o root -g root -m 0644 gettydefs $(DESTDIR)${PREFIX}/etc/gettydefs
+
 clean:
 	rm -f m plugh *.o
--- plugh-orig/README	2002-09-30 20:27:56.000000000 +0200
+++ plugh/README	2005-12-21 14:33:59.000000000 +0100
@@ -19,7 +19,11 @@
 
 with
 
-    cc:M:respawn:/home/orc/tmp/ogetty/plugh orc ttyc VC linux
+    cc:M:respawn:/opt/plugh/bin/plugh -L -u root ttyS0 VC linux
+
+or
+
+    cc:M:respawn:/opt/plugh/bin/plugh -L -i -c /opt/plugh/etc/gettydefs -l /opt/plugh/bin/login -u root ttyS0 115200 linux
 
 to have the user `orc' constantly logged into ttyc (ALT-F12)
 
--- plugh-orig/gettydefs	1970-01-01 01:00:00.000000000 +0100
+++ plugh/gettydefs	2005-12-21 10:46:35.000000000 +0100
@@ -0,0 +1,67 @@
+# [ put this file in /etc/gettydefs ]
+#
+# This file contains the startup and final flags for the
+# tty lines.  Each line starts with a SPEED value; this is
+# the same SPEED that you pass to [uu]getty.  Note that the
+# SPEED identifier is just a string; use whatever names
+# you want.
+#
+# The blank lines in this file are important (so I hear).
+#
+# The flags are the same flags you would pass to the stty
+# program.
+#
+# Format: <speed># <init flags> # <final flags> #<login string>#<next-speed>
+#
+#
+# Virtual Console entry
+VC# B9600 SANE CLOCAL # B9600 SANE -ISTRIP CLOCAL #@S login: #VC
+
+# 38400 fixed baud Dumb Terminal entry
+DT38400# B38400 CS8 CLOCAL CRTSCTS # B38400 SANE -ISTRIP CLOCAL CRTSCTS #@S login: #DT38400
+
+# 19200 fixed baud Dumb Terminal entry
+DT19200# B19200 CS8 CLOCAL # B19200 SANE -ISTRIP CLOCAL #@S login: #DT19200
+
+# 9600 baud Dumb Terminal entry
+DT9600# B9600 CS8 CLOCAL # B9600 SANE -ISTRIP CLOCAL #@S login: #DT9600
+
+# 230400 fixed-baud modem entry
+F230400# B230400 CS8 CRTSCTS # B230400 SANE -ISTRIP HUPCL CRTSCTS #@S login: #F230400
+
+# 115200 fixed-baud modem entry
+## removed CRTSCTS hardware flow control flag  [-dL]
+#F115200# B115200 CS8 CRTSCTS # B115200 SANE -ISTRIP HUPCL CRTSCTS #@S login: #F115200
+F115200# B115200 CS8 # B115200 SANE -ISTRIP HUPCL #@S login: #F115200
+
+# 57600 fixed-baud modem entry
+F57600# B57600 CS8 CRTSCTS # B57600 SANE -ISTRIP HUPCL CRTSCTS #@S login: #F57600
+
+# 38400 fixed-baud modem entry
+F38400# B38400 CS8 CRTSCTS # B38400 SANE -ISTRIP HUPCL CRTSCTS #@S login: #F38400
+
+# 19200 fixed-baud modem entry
+F19200# B19200 CS8 CRTSCTS # B19200 SANE -ISTRIP HUPCL CRTSCTS #@S login: #F19200
+
+# 9600 fixed-baud modem entry
+F9600# B9600 CS8 CRTSCTS # B9600 SANE -ISTRIP HUPCL CRTSCTS #@S login: #F9600
+
+# 2400 fixed-baud modem entry
+F2400# B2400 CS8 CRTSCTS # B2400 SANE -ISTRIP HUPCL CRTSCTS #@S login:  #F2400
+
+# 230400 autobauding Modem entry with hard flow control
+230400# B230400 CS8 CRTSCTS # B230400 SANE -ISTRIP HUPCL CRTSCTS #@S login: #115200
+
+## removed CRTSCTS hardware flow control flag  [-dL]
+#115200# B115200 CS8 CRTSCTS # B115200 SANE -ISTRIP HUPCL CRTSCTS #@S login: #57600
+115200# B115200 CS8 # B115200 SANE -ISTRIP HUPCL #@S login: #57600
+
+57600# B57600 CS8 CRTSCTS # B57600 SANE -ISTRIP HUPCL CRTSCTS #@S login: #38400
+
+38400# B38400 CS8 CRTSCTS # B38400 SANE -ISTRIP HUPCL CRTSCTS #@S login: #19200
+
+19200# B19200 CS8 CRTSCTS # B19200 SANE -ISTRIP HUPCL CRTSCTS #@S login: #9600
+
+9600# B9600 CS8 CRTSCTS # B9600 SANE -ISTRIP HUPCL CRTSCTS #@S login: #2400
+
+2400# B2400 CS8 CRTSCTS # B2400 SANE -ISTRIP HUPCL CRTSCTS #@S login: #230400
--- plugh-orig/gettydefs.c	2002-09-30 20:27:56.000000000 +0200
+++ plugh/gettydefs.c	2005-12-21 10:20:42.000000000 +0100
@@ -197,20 +197,6 @@
     { NULL }
 };
 
-#define CINTR	003	/* ^C */
-#define	CQUIT	034	/* ^\ */
-#define CERASE	010	/* ^H */
-#define	CKILL	025	/* ^U */
-#define CEOF	004	/* ^D */
-#define CEOL	015	/* ^M */
-#define CSUSP	032	/* ^Z */
-#define CSTART	021	/* ^Q */
-#define CSTOP	023	/* ^S */
-#define	CRPRNT	022	/* ^R */
-#define CFLUSH	017	/* ^O */
-#define	CWERASE	027	/* ^W */
-#define CLNEXT	026	/* ^V */
-
 /* c_cc special characters */
 static struct modeword ccchars[] = {
     {"vintr", VINTR, CINTR},
--- plugh-orig/plugh.c	2002-09-30 20:27:56.000000000 +0200
+++ plugh/plugh.c	2005-12-21 15:21:20.000000000 +0100
@@ -1,5 +1,8 @@
 /*
  *   Copyright (c) 1998 David Parsons. All rights reserved.
+ *
+ *   Modified version based on the code from David Parsons
+ *   Copyright (c) 2005 Infomaniak Network SA by Guy Baconniere.
  *   
  *   Redistribution and use in source and binary forms, with or without
  *   modification, are permitted provided that the following conditions
@@ -34,19 +37,20 @@
  */
 static const char rcsid[] = "$Id$";
 /*
- * plugh: somewhat like a getty, except that it simply plops the user into a shell.
+ * plugh: somewhat like a getty, except that it simply plops the user into a login.
  *
- * usage: getty [-cdmq] [-i issue] [-l login] user tty [tag [term-type]]
+ * usage: getty [-dLi] [-c gettydefs_file] [-f issue_file] [-l login] [-u user] ttydevice gettydefs [term]
  *
- *  -d		don't clear the screen before the login prompt.
- *  -m		this is a modem-- don't reset the line before prompting.
- *  -q		don't display the issue file.
- *  -i		name an issue file.
- *  -l		use the following program as the login program.
- *  user	the user we create a shell for.
- *  tty		the tty we're talking to, in /dev
- *  tag		which /etc/gettydefs entry to use.
- *  term-type	what sort of terminal is this (for clearing the screen)
+ *  -d			don't clear the screen before the login prompt.
+ *  -L			this is not a modem-- reset the line before prompting.
+ *  -i			don't display the issue file.
+ *  -f file		name an issue file.
+ *  -c file		name an gettydefs file.
+ *  -l program	use the following program as the login program.
+ *  -u user		the user we create a login for.
+ *  ttydevice	the tty we're talking to, in /dev
+ *  gettydefs	which /etc/gettydefs entry to use.
+ *  term		what sort of terminal is this (for clearing the screen)
  */
 
 #include <stdio.h>
@@ -64,24 +68,27 @@
 #include <grp.h>
 #include <malloc.h>
 #include <utmp.h>
+#include <asm/ioctls.h>
 
 #include "gettydefs.h"
 
-void error(char *fmt, ...);
-void login(struct passwd *, char *);
+void syslog_error(char *fmt, ...);
+void login_record(struct passwd *, char *);
 
 static struct utsname sysinfo;	/* system information for login: prompt */
 int tty;			/* tty we're talking to */
 char *program;			/* our program name, for syslog() */
-int local = 1;		/* if we're on a modem, don't hangup before prompt*/
+int local = 0;		/* if we're on a modem, don't hangup before prompt*/
 char *issue = "/etc/issue";	/* issue file before login */
-char *user;			/* who we are */
+char *gettydefs = "/etc/gettydefs";	/* gettydefs file */
+char *user = "uucp";			/* who we are */
 int dumb = 0;			/* dumb terminal - don't bother to clear */
 char *clear = (char*)0;		/* clear screen */
 char *logintty = (char*)0;	/* the tty we're on, for @L escape */
 
 #define CTL(x)	(x - '@')
 #define DEL	0x7f
+#define PATH_LOGIN "/bin/login"
 
 /* if no gettydefs tag is supplied, use this one.
  */
@@ -124,27 +131,30 @@
     char term_type[80];	/* the terminal type, for putenv() */
     GDE *tio;		/* the gettydefs entry we're using now */
     int opt;		/* option, for getopt() and other functions */
-    char *shell = 0;
+    char *login = 0;
     static char termcap_bfr[2048];	/* a scratchspace for termcaps */
     char *arg0;
     char *p;
 
-    if (program=strchr(argv[0], '/'))
-	++program;
-    else
-	program = argv[0];
+    if (program=strchr(argv[0], '/')) {
+		++program;
+	} else {
+		program = argv[0];
+	}
 
     /* first we pick apart the arguments
      */
     opterr=0;
-    while ((opt=getopt(argc, argv, "cdmqi:l:")) != EOF) {
-	switch (opt) {
-	case 'm': local = 0; break;
-	case 'l': shell = optarg; break;
-	case 'q': issue = (char*)0; break;
-	case 'i': issue = optarg; break;
-	case 'd': dumb = 1; break;
-	}
+    while ((opt=getopt(argc, argv, "Ldiu:c:f:l:")) != EOF) {
+		switch (opt) {
+			case 'L': local = 1; break;
+			case 'l': login = optarg; break;
+			case 'i': issue = (char*)0; break;
+			case 'f': issue = optarg; break;
+			case 'u': user = optarg; break;
+			case 'c': gettydefs = optarg; break;
+			case 'd': dumb = 1; break;
+		}
     }
     argc -= (optind-1);
     argv += (optind-1);
@@ -155,51 +165,54 @@
     environ[0] = 0;
 
     /* load the gettydefs file, (optionally checking if -c was specified) */
-    loadgettydefs("/etc/gettydefs");
+    loadgettydefs(gettydefs);
 
-    if (argc < 3)
-	error("usage: plugh [options] user tty [tag [term-type]]");
+    if (argc < 2) {
+		syslog_error("usage: plugh [-dLi] [-c gettydefs_file] [-f issue_file] [-l login] [-u user] ttydevice gettydefs [term]");
+	}
 
-    user = argv[1];
-    if ((pwd = getpwnam(user)) == 0)
-	error("unknown user <%s>", user);
-    argv++;
-    argc--;
-
-    if (argc >= 3) {
-	tio = getgettydef(argv[2]);
-	if (tio == (GDE*)0)
-	    error("unknown tag <%s>", argv[2]);
-    }
-    else
-	tio = &default_tio;
+    if ((pwd = getpwnam(user)) == 0) {
+		syslog_error("unknown user <%s>", user);
+	}
+
+    if (argc >= 2) {
+		tio = getgettydef(argv[2]);
+		if (tio == (GDE*)0) {
+			syslog_error("unknown gettydefs <%s>", argv[2]);
+		}
+    } else {
+		tio = &default_tio;
+	}
 
     /* If we're setting the terminal type, poke around in /etc/termcap
      * to find out how to clear the screen
      */
-    if (argc > 3) {
-	setenv("TERM", argv[3], 1);
-	if (!dumb) {
-	    int ret;
-	    char *p = termcap_bfr;
-
-	    if (tgetent(termcap_bfr, argv[3]) != 1)
-		dumb = 1;
-	    else
-		clear = tgetstr("cl", &p);
-	}
+    if (argc > 2) {
+		setenv("TERM", argv[3], 1);
+		if (!dumb) {
+		    int ret;
+		    char *p = termcap_bfr;
+
+		    if (tgetent(termcap_bfr, argv[3]) != 1) {
+				dumb = 1;
+			} else {
+				clear = tgetstr("cl", &p);
+			}
+		}
     }
 
-    if (strchr(argv[1], '/') != 0)
-	error("badly formed tty name <%s>", argv[1]);
+    if (strchr(argv[1], '/') != 0) {
+		syslog_error("badly formed tty name <%s>", argv[1]);
+	}
 
     close(0);	/* close the standard file descriptors, then open */
     close(1);	/* the terminal and fill them in */
     close(2);
 
     sprintf(terminal, "/dev/%s", logintty = argv[1]);
-    if ((tty = open(terminal, O_RDWR)) < 0)
-	error("cannot open tty <%s>", argv[1]);
+    if ((tty = open(terminal, O_RDWR)) < 0) {
+		syslog_error("cannot open tty <%s>", argv[1]);
+	}
 
     dup(tty);
     dup(tty);
@@ -207,79 +220,78 @@
     opt = getpid();		/* get a new process group */
     ioctl(0, TIOCSPGRP, &opt);
 
-    if (uname(&sysinfo) != 0)
-	error("uname failed: %s", strerror(errno));
+    if (uname(&sysinfo) != 0) {
+		syslog_error("uname failed: %s", strerror(errno));
+	}
 
     /* set the terminal settings so that the user can actually do
-     * something with their shell
+     * something with their login
      */
     tcsetattr(tty, TCSADRAIN, &(tio->after));
 
     /* clear the screen on terminals that support it
      */
-    if (clear && !dumb)
-	write(tty, clear, strlen(clear));
+    if (clear && !dumb) {
+		write(tty, clear, strlen(clear));
+	}
     /* spit out the issue message, if any
      */
-    if (issue)
-	cat(issue);
+    if (issue) {
+		cat_file(issue);
+	}
 
-    /* set up arg0 so that it's got the - to tell the shell that
+    /* set up arg0 so that it's got the - to tell the login that
      * yes, indeed, we are a login shell
      */
-    if (shell == 0)
-	shell = (pwd->pw_shell == 0) ? _PATH_BSHELL : pwd->pw_shell;
+    if (login == 0) {
+		login = PATH_LOGIN;
+	}
 
-    if ((p = strrchr(shell, '/')) != 0)
-	++p;
-    else
-	p = shell;
+    if ((p = strrchr(login, '/')) != 0) {
+		++p;
+	} else {
+		p = login;
+	}
 
     arg0 = malloc(sizeof(p)+2);
     sprintf(arg0, "-%s", p);
 
     /* add utmp/wtmp entries
      */
-    login(pwd, logintty);
-
-    /* change our group and id to the user
-     */
-
-    initgroups(user,pwd->pw_gid);
-    setgid(pwd->pw_gid);
-    setuid(pwd->pw_uid);
+    login_record(pwd, logintty);
 
     /* set appropriate things in our environment
      */
     setenv("LOGNAME", user, 1);
     setenv("PATH", "/bin:/usr/bin:/usr/local/bin", 1);
     setenv("HOME", pwd->pw_dir, 1);
-    setenv("SHELL", shell, 1);
+    setenv("SHELL", pwd->pw_shell, 1);
 
     /* go $HOME
      */
     chdir(pwd->pw_dir);
 
-    execl(shell, arg0, 0);
-    error("cannot exec shell <%s>", shell);
+    execl(login, arg0, "-f", user, 0);
+    syslog_error("cannot exec login <%s>", login);
     exit(0);
 } /* main */
 
 
 /*
- * cat() dumps a file to the terminal
+ * cat_file() dumps a file to the terminal
  */
-cat(char *file)
+cat_file(char *file)
 {
     FILE *f;
     char c;
 
     if (f = fopen(file, "r")) {
-	while ((c=fgetc(f)) != EOF)
-	    putchar(c);
-	fclose(f);
+		while ((c=fgetc(f)) != EOF) {
+		    putchar(c);
+		}
+		fclose(f);
     }
-} /* cat */
+} /* cat_file */
 
 
 /* 
@@ -287,7 +299,7 @@
  * then quit
  */
 void
-error(char *fmt, ...)
+syslog_error(char *fmt, ...)
 {
     va_list ptr;
 
@@ -298,14 +310,14 @@
     closelog();
     sleep(10);
     exit(1);
-} /* error */
+} /* syslog_error */
 
 
 /*
  * write entries to utmp and wtmp
  */
 void
-login(struct passwd *pwd, char *tty)
+login_record(struct passwd *pwd, char *tty)
 {
     struct utmp ut;
     char *ttyabbrev;
@@ -330,4 +342,4 @@
 	flock(wtmp, LOCK_UN);
 	close(wtmp);
     }
-} /* login */
+} /* login_record */
