>Number:         165429
>Category:       bin
>Synopsis:       [patch] wall(1): add multibyte character support
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Feb 23 21:20:11 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator:     Dmitry Marakasov
>Release:        FreeBSD 9.0-RELEASE amd64
>Organization:
>Environment:
System: FreeBSD hades.panopticon 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan 10 
01:33:18 MSK 2012 [email protected]:/usr/obj/usr/src/sys/HADES amd64


>Description:
wall(1) doesn't support multibyte characters. Fix it in a similar way to 
write(1) (see bin/164317 or SVN rev 231586).

>How-To-Repeat:
>Fix:

--- wall.patch begins here ---
diff --git usr.bin/wall/wall.1 usr.bin/wall/wall.1
index 1c2d067..4fa82dd 100644
--- usr.bin/wall/wall.1
+++ usr.bin/wall/wall.1
@@ -28,7 +28,7 @@
 .\"     @(#)wall.1     8.1 (Berkeley) 6/6/93
 .\" $FreeBSD$
 .\"
-.Dd July 17, 2004
+.Dd February 24, 2012
 .Dt WALL 1
 .Os
 .Sh NAME
@@ -73,7 +73,3 @@ setting is used to determine which characters are safe to 
write to a
 terminal, not the receiver's (which
 .Nm
 has no way of knowing).
-.Pp
-The
-.Nm
-utility does not recognize multibyte characters.
diff --git usr.bin/wall/wall.c usr.bin/wall/wall.c
index c3aa323..dafd448 100644
--- usr.bin/wall/wall.c
+++ usr.bin/wall/wall.c
@@ -62,6 +62,8 @@ static const char sccsid[] = "@(#)wall.c      8.2 (Berkeley) 
11/16/93";
 #include <time.h>
 #include <unistd.h>
 #include <utmpx.h>
+#include <wchar.h>
+#include <wctype.h>
 
 #include "ttymsg.h"
 
@@ -185,14 +187,15 @@ void
 makemsg(char *fname)
 {
        int cnt;
-       unsigned char ch;
+       wchar_t ch;
        struct tm *lt;
        struct passwd *pw;
        struct stat sbuf;
        time_t now;
        FILE *fp;
        int fd;
-       char *p, hostname[MAXHOSTNAMELEN], lbuf[256], tmpname[64];
+       char hostname[MAXHOSTNAMELEN], tmpname[64];
+       wchar_t *p, *tmp, lbuf[256], codebuf[13];
        const char *tty;
        const char *whom;
        gid_t egid;
@@ -220,78 +223,61 @@ makemsg(char *fname)
                 * Which means that we may leave a non-blank character
                 * in column 80, but that can't be helped.
                 */
-               (void)fprintf(fp, "\r%79s\r\n", " ");
-               (void)snprintf(lbuf, sizeof(lbuf), 
-                   "Broadcast Message from %s@%s",
+               (void)fwprintf(fp, L"\r%79s\r\n", " ");
+               (void)swprintf(lbuf, sizeof(lbuf)/sizeof(wchar_t),
+                   L"Broadcast Message from %s@%s",
                    whom, hostname);
-               (void)fprintf(fp, "%-79.79s\007\007\r\n", lbuf);
-               (void)snprintf(lbuf, sizeof(lbuf),
-                   "        (%s) at %d:%02d %s...", tty,
+               (void)fwprintf(fp, L"%-79.79S\007\007\r\n", lbuf);
+               (void)swprintf(lbuf, sizeof(lbuf)/sizeof(wchar_t),
+                   L"        (%s) at %d:%02d %s...", tty,
                    lt->tm_hour, lt->tm_min, lt->tm_zone);
-               (void)fprintf(fp, "%-79.79s\r\n", lbuf);
+               (void)fwprintf(fp, L"%-79.79S\r\n", lbuf);
        }
-       (void)fprintf(fp, "%79s\r\n", " ");
+       (void)fwprintf(fp, L"%79s\r\n", " ");
 
        if (fname) {
                egid = getegid();
                setegid(getgid());
-               if (freopen(fname, "r", stdin) == NULL)
+               if (freopen(fname, "r", stdin) == NULL)
                        err(1, "can't read %s", fname);
                setegid(egid);
        }
        cnt = 0;
-       while (fgets(lbuf, sizeof(lbuf), stdin)) {
-               for (p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
-                       if (ch == '\r') {
-                               putc('\r', fp);
+       while (fgetws(lbuf, sizeof(lbuf)/sizeof(wchar_t), stdin)) {
+               for (p = lbuf; (ch = *p) != L'\0'; ++p, ++cnt) {
+                       if (ch == L'\r') {
+                               putwc(L'\r', fp);
                                cnt = 0;
                                continue;
-                       } else if (ch == '\n') {
+                       } else if (ch == L'\n') {
                                for (; cnt < 79; ++cnt)
-                                       putc(' ', fp);
-                               putc('\r', fp);
-                               putc('\n', fp);
+                                       putwc(L' ', fp);
+                               putwc(L'\r', fp);
+                               putwc(L'\n', fp);
                                break;
                        }
                        if (cnt == 79) {
-                               putc('\r', fp);
-                               putc('\n', fp);
+                               putwc(L'\r', fp);
+                               putwc(L'\n', fp);
                                cnt = 0;
                        }
-                       if (((ch & 0x80) && ch < 0xA0) ||
-                                  /* disable upper controls */
-                                  (!isprint(ch) && !isspace(ch) &&
-                                   ch != '\a' && ch != '\b')
-                                 ) {
-                               if (ch & 0x80) {
-                                       ch &= 0x7F;
-                                       putc('M', fp);
+                       if (iswprint(ch) || iswspace(ch) || ch == L'\a' || ch 
== L'\b') {
+                               putwc(ch, fp);
+                       } else {
+                               (void)swprintf(codebuf, 
sizeof(codebuf)/sizeof(wchar_t), L"<0x%X>", ch);
+                               for (tmp = codebuf; *tmp != L'\0'; ++tmp) {
+                                       putwc(*tmp, fp);
                                        if (++cnt == 79) {
-                                               putc('\r', fp);
-                                               putc('\n', fp);
-                                               cnt = 0;
-                                       }
-                                       putc('-', fp);
-                                       if (++cnt == 79) {
-                                               putc('\r', fp);
-                                               putc('\n', fp);
-                                               cnt = 0;
-                                       }
-                               }
-                               if (iscntrl(ch)) {
-                                       ch ^= 040;
-                                       putc('^', fp);
-                                       if (++cnt == 79) {
-                                               putc('\r', fp);
-                                               putc('\n', fp);
+                                               putwc(L'\r', fp);
+                                               putwc(L'\n', fp);
                                                cnt = 0;
                                        }
                                }
+                               --cnt;
                        }
-                       putc(ch, fp);
                }
        }
-       (void)fprintf(fp, "%79s\r\n", " ");
+       (void)fwprintf(fp, L"%79s\r\n", " ");
        rewind(fp);
 
        if (fstat(fd, &sbuf))
--- wall.patch ends here ---

>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "[email protected]"

Reply via email to