Guest User

Untitled

a guest
Jun 20th, 2018
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.79 KB | None | 0 0
  1. /* $NetBSD: cat.c,v 1.47 2008/07/20 00:52:39 lukem Exp $ */
  2.  
  3. /*
  4. * Copyright (c) 1989, 1993
  5. * The Regents of the University of California. All rights reserved.
  6. *
  7. * This code is derived from software contributed to Berkeley by
  8. * Kevin Fall.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. * 3. Neither the name of the University nor the names of its contributors
  19. * may be used to endorse or promote products derived from this software
  20. * without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32. * SUCH DAMAGE.
  33. */
  34.  
  35. #if HAVE_NBTOOL_CONFIG_H
  36. #include "nbtool_config.h"
  37. #endif
  38.  
  39. #include <sys/cdefs.h>
  40. #if !defined(lint)
  41. __COPYRIGHT(
  42. "@(#) Copyright (c) 1989, 1993\
  43. The Regents of the University of California. All rights reserved.");
  44. #if 0
  45. static char sccsid[] = "@(#)cat.c 8.2 (Berkeley) 4/27/95";
  46. #else
  47. __RCSID("$NetBSD: cat.c,v 1.47 2008/07/20 00:52:39 lukem Exp $");
  48. #endif
  49. #endif /* not lint */
  50.  
  51. #include <sys/param.h>
  52. #include <sys/stat.h>
  53.  
  54. #include <ctype.h>
  55. #include <err.h>
  56. #include <errno.h>
  57. #include <fcntl.h>
  58. #include <locale.h>
  59. #include <stdio.h>
  60. #include <stdlib.h>
  61. #include <string.h>
  62. #include <unistd.h>
  63.  
  64. int bflag, eflag, fflag, lflag, nflag, sflag, tflag, vflag;
  65. int rval;
  66. const char *filename;
  67.  
  68. int main(int, char *[]);
  69. void cook_args(char *argv[]);
  70. void cook_buf(FILE *);
  71. void raw_args(char *argv[]);
  72. void raw_cat(int);
  73.  
  74. int
  75. main(int argc, char *argv[])
  76. {
  77. int ch;
  78. struct flock stdout_lock;
  79.  
  80. setprogname(argv[0]);
  81. (void)setlocale(LC_ALL, "");
  82.  
  83. while ((ch = getopt(argc, argv, "beflnstuv")) != -1)
  84. switch (ch) {
  85. case 'b':
  86. bflag = nflag = 1; /* -b implies -n */
  87. break;
  88. case 'e':
  89. eflag = vflag = 1; /* -e implies -v */
  90. break;
  91. case 'f':
  92. fflag = 1;
  93. break;
  94. case 'l':
  95. lflag = 1;
  96. break;
  97. case 'n':
  98. nflag = 1;
  99. break;
  100. case 's':
  101. sflag = 1;
  102. break;
  103. case 't':
  104. tflag = vflag = 1; /* -t implies -v */
  105. break;
  106. case 'u':
  107. setbuf(stdout, NULL);
  108. break;
  109. case 'v':
  110. vflag = 1;
  111. break;
  112. default:
  113. case '?':
  114. (void)fprintf(stderr,
  115. "usage: cat [-beflnstuv] [-] [file ...]\n");
  116. exit(EXIT_FAILURE);
  117. /* NOTREACHED */
  118. }
  119. argv += optind;
  120.  
  121. if (lflag) {
  122. stdout_lock.l_len = 0;
  123. stdout_lock.l_start = 0;
  124. stdout_lock.l_type = F_WRLCK;
  125. stdout_lock.l_whence = SEEK_SET;
  126. if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) == -1)
  127. err(EXIT_FAILURE, "stdout");
  128. }
  129.  
  130. if (bflag || eflag || nflag || sflag || tflag || vflag)
  131. cook_args(argv);
  132. else
  133. raw_args(argv);
  134. if (fclose(stdout))
  135. err(EXIT_FAILURE, "stdout");
  136. return (rval);
  137. }
  138.  
  139. void
  140. cook_args(char **argv)
  141. {
  142. FILE *fp;
  143.  
  144. fp = stdin;
  145. filename = "stdin";
  146. do {
  147. if (*argv) {
  148. if (!strcmp(*argv, "-"))
  149. fp = stdin;
  150. else if ((fp = fopen(*argv,
  151. fflag ? "rf" : "r")) == NULL) {
  152. warn("%s", *argv);
  153. rval = EXIT_FAILURE;
  154. ++argv;
  155. continue;
  156. }
  157. filename = *argv++;
  158. }
  159. cook_buf(fp);
  160. if (fp != stdin)
  161. (void)fclose(fp);
  162. else
  163. clearerr(fp);
  164. } while (*argv);
  165. }
  166.  
  167. void
  168. cook_buf(FILE *fp)
  169. {
  170. int ch, gobble, line, prev;
  171.  
  172. line = gobble = 0;
  173. for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
  174. if (prev == '\n') {
  175. if (ch == '\n') {
  176. if (sflag) {
  177. if (!gobble && nflag && !bflag)
  178. (void)fprintf(stdout,
  179. "%6d\t\n", ++line);
  180. else if (!gobble && putchar(ch) == EOF)
  181. break;
  182. gobble = 1;
  183. continue;
  184. }
  185. if (nflag) {
  186. if (!bflag) {
  187. (void)fprintf(stdout,
  188. "%6d\t", ++line);
  189. if (ferror(stdout))
  190. break;
  191. } else if (eflag) {
  192. (void)fprintf(stdout,
  193. "%6s\t", "");
  194. if (ferror(stdout))
  195. break;
  196. }
  197. }
  198. } else if (nflag) {
  199. (void)fprintf(stdout, "%6d\t", ++line);
  200. if (ferror(stdout))
  201. break;
  202. }
  203. }
  204. gobble = 0;
  205. if (ch == '\n') {
  206. if (eflag)
  207. if (putchar('$') == EOF)
  208. break;
  209. } else if (ch == '\t') {
  210. if (tflag) {
  211. if (putchar('^') == EOF || putchar('I') == EOF)
  212. break;
  213. continue;
  214. }
  215. } else if (vflag) {
  216. if (!isascii(ch)) {
  217. if (putchar('M') == EOF || putchar('-') == EOF)
  218. break;
  219. ch = toascii(ch);
  220. }
  221. if (iscntrl(ch)) {
  222. if (putchar('^') == EOF ||
  223. putchar(ch == '\177' ? '?' :
  224. ch | 0100) == EOF)
  225. break;
  226. continue;
  227. }
  228. }
  229. if (putchar(ch) == EOF)
  230. break;
  231. }
  232. if (ferror(fp)) {
  233. warn("%s", filename);
  234. rval = EXIT_FAILURE;
  235. clearerr(fp);
  236. }
  237. if (ferror(stdout))
  238. err(EXIT_FAILURE, "stdout");
  239. }
  240.  
  241. void
  242. raw_args(char **argv)
  243. {
  244. int fd;
  245.  
  246. fd = fileno(stdin);
  247. filename = "stdin";
  248. do {
  249. if (*argv) {
  250. if (!strcmp(*argv, "-"))
  251. fd = fileno(stdin);
  252. else if (fflag) {
  253. struct stat st;
  254. fd = open(*argv, O_RDONLY|O_NONBLOCK, 0);
  255. if (fd < 0)
  256. goto skip;
  257.  
  258. if (fstat(fd, &st) == -1) {
  259. close(fd);
  260. goto skip;
  261. }
  262. if (!S_ISREG(st.st_mode)) {
  263. close(fd);
  264. warnx("%s: not a regular file", *argv);
  265. goto skipnomsg;
  266. }
  267. }
  268. else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
  269. skip:
  270. warn("%s", *argv);
  271. skipnomsg:
  272. rval = EXIT_FAILURE;
  273. ++argv;
  274. continue;
  275. }
  276. filename = *argv++;
  277. }
  278. raw_cat(fd);
  279. if (fd != fileno(stdin))
  280. (void)close(fd);
  281. } while (*argv);
  282. }
  283.  
  284. void
  285. raw_cat(int rfd)
  286. {
  287. static char *buf;
  288. static char fb_buf[BUFSIZ];
  289. static size_t bsize;
  290.  
  291. ssize_t nr, nw, off;
  292. int wfd;
  293.  
  294. wfd = fileno(stdout);
  295. if (buf == NULL) {
  296. struct stat sbuf;
  297.  
  298. if (fstat(wfd, &sbuf) == 0 &&
  299. sbuf.st_blksize > sizeof(fb_buf)) {
  300. bsize = sbuf.st_blksize;
  301. buf = malloc(bsize);
  302. }
  303. if (buf == NULL) {
  304. bsize = sizeof(fb_buf);
  305. buf = fb_buf;
  306. }
  307. }
  308. while ((nr = read(rfd, buf, bsize)) > 0)
  309. for (off = 0; nr; nr -= nw, off += nw)
  310. if ((nw = write(wfd, buf + off, (size_t)nr)) < 0)
  311. err(EXIT_FAILURE, "stdout");
  312. if (nr < 0) {
  313. warn("%s", filename);
  314. rval = EXIT_FAILURE;
  315. }
  316. }
Add Comment
Please, Sign In to add comment