diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..4b2c4395be2455a8a91bc983469c1939cc07bc0b --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +LIBS = $(shell pkg-config --libs libcurl fuse) +CFLAGS = $(shell pkg-config --cflags libcurl fuse) -ggdb \ + -std=c++2a -Wall -Wextra -pedantic \ + -D_FILE_OFFSET_BITS=64 + +all: + g++ $(LIBS) $(CFLAGS) -o mfs mediawikifs.cpp diff --git a/mediawikifs.cpp b/mediawikifs.cpp new file mode 100644 index 0000000000000000000000000000000000000000..19c9252ef6c008812e2fc82f2a83f2ff412b290c --- /dev/null +++ b/mediawikifs.cpp @@ -0,0 +1,130 @@ +#include "mediawikifs.h" + +#include <map> +#include <string> +#include <iostream> + +#include <cstdio> +#include <cstring> +#include <cstdlib> + +#include <sys/types.h> +#include <sys/stat.h> +#include <curl/curl.h> +#include <fuse.h> + + +static std::string str; + +static CURL* curl; + +page* get_page(const char* path) { + static std::map<const char*, page> pages; + page* p = & pages[path]; + + if (p->init) return p; + + str = ""; + CURLcode code; + code = curl_easy_setopt (curl, CURLOPT_URL, url); + if (code != CURLE_OK) ERR("Set url"); + code = curl_easy_perform (curl); + if (code != CURLE_OK) ERR("Perform %i", code); + + p->init = true; + p->name = path; + p->data = str; + p->size = str.size(); + p->timestamp = 1; + + return p; +} + +size_t handle_data (void* buffer, size_t, size_t nmemb, void*) { + str += (char*) buffer; + return nmemb; +} + +int getattr_callback(const char* path, struct stat* st) { + if (strcmp(path, "/") == 0) { + // TODO get size of map + return 2; + } + + page* p = get_page(path); + st->st_mode = 0444; + st->st_size = p->size; + // st->st_mtime + return 0; +} + +int open_callback (const char* /*path*/, struct fuse_file_info* /*f*/) { + return 0; +} + +int read_callback ( + const char* path, + char* buf, + size_t size, + off_t offset, + struct fuse_file_info* /*f*/) +{ + page* p = get_page (path); + + std::string* s = & p->data; + ssize_t len = s->size(); + + if (offset >= len) return 0; + + if (offset + (off_t) size > len) { + memcpy (buf, s->c_str() + offset, len - offset); + return len - offset; + } + + memcpy (buf, s->c_str() + offset, size); + return size; +} + +int readdir_callback ( + const char* path, + void* buf, + fuse_fill_dir_t filler, + off_t /* offset */, + struct fuse_file_info* /*f*/) +{ + if (strcmp(path, "/") != 0) { + return 1; + } + + filler(buf, ".", NULL, 0); + filler(buf, "..", NULL, 0); + filler(buf, "Tottaly a file", NULL, 0); + + return 0; +} + +int main (int argc, char* argv[]) { + CURLcode code; + code = curl_global_init (CURL_GLOBAL_DEFAULT); + if (code != CURLE_OK) ERR("Global init"); + + curl = curl_easy_init (); + if (curl == NULL) ERR("curl"); + + code = curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, handle_data); + if (code != CURLE_OK) ERR("Write data"); + + + struct fuse_operations fops; + fops.getattr = getattr_callback; + fops.open = open_callback; + fops.read = read_callback; + fops.readdir = readdir_callback; + + // page* p = get_page("Bishibosh"); + // std::cout << p->data << std::endl; + + return fuse_main (argc, argv, &fops, NULL); + // puts(str.c_str()); + // curl_easy_cleanup (curl); +} diff --git a/mediawikifs.h b/mediawikifs.h new file mode 100644 index 0000000000000000000000000000000000000000..526e329ae227cfceeca9709fa0d8efe38a085aad --- /dev/null +++ b/mediawikifs.h @@ -0,0 +1,25 @@ +#define FUSE_USE_VERSION 28 + +#include <string> + +#include <sys/types.h> +#include <fuse.h> + +#define url "https://datorhandbok.lysator.liu.se/index.php/Special:Exportera/Bishibosh" + +#define ERR(s, ...) fprintf(stderr, "\x1b[0;31mERR\x1b[m " s "\n", ## __VA_ARGS__) + +struct page { + bool init = false; + std::string name; + size_t size; + uint64_t timestamp; + std::string data; +}; + +extern "C" { + int getattr_callback(const char*, struct stat*); + int open_callback (const char*, struct fuse_file_info*); + int read_callback (const char*, char*, size_t, off_t, struct fuse_file_info*); + int readdir_callback (const char*, void*, fuse_fill_dir_t, off_t, struct fuse_file_info*); +}