Date: Thu, 22 Mar 2001 20:28:02 +0100 (CET) From: Cyrille Lefevre <clefevre@poboxes.com> To: FreeBSD-gnats-submit@freebsd.org Subject: bin/26005: MIME quoted-printable encoding added to vis/unvis + bug fix Message-ID: <200103221928.f2MJS2I22918@gits.dyndns.org>
next in thread | raw e-mail | index | archive | help
>Number: 26005
>Category: bin
>Synopsis: MIME quoted-printable encoding added to vis/unvis + bug fix
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Thu Mar 22 11:30:01 PST 2001
>Closed-Date:
>Last-Modified:
>Originator: Cyrille Lefevre
>Release: FreeBSD 4.3-BETA i386
>Organization:
ACME
>Environment:
System: FreeBSD gits 4.3-BETA FreeBSD 4.3-BETA #18: Sat Mar 17 02:17:40 CET 2001 root@:/disk2/4.x-stable/src/sys/compile/CUSTOM i386
>Description:
MIME quoted-printable encoding added to vis/unvis.
this allow you to read quoted-printable messages through
the mail interface using !unvis -q which may be somewhat
usefull.
the bug fix is in the S_START case of unvis where
*cp = isdigit(c) ? (c - '0') : (tolower(c) - 'a');
must be
*cp = isdigit(c) ? (c - '0') : (tolower(c) - 'a' + 10);
also, added references to strunvisx in the unvis(3) manual page.
the unvis(3) API has been change since characters from
stdio are in and not char. following this rule, I get rid
of all uneeded casts. I've checked all the source tree,
unvis(3) is only used by unvis(1).
new -h and -q flags added to unvis(1).
well, I know that my english is very poor. so, the manual
pages need to be reviewed. at least, the added parts.
>How-To-Repeat:
validation tests are :
vis -q /bin/ls | unvis -q | cmp - /bin/ls
vis -q /bin/ls | mimencode -u -q | cmp - /bin/ls
mimencode -q /bin/ls | unvis -q | cmp - /bin/ls
mimencode come from the metamail port.
>Fix:
Index: include/vis.h
===================================================================
RCS file: /home/ncvs/src/include/vis.h,v
retrieving revision 1.6.2.1
diff -u -r1.6.2.1 vis.h
--- include/vis.h 2000/08/17 08:25:53 1.6.2.1
+++ include/vis.h 2001/03/21 23:39:51
@@ -47,24 +47,25 @@
/*
* to select alternate encoding format
*/
-#define VIS_OCTAL 0x01 /* use octal \ddd format */
-#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropriate */
+#define VIS_OCTAL 0x001 /* use octal \ddd format */
+#define VIS_CSTYLE 0x002 /* use \[nrft0..] where appropriate */
/*
* to alter set of characters encoded (default is to encode all
* non-graphic except space, tab, and newline).
*/
-#define VIS_SP 0x04 /* also encode space */
-#define VIS_TAB 0x08 /* also encode tab */
-#define VIS_NL 0x10 /* also encode newline */
+#define VIS_SP 0x004 /* also encode space */
+#define VIS_TAB 0x008 /* also encode tab */
+#define VIS_NL 0x010 /* also encode newline */
#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
-#define VIS_SAFE 0x20 /* only encode "unsafe" characters */
+#define VIS_SAFE 0x020 /* only encode "unsafe" characters */
/*
* other
*/
-#define VIS_NOSLASH 0x40 /* inhibit printing '\' */
-#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */
+#define VIS_NOSLASH 0x040 /* inhibit printing '\' */
+#define VIS_HTTPSTYLE 0x080 /* http-style escape % HEX HEX */
+#define VIS_QPSTYLE 0x100 /* quoted-printable-style escape = HEX HEX */
/*
* unvis return codes
@@ -86,8 +87,9 @@
char *vis __P((char *, int, int, int));
int strvis __P((char *, const char *, int));
int strvisx __P((char *, const char *, size_t, int));
+int unvis __P((int *, int, int *, int));
int strunvis __P((char *, const char *));
-int unvis __P((char *, int, int *, int));
+int strunvisx __P((char *, const char *, int));
__END_DECLS
#endif /* !_VIS_H_ */
Index: usr.bin/vis/foldit.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/vis/foldit.c,v
retrieving revision 1.4
diff -u -r1.4 foldit.c
--- usr.bin/vis/foldit.c 1999/08/28 01:07:25 1.4
+++ usr.bin/vis/foldit.c 2001/03/21 04:19:54
@@ -40,7 +40,10 @@
#endif /* not lint */
#include <stdio.h>
+#include <vis.h>
+extern int eflags;
+
int
foldit(chunk, col, max)
char *chunk;
@@ -54,24 +57,34 @@
again:
cp = chunk;
while (*cp) {
- switch(*cp) {
- case '\n':
- case '\r':
- col = 0;
- break;
- case '\t':
- col = col + 8 &~ 07;
- break;
- case '\b':
- col = col ? col - 1 : 0;
- break;
- default:
- col++;
- }
- if (col > (max - 2)) {
- printf("\\\n");
- col = 0;
- goto again;
+ if (eflags & VIS_QPSTYLE) {
+ if (*cp == '\n')
+ col = 0;
+ else if (++col > (max - 2)) {
+ printf ("=\n");
+ col = 0;
+ goto again;
+ }
+ } else {
+ switch(*cp) {
+ case '\n':
+ case '\r':
+ col = 0;
+ break;
+ case '\t':
+ col = col + 8 &~ 07;
+ break;
+ case '\b':
+ col = col ? col - 1 : 0;
+ break;
+ default:
+ col++;
+ }
+ if (col > (max - 2)) {
+ printf ("\\\n");
+ col = 0;
+ goto again;
+ }
}
cp++;
}
Index: usr.bin/vis/vis.1
===================================================================
RCS file: /home/ncvs/src/usr.bin/vis/vis.1,v
retrieving revision 1.6
diff -u -r1.6 vis.1
--- usr.bin/vis/vis.1 1999/08/28 01:07:25 1.6
+++ usr.bin/vis/vis.1 2001/03/22 02:31:39
@@ -40,7 +40,7 @@
.Nd display non-printable characters in a visual format
.Sh SYNOPSIS
.Nm
-.Op Fl cbflnostw
+.Op Fl cbfhlnoqstw
.Op Fl F Ar foldwidth
.Op Ar
.Sh DESCRIPTION
@@ -83,6 +83,12 @@
.It Fl f
Same as
.Fl F .
+.It Fl h
+Request a format which displays non-printable characters using URI
+encoding sequences (%dd where dd is an hexadecimal number) as
+described in RFC 2396. The
+.Fl b
+option is implied.
.It Fl l
Mark newlines with the visible sequence
.Ql \e$ ,
@@ -106,6 +112,14 @@
.It Fl o
Request a format which displays non-printable characters as
an octal number, \eddd.
+.It Fl q
+Request a format which displays non-printable characters in MIME
+quoted-printable sequences (=dd where dd is an hexadecimal number) as
+described in RFC 2045. The
+.Fl b
+and
+.Fl F 77
+options are implied.
.It Fl s
Only characters considered unsafe to send to a terminal are encoded.
This flag allows backspace, bell, and carriage return in addition
@@ -117,7 +131,24 @@
.El
.Sh SEE ALSO
.Xr unvis 1 ,
-.Xr vis 3
+.Xr vis 3 ,
+.Xr unvis 3 .
+.Rs
+.%T Multipurpose Internet Mail Extensions (MIME) Part One
+.%R Format of Internet Message Bodies.
+.%A N. Freed
+.%A N. Borenstein
+.%D November 1996
+.%O RFC2045
+.Re
+.Rs
+.%T Relative Uniform Resource Locators (URI)
+.%R Generic Syntax
+.%A T. Berners-Lee
+.%A R. Fielding
+.%D August 1998
+.%O RFC2396
+.Re
.Sh HISTORY
The
.Nm
Index: usr.bin/vis/vis.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/vis/vis.c,v
retrieving revision 1.6
diff -u -r1.6 vis.c
--- usr.bin/vis/vis.c 1999/08/28 01:07:25 1.6
+++ usr.bin/vis/vis.c 2001/03/22 03:48:21
@@ -67,7 +67,7 @@
(void) setlocale(LC_CTYPE, "");
- while ((ch = getopt(argc, argv, "nwctsobfF:ld")) != -1)
+ while ((ch = getopt(argc, argv, "nwchqtsobfF:ld")) != -1)
switch((char)ch) {
case 'n':
none++;
@@ -78,6 +78,12 @@
case 'c':
eflags |= VIS_CSTYLE;
break;
+ case 'h':
+ eflags |= VIS_HTTPSTYLE;
+ break;
+ case 'q':
+ eflags |= VIS_QPSTYLE;
+ break;
case 't':
eflags |= VIS_TAB;
break;
@@ -112,6 +118,11 @@
argc -= optind;
argv += optind;
+ if (eflags & VIS_QPSTYLE) {
+ foldwidth = 77;
+ fold++;
+ }
+
if (*argv)
while (*argv) {
if ((fp=fopen(*argv, "r")) != NULL)
@@ -125,14 +136,13 @@
exit(0);
}
-
static void
usage()
{
#ifdef DEBUG
- fprintf(stderr, "usage: vis [-cbflnostwd] [-F foldwidth] [file ...]\n");
+ fprintf(stderr, "usage: vis [-cbfhlnoqstwd] [-F foldwidth] [file ...]\n");
#else
- fprintf(stderr, "usage: vis [-cbflnostw] [-F foldwidth] [file ...]\n");
+ fprintf(stderr, "usage: vis [-cbfhlnoqstw] [-F foldwidth] [file ...]\n");
#endif
exit(1);
}
@@ -156,7 +166,8 @@
if (c == '\\')
*cp++ = '\\';
*cp = '\0';
- } else if (markeol && c == '\n') {
+ } else if (markeol && c == '\n' &&
+ !(eflags & (VIS_HTTPSTYLE|VIS_QPSTYLE))) {
cp = buff;
if ((eflags & VIS_NOSLASH) == 0)
*cp++ = '\\';
@@ -164,7 +175,7 @@
*cp++ = '\n';
*cp = '\0';
} else
- (void) vis(buff, (char)c, eflags, (char)rachar);
+ (void) vis(buff, c, eflags, rachar);
cp = buff;
if (fold) {
@@ -186,6 +197,11 @@
/*
* terminate partial line with a hidden newline
*/
- if (fold && *(cp-1) != '\n')
- printf("\\\n");
+ if (fold && *(cp-1) != '\n') {
+ if (eflags & VIS_QPSTYLE)
+ putchar ('=');
+ else
+ putchar ('\\');
+ putchar ('\n');
+ }
}
Index: usr.bin/unvis/unvis.1
===================================================================
RCS file: /home/ncvs/src/usr.bin/unvis/unvis.1,v
retrieving revision 1.5
diff -u -r1.5 unvis.1
--- usr.bin/unvis/unvis.1 1999/08/28 01:07:12 1.5
+++ usr.bin/unvis/unvis.1 2001/03/22 02:30:49
@@ -40,6 +40,7 @@
.Nd "revert a visual representation of data back to original form"
.Sh SYNOPSIS
.Nm
+.Op Fl hq
.Op Ar
.Sh DESCRIPTION
.Nm Unvis
@@ -47,10 +48,36 @@
.Xr vis 1 .
It reverts
a visual representation of data back to its original form on standard output.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl h
+Inputs are in URI encoded form (%dd where dd is an hexadecimal number)
+as described in RFC 2396.
+.It Fl q
+Inputs are in MIME quoted-printable from (=dd where dd is an
+hexadecimal number) as described in RFC 2045.
+.El
.Sh SEE ALSO
.Xr vis 1 ,
.Xr unvis 3 ,
-.Xr vis 3
+.Xr vis 3 .
+.Rs
+.%T Multipurpose Internet Mail Extensions (MIME) Part One
+.%R Format of Internet Message Bodies.
+.%A N. Freed
+.%A N. Borenstein
+.%D November 1996
+.%O RFC2045
+.Re
+.Rs
+.%T Relative Uniform Resource Locators (URI)
+.%R Generic Syntax
+.%A T. Berners-Lee
+.%A R. Fielding
+.%D August 1998
+.%O RFC2396
+.Re
.Sh HISTORY
The
.Nm
Index: usr.bin/unvis/unvis.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/unvis/unvis.c,v
retrieving revision 1.5
diff -u -r1.5 unvis.c
--- usr.bin/unvis/unvis.c 1999/08/28 01:07:13 1.5
+++ usr.bin/unvis/unvis.c 2001/03/21 05:53:52
@@ -50,6 +50,8 @@
#include <unistd.h>
#include <vis.h>
+int eflags;
+
void process __P((FILE *, char *));
static void usage __P((void));
@@ -60,8 +62,14 @@
FILE *fp;
int ch;
- while ((ch = getopt(argc, argv, "")) != -1)
+ while ((ch = getopt(argc, argv, "hq")) != -1)
switch((char)ch) {
+ case 'h':
+ eflags |= VIS_HTTPSTYLE;
+ break;
+ case 'q':
+ eflags |= VIS_QPSTYLE;
+ break;
case '?':
default:
usage();
@@ -85,7 +93,7 @@
static void
usage()
{
- fprintf(stderr, "usage: unvis [file ...]\n");
+ fprintf(stderr, "usage: unvis [-hq] [file ...]\n");
exit(1);
}
@@ -96,12 +104,12 @@
{
register int offset = 0, c, ret;
int state = 0;
- char outc;
+ int outc;
while ((c = getc(fp)) != EOF) {
offset++;
again:
- switch(ret = unvis(&outc, (char)c, &state, 0)) {
+ switch(ret = unvis(&outc, c, &state, eflags)) {
case UNVIS_VALID:
putchar(outc);
break;
@@ -119,6 +127,6 @@
errx(1, "bad return value (%d), can't happen", ret);
}
}
- if (unvis(&outc, (char)0, &state, UNVIS_END) == UNVIS_VALID)
+ if (unvis(&outc, 0, &state, UNVIS_END) == UNVIS_VALID)
putchar(outc);
}
Index: lib/libc/gen/unvis.3
===================================================================
RCS file: /home/ncvs/src/lib/libc/gen/unvis.3,v
retrieving revision 1.6.2.3
diff -u -r1.6.2.3 unvis.3
--- lib/libc/gen/unvis.3 2000/12/29 14:44:45 1.6.2.3
+++ lib/libc/gen/unvis.3 2001/03/22 02:29:27
@@ -47,32 +47,45 @@
.Fn unvis "char *cp" "int c" "int *astate" "int flag"
.Ft int
.Fn strunvis "char *dst" "const char *src"
+.Ft int
+.Fn strunvisx "char *dst" "const char *src" "int flag"
.Sh DESCRIPTION
The
-.Fn unvis
-and
+.Fn unvis ,
.Fn strunvis
+and
+.Fn strunvisx
functions
are used to decode a visual representation of characters, as produced
by the
.Xr vis 3
function, back into
-the original form. Unvis is called with successive characters in
+the original form. The
+.Fn unvis
+function is called with successive characters in
.Ar c
until a valid
sequence is recognized, at which time the decoded character is
available at the character pointed to by
.Ar cp .
-Strunvis decodes the
+The
+.Fn strunvis
+function decodes the
characters pointed to by
.Ar src
into the buffer pointed to by
.Ar dst .
+The
+.Fa flag
+parameter is used for altering the default range of
+characters considered for decoding.
.Pp
The
.Fn strunvis
-function
-simply copies
+and
+.Fn strunvisx
+functions
+simply copy
.Ar src
to
.Ar dst ,
@@ -124,9 +137,30 @@
unknown state. The decoder is placed into the starting state.
.El
.Pp
+Two forms of encoding style need to be specified to be recognized.
+Those forms are :
+.Bl -tag -width VIS_HTTPSTYLE
+.It Dv VIS_HTTPSTYLE
+Interpret URI encoded sequences as described in RFC 2396.
+Encoded values have the form
+.Ql %dd
+where
+.Em d
+represents an hexadecimal digit.
+.It Dv VIS_QPSTYLE
+Interpret MIME quoted-printable sequences as described in RFC 2045.
+Encoded values have the form
+.Ql =dd
+where
+.Em d
+represents an hexadecimal digit.
+.El
+.Pp
When all bytes in the stream have been processed, call
.Fn unvis
-one more time with flag set to
+one more time with
+.Fa flag
+set to
.Dv UNVIS_END
to extract any remaining character (the character passed in is ignored).
.Pp
@@ -157,7 +191,26 @@
(void) putchar(out);
.Ed
.Sh SEE ALSO
-.Xr vis 1
+.Xr unvis 1 ,
+.Xr vis 1 ,
+.Xr strvis 3 ,
+.Xr vis 3 .
+.Rs
+.%T Multipurpose Internet Mail Extensions (MIME) Part One
+.%R Format of Internet Message Bodies.
+.%A N. Freed
+.%A N. Borenstein
+.%D November 1996
+.%O RFC2045
+.Re
+.Rs
+.%T Relative Uniform Resource Locators (URI)
+.%R Generic Syntax
+.%A T. Berners-Lee
+.%A R. Fielding
+.%D August 1998
+.%O RFC2396
+.Re
.Sh HISTORY
The
.Fn unvis
Index: lib/libc/gen/unvis.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/gen/unvis.c,v
retrieving revision 1.4.8.1
diff -u -r1.4.8.1 unvis.c
--- lib/libc/gen/unvis.c 2000/08/17 08:25:54 1.4.8.1
+++ lib/libc/gen/unvis.c 2001/03/22 18:41:49
@@ -38,6 +38,7 @@
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
+#include <stdio.h>
#include <vis.h>
/*
@@ -53,19 +54,18 @@
#define S_HEX2 7 /* hex digit 2 */
#define S_HTTP 0x080 /* %HEXHEX escape */
+#define S_QP 0x100 /* =HEXHEX escape */
-#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
-#define ishex(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '9' || ((u_char)(c)) >= 'a' && ((u_char)(c)) <= 'f')
+#define isoctal(c) ((c) >= '0' && (c) <= '7')
+#define ishex(c) ((c) >= '0' && (c) <= '9' || (c) >= 'a' && (c) <= 'f')
/*
* unvis - decode characters previously encoded by vis
*/
int
unvis(cp, c, astate, flag)
- char *cp;
- int c, *astate, flag;
+ int *cp, c, *astate, flag;
{
-
if (flag & UNVIS_END) {
if (*astate == S_OCTAL2 || *astate == S_OCTAL3) {
*astate = S_GROUND;
@@ -74,15 +74,19 @@
return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
}
- switch (*astate & ~S_HTTP) {
+ switch (*astate & ~(S_HTTP|S_QP)) {
case S_GROUND:
*cp = 0;
- if (c == '\\') {
+ if (c == '\\' && !(flag & VIS_QPSTYLE)) {
*astate = S_START;
return (0);
+ }
+ if (c == '=' && (flag & VIS_QPSTYLE)) {
+ *astate = S_START | S_QP;
+ return (0);
}
- if (flag & VIS_HTTPSTYLE && c == '%') {
+ if (c == '%' && (flag & VIS_HTTPSTYLE)) {
*astate = S_START | S_HTTP;
return (0);
}
@@ -90,9 +94,9 @@
return (UNVIS_VALID);
case S_START:
- if (*astate & S_HTTP) {
+ if (*astate & (S_HTTP|S_QP)) {
if (ishex(tolower(c))) {
- *cp = isdigit(c) ? (c - '0') : (tolower(c) - 'a');
+ *cp = isdigit(c) ? (c - '0') : (tolower(c) - 'a' + 10);
*astate = S_HEX2;
return (0);
}
@@ -218,7 +222,8 @@
case S_HEX2: /* second mandatory hex digit */
if (ishex(tolower(c))) {
- *cp = (isdigit(c) ? (*cp << 4) + (c - '0') : (*cp << 4) + (tolower(c) - 'a' + 10));
+ *cp = (*cp << 4) + (isdigit(c) ?
+ (c - '0') : (tolower(c) - 'a' + 10));
}
*astate = S_GROUND;
return (UNVIS_VALID);
@@ -244,18 +249,19 @@
register char *dst;
register const char *src;
{
- register char c;
+ register int c;
+ int tc;
char *start = dst;
int state = 0;
while ( (c = *src++) ) {
again:
- switch (unvis(dst, c, &state, 0)) {
+ switch (unvis(&tc, c, &state, 0)) {
case UNVIS_VALID:
- dst++;
+ *dst++ = tc;
break;
case UNVIS_VALIDPUSH:
- dst++;
+ *dst++ = tc;
goto again;
case 0:
case UNVIS_NOCHAR:
@@ -264,8 +270,8 @@
return (-1);
}
}
- if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID)
- dst++;
+ if (unvis(&tc, c, &state, UNVIS_END) == UNVIS_VALID)
+ *dst++ = tc;
*dst = '\0';
return (dst - start);
}
@@ -274,19 +280,21 @@
strunvisx(dst, src, flag)
register char *dst;
register const char *src;
+ int flag;
{
- register char c;
+ register int c;
+ int tc;
char *start = dst;
int state = 0;
while ( (c = *src++) ) {
again:
- switch (unvis(dst, c, &state, flag)) {
+ switch (unvis(&tc, c, &state, flag)) {
case UNVIS_VALID:
- dst++;
+ *dst++ = tc;
break;
case UNVIS_VALIDPUSH:
- dst++;
+ *dst++ = tc;
goto again;
case 0:
case UNVIS_NOCHAR:
@@ -295,8 +303,8 @@
return (-1);
}
}
- if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID)
- dst++;
+ if (unvis(&tc, c, &state, UNVIS_END) == UNVIS_VALID)
+ *dst++ = tc;
*dst = '\0';
return (dst - start);
}
Index: lib/libc/gen/vis.3
===================================================================
RCS file: /home/ncvs/src/lib/libc/gen/vis.3,v
retrieving revision 1.8.2.4
diff -u -r1.8.2.4 vis.3
--- lib/libc/gen/vis.3 2001/03/06 16:45:55 1.8.2.4
+++ lib/libc/gen/vis.3 2001/03/22 02:24:03
@@ -67,7 +67,9 @@
encoding a set of characters into a buffer, the size of the buffer should
be four times the number of characters encoded, plus one for the trailing
.Dv NUL .
-The flag parameter is used for altering the default range of
+The
+.Fa flag
+parameter is used for altering the default range of
characters considered for encoding and for altering the visual
representation.
The additional character,
@@ -132,8 +134,7 @@
except space, tab, and newline are encoded.
(See
.Xr isgraph 3 . )
-The following flags
-alter this:
+The following flags alter this:
.Bl -tag -width VIS_WHITEX
.It Dv VIS_SP
Also encode space.
@@ -239,12 +240,19 @@
is an octal digit, the latter representation is used to
avoid ambiguity.
.It Dv VIS_HTTPSTYLE
-Use URI encoding as described in RFC 1808.
+Use URI encoding as described in RFC 2396.
The form is
.Ql %dd
where
+.Em d
+represents an hexadecimal digit.
+.It Dv VIS_QPSTYLE
+Use MIME quoted-printable encoding as described in RFC 2045.
+The form is
+.Ql =dd
+where
.Em d
-represents a hexadecimal digit.
+represents an hexadecimal digit.
.It Dv VIS_OCTAL
Use a three digit octal sequence. The form is
.Ql \eddd
@@ -253,6 +261,13 @@
represents an octal digit.
.El
.Pp
+If more than one style is specified, precedences are as follow :
+.Dv VIS_QPSTYLE ,
+.Dv VIS_HTTPSTYLE ,
+.Dv VIS_CSTYLE ,
+.Dv VIS_OCTAL ,
+.Dv (default) .
+.Pp
There is one additional flag,
.Dv VIS_NOSLASH ,
which inhibits the
@@ -263,15 +278,33 @@
meta characters as
.Ql M-C ) .
With this flag set, the encoding is
-ambiguous and non-invertible.
+ambiguous and non-invertible. The
+.Dv VIS_NOSLASH
+flag is implied by
+.Dv VIS_HTTPSTYLE
+or
+.Dv VIS_QPSTYLE
+styles.
.Sh SEE ALSO
+.Xr vis 1 ,
.Xr unvis 1 ,
.Xr strunvis 3 ,
-.Xr unvis 3
+.Xr unvis 3 .
+.Rs
+.%T Multipurpose Internet Mail Extensions (MIME) Part One
+.%R Format of Internet Message Bodies.
+.%A N. Freed
+.%A N. Borenstein
+.%D November 1996
+.%O RFC2045
+.Re
.Rs
+.%T Relative Uniform Resource Locators (URI)
+.%R Generic Syntax
+.%A T. Berners-Lee
.%A R. Fielding
-.%T Relative Uniform Resource Locators
-.%O RFC1808
+.%D August 1998
+.%O RFC2396
.Re
.Sh HISTORY
These functions first appeared in
Index: lib/libc/gen/vis.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/gen/vis.c,v
retrieving revision 1.5.8.2
diff -u -r1.5.8.2 vis.c
--- lib/libc/gen/vis.c 2001/03/05 09:44:34 1.5.8.2
+++ lib/libc/gen/vis.c 2001/03/22 18:42:22
@@ -54,33 +54,84 @@
int c, nextc;
register int flag;
{
- c = (unsigned char)c;
+ static int lastc = EOF;
+ if (flag & VIS_QPSTYLE) {
+ /* Described in RFC 2045 */
+ if (c == '\n') {
+ if (isascii(lastc) && isblank(lastc)) {
+ *dst++ = '=';
+ *dst++ = c;
+ }
+ *dst++ = c;
+ goto done;
+ }
+ if (c == '=' || !(isascii(c) && (isgraph(c) || isblank(c)))) {
+ *dst++ = '=';
+ snprintf(dst, 4, "%02X", c);
+ dst += 2;
+ goto done;
+ }
+ }
+
if (flag & VIS_HTTPSTYLE) {
- /* Described in RFC 1808 */
- if (!(isalnum(c) /* alpha-numeric */
+ if (!(
+#define RFC 0
+#if RFC == 2396
+ isalnum(c) /* alpha-numeric */
+ /* reserved */
+ || c == ';' || c == '/' || c == '?' || c == ':'
+ || c == '@' || c == '&' || c == '=' || c == '+'
+ || c == '$' || c == ','
+ /* mark */
+ || c == '-' || c == '_' || c == '.' || c == '!'
+ || c == '~' || c == '*' || c == '\'' || c == '('
+ || c == ')'
+ /* delims /
+ || c == '<' || c == '>' || c == '#' || c == '%'
+ || c == '"'
+ /* unwise */
+ || c == '{' || c == '}' || c == '|' || c == '\\'
+ || c == '^' || c == '[' || c == ']' || c == '`'
+#elif RFC == 1808 /* obsoleted by RFC2396 */
+ !(isalnum(c) /* alpha-numeric */
/* safe */
- || c == '$' || c == '-' || c == '_' || c == '.' || c == '+'
+ || c == '$' || c == '-' || c == '_' || c == '.'
+ || c == '+'
/* extra */
|| c == '!' || c == '*' || c == '\'' || c == '('
- || c == ')' || c == ',')) {
+ || c == ')' || c == ','
+ /* national */
+ || c == '{' || c == '}' || c == '|' || c == '\\'
+ || c == '^' || c == '~' || c == '[' || c == ']'
+ || c == '`'
+ /* reserved */
+ || c == ';' || c == '/' || c == '?' || c == ':'
+ || c == '@' || c == '&' || c == '='
+ /* punctuation */
+ || c == '<' || c == '>' || c == '#' || c == '%'
+ || c == '"'
+#else /* same as above, but faster. */
+ isgraph(c) && isascii(c)
+#endif
+ )) {
*dst++ = '%';
- snprintf(dst, 4, (c < 16 ? "0%X" : "%X"), c);
+ snprintf(dst, 4, "%02X", c);
dst += 2;
goto done;
}
}
if (isgraph(c) ||
- ((flag & VIS_SP) == 0 && c == ' ') ||
- ((flag & VIS_TAB) == 0 && c == '\t') ||
- ((flag & VIS_NL) == 0 && c == '\n') ||
- ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) {
+ (c == ' ' && !(flag & VIS_SP)) ||
+ (c == '\t' && !(flag & VIS_TAB)) ||
+ (c == '\n' && !(flag & VIS_NL)) ||
+ ((c == '\b' || c == '\007' || c == '\r')) && (flag & VIS_SAFE)) {
*dst++ = c;
- if (c == '\\' && (flag & VIS_NOSLASH) == 0)
+ if (c == '\\' &&
+ !(flag & (VIS_NOSLASH|VIS_QPSTYLE|VIS_HTTPSTYLE)))
*dst++ = '\\';
- *dst = '\0';
- return (dst);
+ goto done;
}
if (flag & VIS_CSTYLE) {
@@ -133,9 +184,9 @@
}
if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
*dst++ = '\\';
- *dst++ = ((u_char)c >> 6 & 07) + '0';
- *dst++ = ((u_char)c >> 3 & 07) + '0';
- *dst++ = ((u_char)c & 07) + '0';
+ *dst++ = (c >> 6 & 07) + '0';
+ *dst++ = (c >> 3 & 07) + '0';
+ *dst++ = (c & 07) + '0';
goto done;
}
if ((flag & VIS_NOSLASH) == 0)
@@ -155,6 +206,7 @@
*dst++ = c;
}
done:
+ lastc = c;
*dst = '\0';
return (dst);
}
@@ -175,10 +227,10 @@
register const char *src;
int flag;
{
- register char c;
- char *start;
+ register int c;
+ char *start = dst;
- for (start = dst; (c = *src); )
+ while ( (c = *src) )
dst = vis(dst, c, flag, *++src);
*dst = '\0';
return (dst - start);
@@ -191,15 +243,15 @@
register size_t len;
int flag;
{
- int c;
- char *start;
+ register int c;
+ char *start = dst;
- for (start = dst; len > 1; len--) {
+ while (len-- > 1) {
c = *src;
dst = vis(dst, c, flag, *++src);
}
- if (len)
- dst = vis(dst, *src, flag, '\0');
+ if (len > 0)
+ dst = vis(dst, *src, flag, 0);
*dst = '\0';
return (dst - start);
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200103221928.f2MJS2I22918>
