urlencode.c - 9base - revived minimalist port of Plan 9 userland to Unix
 (HTM) git clone git://git.suckless.org/9base
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) 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 }