mingetty-utf8.patch 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. diff -Nru mingetty-1.07.orig/mingetty.c mingetty-1.07/mingetty.c
  2. --- mingetty-1.07.orig/mingetty.c 2004-01-03 15:15:56.000000000 +0200
  3. +++ mingetty-1.07/mingetty.c 2006-11-22 22:13:26.967910100 +0200
  4. @@ -16,10 +16,15 @@
  5. * - autologin only at first login
  6. * - /etc/mingetty.conf that can be used instead of /etc/inittab for
  7. * command line options
  8. - * - Can UTF-8 setup be done within mingetty?
  9. + * - Can UTF-8 setup be done within mingetty? Let's try now :-) (VinzC)
  10. * - Also add /bin/login-type functionality in here?
  11. */
  12. +/* Additional comments: Vincent Cadet <vcadet@hotmail.com> (2006-11-21)
  13. + * - Attempt to make mingetty support UTF-8. Modifications were imported
  14. + * from Suse migetty.c 0.9.6s.
  15. + */
  16. +
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <unistd.h>
  20. @@ -39,6 +44,19 @@
  21. #include <syslog.h>
  22. #include <sys/utsname.h>
  23. #include <time.h>
  24. +#include <locale.h>
  25. +#include <iconv.h>
  26. +#include <wctype.h>
  27. +#include <sys/kd.h>
  28. +#include <sys/ttydefaults.h>
  29. +
  30. +#ifndef IUTF8
  31. +# ifndef ASM_IUTF8
  32. +# error ASM_IUTF8 input flag not defined - Cannot define IUTF8
  33. +# else
  34. +# define IUTF8 ASM_IUTF8
  35. +# endif
  36. +#endif
  37. /* name of this program (argv[0]) */
  38. static char *progname;
  39. @@ -74,6 +92,8 @@
  40. static char *autologin = NULL;
  41. /* try to read a char before dropping to login prompt */
  42. static int loginpause = 0;
  43. +/* terminal mode */
  44. +static int mode = K_RAW;
  45. /* error() - output error messages */
  46. static void error (const char *fmt, ...)
  47. @@ -187,10 +207,21 @@
  48. if (fd > 2)
  49. close (fd);
  50. + /* Detect mode of current keyboard setup, e.g. for UTF-8 */
  51. + if (ioctl(0, KDGKBMODE, &mode) < 0)
  52. + mode = K_RAW;
  53. +
  54. /* Write a reset string to the terminal. This is very linux-specific
  55. and should be checked for other systems. */
  56. if (noclear == 0)
  57. - write (0, "\033c", 2);
  58. + /* don't write a full reset (ESC c) because this leaves the
  59. + unicode mode again if the terminal was in unicode mode
  60. + and also undos the ESC sequences in CONSOLE_MAGIC which
  61. + are needed for some languages/console-fonts.
  62. + Just put the cursor to the home position (ESC [ H),
  63. + erase everything below the cursor (ESC [ J), and set the
  64. + scrolling region to the full window (ESC [ r) */
  65. + write (0, "\033[r\033[H\033[J", 9);
  66. sigaction (SIGHUP, &sa_old, NULL);
  67. }
  68. @@ -292,32 +323,75 @@
  69. static char *get_logname (void)
  70. {
  71. - static char logname[40];
  72. + static char logname[4*UT_NAMESIZE];
  73. char *bp;
  74. unsigned char c;
  75. + int ascii;
  76. + iconv_t ic;
  77. tcflush (0, TCIFLUSH); /* flush pending input */
  78. +
  79. + /* Check for UTF-8 mode */
  80. + switch(mode) {
  81. + case K_UNICODE:
  82. + ascii = 0;
  83. + setlocale(LC_CTYPE, "en_US.UTF-8");
  84. + break;
  85. + case K_RAW:
  86. + case K_MEDIUMRAW:
  87. + case K_XLATE:
  88. + default:
  89. + ascii = 1;
  90. + setlocale(LC_CTYPE, "POSIX");
  91. + break;
  92. + }
  93. +
  94. for (*logname = 0; *logname == 0;) {
  95. do_prompt (1);
  96. for (bp = logname;;) {
  97. if (read (0, &c, 1) < 1) {
  98. - if (errno == EINTR || errno == EIO
  99. - || errno == ENOENT)
  100. + if (errno == EINTR || errno == EAGAIN) {
  101. + usleep(1000);
  102. + continue;
  103. + }
  104. + if (errno == EIO || errno == ENOENT)
  105. exit (EXIT_SUCCESS);
  106. error ("%s: read: %s", tty, strerror (errno));
  107. }
  108. if (c == '\n' || c == '\r') {
  109. *bp = 0;
  110. break;
  111. - } else if (!isprint (c))
  112. - error ("%s: invalid character 0x%x in login"
  113. - " name", tty, c);
  114. + }
  115. +
  116. + if (ascii && !isprint (c))
  117. + error ("%s: invalid character 0x%x in login name", tty, c);
  118. else if ((size_t)(bp - logname) >= sizeof (logname) - 1)
  119. error ("%s: too long login name", tty);
  120. - else
  121. - *bp++ = c;
  122. +
  123. + *bp++ = c;
  124. }
  125. }
  126. +
  127. + if (!ascii && (ic = iconv_open("WCHAR_T", "UTF-8"))) {
  128. + char tmpbuf[4*sizeof(logname)], *op, *lp;
  129. + size_t len = bp - logname;
  130. + size_t out = sizeof(tmpbuf) - 1;
  131. + size_t wcl;
  132. + wint_t *wcp;
  133. +
  134. + op = tmpbuf;
  135. + lp = logname;
  136. + if ((wcl = iconv(ic , &lp, &len, &op, &out)) == (size_t)-1)
  137. + error ("%s: invalid character conversion for login name", tty);
  138. + iconv_close(ic);
  139. +
  140. + wcp = (wint_t*)tmpbuf;
  141. + wcp[wcl] = (wint_t)0;
  142. + while (*wcp) {
  143. + if (!iswprint(*wcp++))
  144. + error ("%s: invalid character for login name found", tty);
  145. + }
  146. + }
  147. return logname;
  148. }