Advertisement
sserban21

stadiuFinalSO

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