urlencode.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
urlencode.c (1546B) | |
--- | |
1 #include <u.h> | |
2 #include <libc.h> | |
3 #include <bio.h> | |
4 | |
5 Biobuf bin; | |
6 Biobuf bout; | |
7 int dflag; | |
8 | |
9 char hex[] = "0123456789abcdef"; | |
10 char Hex[] = "0123456789ABCDEF"; | |
11 | |
12 int | |
13 hexdigit(int c) | |
14 { | |
15 char *p; | |
16 | |
17 if(c > 0){ | |
18 if((p = strchr(Hex, c)) != 0) | |
19 return p - Hex; | |
20 if((p = strchr(hex, c)) != 0) | |
21 return p - hex; | |
22 } | |
23 return -1; | |
24 } | |
25 | |
26 void | |
27 usage(void) | |
28 { | |
29 fprint(2, "Usage: %s [ -d ] [ file ]\n", argv0); | |
30 exits("usage"); | |
31 } | |
32 | |
33 void | |
34 main(int argc, char *argv[]) | |
35 { | |
36 int c; | |
37 | |
38 ARGBEGIN { | |
39 case 'd': | |
40 dflag = 1; | |
41 break; | |
42 default: | |
43 usage(); | |
44 } ARGEND; | |
45 | |
46 if(argc == 1){ | |
47 int fd; | |
48 | |
49 fd = open(*argv, OREAD); | |
50 if(fd < 0) | |
51 sysfatal("%r"); | |
52 if(fd != 0) dup(fd, 0); | |
53 } else if(argc > 1) | |
54 usage(); | |
55 | |
56 Binit(&bin, 0, OREAD); | |
57 Binit(&bout, 1, OWRITE); | |
58 | |
59 if(dflag){ | |
60 while((c = Bgetc(&bin)) >= 0){ | |
61 if(c == '%'){ | |
62 int c1, c2, x1, x2; | |
63 | |
64 if((c1 = Bgetc(&bin)) < 0) | |
65 break; | |
66 if((x1 = hexdigit(c1)) < 0){ | |
67 Bungetc(&bin); | |
68 Bputc(&bout, c); | |
69 continue; | |
70 } | |
71 if((c2 = Bgetc(&bin)) < 0) | |
72 break; | |
73 if((x2 = hexdigit(c2)) < 0){ | |
74 Bungetc(&bin); | |
75 Bputc(&bout, c); | |
76 Bputc(&bout, c1); | |
77 continue; | |
78 } | |
79 c = x1<<4 | x2; | |
80 } else if(c == '+') | |
81 c = ' '; | |
82 Bputc(&bout, c); | |
83 } | |
84 } else { | |
85 while((c = Bgetc(&bin)) >= 0){ | |
86 if(c>0 && strchr("/$-_@.!*'(),", c) | |
87 || 'a'<=c && c<='z' | |
88 || 'A'<=c && c<='Z' | |
89 || '0'<=c && c<='9') | |
90 Bputc(&bout, c); | |
91 else if(c == ' ') | |
92 Bputc(&bout, '+'); | |
93 else { | |
94 Bputc(&bout, '%'); | |
95 Bputc(&bout, Hex[c>>4]); | |
96 Bputc(&bout, Hex[c&15]); | |
97 } | |
98 } | |
99 } | |
100 | |
101 Bflush(&bout); | |
102 exits(0); | |
103 } |