strings.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * strings implementation for busybox
  4. *
  5. * Copyright 2003 Tito Ragusa <farmatito@tiscali.it>
  6. *
  7. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  8. */
  9. //config:config STRINGS
  10. //config: bool "strings (4.8 kb)"
  11. //config: default y
  12. //config: help
  13. //config: strings prints the printable character sequences for each file
  14. //config: specified.
  15. //applet:IF_STRINGS(APPLET(strings, BB_DIR_USR_BIN, BB_SUID_DROP))
  16. //kbuild:lib-$(CONFIG_STRINGS) += strings.o
  17. //usage:#define strings_trivial_usage
  18. //usage: "[-fo] [-t o|d|x] [-n LEN] [FILE]..."
  19. //usage:#define strings_full_usage "\n\n"
  20. //usage: "Display printable strings in a binary file\n"
  21. //We usually don't bother user with "nop" options. They work, but are not shown:
  22. ////usage: "\n -a Scan whole file (default)"
  23. //unimplemented alternative is -d: Only strings from initialized, loaded data sections
  24. //usage: "\n -f Precede strings with filenames"
  25. //usage: "\n -o Precede strings with octal offsets"
  26. //usage: "\n -t o|d|x Precede strings with offsets in base 8/10/16"
  27. //usage: "\n -n LEN At least LEN characters form a string (default 4)"
  28. #include "libbb.h"
  29. #define WHOLE_FILE 1
  30. #define PRINT_NAME 2
  31. #define PRINT_OFFSET 4
  32. #define SIZE 8
  33. #define PRINT_RADIX 16
  34. int strings_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  35. int strings_main(int argc UNUSED_PARAM, char **argv)
  36. {
  37. int n, c;
  38. exitcode_t status = EXIT_SUCCESS;
  39. unsigned count;
  40. off_t offset;
  41. FILE *file;
  42. char *string;
  43. const char *fmt = "%s: ";
  44. const char *n_arg = "4";
  45. /* default for -o */
  46. const char *radix = "o";
  47. char *radix_fmt;
  48. getopt32(argv, "afon:t:", &n_arg, &radix);
  49. /* -a is our default behaviour */
  50. /*argc -= optind;*/
  51. argv += optind;
  52. n = xatou_range(n_arg, 1, INT_MAX);
  53. string = xzalloc(n + 1);
  54. n--;
  55. if ((radix[0] != 'd' && radix[0] != 'o' && radix[0] != 'x') || radix[1] != 0)
  56. bb_show_usage();
  57. radix_fmt = xasprintf("%%7"OFF_FMT"%s ", radix);
  58. if (!*argv) {
  59. fmt = "{%s}: ";
  60. *--argv = (char *)bb_msg_standard_input;
  61. }
  62. do {
  63. file = fopen_or_warn_stdin(*argv);
  64. if (!file) {
  65. status = EXIT_FAILURE;
  66. continue;
  67. }
  68. offset = 0;
  69. count = 0;
  70. do {
  71. c = fgetc(file);
  72. if (isprint_asciionly(c) || c == '\t') {
  73. if (count > n) {
  74. bb_putchar(c);
  75. } else {
  76. string[count] = c;
  77. if (count == n) {
  78. if (option_mask32 & PRINT_NAME) {
  79. printf(fmt, *argv);
  80. }
  81. if (option_mask32 & (PRINT_OFFSET | PRINT_RADIX)) {
  82. printf(radix_fmt, offset - n);
  83. }
  84. fputs_stdout(string);
  85. }
  86. count++;
  87. }
  88. } else {
  89. if (count > n) {
  90. bb_putchar('\n');
  91. }
  92. count = 0;
  93. }
  94. offset++;
  95. } while (c != EOF);
  96. fclose_if_not_stdin(file);
  97. } while (*++argv);
  98. if (ENABLE_FEATURE_CLEAN_UP) {
  99. free(string);
  100. free(radix_fmt);
  101. }
  102. fflush_stdout_and_exit(status);
  103. }