1 | /** |
---|
2 | * strip-null-bytes: A small C program which strips null bytes |
---|
3 | * at beginning and end of STDIN and echos the data (without the |
---|
4 | * null bytes) to STDOUT. |
---|
5 | * |
---|
6 | * why not a perl tool? perl is nice for complex jobs, but not for |
---|
7 | * something like this low level thing ;-) |
---|
8 | * |
---|
9 | * (c) 14.06.08 sven |
---|
10 | * use it as LPGL |
---|
11 | * |
---|
12 | **/ |
---|
13 | |
---|
14 | #include <stdio.h> |
---|
15 | #include <string.h> |
---|
16 | #include <stdlib.h> |
---|
17 | #define DPRINTF(bla...) { if(flag_debug) fprintf(stderr,bla); } |
---|
18 | |
---|
19 | int stream_get_contents(FILE *stream, unsigned char **content) { |
---|
20 | /** |
---|
21 | * helper function to read in stdin into heap array; from |
---|
22 | * PaperTape cairo project -> from Glib. |
---|
23 | **/ |
---|
24 | |
---|
25 | unsigned char buf[4096]; |
---|
26 | size_t bytes; // gerade eben eingelesene bytes |
---|
27 | unsigned char *str = NULL; |
---|
28 | size_t total_bytes = 0; // alle bis jetzt eingelesenen bytes |
---|
29 | size_t total_allocated = 0; |
---|
30 | unsigned char *tmp; // fuers realloc |
---|
31 | |
---|
32 | while(!feof(stream)) { |
---|
33 | bytes = fread(buf, 1, sizeof(buf), stream); |
---|
34 | |
---|
35 | while( (total_bytes + bytes) > total_allocated) { |
---|
36 | if(str) |
---|
37 | total_allocated *= 2; |
---|
38 | else |
---|
39 | total_allocated = bytes > sizeof(buf) ? bytes : sizeof(buf); |
---|
40 | |
---|
41 | tmp = realloc(str, total_allocated); |
---|
42 | |
---|
43 | if(tmp == NULL) { |
---|
44 | fprintf(stderr, "*** file_get_contents ERROR *** Could not reallocate\n"); |
---|
45 | exit(1); |
---|
46 | } |
---|
47 | |
---|
48 | str = tmp; |
---|
49 | } // while innen |
---|
50 | |
---|
51 | memcpy(str + total_bytes, buf, bytes); |
---|
52 | total_bytes += bytes; |
---|
53 | } // while |
---|
54 | |
---|
55 | if(total_allocated == 0) |
---|
56 | str = malloc(1); // ein leerer String halt. |
---|
57 | |
---|
58 | *content = str; |
---|
59 | return total_bytes; |
---|
60 | } |
---|
61 | |
---|
62 | int main(int argc, char **argv) { |
---|
63 | unsigned char *bytes; |
---|
64 | int length; |
---|
65 | int x_start, x_end, x; |
---|
66 | int flag_start, flag_end, flag_debug; |
---|
67 | flag_debug = flag_start = flag_end = 0; |
---|
68 | |
---|
69 | int c; |
---|
70 | while( (c = getopt(argc, argv, "bsehd")) != -1) |
---|
71 | switch(c) { |
---|
72 | case 'd': |
---|
73 | flag_debug = 1; |
---|
74 | break; |
---|
75 | case 'h': |
---|
76 | fprintf(stderr, "Usage: %s [-d] [-s/b] [-e] [-h]\n" |
---|
77 | " optional parameters:\n" |
---|
78 | " -d debug mode (print everything to stderr)\n" |
---|
79 | " -h display this help message\n\n" |
---|
80 | " -b same as -s\n" |
---|
81 | " -s strip null bytes at START of stdin\n" |
---|
82 | " -e strip null bytes a END of stdin\n\n" |
---|
83 | " without any parameters, null bytes will be stripped\n" |
---|
84 | " both at start and at end of stdin.\n" |
---|
85 | ,argv[0]); |
---|
86 | return 0; |
---|
87 | case 'b': |
---|
88 | case 's': |
---|
89 | flag_start = 1; |
---|
90 | break; |
---|
91 | case 'e': |
---|
92 | flag_end = 1; |
---|
93 | } |
---|
94 | |
---|
95 | DPRINTF("Reading in from stdin, finish with eof/[STRG] + [D]\n"); |
---|
96 | length = stream_get_contents(stdin, &bytes); |
---|
97 | DPRINTF("Finished reading in.\n"); |
---|
98 | |
---|
99 | /* stripping at start */ |
---|
100 | if( flag_start || (!flag_start && !flag_end) ) |
---|
101 | for(x_start = 0; x_start < length; x_start++) { |
---|
102 | DPRINTF("start char %d/%d: 0x%x\n", x_start, length, bytes[x_start]); |
---|
103 | if(bytes[x_start]) |
---|
104 | break; |
---|
105 | } |
---|
106 | else { |
---|
107 | x_start = 0; |
---|
108 | DPRINTF("skipping stripping at start\n"); |
---|
109 | } |
---|
110 | |
---|
111 | /* stripping at end */ |
---|
112 | if( flag_end || (!flag_start && !flag_end) ) |
---|
113 | for(x_end = length; x_end > 0; x_end--) { |
---|
114 | DPRINTF("end char %d/%d: 0x%x\n", x_end, length, bytes[x_end]); |
---|
115 | if(bytes[x_end]) |
---|
116 | break; |
---|
117 | } |
---|
118 | else { |
---|
119 | x_end = length; |
---|
120 | DPRINTF("skipping stripping at end\n"); |
---|
121 | } |
---|
122 | |
---|
123 | DPRINTF("found data chunk: begin at %d, end at %d\n", x_start, x_end); |
---|
124 | |
---|
125 | for(x=x_start; x<=x_end; x++) |
---|
126 | fputc(bytes[x], stdout); |
---|
127 | |
---|
128 | return 0; |
---|
129 | } |
---|