]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
agetty: add --{erase,kill}-chars options
authorKarel Zak <kzak@redhat.com>
Thu, 22 Nov 2012 10:14:02 +0000 (11:14 +0100)
committerKarel Zak <kzak@redhat.com>
Thu, 22 Nov 2012 10:17:51 +0000 (11:17 +0100)
We need way to disable the default kill and erase agetty chars to make
the getty usable for Active Directory users with '@' in username.

It seems that the most extendible solution is to add options that
allow to complete control additional erase/kill chars. If you specify
empty strings then the chars are disabled at all.

Note that this patch is backwardly compatible.

Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=870854
Signed-off-by: Karel Zak <kzak@redhat.com>
term-utils/agetty.8
term-utils/agetty.c

index e51017d0d5e4525690c7ec31a243c77d9ea041a3..2110cae5c0bcbe61308105453b9e5acaa07571d8 100644 (file)
@@ -29,6 +29,7 @@ The program can handle 7-bit characters with even, odd, none or space
 parity, and 8-bit characters with no parity. The following special
 characters are recognized: @ and Control-U (kill); #, DEL and
 back space (erase); carriage return and line feed (end of line).
+See also \fB\-\-erase-chars\fP and \fB\-\-kill-chars\fP options.
 .IP o
 Optionally deduces the baud rate from the CONNECT messages produced by
 Hayes(tm)-compatible modems.
@@ -217,6 +218,16 @@ By default the hostname is only printed until the first dot.  With
 this option enabled, the full qualified hostname by gethostname()
 or if not found by getaddrinfo() is shown.
 .TP
+\-\-erase\-chars \fIstring\fP
+This option specifies additional chars that should be interpreted as a
+backspace (ignore previous char) when user specifies login name. The default is
+\'#\', specify empty string to disable the default.
+.TP
+\-\-kill\-chars \fIstring\fP
+This option specifies additional chars that should be interpreted as a
+kill (ignore all previous chars) when user specifies login name. 
+The default is \'@\', specify empty string to disable the default.
+.TP
 \-\-version
 Output version information and exit.
 .TP
index 152fc9106c4905319753bcb9f275f5844cf857b8..c63dd3fde1e0d859bb13bc68ddd834f94e8cb00c 100644 (file)
@@ -144,6 +144,8 @@ struct options {
        char *term;                     /* terminal type */
        char *initstring;               /* modem init string */
        char *issue;                    /* alternative issue file */
+       char *erasechars;               /* string with erase chars */
+       char *killchars;                /* string with kill chars */
        int delay;                      /* Sleep seconds before prompt */
        int nice;                       /* Run login with this priority */
        int numspeed;                   /* number of baud rates to try */
@@ -283,7 +285,9 @@ int main(int argc, char **argv)
                .flags  =  F_ISSUE,             /* show /etc/issue (SYSV_STYLE) */
                .login  =  _PATH_LOGIN,         /* default login program */
                .tty    = "tty1",               /* default tty line */
-               .issue  =  ISSUE                /* default issue file */
+               .issue  =  ISSUE,               /* default issue file */
+               .erasechars = "#",              /* default additional erase char */
+               .killchars  = "@"               /* default additional kill char */
        };
        char *login_argv[LOGIN_ARGV_MAX + 1];
        int login_argc = 0;
@@ -547,7 +551,9 @@ static void parse_args(int argc, char **argv, struct options *op)
                NOHINTS_OPTION,
                NOHOSTNAME_OPTION,
                LONGHOSTNAME_OPTION,
-               HELP_OPTION
+               HELP_OPTION,
+               ERASE_CHARS_OPTION,
+               KILL_CHARS_OPTION,
        };
        const struct option longopts[] = {
                {  "8bits",          no_argument,        0,  '8'  },
@@ -581,6 +587,8 @@ static void parse_args(int argc, char **argv, struct options *op)
                {  "long-hostname",  no_argument,        0,  LONGHOSTNAME_OPTION },
                {  "version",        no_argument,        0,  VERSION_OPTION  },
                {  "help",           no_argument,        0,  HELP_OPTION     },
+               {  "erase-chars",    required_argument,  0,  ERASE_CHARS_OPTION },
+               {  "kill-chars",     required_argument,  0,  KILL_CHARS_OPTION },
                { NULL, 0, 0, 0 }
        };
 
@@ -675,6 +683,12 @@ static void parse_args(int argc, char **argv, struct options *op)
                case LONGHOSTNAME_OPTION:
                        op->flags |= F_LONGHNAME;
                        break;
+               case ERASE_CHARS_OPTION:
+                       op->erasechars = optarg;
+                       break;
+               case KILL_CHARS_OPTION:
+                       op->killchars = optarg;
+                       break;
                case VERSION_OPTION:
                        printf(_("%s from %s\n"), program_invocation_short_name,
                               PACKAGE_STRING);
@@ -1427,6 +1441,8 @@ static char *get_logname(struct options *op, struct termios *tp, struct chardata
                /* Read name, watch for break and end-of-line. */
                while (cp->eol == '\0') {
 
+                       char key;
+
                        if (read(STDIN_FILENO, &c, 1) < 1) {
 
                                /* Do not report trivial like EINTR/EIO errors. */
@@ -1459,8 +1475,15 @@ static char *get_logname(struct options *op, struct termios *tp, struct chardata
                                cp->parity |= ((bits & 1) ? 1 : 2);
                        }
 
+                       if (op->killchars && strchr(op->killchars, ascval))
+                               key = CTL('U');
+                       else if (op->erasechars && strchr(op->erasechars, ascval))
+                               key = DEL;
+                       else
+                               key = ascval;
+
                        /* Do erase, kill and end-of-line processing. */
-                       switch (ascval) {
+                       switch (key) {
                        case 0:
                                *bp = 0;
                                if (op->numspeed > 1)
@@ -1473,7 +1496,6 @@ static char *get_logname(struct options *op, struct termios *tp, struct chardata
                                break;
                        case BS:
                        case DEL:
-                       case '#':
                                cp->erase = ascval; /* set erase character */
                                if (bp > logname) {
                                        if ((tp->c_lflag & ECHO) == 0)
@@ -1482,7 +1504,6 @@ static char *get_logname(struct options *op, struct termios *tp, struct chardata
                                }
                                break;
                        case CTL('U'):
-                       case '@':
                                cp->kill = ascval;              /* set kill character */
                                while (bp > logname) {
                                        if ((tp->c_lflag & ECHO) == 0)
@@ -1676,6 +1697,8 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
                       "     --nonewline            do not print a newline before issue\n"
                       "     --no-hostname          no hostname at all will be shown\n"
                       "     --long-hostname        show full qualified hostname\n"
+                      "     --erase-chars <string> additional backspace chars\n"
+                      "     --kill-chars <string>  additional kill chars\n"
                       "     --version              output version information and exit\n"
                       "     --help                 display this help and exit\n\n"));