Guest User

Untitled

a guest
Feb 12th, 2016
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.32 KB | None | 0 0
  1. #include <sys/wait.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <termios.h>
  7.  
  8. #include <fcntl.h>
  9. #include <dirent.h>
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <assert.h>
  13.  
  14. #define BUFFERSIZE 4096
  15.  
  16. char * history_path = "./history.log";
  17.  
  18. int argument_count;
  19. int pipe_count;
  20.  
  21. void display_error(char *, char *);
  22. int copyDir(char *src, char *dest);
  23. int copyFiles(char *src, char *dest);
  24. int dostat(char *filename);
  25. int mode_isReg(struct stat info);
  26.  
  27. int custom_cd(char **args);
  28. int custom_cp(char **args);
  29. int custom_help(char **args);
  30. int custom_exit(char **args);
  31. int custom_version(char **args);
  32. int custom_pipe(char **args);
  33. int custom_mv(char **args);
  34. int custom_dirname(char **args);
  35. int custom_pipe(char **args);
  36.  
  37. char *custom_Function_names[] = {
  38. "cd",
  39. "help",
  40. "exit",
  41. "version",
  42. "cp",
  43. "mv",
  44. "dirname"
  45. };
  46.  
  47. int (*builtin_func[]) (char **) = {
  48. &custom_cd,
  49. &custom_help,
  50. &custom_exit,
  51. &custom_version,
  52. &custom_cp,
  53. &custom_mv,
  54. &custom_dirname
  55. };
  56.  
  57.  
  58. int builtin_function_count() {
  59. return sizeof(custom_Function_names) / sizeof(char *);
  60. }
  61.  
  62. int custom_version(char ** args)
  63. {
  64. printf("Basic command interpretor:\n");
  65. printf("Proiect pentru disciplina \"Sisteme de Operare \":\n");
  66. printf("Echipa 11 : Gavra Andrei si Galbenu Dorin\n");
  67.  
  68. return 1;
  69. }
  70.  
  71. int custom_dirname(char **args)
  72. {
  73. int slash_index =-1,i;
  74.  
  75. if(argument_count==2)
  76. {
  77. for(i=0;i<strlen(args[1]);i++)
  78. if(args[1][i]=='/')
  79. slash_index=i;
  80.  
  81.  
  82. if(slash_index==-1)
  83. printf(".");
  84.  
  85. else
  86. {
  87.  
  88. char* output_string = (char*)(malloc(strlen(args[1])));
  89.  
  90. strcpy(output_string,args[1]);
  91.  
  92. output_string[slash_index]=NULL;
  93.  
  94. printf("%s ",output_string);
  95.  
  96. }
  97.  
  98. printf("\n");
  99.  
  100. }
  101. else
  102. printf("Dirname function must receive 2 parameters");
  103.  
  104. return 1;
  105. }
  106.  
  107. int custom_mv(char **args)
  108. {
  109. if(argument_count < 3)
  110. {
  111. printf("Not enough argument passed to function \n");
  112. return 1;
  113. }
  114.  
  115. char* source = args[1];
  116.  
  117. char* destination = (char*)(malloc(sizeof(args[1])+sizeof(args[2])+1));
  118.  
  119. strcpy(destination,args[2]);
  120.  
  121. char* buf[2];
  122.  
  123. int fd1,fd2,i;
  124.  
  125. if(destination[0]=='/')
  126. {
  127. strcat(destination,"/");
  128. strcat(destination,source);
  129. }
  130.  
  131.  
  132. fd1=open(source,O_RDONLY,0777);
  133.  
  134. fd2=creat(destination,S_IWUSR);
  135.  
  136. while(i=read(fd1,buf,1)>0)
  137. {
  138. write(fd2,buf,1);
  139. }
  140.  
  141. if(fd2!=-1)
  142. remove(source);
  143.  
  144. close(fd1);
  145. close(fd2);
  146.  
  147.  
  148. return 1;
  149. }
  150.  
  151.  
  152. int custom_pipe(char **args) {
  153.  
  154. const int commands = pipe_count + 1;
  155. int i = 0;
  156.  
  157. int pipefds[2*pipe_count];
  158.  
  159. for(i = 0; i < pipe_count; i++){
  160. if(pipe(pipefds + i*2) < 0) {
  161. perror("Couldn't Pipe");
  162. exit(EXIT_FAILURE);
  163. }
  164. }
  165.  
  166. int pid;
  167. int status;
  168.  
  169. int j = 0;
  170. int k = 0;
  171. int s = 1;
  172. int place;
  173. int commandStarts[10];
  174. commandStarts[0] = 0;
  175.  
  176.  
  177. while (args[k] != NULL){
  178. if(!strcmp(args[k], "|")){
  179. args[k] = NULL;
  180. commandStarts[s] = k+1;
  181. s++;
  182. }
  183. k++;
  184. }
  185.  
  186.  
  187.  
  188. for (i = 0; i < commands; ++i) {
  189. place = commandStarts[i];
  190.  
  191. pid = fork();
  192. if(pid == 0) {
  193. //if not last command
  194. if(i < pipe_count){
  195. if(dup2(pipefds[j + 1], 1) < 0){
  196. perror("dup2");
  197. exit(EXIT_FAILURE);
  198. }
  199. }
  200.  
  201. //if not first command&& j!= 2*pipe_count
  202. if(j != 0 ){
  203. if(dup2(pipefds[j-2], 0) < 0){
  204. perror("dup2");
  205. exit(EXIT_FAILURE);
  206. }
  207. }
  208.  
  209. int q;
  210. for(q = 0; q < 2*pipe_count; q++){
  211. close(pipefds[q]);
  212. }
  213.  
  214. // The commands are executed here,
  215. if( execvp(args[place], args+place) < 0){
  216. perror(*args);
  217. exit(EXIT_FAILURE);
  218. }
  219. }
  220. else if(pid < 0){
  221. perror("error");
  222. exit(EXIT_FAILURE);
  223. }
  224.  
  225. j+=2;
  226. }
  227.  
  228. for(i = 0; i < 2 * pipe_count; i++){
  229. close(pipefds[i]);
  230. }
  231.  
  232. for(i = 0; i < pipe_count + 1; i++){
  233. wait(&status);
  234. }
  235. }
  236.  
  237.  
  238.  
  239. int custom_cp(char **args)
  240. {
  241. if(argument_count < 3)
  242. {
  243. printf("Not enough arguments passed to function \n");
  244. return 1;
  245. }
  246.  
  247. char * src= args[1];
  248.  
  249. char * dest = args[2];
  250.  
  251.  
  252. if( src[0] != '/' && dest[0] != '/' )//cp1 file1.txt file2.txt
  253. {
  254. copyFiles(src, dest);
  255. }
  256. else if( src[0] != '/' && dest[0] == '/' )
  257. {
  258. int i;
  259. for(i=1; i<=strlen(dest); i++)
  260. {
  261. dest[(i-1)] = dest[i];
  262. }
  263. strcat(dest, "/");
  264. strcat(dest, src);
  265.  
  266.  
  267. copyFiles(src, dest);
  268. }
  269. else if( src[0] == '/' && dest[0] == '/' )//cp1 /dir1 /dir2
  270. { //- copies all regular files from /dir1 to /dir2
  271. int i;
  272. for(i=1; i<=strlen(dest); i++)
  273. {
  274. dest[(i-1)] = dest[i];
  275. }
  276. for(i=1; i<=strlen(src); i++)
  277. {
  278. src[(i-1)] = src[i];
  279. }
  280. copyDir(src, dest);
  281. }
  282.  
  283. return 1;
  284. }
  285.  
  286. int custom_cd(char **args)
  287. {
  288. if (args[1] == NULL) {
  289. fprintf(stderr, "Eroare: Introduceti un argument pentru comanda \"cd\"\n");
  290. } else {
  291. if (chdir(args[1]) != 0) {
  292. perror("shell");
  293. }
  294. }
  295. return 1;
  296. }
  297.  
  298. int custom_help(char **args)
  299. {
  300. int i;
  301.  
  302. printf("Urmatoarele comenzi sunt implementate:\n");
  303. for (i = 0; i < builtin_function_count(); i++) {
  304. printf(" %s\n", custom_Function_names[i]);
  305. }
  306. printf("Folositi comanda \'man\' pentru informatii despre alte comenzi .\n");
  307.  
  308. return 1;
  309. }
  310.  
  311. int custom_exit(char **args)
  312. {
  313. write_history (history_path);
  314. return 0;
  315. }
  316.  
  317. int launch_process(char **args)
  318. {
  319. pid_t pid, wpid;
  320. int command_result;
  321. pid = fork();
  322. if (pid == 0) {
  323. if (execvp(args[0], args) == -1) {
  324. perror("shell");
  325. }
  326. exit(EXIT_FAILURE);
  327. } else if (pid < 0) {
  328. perror("shell");
  329. } else {
  330. do {
  331. wpid = waitpid(pid, &
  332. command_result, WUNTRACED);
  333. } while (!WIFEXITED(
  334. command_result) && !WIFSIGNALED(
  335. command_result));
  336. }
  337. return 1;
  338. }
  339.  
  340.  
  341.  
  342. int execute_command(char **args)
  343. {
  344. int i,j;
  345.  
  346. if (args[0] == NULL) {
  347. return 1;
  348. }
  349.  
  350. //Check if the command contains pipes and if so
  351. //Call the custom pipe function
  352.  
  353. pipe_count=0;
  354.  
  355. for(i=0;i<argument_count;i++)
  356. {
  357. for(j=0;j<strlen(args[i]);j++)
  358. if(args[i][j]=='|')
  359. {
  360. pipe_count++;
  361. }
  362. }
  363.  
  364. if(pipe_count>0)
  365. {
  366. pipe_count++;
  367. return custom_pipe(args);
  368. }
  369.  
  370. for (i = 0; i < builtin_function_count(); i++)
  371. if (strcmp(args[0], custom_Function_names[i]) == 0)
  372. { // read old history
  373. read_history (history_path);
  374. return (*builtin_func[i])(args);
  375. }
  376.  
  377. return launch_process(args);
  378. }
  379.  
  380. char *read_line(void)
  381. {
  382. char *line = NULL;
  383. ssize_t bufsize = 0;
  384. getline(&line, &bufsize, stdin);
  385.  
  386. add_history(line);
  387. return line;
  388. }
  389. char **split_line(char *line)
  390. {
  391. int maximum_arguments = 32, pos = 0;
  392. char * separator = " \t\r\n\a";
  393. char **parameters = malloc(maximum_arguments * sizeof(char*));
  394. char *token;
  395.  
  396. if (!parameters) {
  397. fprintf(stderr, "Eroare de alocare a memoriei \n");
  398. exit(EXIT_FAILURE);
  399. }
  400.  
  401. token = strtok(line, separator);
  402. while (token != NULL) {
  403. parameters[pos++] = token;
  404. if (pos >= maximum_arguments) {
  405. fprintf(stderr, "Prea multe argumente au fost gasite in comanda. \n");
  406. exit(EXIT_FAILURE);
  407.  
  408. }
  409. token = strtok(NULL, separator);
  410. }
  411.  
  412. parameters[pos] = NULL;
  413.  
  414. argument_count=pos;
  415.  
  416. return parameters;
  417. }
  418.  
  419.  
  420.  
  421.  
  422. int copyDir(char *source, char *destination)
  423. {
  424. DIR *dir_ptr = NULL;
  425. struct dirent *direntp;
  426. char tempDest[strlen(destination)+1];
  427. char tempSrc[strlen(source)+1];
  428. strcat(destination, "/");
  429. strcat(source, "/");
  430. strcpy(tempDest, destination);
  431. strcpy(tempSrc, source);
  432.  
  433. struct stat fileinfo;
  434.  
  435. if( (dir_ptr = opendir(source)) == NULL )
  436. {
  437. fprintf(stderr, "cp1: cannot open %s for copying\n", source);
  438. return 0; // read old history
  439. }
  440. else
  441. {
  442. while( (direntp = readdir(dir_ptr)))
  443. {
  444.  
  445. if(dostat(direntp->d_name))
  446. {
  447. strcat(tempDest, direntp->d_name);
  448. strcat(tempSrc, direntp->d_name);
  449. copyFiles(tempSrc, tempDest);
  450. strcpy(tempDest, destination);
  451. strcpy(tempSrc, source);
  452. }
  453. }
  454. closedir(dir_ptr);
  455. return 1;
  456. }
  457.  
  458.  
  459. }
  460.  
  461.  
  462. int dostat(char *filename)
  463. {
  464. struct stat fileInfo;
  465.  
  466. //printf("Next File %s\n", filename);
  467. if(stat(filename, &fileInfo) >=0)
  468. if(S_ISREG(fileInfo.st_mode))
  469. return 1;
  470. else return 0;
  471.  
  472. return 1;
  473. }
  474.  
  475.  
  476.  
  477.  
  478. int copyFiles(char *source, char *destination)
  479. {
  480. int in_fd, out_fd, n_chars;
  481. char buf[BUFFERSIZE];
  482.  
  483.  
  484. /* open files */
  485. if( (in_fd=open(source, O_RDONLY)) == -1 )
  486. {
  487. display_error("Cannot open ", source);
  488. }
  489.  
  490.  
  491. if( (out_fd=creat(destination, 0644)) == -1 )
  492. {
  493. display_error("Cannot creat ", destination);
  494. }
  495.  
  496.  
  497. /* copy files */
  498. while( (n_chars = read(in_fd, buf, BUFFERSIZE)) > 0 )
  499. {
  500. if( write(out_fd, buf, n_chars) != n_chars )
  501. {
  502. display_error("Write error to ", destination);
  503. }
  504.  
  505.  
  506. if( n_chars == -1 )
  507. {
  508. display_error("Read error from ", source);
  509. }
  510. }
  511.  
  512.  
  513. /* close files */
  514. if( close(in_fd) == -1 || close(out_fd) == -1 )
  515. {
  516. display_error("Error closing files", "");
  517. }
  518.  
  519.  
  520. return 1;
  521. }
  522.  
  523. void display_error(char *s1, char *s2)
  524. {
  525. fprintf(stderr, "Error: %s ", s1);
  526. perror(s2);
  527. }
  528.  
  529.  
  530. void shell_loop()
  531. {
  532.  
  533. char *line, *prompt;
  534. char **args;
  535.  
  536. int status;
  537.  
  538. // read old history
  539. read_history (history_path);
  540.  
  541. do {
  542.  
  543. prompt = malloc(1+strlen("$> "));
  544.  
  545. strcpy(prompt, "$> ");
  546.  
  547. line = readline(prompt);
  548.  
  549. //add new commandline
  550. add_history(line);
  551.  
  552. args = split_line(line);
  553.  
  554. status = execute_command(args);
  555.  
  556. free(line);
  557. free(args);
  558. }
  559. while (status);
  560.  
  561. }
  562.  
  563. int main(int argc, char **argv)
  564. {
  565. shell_loop();
  566.  
  567. return EXIT_SUCCESS;
  568. }
Add Comment
Please, Sign In to add comment