Guest User

Untitled

a guest
Nov 9th, 2019
93
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <getopt.h>
  4. #include <errno.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <stdarg.h>
  8. #include <fcntl.h>
  9. #include <unistd.h>
  10. #include <string.h>
  11. #include "kitten.h"
  12.  
  13. #define ERR_SIZE 256
  14. extern int errno;
  15.  
  16. char err_buf[ERR_SIZE];
  17.  
  18. int main ( int argc, char* argv[])
  19. {
  20. struct global_opt opt = {
  21. .number_nonblank = false, .number = false,
  22. .squeeze_blank = false, .show_nonprinting = false,
  23. .show_ends = false, .show_tabs = false
  24. };
  25. bool ok;
  26. int c;
  27.  
  28. while (( c = getopt_long(argc, argv, "bnsvET", NULL, NULL)) != -1)
  29. {
  30. switch(c)
  31. {
  32. case 'b':
  33. opt.number = true;
  34. opt.number_nonblank = true;
  35. break;
  36. case 'n':
  37. opt.number = true;
  38. break;
  39. case 's':
  40. opt.squeeze_blank = true;
  41. break;
  42. case 'v':
  43. opt.show_nonprinting = true;
  44. break;
  45. case 'E':
  46. opt.show_ends = true;
  47. break;
  48. case 'T':
  49. opt.show_tabs = true;
  50. break;
  51. default:
  52. return -1;
  53.  
  54. }
  55. }
  56.  
  57. char *file = "-";
  58. int argid = optind;
  59. int input_desc;
  60.  
  61. do
  62. {
  63. if( argid < argc)
  64. file = argv[argid];
  65. if( STREQ(file, "-"))
  66. input_desc = STDIN_FILENO;
  67. else
  68. {
  69. input_desc = open (file, O_RDONLY);
  70. if (input_desc < 0)
  71. {
  72. strncat(err_buf, "Cannot open ", 13);
  73. strncat(err_buf, file, strlen(file));
  74. strncat(err_buf, ": ", 2);
  75. strerror_r (errno,err_buf+13+strlen(file), ERR_SIZE);
  76. strncat(err_buf, "\n", 2);
  77. write ( STDOUT_FILENO, err_buf, ERR_SIZE);
  78. continue;
  79. }
  80. }
  81. if (! (opt.number || opt.show_ends || opt.show_nonprinting
  82. || opt.show_tabs || opt.squeeze_blank))
  83. ok &= simple_cat(input_desc);
  84. else ok &= cat_opt ( &opt, input_desc);
  85. }
  86. while ( ++argid < argc);
  87.  
  88.  
  89.  
  90.  
  91.  
  92. return ok ? EXIT_SUCCESS : EXIT_FAILURE;
  93. }
  94.  
  95. static char line_buf[ LINE_COUNTER] =
  96. {
  97. ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0', '\t', '\0'
  98. };
  99. static char* num_print = line_buf + LINE_COUNTER - 6;
  100.  
  101. void next_line_num (void)
  102. {
  103. static char* num_start = line_buf + LINE_COUNTER - 3;
  104. char* endp = line_buf + LINE_COUNTER - 3;
  105.  
  106. do
  107. {
  108. if( (*endp)++ < '9')
  109. return;
  110. *endp-- = '0';
  111. } while ( endp >= num_start);
  112. if (num_start > line_buf)
  113. *--num_start = '1';
  114. else
  115. *line_buf = '>';
  116.  
  117. if(num_start < num_print)
  118. num_print--;
  119. }
  120.  
  121. bool simple_cat(int input_desc)
  122. {
  123. char buf[BUF_SIZE] = {0};
  124. int char_read;
  125.  
  126. while ( true )
  127. {
  128. char_read = read ( input_desc, buf, BUF_SIZE);
  129.  
  130. if( char_read == -1 )
  131. {
  132. strerror_r (errno,err_buf, ERR_SIZE);
  133. strncat(err_buf, "\n", 2);
  134. write ( STDOUT_FILENO, err_buf, ERR_SIZE);
  135. return false;
  136. }
  137.  
  138. if ( char_read == 0 )
  139. return true;
  140.  
  141. {
  142. int n = char_read;
  143. if( write (STDOUT_FILENO, buf, n) != n )
  144. {
  145. strerror_r (errno,err_buf, ERR_SIZE);
  146. strncat(err_buf, "\n", 2);
  147. write ( STDOUT_FILENO, err_buf, ERR_SIZE);
  148. }
  149. }
  150.  
  151. }
  152.  
  153. }
  154.  
  155. static inline void write_remain ( char* outbuf, char** bpout)
  156. {
  157. int n_write = *bpout - outbuf;
  158.  
  159. if ( n_write > 0)
  160. {
  161. if(write (STDOUT_FILENO, outbuf, n_write) != n_write)
  162. {
  163. strerror_r (errno,err_buf, ERR_SIZE);
  164. strncat(err_buf, "\n", 2);
  165. write ( STDOUT_FILENO, err_buf, ERR_SIZE);
  166. }
  167. *bpout = outbuf;
  168. }
  169. }
  170.  
  171. bool cat_opt( struct global_opt* p_opt, int input_desc)
  172. {
  173. char inbuf [BUF_SIZE];
  174. char outbuf [2*BUF_SIZE];
  175.  
  176. int newlines = 0;
  177.  
  178. unsigned char ch;
  179.  
  180. char *bpin;
  181.  
  182. char *eob;
  183.  
  184. char *bpout;
  185.  
  186. int n_read = 1;
  187.  
  188. eob = inbuf;
  189. bpin = eob + 1;
  190.  
  191. bpout = outbuf;
  192.  
  193. while (n_read != 0)
  194. {
  195. do
  196. {
  197. if (outbuf + n_read <= bpout)
  198. {
  199. int n_write = bpout - outbuf;
  200. if( write ( STDOUT_FILENO, outbuf, n_write) != n_write)
  201. {
  202. strerror_r (errno,err_buf, ERR_SIZE);
  203. strncat(err_buf, "\n", 2);
  204. write ( STDOUT_FILENO, err_buf, ERR_SIZE);
  205. }
  206. bpout = outbuf;
  207. }
  208.  
  209. if ( bpin > eob)
  210. {
  211. n_read = read ( input_desc, inbuf, BUF_SIZE);
  212. if ( n_read == -1)
  213. {
  214. strerror_r (errno,err_buf, ERR_SIZE);
  215. strncat(err_buf, "\n", 2);
  216. write ( STDOUT_FILENO, err_buf, ERR_SIZE);
  217.  
  218. write_remain (outbuf, &bpout);
  219. return false;
  220. }
  221.  
  222. if ( n_read == 0)
  223. {
  224. write_remain (outbuf, &bpout);
  225. return true;
  226. }
  227.  
  228. bpin = inbuf;
  229. eob = bpin + n_read;
  230. *eob = '\n';
  231.  
  232. }
  233. else
  234. {
  235. if( ++newlines > 0)
  236. {
  237. if( newlines >= 2)
  238. if( p_opt -> squeeze_blank)
  239. {
  240. ch = *bpin++;
  241. continue;
  242. }
  243.  
  244. if(p_opt -> number && !(p_opt -> number_nonblank))
  245. {
  246. next_line_num();
  247. bpout = stpcpy(bpout, num_print);
  248. }
  249. }
  250.  
  251. if (p_opt -> show_ends)
  252. *bpout++ = '$';
  253.  
  254. *bpout++ = '\n';
  255. }
  256.  
  257. ch = *bpin++;
  258.  
  259. } while ( ch == '\n');
  260.  
  261.  
  262. if( newlines > -1 && p_opt -> number)
  263. {
  264. next_line_num();
  265. bpout = stpcpy (bpout, num_print);
  266. }
  267.  
  268.  
  269. while (bpout < outbuf + 2*BUF_SIZE )
  270. {
  271. if(ch == '\t' && p_opt -> show_tabs)
  272. {
  273. *bpout++ = '^';
  274. *bpout++ = 'I';
  275. }
  276. else if ( ch != '\n' )
  277. *bpout++ = ch;
  278. else
  279. {
  280. newlines = -1;
  281. break;
  282.  
  283. }
  284.  
  285. ch = *bpin++;
  286. }
  287. }
  288. return true;
  289. }
RAW Paste Data