#include #include #include #include #include #include #include #include #include // 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); } } }