Contents of paper-tape/perl-tools/strip-null-bytes.c

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