Skocz do zawartości

Błąd ze ścieżkami pod linuxem przy użyciu FUSE


mihers

Pomocna odpowiedź

Hej, mam zadanie na studia, żeby napisać program pełniący rolę adaptera FUSE pod linuxem, program ma się odpalać następująco  ./prog zip_file mount_point, zip_file - zip, z którego będziemy chcieli odczytywać pliki / foldery, mount_point - tymczasowe miejsce dla naszego systemu plikow.  na czym polega problem? Otóż do_readdir pobiera nazwy, które będziemy wyświetlać w mount_poincie za pomocą polecenia 'ls', problem jest taki, że jak nie podmienie w nazwie '/' na #, to program wogóle nie wykrywa folderów z zipa, a jak podmienie '/' na '#', to wtedy funkcja, do_read, nie będzie wstanie wstrzyknąć zawartości pliku w odpowiednie miejsce, bo ścieżki nie będą się zgadzać.

#define FUSE_USE_VERSION 30
#include <fuse.h>
#include <zip.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <time.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>

#define MAX_SIZE 100
zip_t *archive;
char *directory_name;
static int do_getattr(const char *path, struct stat *st)
{
    if (strcmp(path, "/") == 0)
    {
        st->st_mode = S_IFDIR | 0777;
        st->st_nlink = 2;
    }
    else if (path[strlen(path) - 1] == '#')
    {
        st->st_mode = S_IFDIR | 0777;
        st->st_nlink = 1;
        st->st_size = 1024;
    }
    else
    {
        st->st_mode = S_IFREG | 0777;
        st->st_nlink = 1;
        st->st_size = 1024;
    }
    return 0;
}
void replaceCharacter(const char *str, char findChar, char replaceChar, char *modifiedStr)
{
    int length = strlen(str);
    for (int i = 0; i < length; i++)
    {
        if (str[i] == findChar)
        {
            modifiedStr[i] = replaceChar;
        }
        else
        {
            modifiedStr[i] = str[i];
        }
    }
    modifiedStr[length] = '\0';
}

static int readdir_callback(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
{
    (void)offset;
    (void)fi;
    filler(buf, ".", NULL, 0);
    filler(buf, "..", NULL, 0);
    if (strcmp(path, "/") == 0)
    {
        int num_entries = zip_get_num_entries(archive, 0);
        for (int i = 0; i < num_entries; i++)
        {
            const char *entry_name = zip_get_name(archive, i, 0);
            if (entry_name[strlen(entry_name) - 1] == '/')
            {

                char dirname[255];
                replaceCharacter(entry_name, '/', '#', dirname);
               // printf("ADDED FOLDER:%s\n", dirname);
                filler(buf, dirname, NULL, 0);
            }
            else
            {
                char *modifiedString = (char *)malloc((strlen(entry_name) + 1) * sizeof(char));
                replaceCharacter(entry_name, '/', '#', modifiedString);
                filler(buf, modifiedString, NULL, 0);
            }
        }
    }
    return 0;
}
static int do_read(const char *path, char *buffer, size_t size, off_t offset, struct fuse_file_info *fi)
{
    int num_entries = zip_get_num_entries(archive, 0);
    for (int i = 0; i < num_entries; i++)
    {
        const char *entry_name = zip_get_name(archive, i, 0);
        char name[MAX_SIZE];
        // replaceCharacter(entry_name, '/', '#', name);
        snprintf(name, MAX_SIZE, "/%s", entry_name);

       // printf("NAME NAME:%s\n", name);
        if (strcmp(path, name) == 0)
        {
            struct zip_file *entry_file = zip_fopen_index(archive, i, 0);
            if (entry_file == NULL)
            {
                printf("Failed to open entry file '%s'\n", entry_name);
                continue;
            }
            long fileSize = sizeof(entry_file);
            char *content = (char *)malloc(fileSize + 1);
            zip_int64_t bytes_read = zip_fread(entry_file, content, fileSize);
            memcpy(buffer, content + offset, size);
            return strlen(content) - offset;
        }
    }
    return 0;
}
static struct fuse_operations operations = {
    .getattr = do_getattr,
    .readdir = readdir_callback,
    .read = do_read,
};
int main(int argc, char **argv)
{
    directory_name = malloc(MAX_SIZE);
    directory_name = "/home/user/fuse/mnt";
    if (argc < 3)
    {
        printf("not enought input arguments");
        return 0;
    }
    int error;
    archive = zip_open(argv[1], ZIP_RDONLY, &error);
    if (archive == NULL)
    {
        printf("Failed to open: %s\n", argv[1]);
        return 0;
    }
    return fuse_main(argc - 1, argv + 1, &operations, NULL);
}

 

  • Lubię! 1
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.