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