HomeFedun.SiteGitHubTelegram

Przykładowe zadania 1, 2, 3, 4

Published on 20.10.2026 at 12:49

Last updated on 20.10.2026 at 12:49

Zadanie 1

#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <limits.h>
 
#define ERR(source) (perror(source),\
    fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
    exit(EXIT_FAILURE))
 
void listDir(const char *path) {
    DIR* dirp;
    struct dirent* entry;
    struct stat filestat;
    if((dirp = opendir(path)) == NULL) {
        ERR("opendir");
    }
    do {
        errno = 0;
        if ((entry = readdir(dirp)) != NULL) {
            if (lstat(entry->d_name, &filestat)) {
                ERR("lstat");
            }
            printf("%s %lld\n", entry->d_name, filestat.st_size);
        }
    } while(entry != NULL);
 
    if (errno != 0) {
        ERR("readdir");
    }
 
    if (closedir(dirp) == -1) {
        ERR("closedir");
    }
}
 
int main(int argc, char *argv[]) {
    int c;
    char *paths[argc];
    char path[PATH_MAX];
    int path_count = 0;
 
    if (getcwd(path, PATH_MAX) == NULL)
        ERR("getcwd");
 
    while ((c = getopt(argc, argv, "p:")) != -1) {
        switch (c) {
            case 'p':
                paths[path_count++] = optarg;
                break;
            case '?':
            default:
                fprintf(stderr, "Usage: %s -p <directory>\n", argv[0]);
                exit(EXIT_FAILURE);
        }
    }
 
    for (int i = 0; i < path_count; i++) {
        if (chdir(paths[i])) {
            fprintf(stderr, "Error changing directory to %s\n", paths[i]);
            ERR("chdir");
        }
        printf("SCIEZKA:\n%s\nLISTA PLIKÓW:\n", paths[i]);
        listDir(".");
        if (chdir(path)) {
            ERR("chdir");
        }
    }
    
    return EXIT_SUCCESS;
}

Zadanie 2

#define _POSIX_C_SOURCE 200809L
 
 
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <limits.h>
#include <time.h>
#include <string.h>
 
 
#define MAX_PATH PATH_MAX
 
#define ERR(source) (perror(source), fprintf(stderr, "%s:%d\n", __FILE__, __LINE__), exit(EXIT_FAILURE))
 
 
char* FILE_OUTPUT = "NO";
int FILE1 = 0;
int allowed_depth = 1;
 
int count4=0;
 
void usage(){
    printf("p: MUSISZ PODAC SCIEZKE NORMALNA \n");
}
 
void listing(char* ch , char* restrict1[500] , int depth , FILE* fl){
    //printf("%s\n",ch);
    char* c  = ch;
    DIR* dir = opendir(ch);
    FILE *f = fl;
   
    if(dir == NULL){
        usage();
        return;
        //ERR("opendir");
        //exit(EXIT_FAILURE);
    }
 
    if(FILE1){
        fprintf(f,"SCIEZKA:\n");
        fprintf(f,"%s\n",c);
        fprintf(f,"LISTA PLIKOW: \n");
    }
    else{
        printf("SCIEZKA:\n");
        printf("%s\n",c);
        printf("LISTA PLIKOW: \n");
    }
    errno = 0;
    struct dirent* dr = readdir(dir);
 
    
    if(dr == NULL){
        if(errno !=0){
            perror("readdir");
            exit(EXIT_FAILURE);
        }
        else{
            printf("KONIEC ODCZYTU\n");
        }
    }
    while(dr != NULL){ 
        struct stat st;
 
        char fullpath[PATH_MAX];
        sprintf(fullpath, "%s/%s", ch, dr->d_name);
        if(lstat (fullpath,&st)){
            ERR("lstat");
            exit(EXIT_FAILURE);
        };
 
        if (S_ISDIR(st.st_mode)) {
            if (strcmp(dr->d_name, ".") != 0 &&
                strcmp(dr->d_name, "..") != 0) {
 
                if (depth < allowed_depth) {
                    listing(fullpath, restrict1, depth + 1,fl);
                }
            }
 
            dr = readdir(dir);
            continue;
        }
        
        const char *dot = strrchr(dr->d_name, '.');
        if(count4>0){
        if (dot == NULL) {
            dr = readdir(dir);
            continue;
        }
        int skip = 1;
        for(int i = 0; i < count4; i++){
            if(strcmp( dot+1 ,restrict1[i]) == 0){
                skip = 0;
            }
        }
        if(skip){
            dr = readdir(dir);
            continue;
        }
        }
 
 
        if(!FILE1)printf("%s ",dr->d_name);
        else{
            fprintf(f,"%s ",dr->d_name);
        }
 
        
        
        
        if(!FILE1)printf("%ld\n",st.st_size);
        else{
            fprintf(f,"%ld\n",st.st_size);;
        }
      
        
        errno = 0;
        dr = readdir(dir);
        if(dr == NULL){
        if(errno !=0){
            perror("readdir");
            exit(EXIT_FAILURE);
        }
        else{
            printf("KONIEC ODCZYTU\n");
        }
    }
    }
    if(closedir(dir)){
        exit(EXIT_FAILURE);
    };
   
}
 
 
int main(int argc,char** argv){
    //listing(".");
    int i;
    // DIR* dir = opendir("sopyyy");
    // if(dir == NULL){
    //     printf("SDFSD\n");
    // }
    int count = 0;
    int counto = 0;
    int countr = 0;
 
 
    char *s1[500];
    char *restriction[500];
    FILE* fl=NULL;
 
 
    while( (i = getopt(argc,argv,"op:e:d:")) != -1){
        if(i == 'p'){
            char* s = optarg;
            s1[count] = optarg;
            count++;
        }
        else if  (i == 'o'){
            FILE1 = 1;
            counto++;
            char *env = getenv("L1_OUTPUTFILE");
            if(env == NULL){
                perror("stop");
            }
            if(counto>1){
                fprintf(stderr,"ONLY ONE O");
                return EXIT_FAILURE;
            }
        }
        else if (i == 'e'){
            restriction[countr] = optarg;
            countr++;
            count4 = countr;
        }
        else if(i == 'd'){
            allowed_depth = strtol(optarg, (char **)NULL, 10);
        }
        else {
            usage();
            return EXIT_FAILURE;
        }
    }
    if(FILE1){
         char *env = getenv("L1_OUTPUTFILE");
            if(env == NULL){
                perror("stop");
                return EXIT_FAILURE;
            }
        fl = fopen(env,"w+");
        if(fl == NULL){
            ERR("fopen");
        }
    }
    
    for(int i = 0 ; i < count ;i++){
        listing(s1[i],restriction,1,fl);
    }
 
    if(optind != argc){
        printf("UWAGA nie odczytane wszystkie parametry");
    }
    // if(count == 0){
    //     listing(".");
    // }
    if(FILE1 && fclose(fl)){
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Zadanie 3

#define _POSIX_C_SOURCE 200809L
 
 
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <limits.h>
#include <time.h>
#include <string.h>
 
 
#define MAX_PATH PATH_MAX
 
#define ERR(source) (perror(source), fprintf(stderr, "%s:%d\n", __FILE__, __LINE__), exit(EXIT_FAILURE))
 
void install(char* s1 , char* s2, int size){
            DIR* dir = opendir(".");
            struct dirent* s;
            while((s =readdir(dir))!=NULL){
                if(strcmp(s->d_name,s1)==0){
                    perror("ALREADY EXISTS");
                    return;
                }
            }
 
            FILE* f1 = fopen(s1,"a");
            
            srand(time(NULL));
            
            for(int i = 0; i < size;i++){
                fprintf(f1, "%c", rand() % 26 + 'A');
            }
            
            fclose(f1);
 
            FILE* f2 = fopen("requirements","a");
 
            fprintf(f2,"%s %s\n",s1,s2);
            fclose(f2);  
            closedir(dir);
}
 
void deleteq(char *s1){
    int find = 0;
 
   
    if(unlink(s1) && errno == ENOENT){
        ERR("unlink");
    }
    char c1[500];
    char c[500];
    char sd1[500][500];
    char ver[500][500];
    
    int count = 0; 
    FILE* file = fopen("requirements","r+");
 
    while(fscanf(file,"%s%s",c,c1) == 2){
        if(strcmp(c,s1) != 0){
            strcpy(sd1[count],c);
            strcpy(ver[count],c1);
            count++;
        }
    }
    if(fclose(file)){
        ERR("fclose");
    }
    file = fopen("requirements","w+");
 
    fseek(file,0,SEEK_SET);
 
    for(int j = 0 ; j < count ; j++){
        fprintf(file,"%s %s\n",sd1[j],ver[j]);
    }
 
    if(fclose(file)){
        perror("fclose");
        exit(EXIT_FAILURE);
    }
    
}
 
int main(int argc,char** argv){
    int i = 0;
    int path_size = 500;
    char curr[500] = ".";
    mode_t perm = 0777;
    char path[500];
    getcwd(path,500);
    
    char* dirrectioins[500];
    int count = 0;
 
    while((i = getopt(argc,argv,"v:c:i:d:")) != -1){
        if(i == 'c'){
            char* c = optarg;
            mkdir(c,perm);
            chdir(c);
 
            FILE* x = fopen("requirements","w+");
            fclose(x);
        }
        else if(i == 'v'){
            dirrectioins[count] = optarg;
            count++;
        }
        else if (i == 'i') {
                char path[500];
                getcwd(path, 500);
 
                char name[500];
                char version[500];
 
                char *sep = strstr(optarg, "==");
 
                if (sep == NULL) {
                    fprintf(stderr, "Wrong package format\n");
                    return EXIT_FAILURE;
                }
 
                int len = sep - optarg;
 
                strncpy(name, optarg, len);
                name[len] = '\0';
 
                strcpy(version, sep + 2);
 
                for (int i = 0; i < count; i++) {
                    chdir(dirrectioins[i]);
                    install(name, version, 500);
                    chdir(path);
                }
            }
        else if(i == 'd'){
            char path[500];
            getcwd(path,500);
 
            for(int i=0;i<count;i++){
                chdir(dirrectioins[i]);
                deleteq(optarg);
                chdir(path);
            }              
        }
    
    }
    printf("%s\n","KONIEC");
    return EXIT_SUCCESS;
}

Zadanie 4

main.c
#define _POSIX_C_SOURCE 200809L
 
#include "etap-4.h"
 
#include <dirent.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
 
#define ERR(source) (perror(source), fprintf(stderr, "%s:%d\n", __FILE__, __LINE__), exit(EXIT_FAILURE))
 
enum { MAX_TITLE = 64 };
 
/* Wynik jest nowym blokiem pamięci; wywołujący zwalnia go przez free(). */
char *join_paths(const char *path1, const char *path2)
{
    size_t first = strlen(path1);
    size_t second = strlen(path2);
    int separator = first != 0 && path1[first - 1] != '/';
 
    if (second > SIZE_MAX - 2 || first > SIZE_MAX - second - 2) {
        errno = ENOMEM;
        ERR("join_paths");
    }
    char *result = malloc(first + second + 2);
    if (result == NULL)
        ERR("malloc");
    memcpy(result, path1, first);
    if (separator)
        result[first++] = '/';
    memcpy(result + first, path2, second + 1);
    return result;
}
 
void usage(const char *program)
{
    fprintf(stderr, "USAGE: %s [database]\n", program);
    exit(EXIT_FAILURE);
}
 
/* Czyta tytuł i gatunek. Wartości są obcinane do 64 bajtów, jak nazwy w indeksie. */
void seek_(const char *pathname, char title[MAX_TITLE + 1], char genre[MAX_TITLE + 1])
{
    FILE *file = fopen(pathname, "r");
    if (file == NULL)
        ERR("fopen");
 
    char *line = NULL;
    size_t capacity = 0;
    ssize_t length;
    title[0] = '\0';
    genre[0] = '\0';
 
    while ((length = getline(&line, &capacity, file)) != -1) {
        char *colon = strchr(line, ':');
        if (colon == NULL)
            continue;
        size_t key_length = (size_t)(colon - line);
        char *value = colon + 1;
        size_t value_length = (size_t)(line + length - value);
        while (value_length > 0 &&
               (value[value_length - 1] == '\n' || value[value_length - 1] == '\r'))
            value_length--;
        if (value_length > MAX_TITLE)
            value_length = MAX_TITLE;
 
        char *destination = NULL;
        if (key_length == 5 && memcmp(line, "title", 5) == 0)
            destination = title;
        else if (key_length == 5 && memcmp(line, "genre", 5) == 0)
            destination = genre;
        if (destination != NULL) {
            memcpy(destination, value, value_length);
            destination[value_length] = '\0';
        }
    }
 
    if (ferror(file))
        ERR("getline");
    free(line);
    if (fclose(file) == EOF)
        ERR("fclose");
}
 
void seek_fgets(const char *pathname, char title[MAX_TITLE + 1], char genre[MAX_TITLE + 1])
{
    FILE *file = fopen(pathname, "r");
    if (file == NULL)
        ERR("fopen");
 
    char line[1024];
    title[0] = '\0';
    genre[0] = '\0';
 
    while (fgets(line, sizeof(line), file) != NULL) {
        int has_non_cr_suffix = 0;
        if (strchr(line, '\n') == NULL) {
            /* Discard the rest of this line, preserving trailing-CR semantics. */
            int character;
            while ((character = fgetc(file)) != EOF && character != '\n') {
                if (character != '\r')
                    has_non_cr_suffix = 1;
            }
        }
 
        char *colon = strchr(line, ':');
        if (colon == NULL)
            continue;
        size_t key_length = (size_t)(colon - line);
        char *value = colon + 1;
        size_t value_length = strlen(value);
        while (!has_non_cr_suffix && value_length > 0 &&
               (value[value_length - 1] == '\n' || value[value_length - 1] == '\r'))
            value_length--;
        if (value_length > MAX_TITLE)
            value_length = MAX_TITLE;
 
        char *destination = NULL;
        if (key_length == 5 && memcmp(line, "title", 5) == 0)
            destination = title;
        else if (key_length == 5 && memcmp(line, "genre", 5) == 0)
            destination = genre;
        if (destination != NULL) {
            strncpy(destination, value, value_length);
            destination[value_length] = '\0';
        }
    }
 
    if (ferror(file))
        ERR("fgets");
    if (fclose(file) == EOF)
        ERR("fclose");
}
 
void recursivesearch(const char *directory_path, const char *relative_path)
{
    DIR *directory = opendir(directory_path);
    if (directory == NULL)
        ERR("opendir");
 
    for (;;) {
        errno = 0;
        struct dirent *entry = readdir(directory);
        if (entry == NULL) {
            if (errno != 0)
                ERR("readdir");
            break;
        }
        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
            continue;
 
        char *source = join_paths(directory_path, entry->d_name);
        char *relative = join_paths(relative_path, entry->d_name);
        struct stat info;
        if (lstat(source, &info) == -1)
            ERR("lstat");
 
        if (S_ISDIR(info.st_mode)) {
            recursivesearch(source, relative);
        } else if (S_ISREG(info.st_mode)) {
            char title[MAX_TITLE + 1];
            char genre[MAX_TITLE + 1];
            seek_(source, title, genre);
 
            char *visible_target = join_paths("../../library", relative);
            char *visible_link = join_paths("index/by-visible-title", entry->d_name);
            if (symlink(visible_target, visible_link) == -1)
                ERR("symlink");
            free(visible_target);
            free(visible_link);
 
            if (title[0] != '\0') {
                if (strchr(title, '/') != NULL || !strcmp(title, ".") ||
                    !strcmp(title, "..")) {
                    fprintf(stderr, "Niepoprawny tytuł w pliku: %s\n", source);
                    exit(EXIT_FAILURE);
                }
                char *title_link = join_paths("index/by-title", title);
                char *title_target = join_paths("../../library", relative);
                if (symlink(title_target, title_link) == -1)
                    ERR("symlink");
                free(title_link);
                free(title_target);
 
                if (genre[0] != '\0') {
                    if (strchr(genre, '/') != NULL || !strcmp(genre, ".") ||
                        !strcmp(genre, "..")) {
                        fprintf(stderr, "Niepoprawny gatunek w pliku: %s\n", source);
                        exit(EXIT_FAILURE);
                    }
                    char *genre_dir = join_paths("index/by-genre", genre);
                    if (mkdir(genre_dir, 0777) == -1 && errno != EEXIST)
                        ERR("mkdir");
                    char *genre_link = join_paths(genre_dir, title);
                    char *genre_target = join_paths("../../../library", relative);
                    if (symlink(genre_target, genre_link) == -1)
                        ERR("symlink");
                    free(genre_dir);
                    free(genre_link);
                    free(genre_target);
                }
            }
        }
        free(source);
        free(relative);
    }
    if (closedir(directory) == -1)
        ERR("closedir");
}
 
 
void Recursie_search(void)
{
    if (mkdir("index", 0777) == -1)
        ERR("mkdir index");
    if (mkdir("index/by-visible-title", 0777) == -1)
        ERR("mkdir by-visible-title");
    if (mkdir("index/by-title", 0777) == -1)
        ERR("mkdir by-title");
    if (mkdir("index/by-genre", 0777) == -1)
        ERR("mkdir by-genre");
    recursivesearch("library", "");
}
 
int main(int argc, char **argv)
{
    if (argc > 2)
        usage(argv[0]);
 
    struct stat library_info;
    if (stat("library", &library_info) == -1)
        ERR("stat library");
    if (!S_ISDIR(library_info.st_mode)) {
        fprintf(stderr, "library nie jest katalogiem\n");
        return EXIT_FAILURE;
    }
 
    Recursie_search();
    if (argc == 2)
        return verify_database(argv[1], "index/by-title") == 0
                   ? EXIT_SUCCESS : EXIT_FAILURE;
    return EXIT_SUCCESS;
}
etap-4.c
#define _POSIX_C_SOURCE 200809L
 
#include "etap-4.h"
 
#include <errno.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <unistd.h>
#include <fcntl.h>
 
enum { TITLE_BYTES = 64, RECORD_BYTES = 68 };
 
_Static_assert(sizeof(uint32_t) == 4, "Rozmiar pola rozmiaru musi wynosic 4 bajty");
 
struct book_record {
    uint32_t expected_size;
    char title[TITLE_BYTES + 1];
};
 
/* readv() może zwrócić mniej bajtów niż żądano, także w środku rekordu. */
static int read_record(int fd, struct book_record *record)
{
    size_t offset = 0;
    memset(record, 0, sizeof(*record));
 
    while (offset < RECORD_BYTES) {
        struct iovec parts[2];
        int count = 0;
 
        if (offset < sizeof(record->expected_size)) {
            parts[count].iov_base = (char *)&record->expected_size + offset;
            parts[count].iov_len = sizeof(record->expected_size) - offset;
            count++;
            parts[count].iov_base = record->title;
            parts[count].iov_len = TITLE_BYTES;
            count++;
        } else {
            parts[count].iov_base = record->title + offset - sizeof(record->expected_size);
            parts[count].iov_len = RECORD_BYTES - offset;
            count++;
        }
 
        ssize_t n = readv(fd, parts, count);
        if (n == -1) {
            if (errno == EINTR)
                continue;
            return -1;
        }
        if (n == 0)
            return -2; /* niepełny rekord, np. baza skrócona podczas czytania */
        offset += (size_t)n;
    }
 
    record->title[TITLE_BYTES] = '\0';
    return 0;
}
 
static int valid_title(const char title[TITLE_BYTES + 1])
{
    size_t len = strnlen(title, TITLE_BYTES);
    if (len == 0 || strchr(title, '/') || !strcmp(title, ".") || !strcmp(title, ".."))
        return 0;
    for (size_t i = len; i < TITLE_BYTES; i++) {
        if (title[i] != '\0')
            return 0; /* pole krótsze niż 64 bajty musi być dopełnione zerami */
    }
    return 1;
}
 
static char *index_path(const char *dir, const char *title)
{
    size_t dir_len = strlen(dir);
    size_t title_len = strlen(title);
    if (title_len > SIZE_MAX - 2 || dir_len > SIZE_MAX - title_len - 2) {
        errno = ENOMEM;
        return NULL;
    }
    char *path = malloc(dir_len + title_len + 2);
    if (path == NULL)
        return NULL;
    memcpy(path, dir, dir_len);
    path[dir_len] = '/';
    memcpy(path + dir_len + 1, title, title_len + 1);
    return path;
}
 
int verify_database(const char *database_path, const char *by_title_dir)
{
    int fd = open(database_path, O_RDONLY);
    if (fd == -1) {
        perror(database_path);
        return -1;
    }
 
    struct stat database_stat;
    if (fstat(fd, &database_stat) == -1) {
        perror("fstat");
        close(fd);
        return -1;
    }
    if (!S_ISREG(database_stat.st_mode) || database_stat.st_size % RECORD_BYTES != 0) {
        fprintf(stderr, "Niepoprawny format bazy: oczekiwano rekordów po %d bajtów\n",
                RECORD_BYTES);
        close(fd);
        return -1;
    }
 
    int result = 0;
    off_t records = database_stat.st_size / RECORD_BYTES;
    for (off_t i = 0; i < records; i++) {
        struct book_record book;
        int read_result = read_record(fd, &book);
        if (read_result != 0) {
            if (read_result == -1)
                perror("readv");
            else
                fprintf(stderr, "Niepełny rekord bazy na pozycji %jd\n", (intmax_t)i);
            result = -1;
            break;
        }
        if (!valid_title(book.title)) {
            fprintf(stderr, "Niepoprawny tytuł w rekordzie %jd\n", (intmax_t)i);
            result = -1;
            break;
        }
 
        char *path = index_path(by_title_dir, book.title);
        if (path == NULL) {
            perror("malloc");
            result = -1;
            break;
        }
 
        struct stat book_stat;
        if (stat(path, &book_stat) == -1) {
            if (errno == ENOENT || errno == ENOTDIR) {
                if (printf("Book \"%s\" is missing\n", book.title) < 0)
                    result = -1;
                else if (result == 0)
                    result = 1;
            } else {
                perror(path);
                result = -1;
            }
        } else if (!S_ISREG(book_stat.st_mode)) {
            if (printf("Book \"%s\" is missing\n", book.title) < 0)
                result = -1;
            else if (result == 0)
                result = 1;
        } else if (book_stat.st_size != (off_t)book.expected_size) {
            if (printf("Book \"%s\" size mismatch (%" PRIu32 " vs %jd)\n",
                       book.title, book.expected_size, (intmax_t)book_stat.st_size) < 0)
                result = -1;
            else if (result == 0)
                result = 1;
        }
        free(path);
        if (result == -1)
            break;
    }
 
    if (close(fd) == -1) {
        perror("close");
        result = -1;
    }
    if (fflush(stdout) == EOF) {
        perror("fflush");
        result = -1;
    }
    return result;
}
etap-4.h
#ifndef SOP_L1_ETAP_4_H
#define SOP_L1_ETAP_4_H
 
/* Zwraca 0, gdy baza zgadza się z indeksem; 1 przy brakach lub różnicach,
 * -1 przy błędzie odczytu albo niepoprawnym formacie bazy. */
int verify_database(const char *database_path, const char *by_title_dir);
 
#endif