- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/mman.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <limits.h> // necesar pentru PATH_MAX
- #define SECTOR_SIZE 4096
- char numeFisiere[SECTOR_SIZE][SECTOR_SIZE], rezultat[SECTOR_SIZE][SECTOR_SIZE];
- int nrFisiere, nrLiniiRez;
- int isNumber; // flag validare numar
- int nr;
- int lastOption; // ultima optiune selectata
- int fn, fc; // flag pentru optiunile -c si -n
- int nLines, cLines;
- void reverse(char *sir);
- int cifra(char c);
- void number(char *sir);
- void getData(char *map_addr, int length);
- void recursive(int f, int length, int offset, int PageSize);
- int main(int argc, char **argv)
- {
- if (argc < 2) // Nu amm fisier
- {
- perror("Introdu numele fisierului.");
- exit(1);
- }
- else if (argc == 2) // am doar numele fisierului
- {
- strcpy(numeFisiere[++nrFisiere], argv[1]);
- fn = 1;
- lastOption = 2;
- nLines = 10;
- fc = 0;
- }
- else // am mai multe fisiere sau argumente
- {
- for (int i = 1; i < argc; i++)
- {
- if (strcmp(argv[i], "-c") == 0)
- {
- if (i < argc - 1) // daca mai am un numar dupa el
- {
- number(argv[i + 1]);
- if (isNumber == 1)
- {
- fc = 1;
- cLines = nr;
- lastOption = 1;
- i++;
- }
- else
- {
- printf("Argumentul introdus de dumneavoastra pentru optiunea -c nu este un numar.\n");
- exit(2);
- }
- }
- else
- {
- printf("Introduceti un argument pentru optiunea -c.\n");
- exit(1);
- }
- }
- else if (strcmp(argv[i], "-n") == 0)
- {
- if (i < argc - 1) // daca mai am un numar dupa el
- {
- number(argv[i + 1]);
- if (isNumber == 1)
- {
- fn = 1;
- nLines = nr;
- lastOption = 2;
- i++;
- }
- else
- {
- printf("Argumentul introdus de dumneavoastra pentru optiunea -n nu este un numar.\n");
- exit(2);
- }
- }
- else
- {
- printf("Introduceti un argument pentru optiunea -n.\n");
- exit(1);
- }
- }
- else
- strcpy(numeFisiere[++nrFisiere], argv[i]);
- }
- }
- int auxc = cLines;
- int auxn = nLines;
- for (int i = 1; i <= nrFisiere; i++)
- {
- int f = open(numeFisiere[i], O_RDONLY);
- if (f == -1)
- {
- perror("A aparut o eroare cand am incercat sa deschide fisierul");
- exit(2);
- }
- long PageSize = sysconf(_SC_PAGE_SIZE);
- struct stat sb;
- if (PageSize == -1)
- {
- perror("Eroare la sysconf");
- exit(1);
- }
- if (fstat(f, &sb) == -1)
- {
- perror("Eroare la fstat");
- exit(2);
- }
- nLines = auxn;
- cLines = auxc;
- for (int i = 0; i < SECTOR_SIZE; i++)
- rezultat[i][0] = '\0';
- nrLiniiRez = 0;
- recursive(f, sb.st_size, 0, PageSize);
- printf("==> %s <==\n", numeFisiere[i]);
- if (lastOption == 2 && auxn < 0)
- nrLiniiRez += auxn;
- cLines = auxc;
- if (lastOption == 1 && auxc < 0)
- {
- for (int k = nrLiniiRez; k >= 1; k--)
- {
- int lg = strlen(rezultat[k]) - 1;
- for (int j = lg; j >= 0 && cLines != 0; j--, cLines++)
- rezultat[k][j] = '\0';
- if (rezultat[k][0] == '\0')
- nrLiniiRez--;
- }
- }
- for (int k = 1; k <= nrLiniiRez; k++)
- {
- if (lastOption == 2)
- {
- printf("%s\n", rezultat[k]);
- }
- else
- for (int j = 0; j < strlen(rezultat[k]); j++)
- printf("%c", rezultat[k][j]);
- }
- }
- }
- void reverse(char *sir)
- {
- int lg = strlen(sir) - 1;
- for (int i = 0; i <= lg / 2; i++)
- {
- char aux = sir[i];
- sir[i] = sir[lg - i];
- sir[lg - i] = aux;
- }
- }
- int cifra(char c)
- {
- return c >= '0' && c <= '9';
- }
- void number(char *sir)
- {
- isNumber = 1;
- nr = 0;
- int minus = (sir[0] == '-');
- for (int i = minus; i < strlen(sir); i++)
- if (cifra(sir[i]))
- nr = nr * 10 + sir[i] - '0';
- else
- {
- isNumber = 0;
- return;
- }
- if (minus == 1)
- nr = -nr;
- }
- void getData(char *map_addr, int length)
- {
- for (int i = 0; i <= length; i++)
- {
- if (lastOption == 1) // optiunea -c
- {
- if (cLines != 0)
- {
- if (nrLiniiRez == 0 || strlen(rezultat[nrLiniiRez]) + 1 > SECTOR_SIZE)
- nrLiniiRez++;
- int lg = strlen(rezultat[nrLiniiRez]);
- rezultat[nrLiniiRez][lg] = map_addr[i];
- rezultat[nrLiniiRez][lg + 1] = '\0';
- if (cLines > 0)
- cLines--;
- }
- else
- break;
- }
- else
- {
- if (nLines != 0)
- {
- char aux[SECTOR_SIZE] = {0};
- while (i < length && map_addr[i] != '\n')
- {
- int lgAux = strlen(aux);
- aux[lgAux++] = map_addr[i++];
- }
- strcpy(rezultat[++nrLiniiRez], aux);
- if (nLines > 0)
- nLines--;
- }
- else
- break;
- }
- }
- }
- void recursive(int f, int length, int offset, int PageSize)
- {
- if ((lastOption == 1 && cLines != 0) || (lastOption == 2 && nLines != 0))
- {
- char *map_addr;
- if (length > PageSize)
- {
- map_addr = mmap(NULL, PageSize, PROT_READ, MAP_PRIVATE, f, offset);
- getData(map_addr, PageSize);
- recursive(f, length - PageSize, offset + PageSize, PageSize);
- if (munmap(map_addr, PageSize) == -1)
- {
- perror("Erroare la munmap.");
- exit(4);
- }
- return;
- }
- map_addr = mmap(NULL, length, PROT_READ, MAP_PRIVATE, f, offset);
- getData(map_addr, length);
- if (munmap(map_addr, length) == -1)
- {
- perror("Erroare la munmap.");
- exit(4);
- }
- }
- }