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