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.50 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. int z = read(fd, buff,1);
  101. if(z==0){break;}
  102. ssize_t wres = write(STDOUT_FILENO,buff,1); // output file content
  103. if(wres == 0 ){
  104. do{
  105. wres = write(STDOUT_FILENO,buff,1);
  106. }while(wres==0);
  107. }
  108. if(wres < 0) {
  109. perror("tail: error writing 'standard output'"); // output error
  110. return -1;
  111. }
  112. }
  113. return 0;
  114. }
  115.  
  116. int go_to_tenth_line(int fd,int i, char* argv[]){
  117. //------------------------------------------------------------------------
  118. // FUNCTION: go_to_tenth_line(int fd,int i, char* argv[]){
  119. // move with lseek to the 10th \n from down to up
  120. // PARAMETERS:
  121. // int fd - the file descriptor
  122. // int i - the current argument number
  123. // char* argv[i] - the filename
  124. //------------------------------------------------------------------------
  125. int count,line_count = 10;
  126. ssize_t rres;
  127. char buff[1];
  128. off_t offset;
  129.  
  130. // go to 10th line from downward
  131. for(count = -1;line_count != 0;count--){
  132. offset = lseek(fd, count, SEEK_END); // go to current byte
  133. if(offset == -1) break; // error occured
  134. if(count != 0) rres = read(fd,buff,1); // read one byte
  135. if(rres < 0){
  136. read_error(i,argv); // output read error
  137. return 1; // error
  138. }
  139. if(*buff =='\n') if(count != -1) line_count--; // if found new line char, update how much lines are left
  140. }
  141.  
  142. if (*buff != '\n') write(STDOUT_FILENO, buff, 1); // add last char if file is less than 10 lines
  143. return count;
  144. }
  145.  
  146. int standart_input(int i, char* argv[i]){
  147. //------------------------------------------------------------------------
  148. // FUNCTION: standart_input(int i, char* argv[i])
  149. // get terminal input and output it to a file, then print the last 10 lines
  150. // PARAMETERS:
  151. // int i - the current argument number
  152. // char* argv[i] - the filename
  153. //------------------------------------------------------------------------
  154. int fd = open("tester.txt",O_CREAT | O_RDWR , 0664 ); // open file to which the standart input was outputed to
  155. standart_read(fd); //read from the terminal and write the input to a file
  156.  
  157. char buff[1];
  158. int count = go_to_tenth_line(fd,i,argv); // move with lseek to the 10th \n from down to up
  159.  
  160. if(file_output(count,buff,fd) < 0 || count > 0) return -1; // print last 10 lines;error occured
  161. if(close(fd) <0) close_error(i,argv); // close file; error occured
  162.  
  163. return 0;
  164. }
  165.  
  166.  
  167. int main(int argc,char* argv[]){
  168. int i = 1,error = 0;
  169. char buff[1];
  170.  
  171. if(argc == 1 || ( *argv[i] == '-' && argc == 2 )){ // if there is only - or nothing
  172. standart_input(++i,argv); // takes care of - input
  173. return 0;
  174. }
  175.  
  176.  
  177. while(i <= argc-1){
  178. while(*argv[i] == '-'){
  179. print_labels(i,argv,error); // output messages when more than 2 files
  180. if(standart_input(++i,argv) < 0) return -1;
  181. if(i == argc) return 0;
  182. }
  183.  
  184. int fd = open(argv[i],O_RDONLY); // file is opened
  185.  
  186. while(fd < 0){ // while file can't be opened, go for the next
  187. open_error(i,argv); // output error mssg
  188. error = 1;
  189. if(i++ == argc-1) return -1;
  190. fd = open(argv[i],O_RDONLY);
  191. }
  192.  
  193. if(argc > 2) print_labels(i,argv,error); // output messages when more than 2 files
  194.  
  195. int count = go_to_tenth_line(fd,i,argv);
  196. if(count > 0) return -1; // error occured
  197. if(file_output(count,buff,fd)< 0) return -1; // error
  198. if(close(fd) <0) close_error(i,argv); // close file
  199. i++;
  200. }
  201.  
  202. return 0;
  203. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement