Advertisement
Guest User

Untitled

a guest
Nov 18th, 2017
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.44 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <sys/syscall.h>
  8.  
  9. void print_labels(int i,char* argv[i],int error){
  10. //------------------------------------------------------------------------
  11. // FUNCTION: print_labels(int i,char* argv[i],int error)
  12. // output the labels when we have more than 1 file
  13. // PARAMETERS:
  14. // int i - the current argument number
  15. // char* argv[i] - the filename
  16. // int error - if an error occured up to now
  17. //------------------------------------------------------------------------
  18. char msg[1024] = "==> ";
  19.  
  20. if(i >= 2 && error == 0) write(STDOUT_FILENO, "\n", 1); // adds new line
  21. if(*argv[i] == '-') argv[i] = "standart input"; // the output when we have - should be ==> stand. input <==
  22.  
  23. int compare = strcmp(argv[i],"tester.txt"); // argv[i] ?= tester.txt
  24. if(compare != 0){
  25. strcat(strcat(msg,argv[i])," <==\n"); // concatenate msg and argv[i] and the result to last string
  26. write(STDOUT_FILENO, msg, strlen(msg)); // output msg
  27. argv[i] = "tester.txt";
  28. }
  29. }
  30.  
  31. void close_error(int i,char* argv[i]){
  32. //------------------------------------------------------------------------
  33. // FUNCTION: close_error(int i,char* argv[i])
  34. // output message on close error
  35. // PARAMETERS:
  36. // int i - the current argument number
  37. // char* argv[i] - the filename
  38. //------------------------------------------------------------------------
  39. char msg[1024] = "tail: error reading '";
  40. strcat(msg,argv[i]); // concatenate msg and argv[i]
  41. write(2, msg, strlen(msg)); //output msg
  42. perror("'"); // print perror
  43. }
  44.  
  45. void read_error(int i,char* argv[i]){
  46. //------------------------------------------------------------------------
  47. // FUNCTION: read_error(int i,char* argv[i])
  48. // output message on read error, which is the same as close error
  49. // PARAMETERS:
  50. // int i - the current argument number
  51. // char* argv[i] - the filename
  52. //------------------------------------------------------------------------
  53. close_error(i,argv);
  54. }
  55.  
  56. void open_error(int i,char* argv[i]){
  57. //------------------------------------------------------------------------
  58. // FUNCTION: open_error(int i,char* argv[i])
  59. // output message on file open error
  60. // PARAMETERS:
  61. // int i - the current argument number
  62. // char* argv[i] - the filename
  63. //------------------------------------------------------------------------
  64. char msg[1024] = "tail: cannot open '";
  65. strcat(strcat(msg,argv[i]),"' for ");// concatenate msg and argv[i]
  66. write(2, msg, strlen(msg)); // output msg
  67. perror("reading"); // print perror
  68. }
  69.  
  70.  
  71. void standart_read(int fd){
  72. //------------------------------------------------------------------------
  73. // FUNCTION: standart_read(int fd)
  74. // read from the terminal and write the input to a file
  75. // PARAMETERS:
  76. // int fd - the file descriptor
  77. //------------------------------------------------------------------------
  78. char data[10];
  79. while(read(0,data,1) != 0){ // 0 indicated EOF
  80. for(size_t i = 0,len =1; i< len;i++){
  81. size_t wres = write(fd,data+i,1);
  82. if(wres < 0) break; // output
  83. else if(wres == 0) write(fd,data+i,1);
  84.  
  85. }
  86. }
  87. }
  88.  
  89. int file_output(int count,char *buff, int fd){
  90. //------------------------------------------------------------------------
  91. // FUNCTION: file_output(int count,char *buff, int fd)
  92. // read from the terminal and write the input to a file
  93. // PARAMETERS:
  94. // int fd - the file descriptor
  95. // int count - number of bytes to be written
  96. // char* buff - the buffer for read and write
  97. //------------------------------------------------------------------------
  98. count *= -1; // get abs value of bytes
  99. while(count--){
  100. ssize_t wres = write(STDOUT_FILENO,buff,read(fd, buff,1)); // output file content
  101. if(wres == 0){
  102. do{
  103. wres = write(STDOUT_FILENO,buff,1);
  104. }while(wres==0);
  105. }
  106. if(wres < 0) {
  107. perror("tail: error writing 'standard output'"); // output error
  108. return -1;
  109. }
  110. }
  111. return 0;
  112. }
  113.  
  114. int go_to_tenth_line(int fd,int i, char* argv[]){
  115. //------------------------------------------------------------------------
  116. // FUNCTION: go_to_tenth_line(int fd,int i, char* argv[]){
  117. // move with lseek to the 10th \n from down to up
  118. // PARAMETERS:
  119. // int fd - the file descriptor
  120. // int i - the current argument number
  121. // char* argv[i] - the filename
  122. //------------------------------------------------------------------------
  123. int count,line_count = 10;
  124. ssize_t rres;
  125. char buff[1];
  126. off_t offset;
  127.  
  128. // go to 10th line from downward
  129. for(count = -1;line_count != 0;count--){
  130. offset = lseek(fd, count, SEEK_END); // go to current byte
  131. if(offset == -1) break; // error occured
  132. if(count != 0) rres = read(fd,buff,1); // read one byte
  133. if(rres < 0){
  134. read_error(i,argv); // output read error
  135. return 1; // error
  136. }
  137. if(*buff =='\n') if(count != -1) line_count--; // if found new line char, update how much lines are left
  138. }
  139.  
  140. if (*buff != '\n') write(STDOUT_FILENO, buff, 1); // add last char if file is less than 10 lines
  141. return count;
  142. }
  143.  
  144. int standart_input(int i, char* argv[i]){
  145. //------------------------------------------------------------------------
  146. // FUNCTION: standart_input(int i, char* argv[i])
  147. // get terminal input and output it to a file, then print the last 10 lines
  148. // PARAMETERS:
  149. // int i - the current argument number
  150. // char* argv[i] - the filename
  151. //------------------------------------------------------------------------
  152. int fd = open("tester.txt",O_CREAT | O_RDWR , 0664 ); // open file to which the standart input was outputed to
  153. standart_read(fd); //read from the terminal and write the input to a file
  154.  
  155. char buff[1];
  156. int count = go_to_tenth_line(fd,i,argv); // move with lseek to the 10th \n from down to up
  157.  
  158. if(file_output(count,buff,fd) < 0 || count > 0) return -1; // print last 10 lines;error occured
  159. if(close(fd) <0) close_error(i,argv); // close file; error occured
  160.  
  161. return 0;
  162. }
  163.  
  164.  
  165. int main(int argc,char* argv[]){
  166. int i = 1,error = 0;
  167. char buff[1];
  168.  
  169. if(argc == 1 || ( *argv[i] == '-' && argc == 2 )){ // if there is only - or nothing
  170. standart_input(++i,argv); // takes care of - input
  171. return 0;
  172. }
  173.  
  174.  
  175. while(i <= argc-1){
  176. while(*argv[i] == '-'){
  177. print_labels(i,argv,error); // output messages when more than 2 files
  178. if(standart_input(++i,argv) < 0) return -1;
  179. if(i == argc) return 0;
  180. }
  181.  
  182. int fd = open(argv[i],O_RDONLY); // file is opened
  183.  
  184. while(fd < 0){ // while file can't be opened, go for the next
  185. open_error(i,argv); // output error mssg
  186. error = 1;
  187. if(i++ == argc-1) return -1;
  188. fd = open(argv[i],O_RDONLY);
  189. }
  190.  
  191. if(argc > 2) print_labels(i,argv,error); // output messages when more than 2 files
  192.  
  193. int count = go_to_tenth_line(fd,i,argv);
  194. if(count > 0) return -1; // error occured
  195. if(file_output(count,buff,fd)< 0) return -1; // error
  196. if(close(fd) <0) close_error(i,argv); // close file
  197. i++;
  198. }
  199.  
  200. return 0;
  201. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement