| 1 | #include <stdio.h> |
|---|
| 2 | #include <string.h> |
|---|
| 3 | #include <stdint.h> |
|---|
| 4 | #include <zlib.h> |
|---|
| 5 | |
|---|
| 6 | static int usage(char** argv); |
|---|
| 7 | static int in_operation(); |
|---|
| 8 | static int out_operation(); |
|---|
| 9 | |
|---|
| 10 | enum program_constants { PAD_SIZE=262144 }; |
|---|
| 11 | int main(int argc, char** argv) { |
|---|
| 12 | int err = 1; |
|---|
| 13 | if ( argc > 1 ) { |
|---|
| 14 | if ( 0==strcasecmp(argv[1],"host") ) { |
|---|
| 15 | err = in_operation(); |
|---|
| 16 | } |
|---|
| 17 | else if ( 0==strcasecmp(argv[1],"device") ) { |
|---|
| 18 | err = out_operation(); |
|---|
| 19 | } |
|---|
| 20 | else err = usage(argv); |
|---|
| 21 | } |
|---|
| 22 | else err = usage(argv); |
|---|
| 23 | return err; |
|---|
| 24 | } |
|---|
| 25 | |
|---|
| 26 | int usage(char** argv) { |
|---|
| 27 | FILE* logfile =stderr; |
|---|
| 28 | fprintf(logfile,"usage %s host|device\n",argv[0]); |
|---|
| 29 | return 1; |
|---|
| 30 | } |
|---|
| 31 | |
|---|
| 32 | int in_operation() |
|---|
| 33 | { |
|---|
| 34 | FILE* infile =stdin; |
|---|
| 35 | FILE* outfile =stdout; |
|---|
| 36 | FILE* logfile =stderr; |
|---|
| 37 | |
|---|
| 38 | char pad[PAD_SIZE]; |
|---|
| 39 | int c = EOF; |
|---|
| 40 | long unsigned c0=0, count = 0; |
|---|
| 41 | unsigned long crc; |
|---|
| 42 | |
|---|
| 43 | memset(pad, 0, PAD_SIZE); |
|---|
| 44 | if ( infile ) c = fgetc(infile); |
|---|
| 45 | |
|---|
| 46 | count = c0 = 4; /* crc32 offset */ |
|---|
| 47 | while ( c != EOF ) { |
|---|
| 48 | if ( c == '\n' ) |
|---|
| 49 | pad[count++] = '\0'; |
|---|
| 50 | else |
|---|
| 51 | pad[count++] = c&0xff; |
|---|
| 52 | if ( !ferror(infile) ) |
|---|
| 53 | c = fgetc(infile); |
|---|
| 54 | else |
|---|
| 55 | c = EOF; |
|---|
| 56 | } |
|---|
| 57 | pad[count++] = '\0'; /* double '\0' */ |
|---|
| 58 | c0 = count; |
|---|
| 59 | crc=crc32(0, pad+4, PAD_SIZE-4); |
|---|
| 60 | pad[0] = (crc&0xff); |
|---|
| 61 | pad[1] = (crc>>8)&0xff; |
|---|
| 62 | pad[2] = (crc>>16)&0xff; |
|---|
| 63 | pad[3] = (crc>>24)&0xff; |
|---|
| 64 | fprintf( logfile, "CRC32 = %02x %02x %02x %02x\n", |
|---|
| 65 | (unsigned char)pad[0], |
|---|
| 66 | (unsigned char)pad[1], |
|---|
| 67 | (unsigned char)pad[2], |
|---|
| 68 | (unsigned char)pad[3] ); |
|---|
| 69 | count = 0; |
|---|
| 70 | while ( count < PAD_SIZE ) { |
|---|
| 71 | c= fwrite(pad, 1, PAD_SIZE-count,outfile); |
|---|
| 72 | if ( c > 0 ) count += c; |
|---|
| 73 | else { fprintf( logfile, "write error %d\n", c ); break; } |
|---|
| 74 | } |
|---|
| 75 | fprintf(logfile, "wrote %ld,%ld(padded) characters to output\n", c0, count ); |
|---|
| 76 | return 0; |
|---|
| 77 | } |
|---|
| 78 | |
|---|
| 79 | int out_operation() |
|---|
| 80 | { |
|---|
| 81 | FILE* infile =stdin; |
|---|
| 82 | FILE* outfile =stdout; |
|---|
| 83 | FILE* logfile =stderr; |
|---|
| 84 | |
|---|
| 85 | char pad[PAD_SIZE]; |
|---|
| 86 | int c = EOF, check = 0; |
|---|
| 87 | long unsigned count = 0, c0=0; |
|---|
| 88 | long unsigned crc; |
|---|
| 89 | |
|---|
| 90 | memset(pad, 0, PAD_SIZE); |
|---|
| 91 | if ( infile ) pad[0] = fgetc(infile); |
|---|
| 92 | if ( infile ) pad[1] = fgetc(infile); |
|---|
| 93 | if ( infile ) pad[2] = fgetc(infile); |
|---|
| 94 | if ( infile ) pad[3] = fgetc(infile); |
|---|
| 95 | fprintf( logfile, "orig CRC32 = %02x %02x %02x %02x\n", |
|---|
| 96 | (unsigned char)pad[0], |
|---|
| 97 | (unsigned char)pad[1], |
|---|
| 98 | (unsigned char)pad[2], |
|---|
| 99 | (unsigned char)pad[3] ); |
|---|
| 100 | if ( infile ) c = fgetc(infile); |
|---|
| 101 | count=4; |
|---|
| 102 | while ( c != EOF ) { |
|---|
| 103 | if ( c == '\0' ) { |
|---|
| 104 | if ( check&1 ) { |
|---|
| 105 | fputc('\n', outfile); |
|---|
| 106 | pad[count++] = '\0'; |
|---|
| 107 | break; |
|---|
| 108 | } |
|---|
| 109 | fputc('\n', outfile); |
|---|
| 110 | pad[count++] = '\0'; |
|---|
| 111 | check |= 1; |
|---|
| 112 | } |
|---|
| 113 | else { |
|---|
| 114 | fputc( c, outfile ); |
|---|
| 115 | pad[count++] = c; |
|---|
| 116 | check &= ~1; |
|---|
| 117 | } |
|---|
| 118 | if ( !ferror(infile) ) |
|---|
| 119 | c = fgetc(infile); |
|---|
| 120 | else |
|---|
| 121 | c = EOF; |
|---|
| 122 | } |
|---|
| 123 | c0 = count; |
|---|
| 124 | c0 = PAD_SIZE-4; |
|---|
| 125 | crc=crc32(0, pad+4, c0); |
|---|
| 126 | pad[0] = (crc&0xff); |
|---|
| 127 | pad[1] = (crc>>8)&0xff; |
|---|
| 128 | pad[2] = (crc>>16)&0xff; |
|---|
| 129 | pad[3] = (crc>>24)&0xff; |
|---|
| 130 | |
|---|
| 131 | fprintf( logfile, "CRC32 = %02x %02x %02x %02x\n", |
|---|
| 132 | (unsigned char)pad[0], |
|---|
| 133 | (unsigned char)pad[1], |
|---|
| 134 | (unsigned char)pad[2], |
|---|
| 135 | (unsigned char)pad[3] ); |
|---|
| 136 | count = 0; |
|---|
| 137 | fprintf(logfile, "wrote %ld characters to output\n", c0 ); |
|---|
| 138 | return 0; |
|---|
| 139 | } |
|---|