2012-10-05 21:14:23 +00:00
|
|
|
#include <u.h>
|
|
|
|
#include <libc.h>
|
|
|
|
#include <bio.h>
|
|
|
|
|
|
|
|
Biobuf bin;
|
|
|
|
Biobuf bout;
|
|
|
|
int dflag;
|
|
|
|
|
|
|
|
char hex[] = "0123456789abcdef";
|
|
|
|
char Hex[] = "0123456789ABCDEF";
|
|
|
|
|
|
|
|
int
|
|
|
|
hexdigit(int c)
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
|
2012-10-05 21:30:05 +00:00
|
|
|
if(c > 0){
|
2012-10-05 21:14:23 +00:00
|
|
|
if((p = strchr(Hex, c)) != 0)
|
|
|
|
return p - Hex;
|
|
|
|
if((p = strchr(hex, c)) != 0)
|
|
|
|
return p - hex;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
usage(void)
|
|
|
|
{
|
2020-03-10 17:09:34 +00:00
|
|
|
fprint(2, "usage: %s [ -d ] [ file ]\n", argv0);
|
2012-10-05 21:14:23 +00:00
|
|
|
exits("usage");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
{
|
|
|
|
int c;
|
|
|
|
|
|
|
|
ARGBEGIN {
|
|
|
|
case 'd':
|
|
|
|
dflag = 1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
usage();
|
|
|
|
} ARGEND;
|
2012-10-05 21:21:17 +00:00
|
|
|
|
2012-10-05 21:14:23 +00:00
|
|
|
if(argc == 1){
|
2012-10-13 13:35:39 +00:00
|
|
|
int fd;
|
|
|
|
|
|
|
|
fd = open(*argv, OREAD);
|
|
|
|
if(fd < 0)
|
2012-10-05 21:14:23 +00:00
|
|
|
sysfatal("%r");
|
2012-10-13 13:35:39 +00:00
|
|
|
if(fd != 0) dup(fd, 0);
|
2012-10-05 21:14:23 +00:00
|
|
|
} else if(argc > 1)
|
|
|
|
usage();
|
|
|
|
|
|
|
|
Binit(&bin, 0, OREAD);
|
|
|
|
Binit(&bout, 1, OWRITE);
|
|
|
|
|
|
|
|
if(dflag){
|
|
|
|
while((c = Bgetc(&bin)) >= 0){
|
|
|
|
if(c == '%'){
|
|
|
|
int c1, c2, x1, x2;
|
|
|
|
|
|
|
|
if((c1 = Bgetc(&bin)) < 0)
|
|
|
|
break;
|
|
|
|
if((x1 = hexdigit(c1)) < 0){
|
|
|
|
Bungetc(&bin);
|
|
|
|
Bputc(&bout, c);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if((c2 = Bgetc(&bin)) < 0)
|
|
|
|
break;
|
|
|
|
if((x2 = hexdigit(c2)) < 0){
|
|
|
|
Bungetc(&bin);
|
|
|
|
Bputc(&bout, c);
|
|
|
|
Bputc(&bout, c1);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
c = x1<<4 | x2;
|
2012-10-05 21:21:17 +00:00
|
|
|
} else if(c == '+')
|
|
|
|
c = ' ';
|
2012-10-05 21:14:23 +00:00
|
|
|
Bputc(&bout, c);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
while((c = Bgetc(&bin)) >= 0){
|
2012-10-05 21:38:43 +00:00
|
|
|
if(c>0 && strchr("/$-_@.!*'(),", c)
|
2012-10-05 21:14:23 +00:00
|
|
|
|| 'a'<=c && c<='z'
|
|
|
|
|| 'A'<=c && c<='Z'
|
|
|
|
|| '0'<=c && c<='9')
|
|
|
|
Bputc(&bout, c);
|
|
|
|
else if(c == ' ')
|
|
|
|
Bputc(&bout, '+');
|
|
|
|
else {
|
|
|
|
Bputc(&bout, '%');
|
|
|
|
Bputc(&bout, Hex[c>>4]);
|
|
|
|
Bputc(&bout, Hex[c&15]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Bflush(&bout);
|
|
|
|
exits(0);
|
|
|
|
}
|