1 /*
2 * bencode [file]
3 */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include "coder.h"
7 #define MAXPERLINE 78 /* max chars/line */
8 char *myname;
9
main(argc,argv)10 main(argc,argv)
11 char **argv;
12 {
13 register FILE *fin = stdin, *fout = stdout; /* faster in a register */
14 register int c, bcount, ccount = MAXPERLINE-1;
15 register long word, nbytes;
16 register unsigned crc;
17
18 myname = argv[0];
19 if (sizeof(word) < 4)
20 fprintf(stderr, "%s: word size too small\n", myname), exit(1);
21 if (argc == 2 && (fin = fopen(argv[1], "r")) == NULL) {
22 fprintf(stderr, "%s: ", myname);
23 perror(argv[1]);
24 exit(1);
25 }
26 else if (argc > 2) {
27 fprintf(stderr, "Usage: %s [file]\n", myname);
28 exit(1);
29 }
30
31 #define PUTC(c) \
32 putc(c, fout); \
33 if (--ccount == 0) { \
34 putc('\n', fout); \
35 ccount = MAXPERLINE-1; \
36 }
37
38 fputs(header, fout);
39 word = 0;
40 bcount = 3;
41 crc = 0;
42 for (nbytes = 0; (c = getc(fin)) != EOF; nbytes++) {
43 CRC(crc, c);
44 word <<= 8;
45 word |= c;
46 if (--bcount == 0) {
47 PUTC(ENCODE((word >> 18) & 077));
48 PUTC(ENCODE((word >> 12) & 077));
49 PUTC(ENCODE((word >> 6) & 077));
50 PUTC(ENCODE((word ) & 077));
51 word = 0;
52 bcount = 3;
53 }
54 }
55 /*
56 * A trailing / marks end of data.
57 * The last partial encoded word follows in hex,
58 * preceded by a byte count.
59 */
60 if (ccount != MAXPERLINE-1) /* avoid empty lines */
61 putc('\n', fout);
62 fprintf(fout, "/%d%lx\n", 3-bcount, word);
63 /*
64 * And finally the byte count and CRC.
65 */
66 fprintf(fout, "%ld %x\n", nbytes, crc & 0xffff);
67 exit(0);
68 }
69