head.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * head implementation for busybox
  4. *
  5. * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
  6. *
  7. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  8. */
  9. /* BB_AUDIT SUSv3 compliant */
  10. /* BB_AUDIT GNU compatible -c, -q, and -v options in 'fancy' configuration. */
  11. /* http://www.opengroup.org/onlinepubs/007904975/utilities/head.html */
  12. //usage:#define head_trivial_usage
  13. //usage: "[OPTIONS] [FILE]..."
  14. //usage:#define head_full_usage "\n\n"
  15. //usage: "Print first 10 lines of each FILE (or stdin) to stdout.\n"
  16. //usage: "With more than one FILE, precede each with a filename header.\n"
  17. //usage: "\n -n N[kbm] Print first N lines"
  18. //usage: IF_FEATURE_FANCY_HEAD(
  19. //usage: "\n -c N[kbm] Print first N bytes"
  20. //usage: "\n -q Never print headers"
  21. //usage: "\n -v Always print headers"
  22. //usage: )
  23. //usage: "\n"
  24. //usage: "\nN may be suffixed by k (x1024), b (x512), or m (x1024^2)."
  25. //usage:
  26. //usage:#define head_example_usage
  27. //usage: "$ head -n 2 /etc/passwd\n"
  28. //usage: "root:x:0:0:root:/root:/bin/bash\n"
  29. //usage: "daemon:x:1:1:daemon:/usr/sbin:/bin/sh\n"
  30. #include "libbb.h"
  31. /* This is a NOEXEC applet. Be very careful! */
  32. static const char head_opts[] ALIGN1 =
  33. "n:"
  34. #if ENABLE_FEATURE_FANCY_HEAD
  35. "c:qv"
  36. #endif
  37. ;
  38. static const struct suffix_mult head_suffixes[] = {
  39. { "b", 512 },
  40. { "k", 1024 },
  41. { "m", 1024*1024 },
  42. { "", 0 }
  43. };
  44. #define header_fmt_str "\n==> %s <==\n"
  45. int head_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  46. int head_main(int argc, char **argv)
  47. {
  48. unsigned long count = 10;
  49. unsigned long i;
  50. #if ENABLE_FEATURE_FANCY_HEAD
  51. int count_bytes = 0;
  52. int header_threshhold = 1;
  53. #endif
  54. FILE *fp;
  55. const char *fmt;
  56. char *p;
  57. int opt;
  58. int c;
  59. int retval = EXIT_SUCCESS;
  60. #if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_HEAD
  61. /* Allow legacy syntax of an initial numeric option without -n. */
  62. if (argv[1] && argv[1][0] == '-'
  63. && isdigit(argv[1][1])
  64. ) {
  65. --argc;
  66. ++argv;
  67. p = (*argv) + 1;
  68. goto GET_COUNT;
  69. }
  70. #endif
  71. /* No size benefit in converting this to getopt32 */
  72. while ((opt = getopt(argc, argv, head_opts)) > 0) {
  73. switch (opt) {
  74. #if ENABLE_FEATURE_FANCY_HEAD
  75. case 'q':
  76. header_threshhold = INT_MAX;
  77. break;
  78. case 'v':
  79. header_threshhold = -1;
  80. break;
  81. case 'c':
  82. count_bytes = 1;
  83. /* fall through */
  84. #endif
  85. case 'n':
  86. p = optarg;
  87. #if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_HEAD
  88. GET_COUNT:
  89. #endif
  90. count = xatoul_sfx(p, head_suffixes);
  91. break;
  92. default:
  93. bb_show_usage();
  94. }
  95. }
  96. argc -= optind;
  97. argv += optind;
  98. if (!*argv)
  99. *--argv = (char*)"-";
  100. fmt = header_fmt_str + 1;
  101. #if ENABLE_FEATURE_FANCY_HEAD
  102. if (argc <= header_threshhold) {
  103. header_threshhold = 0;
  104. }
  105. #else
  106. if (argc <= 1) {
  107. fmt += 11; /* "" */
  108. }
  109. /* Now define some things here to avoid #ifdefs in the code below.
  110. * These should optimize out of the if conditions below. */
  111. #define header_threshhold 1
  112. #define count_bytes 0
  113. #endif
  114. do {
  115. fp = fopen_or_warn_stdin(*argv);
  116. if (fp) {
  117. if (fp == stdin) {
  118. *argv = (char *) bb_msg_standard_input;
  119. }
  120. if (header_threshhold) {
  121. printf(fmt, *argv);
  122. }
  123. i = count;
  124. while (i && ((c = getc(fp)) != EOF)) {
  125. if (count_bytes || (c == '\n')) {
  126. --i;
  127. }
  128. putchar(c);
  129. }
  130. if (fclose_if_not_stdin(fp)) {
  131. bb_simple_perror_msg(*argv);
  132. retval = EXIT_FAILURE;
  133. }
  134. die_if_ferror_stdout();
  135. } else {
  136. retval = EXIT_FAILURE;
  137. }
  138. fmt = header_fmt_str;
  139. } while (*++argv);
  140. fflush_stdout_and_exit(retval);
  141. }