strings.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /* vim: tabstop=4 shiftwidth=4 noexpandtab
  2. * This file is part of ToaruOS and is released under the terms
  3. * of the NCSA / University of Illinois License - see LICENSE.md
  4. * Copyright (C) 2018 K. Lange
  5. *
  6. * strings - print printable character sequences found in a file
  7. */
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <getopt.h>
  11. #include <ctype.h>
  12. #include <unistd.h>
  13. #include <errno.h>
  14. int main(int argc, char * argv[]) {
  15. int opt;
  16. char format = 0;
  17. int min_chars = 4;
  18. int ret_val = 0;
  19. while ((opt = getopt(argc, argv, "an:t:")) != -1) {
  20. switch (opt) {
  21. case 'a':
  22. /* TODO: With ELF support, read only the string table
  23. * by default, unless this option is specified. */
  24. break;
  25. case 'n':
  26. min_chars = atoi(optarg);
  27. break;
  28. case 't':
  29. format = optarg[0];
  30. if (format != 'd' && format != 'x') {
  31. fprintf(stderr, "%s: format '%c' is not supported\n", argv[0], format);
  32. format = 0;
  33. }
  34. break;
  35. }
  36. }
  37. for (int i = optind; i < argc; ++i) {
  38. FILE * f = fopen(argv[i], "r");
  39. if (!f) {
  40. fprintf(stderr, "%s: %s: %s\n", argv[0], argv[i], strerror(errno));
  41. ret_val = 1;
  42. continue;
  43. }
  44. char buf[1024] = {0};
  45. int ind = 0;
  46. size_t offset = 0;
  47. while (!feof(f)) {
  48. int c = fgetc(f);
  49. if (c < 0) break;
  50. if (c == '\n' || c == '\0') {
  51. if (ind >= min_chars) {
  52. switch (format) {
  53. case 'x':
  54. fprintf(stdout, "%lx ", offset - ind);
  55. break;
  56. case 'd':
  57. fprintf(stdout, "%lu ", offset - ind);
  58. break;
  59. default:
  60. break;
  61. }
  62. buf[ind] = '\0';
  63. fprintf(stdout, "%s\n", buf);
  64. }
  65. ind = 0;
  66. offset++;
  67. continue;
  68. }
  69. if (!isprint(c)) {
  70. ind = 0;
  71. } else {
  72. if (ind < 1024) {
  73. buf[ind] = c;
  74. ind++;
  75. }
  76. }
  77. offset++;
  78. }
  79. fclose(f);
  80. }
  81. return ret_val;
  82. }