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

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.