Fix line-wrapping bug in baseconv.
[doldaconnect.git] / config / util / baseconv.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <unistd.h>
5
6 #include "utils.h"
7
8 int main(int argc, char **argv)
9 {
10     char buf[25];
11     int ret, linelen;
12     char *decbuf, *encbuf;
13     size_t data, buflen;
14     char *(*decfn)(char *, size_t *);
15     char *(*encfn)(char *, size_t);
16     
17     if(argc < 3) {
18         fprintf(stderr, "usage: baseconv [4568] [4568]\n");
19         fprintf(stderr, "\tenter data on stdin\n");
20         exit(1);
21     }
22     data = 0;
23     if(!strcmp(argv[1], "4")) {
24         decfn = hexdecode;
25     } else if(!strcmp(argv[1], "5")) {
26         decfn = base32decode;
27     } else if(!strcmp(argv[1], "6")) {
28         decfn = base64decode;
29     } else if(!strcmp(argv[1], "8")) {
30         decfn = NULL;
31     } else {
32         fprintf(stderr, "unknown decoding: %s\n", argv[1]);
33         exit(1);
34     }
35     if(!strcmp(argv[2], "4")) {
36         encfn = hexencode;
37     } else if(!strcmp(argv[2], "5")) {
38         encfn = base32encode;
39     } else if(!strcmp(argv[2], "6")) {
40         encfn = base64encode;
41     } else if(!strcmp(argv[2], "8")) {
42         encfn = NULL;
43     } else {
44         fprintf(stderr, "unknown encoding: %s\n", argv[1]);
45         exit(1);
46     }
47     linelen = 0;
48     while((ret = read(0, buf + data, 24 - data)) >= 0) {
49         if(((data += ret) == 24) || (ret == 0)) {
50             if(decfn == NULL) {
51                 decbuf = memcpy(smalloc(data), buf, data);
52                 buflen = data;
53             } else {
54                 buf[data] = 0;
55                 if((decbuf = decfn(buf, &buflen)) == NULL) {
56                     fprintf(stderr, "invalid input\n");
57                     exit(1);
58                 }
59             }
60             if(encfn == NULL) {
61                 encbuf = memcpy(smalloc(buflen), decbuf, buflen);
62                 fwrite(encbuf, 1, buflen, stdout);
63             } else {
64                 encbuf = encfn(decbuf, buflen);
65                 buflen = strlen(encbuf);
66                 if(linelen + buflen > 60) {
67                     fwrite(encbuf, 1, 60 - linelen, stdout);
68                     fwrite("\n", 1, 1, stdout);
69                     memmove(encbuf, encbuf + 60 - linelen, buflen -= 60 - linelen);
70                 }
71                 fwrite(encbuf, 1, buflen, stdout);
72                 linelen += buflen;
73             }
74             fflush(stdout);
75             free(encbuf);
76             free(decbuf);
77             data = 0;
78         }
79         if(ret == 0)
80             break;
81     }
82     if(ret < 0) {
83         perror("read");
84         exit(1);
85     }
86     return(0);
87 }