Advertisement
sserban21

toBeRefactored

Dec 8th, 2022
829
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.22 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <dirent.h>
  4. #include <string.h>
  5. #include <sys/stat.h>
  6. #include <unistd.h>
  7. #include <sys/wait.h>
  8.  
  9. struct stat info;
  10.  
  11. // functie pentru obtinerea extensiei unui fisier
  12. const char *get_file_extension(const char *filename)
  13. {
  14.     // salvam in variabila dot ceea ce este dupa punct
  15.     const char *dot = strrchr(filename, '.');
  16.     if (!dot || dot == filename)
  17.         return "";
  18.     // returnam doar ceea ce este dupa punct
  19.     return dot + 1;
  20. }
  21.  
  22. // functie pentru obtinerea numelui unui fisier fara externsie
  23. char *get_file_name_without_extension(char *restrict filename)
  24. {
  25.     char *copy = strtok(filename, "."); // aici spargem string-ulin functie de punct si luam doar ce e in fata punctului
  26.     return copy;
  27. }
  28.  
  29. void inchidere_proces(int pidd, int someStatus)
  30. {
  31.     if ((pidd = wait(&someStatus)) < 0)
  32.     {
  33.         perror("Eroare la inchidere proces!");
  34.         exit(-1);
  35.     }
  36.     else
  37.     {
  38.         printf("Fiul PID %d al procesului %d s-a terminat cu codul %d\n", pidd, getpid(), someStatus);
  39.     }
  40. }
  41.  
  42. void eroare_pipe()
  43. {
  44.     perror("Eroare pipe!");
  45.     exit(1);
  46. }
  47.  
  48. void eroare_lansare_proces()
  49. {
  50.     perror("Eroare lansare proces!");
  51.     exit(1);
  52. }
  53.  
  54. void eroare_inchidere_proces()
  55. {
  56.     perror("Eroare inchidere proces!");
  57.     exit(1);
  58. }
  59.  
  60. void afisare_info_pid(int pidd, int my_status, int functie)
  61. {
  62.     printf("Fiul PID(interior) %d al procesului %d s-a terminat cu codul %d\n", pidd, functie, my_status);
  63. }
  64.  
  65. void case_n(char string[])
  66. {
  67.     if (!string)
  68.     {
  69.         perror("Fisierul nu are nume!");
  70.     }
  71.     printf("\nNumele: %s\n", string);
  72. }
  73.  
  74. int main(int argc, char **argv)
  75. {
  76.     char *path = argv[1];    // path-ul il salvam in variabila path
  77.     char *comanda = argv[2]; // comenzile le salvam in variabila comanda
  78.     struct dirent *intrare;  // variabila pentru fiecare intrare din director
  79.     DIR *pDir;               // variabila pentru director
  80.  
  81.     // verificam numarul de argumente
  82.     // daca este mai mare de 3 dam eroare si iesim din program
  83.     if (argc > 3)
  84.     {
  85.         perror("Usage: testprog \n");
  86.         return 1;
  87.     }
  88.  
  89.     stat(argv[1], &info);
  90.     if (!S_ISDIR(info.st_mode))
  91.     {
  92.         perror("Nu e un director!");
  93.         exit(1);
  94.     }
  95.  
  96.     // deschidem directorul
  97.     pDir = opendir(argv[1]);
  98.  
  99.     // daca directorul este NULL dam eroare si iesim din program
  100.     if (pDir == NULL)
  101.     {
  102.         // trimitem un mesaj de eroare intuitiv pentru utilizator
  103.         perror("Cannot open directory!");
  104.         return 1;
  105.     }
  106.  
  107.     // in aceste 2 array-uri salvez numele fisierului si al executabilului
  108.     char nume_fisier[500], nume_executabil[500];
  109.  
  110.     // varibile folosite pentru procese
  111.     int pid, pid1, pidPipe, pidFiltrareLinii, pid4;
  112.  
  113.     // array pt pipe
  114.     int pipe_linii[2], pipe_output[2];
  115.  
  116.     // varibaile folosite pentru a afla codul de iesire al celor 3 procese
  117.     int status1, statusBun, statusBun2, status;
  118.  
  119.     // salvez in acest array o parte din comanda
  120.     char comanda2[] = "gcc -o exe";
  121.  
  122.     // verificam cat timp fiecare intrare este diferita de NULL
  123.     while ((intrare = readdir(pDir)) != NULL)
  124.     {
  125.         stat(intrare->d_name, &info);
  126.  
  127.         // in aceasta variabila salvam informatia despre file type pentru a folosi ulterior
  128.         int fileMode = info.st_mode;
  129.  
  130.         // veririficam pentru fiecare intrare din fisier verificam daca aceasta are extensia .c
  131.         if (strcmp(get_file_extension(intrare->d_name), "c") == 0)
  132.         {
  133.             char *realPath = realpath(intrare->d_name, NULL);
  134.             char nume[500];
  135.             strcpy(nume, get_file_name_without_extension(realpath(intrare->d_name, NULL)));
  136.             // lansam un proces
  137.             if ((pid = fork()) < 0)
  138.             {
  139.                 eroare_lansare_proces();
  140.             }
  141.             // intram pe procesul copil
  142.             if (pid == 0)
  143.             {
  144.                 // parcurgem fiecare argument al comenzii
  145.                 for (int i = 1; i < strlen(comanda); i++)
  146.                 {
  147.                     // facem cateva AND uri pentru a afla informatiile necesare despre permisiuni
  148.                     int userRead = fileMode & S_IRUSR;
  149.                     int userWrite = fileMode & S_IWUSR;
  150.                     int userExec = fileMode & S_IXUSR;
  151.                     int groupRead = fileMode & S_IRGRP;
  152.                     int groupWrite = fileMode & S_IWGRP;
  153.                     int groupExec = fileMode & S_IXGRP;
  154.                     int othersRead = fileMode & S_IROTH;
  155.                     int othersWrite = fileMode & S_IWOTH;
  156.                     int othersExec = fileMode & S_IXOTH;
  157.                     switch (comanda[i])
  158.                     {
  159.                     case 'n':
  160.                         case_n(intrare->d_name);
  161.                         break;
  162.                     case 'u':
  163.                         // afisam identificatorul utilizatorului
  164.                         printf("Identificator utilizator: %d\n", info.st_uid);
  165.                         break;
  166.                     case 'a':
  167.                         // afisam detaliile despre permisiuni
  168.                         {
  169.                             printf("Utilizator: Read - %s Write - %s Exec - %s\n", userRead ? "Da" : "Nu", userWrite ? "Da" : "Nu", userExec ? "Da" : "Nu");
  170.                             printf("Grup: Read - %s Write - %s Exec - %s\n", groupRead ? "Da" : "Nu", groupWrite ? "Da" : "Nu", groupExec ? "Da" : "Nu");
  171.                             printf("Altii: Read - %s Write - %s Exec - %s\n", groupRead ? "Da" : "Nu", groupWrite ? "Da" : "Nu", groupExec ? "Da" : "Nu");
  172.                         }
  173.                         break;
  174.                     case 'd':
  175.                         // afisam dimensiunea in octeti
  176.                         printf("Dimensiunea in octeti: %ld\n", info.st_size);
  177.                         break;
  178.                     case 'c':
  179.                         // afisam numarul de legaturi al fisierului
  180.                         printf("Numarul de legaturi al fisierului este: %ld\n", info.st_nlink);
  181.                         break;
  182.                     case 'g':
  183.                         // lansam un proces
  184.                         pid1 = fork();
  185.                         // verificam sa vedem daca procesul s-a lansat
  186.                         if (pid1 < 0)
  187.                         {
  188.                             eroare_lansare_proces();
  189.                         }
  190.                         // intram pe procesul copil
  191.                         if (pid1 == 0)
  192.                         {
  193.                             // compilez fisierele .c folosim execl
  194.                             // execl("gcc", "gcc", realPath, "-o", get_file_name_without_extension(intrare->d_name), NULL);
  195.                             strcat(comanda2, get_file_name_without_extension(intrare->d_name));
  196.                             strcat(comanda2, " ");
  197.                             strcat(comanda2, nume);
  198.                             strcat(comanda2, ".c");
  199.                             system(comanda2);
  200.                             exit(0);
  201.                         }
  202.                         // asteptam procesul pentru a vedea cu ce cod s-a terminat procesul copil
  203.                         if ((pid1 = wait(&status1)) < 0)
  204.                         {
  205.                             eroare_inchidere_proces();
  206.                         }
  207.                         // daca s-a terminat fara vreo problema atunci afisam
  208.                         else
  209.                         {
  210.                             int id = getpid();
  211.                             afisare_info_pid(pid1, status1, id);
  212.                             // printf("Fiul PID(interior) %d al procesului %d s-a terminat cu codul %d\n", pid1, getpid(), status1);
  213.                         }
  214.                         break;
  215.                     case 'p':
  216.                         if (pipe(pipe_linii) < 0)
  217.                         {
  218.                             eroare_pipe();
  219.                         }
  220.  
  221.                         if (pipe(pipe_output) < 0)
  222.                         {
  223.                             eroare_pipe();
  224.                         }
  225.  
  226.                         if ((pidPipe = fork()) < 0)
  227.                         {
  228.                             eroare_lansare_proces();
  229.                         }
  230.  
  231.                         if (pidPipe == 0)
  232.                         {
  233.                             if ((pidFiltrareLinii = fork()) < 0)
  234.                             {
  235.                                 eroare_lansare_proces();
  236.                             }
  237.  
  238.                             if (pidFiltrareLinii == 0)
  239.                             {
  240.                                 close(pipe_linii[0]);
  241.                                 close(pipe_output[1]);
  242.  
  243.                                 dup2(pipe_output[0], 0);
  244.                                 dup2(pipe_linii[1], 1);
  245.  
  246.                                 execlp("grep", "grep", "\\(warning\\|error\\)", NULL);
  247.  
  248.                                 perror("Eroare de executie!");
  249.                                 exit(1);
  250.                             }
  251.                             close(pipe_linii[0]);
  252.                             close(pipe_linii[1]);
  253.                             close(pipe_output[0]);
  254.  
  255.                             dup2(pipe_output[1], 2);
  256.  
  257.                             sprintf(nume_fisier, "%s/%s", argv[1], intrare->d_name);
  258.                             sprintf(nume_executabil, "%s/%s", argv[1], intrare->d_name);
  259.                             nume_executabil[strlen(nume_executabil) - 2] = '\0';
  260.                             execlp("gcc", "gcc", nume_fisier, "-o", nume_executabil, "-Wall", NULL);
  261.  
  262.                             perror("Compilarea a esuat");
  263.                             exit(1);
  264.                         }
  265.                         close(pipe_output[0]);
  266.                         close(pipe_output[1]);
  267.                         close(pipe_linii[1]);
  268.  
  269.                         char linie[500];
  270.                         int counter_erori = 0, counter_warninguri = 0, total_puncte = 0;
  271.  
  272.                         FILE *fisier = fdopen(pipe_linii[0], "r");
  273.                         if (fisier == NULL)
  274.                         {
  275.                             perror("Eroare deschidere fisier!");
  276.                             exit(1);
  277.                         }
  278.  
  279.                         while (fgets(linie, sizeof(linie) / sizeof(char), fisier))
  280.                         {
  281.                             char *ptr1 = strstr(linie, "error");
  282.                             char *ptr2 = strstr(linie, "warning");
  283.                             if (ptr1)
  284.                             {
  285.                                 counter_erori++;
  286.                             }
  287.                             if (ptr2)
  288.                             {
  289.                                 counter_warninguri++;
  290.                             }
  291.                         }
  292.  
  293.                         if (counter_erori > 0)
  294.                         {
  295.                             total_puncte = 1;
  296.                         }
  297.                         if (counter_erori == 0)
  298.                         {
  299.                             if (counter_warninguri <= 10)
  300.                             {
  301.                                 total_puncte = 2 + 8 * (10 - counter_warninguri) / 10;
  302.                             }
  303.                             else
  304.                             {
  305.                                 total_puncte = 2;
  306.                             }
  307.                         }
  308.                         if (counter_erori == 0 && counter_warninguri == 0)
  309.                         {
  310.                             total_puncte = 10;
  311.                         }
  312.  
  313.                         printf("Erori:%d, Warning-uri:%d, Total puncte:%d\n", counter_erori, counter_warninguri, counter_warninguri);
  314.  
  315.                         pidPipe = wait(&status);
  316.                         if (pidPipe < 0)
  317.                         {
  318.                             eroare_inchidere_proces();
  319.                         }
  320.                         else
  321.                         {
  322.                             printf("Fisierul \"%s\" a fost compilat cu succes!\n", intrare->d_name);
  323.                         }
  324.                         int id = getpid();
  325.                         afisare_info_pid(pidPipe, status, id);
  326.                         // printf("Fiul PID %d al procesului %d s-a terminat cu codul %d\n", pidPipe, getpid(), status);
  327.                         break;
  328.                     default:
  329.                         break;
  330.                     }
  331.                 }
  332.                 exit(0);
  333.             }
  334.  
  335.             // aceleasi principii se aplica si aici ca si cele din comentariile anterioare
  336.             pid = wait(&statusBun);
  337.             if (pid < 0)
  338.             {
  339.                 eroare_inchidere_proces();
  340.             }
  341.             else
  342.             {
  343.                 int id = getpid();
  344.                 afisare_info_pid(pid, statusBun, id);
  345.                 // printf("Fiul PID %d al procesului %d s-a terminat cu codul %d\n", pid, getpid(), statusBun);
  346.             }
  347.  
  348.             if ((pid = fork()) < 0)
  349.             {
  350.                 eroare_lansare_proces();
  351.             }
  352.             if (pid == 0)
  353.             {
  354.                 // daca dimensiunea fisierului este mai mica de 100KB atunci vom crea legatura simbolica
  355.                 if (info.st_size < 1000000)
  356.                 {
  357.                     // char *realPath = realpath(intrare->d_name, NULL);
  358.                     int l = symlink(realPath, get_file_name_without_extension(intrare->d_name));
  359.                     if (l == 0)
  360.                     {
  361.                         printf("Soft link creat cu succes!\n");
  362.                     }
  363.                     else
  364.                     {
  365.                         perror("Soft link exista deja!");
  366.                     }
  367.                     exit(0);
  368.                 }
  369.             }
  370.             if ((pid = wait(&statusBun)) < 0)
  371.             {
  372.                 eroare_inchidere_proces();
  373.             }
  374.             else
  375.             {
  376.                 int id = getpid();
  377.                 afisare_info_pid(pid, statusBun, id);
  378.                 // printf("Fiul --PID-- %d al procesului %d s-a terminat cu codul %d\n", pid, getpid(), statusBun);
  379.             }
  380.         }
  381.     }
  382.  
  383.     // aici inchidem directorul
  384.     closedir(pDir);
  385. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement