Hi,
I've attached a patch that makes write work with multi-byte unicode characters.


--- /tmp/bsdmainutils-9.0.12+nmu1/usr.bin/write/write.c 2017-10-04 21:49:14.147403575 -0400
+++ write.c     2017-10-04 21:57:13.818433680 -0400
@@ -63,6 +63,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <utmp.h>
+#include <wchar.h>

 #include <errno.h>
 #include <time.h>
@@ -83,7 +84,7 @@
 void do_write(char *, char *, uid_t);
 static void usage(void);
 int term_chk(char *, int *, time_t *, int);
-void wr_fputs(unsigned char *s);
+void wr_fputs(wchar_t *s);
 void search_utmp(char *, char *, char *, uid_t);
 int utmp_chk(char *, char *);

@@ -313,7 +314,8 @@
        char *nows;
        struct passwd *pwd;
        time_t now;
-       char path[MAXPATHLEN], host[MAXHOSTNAMELEN], line[512];
+       char path[MAXPATHLEN], host[MAXHOSTNAMELEN];
+       wchar_t line[512];

        /* Determine our login name before we reopen() stdout */
        if ((login = getlogin()) == NULL) {
@@ -339,7 +341,7 @@
        (void)printf("\r\n\007\007\007Message from %s@%s on %s at %s ...\r\n",
            login, host, mytty, nows + 11);

-       while (fgets(line, sizeof(line), stdin) != NULL)
+       while (fgetws(line, sizeof(line), stdin) != NULL)
                wr_fputs(line);
 }

@@ -358,10 +360,10 @@
  *     turns \n into \r\n
  */
 void
-wr_fputs(unsigned char *s)
+wr_fputs(wchar_t *s)
 {

-#define        PUTC(c) if (putchar(c) == EOF) err(1, NULL);
+#define        PUTC(c) if (putwchar(c) == WEOF) err(1, NULL);

        for (; *s != '\0'; ++s) {
                if (*s == '\n') {
@@ -371,11 +373,7 @@
                           (!isprint(*s) && !isspace(*s) &&
                            *s != '\a' && *s != '\b')
                          ) {
-                       if (*s & 0x80) {
-                               *s &= ~0x80;
-                               PUTC('M');
-                               PUTC('-');
-                       }
+
                        if (iscntrl(*s)) {
                                *s ^= 0x40;
                                PUTC('^');
--- /tmp/bsdmainutils-9.0.12+nmu1/usr.bin/write/write.c	2017-10-04 21:49:14.147403575 -0400
+++ write.c	2017-10-04 21:57:13.818433680 -0400
@@ -63,6 +63,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <utmp.h>
+#include <wchar.h>
 
 #include <errno.h>
 #include <time.h>
@@ -83,7 +84,7 @@
 void do_write(char *, char *, uid_t);
 static void usage(void);
 int term_chk(char *, int *, time_t *, int);
-void wr_fputs(unsigned char *s);
+void wr_fputs(wchar_t *s);
 void search_utmp(char *, char *, char *, uid_t);
 int utmp_chk(char *, char *);
 
@@ -313,7 +314,8 @@
 	char *nows;
 	struct passwd *pwd;
 	time_t now;
-	char path[MAXPATHLEN], host[MAXHOSTNAMELEN], line[512];
+	char path[MAXPATHLEN], host[MAXHOSTNAMELEN];
+	wchar_t line[512];
 
 	/* Determine our login name before we reopen() stdout */
 	if ((login = getlogin()) == NULL) {
@@ -339,7 +341,7 @@
 	(void)printf("\r\n\007\007\007Message from %s@%s on %s at %s ...\r\n",
 	    login, host, mytty, nows + 11);
 
-	while (fgets(line, sizeof(line), stdin) != NULL)
+	while (fgetws(line, sizeof(line), stdin) != NULL)
 		wr_fputs(line);
 }
 
@@ -358,10 +360,10 @@
  *     turns \n into \r\n
  */
 void
-wr_fputs(unsigned char *s)
+wr_fputs(wchar_t *s)
 {
 
-#define	PUTC(c)	if (putchar(c) == EOF) err(1, NULL);
+#define	PUTC(c)	if (putwchar(c) == WEOF) err(1, NULL);
 
 	for (; *s != '\0'; ++s) {
 		if (*s == '\n') {
@@ -371,11 +373,7 @@
 			   (!isprint(*s) && !isspace(*s) &&
 			    *s != '\a' && *s != '\b')
 			  ) {
-			if (*s & 0x80) {
-				*s &= ~0x80;
-				PUTC('M');
-				PUTC('-');
-			}
+
 			if (iscntrl(*s)) {
 				*s ^= 0x40;
 				PUTC('^');

Reply via email to