Facebook
From Vlad, 4 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 124
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #include <unistd.h>
  6. #include <sys/mman.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10. #include <limits.h> // necesar pentru PATH_MAX
  11.  
  12. #define SECTOR_SIZE 4096
  13.  
  14. char numeFisiere[SECTOR_SIZE][SECTOR_SIZE], rezultat[SECTOR_SIZE][SECTOR_SIZE];
  15. int nrFisiere, nrLiniiRez;
  16.  
  17. int isNumber; // flag validare numar
  18. int nr;
  19. int lastOption; // ultima optiune selectata
  20.  
  21. int fn, fc; // flag pentru optiunile -c si -n
  22. int nLines, cLines;
  23.  
  24. void reverse(char *sir);
  25.  
  26. int cifra(char c);
  27.  
  28. void number(char *sir);
  29.  
  30. void getData(char *map_addr, int length);
  31.  
  32. void recursive(int f, int length, int offset, int PageSize);
  33.  
  34. int main(int argc, char **argv)
  35. {
  36.     if (argc < 2) // Nu amm fisier
  37.     {
  38.         perror("Introdu numele fisierului.");
  39.         exit(1);
  40.     }
  41.     else if (argc == 2) // am doar numele fisierului
  42.     {
  43.         strcpy(numeFisiere[++nrFisiere], argv[1]);
  44.         fn = 1;
  45.         lastOption = 2;
  46.         nLines = 10;
  47.         fc = 0;
  48.     }
  49.     else // am mai multe fisiere sau argumente
  50.     {
  51.         for (int i = 1; i < argc; i++)
  52.         {
  53.             if (strcmp(argv[i], "-c") == 0)
  54.             {
  55.                 if (i < argc - 1) // daca mai am un numar dupa el
  56.                 {
  57.                     number(argv[i + 1]);
  58.  
  59.                     if (isNumber == 1)
  60.                     {
  61.                         fc = 1;
  62.                         cLines = nr;
  63.                         lastOption = 1;
  64.                         i++;
  65.                     }
  66.                     else
  67.                     {
  68.                         printf("Argumentul introdus de dumneavoastra pentru optiunea -c nu este un numar.\n");
  69.                         exit(2);
  70.                     }
  71.                 }
  72.                 else
  73.                 {
  74.                     printf("Introduceti un argument pentru optiunea -c.\n");
  75.                     exit(1);
  76.                 }
  77.             }
  78.             else if (strcmp(argv[i], "-n") == 0)
  79.             {
  80.                 if (i < argc - 1) // daca mai am un numar dupa el
  81.                 {
  82.                     number(argv[i + 1]);
  83.  
  84.                     if (isNumber == 1)
  85.                     {
  86.                         fn = 1;
  87.                         nLines = nr;
  88.                         lastOption = 2;
  89.                         i++;
  90.                     }
  91.                     else
  92.                     {
  93.                         printf("Argumentul introdus de dumneavoastra pentru optiunea -n nu este un numar.\n");
  94.                         exit(2);
  95.                     }
  96.                 }
  97.                 else
  98.                 {
  99.                     printf("Introduceti un argument pentru optiunea -n.\n");
  100.                     exit(1);
  101.                 }
  102.             }
  103.             else
  104.                 strcpy(numeFisiere[++nrFisiere], argv[i]);
  105.         }
  106.     }
  107.  
  108.     int auxc = cLines;
  109.     int auxn = nLines;
  110.  
  111.     for (int t = 1; t <= nrFisiere; t++)
  112.     {
  113.         int f = open(numeFisiere[t], O_RDONLY);
  114.  
  115.         if (f == -1)
  116.         {
  117.             perror("A aparut o eroare cand am incercat sa deschide fisierul");
  118.             exit(2);
  119.         }
  120.  
  121.         long PageSize = sysconf(_SC_PAGE_SIZE);
  122.         struct stat sb;
  123.  
  124.         if (PageSize == -1)
  125.         {
  126.             perror("Eroare la sysconf");
  127.             exit(1);
  128.         }
  129.  
  130.         if (fstat(f, &sb) == -1)
  131.         {
  132.             perror("Eroare la fstat");
  133.             exit(2);
  134.         }
  135.  
  136.         nLines = auxn;
  137.         cLines = auxc;
  138.  
  139.         for (int i = 0; i < SECTOR_SIZE; i++)
  140.             rezultat[i][0] = '\0';
  141.         nrLiniiRez = 0;
  142.  
  143.         recursive(f, sb.st_size, 0, PageSize);
  144.  
  145.         printf("==> %s <==\n", numeFisiere[t]);
  146.  
  147.         for (int k = nrLiniiRez; k >= 1; k--)
  148.         {
  149.             if (lastOption == 2)
  150.             {
  151.                 reverse(rezultat[k]);
  152.                 printf("%s\n", rezultat[k]);
  153.             }
  154.             else
  155.                 for (int j = strlen(rezultat[k]); j >= 0; j--)
  156.                     printf("%c", rezultat[k][j]);
  157.         }
  158.     }
  159. }
  160.  
  161. void reverse(char *sir)
  162. {
  163.     int lg = strlen(sir) - 1;
  164.     for (int i = 0; i <= lg / 2; i++)
  165.     {
  166.         char aux = sir[i];
  167.         sir[i] = sir[lg - i];
  168.         sir[lg - i] = aux;
  169.     }
  170. }
  171.  
  172. int cifra(char c)
  173. {
  174.     return c >= '0' && c <= '9';
  175. }
  176.  
  177. void number(char *sir)
  178. {
  179.     isNumber = 1;
  180.     nr = 0;
  181.     if (!(sir[0] == '-' || cifra(sir[0])))
  182.     {
  183.         isNumber = 0;
  184.         return;
  185.     }
  186.  
  187.     for (int i = 0; i < strlen(sir); i++)
  188.         if (cifra(sir[i]))
  189.             nr = nr * 10 + sir[i] - '0';
  190.         else
  191.         {
  192.             isNumber = 0;
  193.             return;
  194.         }
  195. }
  196.  
  197. void getData(char *map_addr, int length)
  198. {
  199.     for (int i = length; i >= 0; i--) // -2 daca vr fara ultimul \n
  200.     {
  201.         if (lastOption == 1) // optiunea -c
  202.         {
  203.             if (cLines != 0)
  204.             {
  205.                 if (nrLiniiRez == 0 || strlen(rezultat[nrLiniiRez]) + 1 > SECTOR_SIZE)
  206.                     nrLiniiRez++;
  207.                 int lg = strlen(rezultat[nrLiniiRez]);
  208.                 rezultat[nrLiniiRez][lg] = map_addr[i];
  209.                 rezultat[nrLiniiRez][lg + 1] = '\0';
  210.                 cLines--;
  211.             }
  212.             else
  213.                 break;
  214.         }
  215.         else
  216.         {
  217.             if (nLines != 0)
  218.             {
  219.                 char aux[SECTOR_SIZE] = {0};
  220.                 while (i >= 0 && map_addr[i] != '\n')
  221.                 {
  222.                     int lgAux = strlen(aux);
  223.                     aux[lgAux++] = map_addr[i--];
  224.                 }
  225.                 //reverse(aux);
  226.                 strcpy(rezultat[++nrLiniiRez], aux);
  227.                 nLines--;
  228.             }
  229.             else
  230.                 break;
  231.         }
  232.     }
  233. }
  234.  
  235. void recursive(int f, int length, int offset, int PageSize)
  236. {
  237.     int ok = 0;
  238.     if (length > PageSize)
  239.     {
  240.         recursive(f, length - PageSize, offset + PageSize, PageSize);
  241.         ok = 1;
  242.     }
  243.     if (ok == 1)
  244.         length = PageSize;
  245.     char *map_addr = mmap(NULL, length, PROT_READ, MAP_PRIVATE, f, offset);
  246.     if ((lastOption == 1 && cLines != 0) || (lastOption == 2 && nLines != 0))
  247.         getData(map_addr, length);
  248.     if (munmap(map_addr, length) == -1)
  249.     {
  250.         perror("Erroare la munmap.");
  251.         exit(4);
  252.     }
  253. }