Date: Fri, 24 Feb 2012 01:16:38 +0400 (MSK) From: Dmitry Marakasov <amdmi3@FreeBSD.org> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/165429: [patch] wall(1): add multibyte character support Message-ID: <20120223211638.7693EEE6@hades.panopticon> Resent-Message-ID: <201202232120.q1NLKBDB072848@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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 root@hades.panopticon:/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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120223211638.7693EEE6>