successfully mounted the root directory of the server
This commit is contained in:
parent
631ca71834
commit
431cad8ae4
2
Makefile
2
Makefile
|
@ -1,5 +1,5 @@
|
||||||
CC=gcc
|
CC=gcc
|
||||||
CFLAGS= -Wall -Wextra -lgumbo -lcurl -g
|
CFLAGS= -Wall -Wextra -lgumbo -lcurl -lfuse -D_FILE_OFFSET_BITS=64 -g
|
||||||
OBJ = main.o network.o
|
OBJ = main.o network.o
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
|
|
3
data.h
3
data.h
|
@ -29,6 +29,9 @@ typedef struct LinkTable LinkTable;
|
||||||
/** \brief link data type */
|
/** \brief link data type */
|
||||||
typedef struct Link Link;
|
typedef struct Link Link;
|
||||||
|
|
||||||
|
/** \brief root link table */
|
||||||
|
extern LinkTable *ROOT_LINK_TBL;
|
||||||
|
|
||||||
struct Link {
|
struct Link {
|
||||||
char p_url[LINK_LEN_MAX];
|
char p_url[LINK_LEN_MAX];
|
||||||
char f_url[URL_LEN_MAX];
|
char f_url[URL_LEN_MAX];
|
||||||
|
|
89
fuse_local.c
89
fuse_local.c
|
@ -1,89 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
/* must be included before including <fuse.h> */
|
|
||||||
#define FUSE_USE_VERSION 26
|
|
||||||
#include <fuse.h>
|
|
||||||
|
|
||||||
#include "network.h"
|
|
||||||
#include "fuse_local.h"
|
|
||||||
|
|
||||||
static const char *hello_str = "Hello World!\n";
|
|
||||||
static const char *hello_path = "/hello";
|
|
||||||
|
|
||||||
static struct fuse_operations fs_oper = {
|
|
||||||
.getattr = fs_getattr,
|
|
||||||
.readdir = fs_readdir,
|
|
||||||
.open = fs_open,
|
|
||||||
.read = fs_read,
|
|
||||||
};
|
|
||||||
|
|
||||||
/** \brief return the attributes for a single file indicated by path */
|
|
||||||
static int fs_getattr(const char *path, struct stat *stbuf)
|
|
||||||
{
|
|
||||||
int res = 0;
|
|
||||||
|
|
||||||
memset(stbuf, 0, sizeof(struct stat));
|
|
||||||
if (strcmp(path, "/") == 0) {
|
|
||||||
stbuf->st_mode = S_IFDIR | 0755;
|
|
||||||
stbuf->st_nlink = 100;
|
|
||||||
} else if (strcmp(path, hello_path) == 0) {
|
|
||||||
stbuf->st_mode = S_IFREG | 0444;
|
|
||||||
stbuf->st_nlink = 100;
|
|
||||||
stbuf->st_size = strlen(hello_str);
|
|
||||||
} else
|
|
||||||
res = -ENOENT;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief read the directory indicated by the path*/
|
|
||||||
static int fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
|
||||||
off_t offset, struct fuse_file_info *fi)
|
|
||||||
{
|
|
||||||
(void) offset;
|
|
||||||
(void) fi;
|
|
||||||
|
|
||||||
if (strcmp(path, "/") != 0)
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
filler(buf, ".", NULL, 0);
|
|
||||||
filler(buf, "..", NULL, 0);
|
|
||||||
filler(buf, hello_path + 1, NULL, 0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief open a file indicated by the path */
|
|
||||||
static int fs_open(const char *path, struct fuse_file_info *fi)
|
|
||||||
{
|
|
||||||
if (strcmp(path, hello_path) != 0)
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
if ((fi->flags & 3) != O_RDONLY)
|
|
||||||
return -EACCES;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief read a file */
|
|
||||||
static int fs_read(const char *path, char *buf, size_t size, off_t offset,
|
|
||||||
struct fuse_file_info *fi)
|
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
(void) fi;
|
|
||||||
if(strcmp(path, hello_path) != 0)
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
len = strlen(hello_str);
|
|
||||||
if (offset < len) {
|
|
||||||
if (offset + size > len)
|
|
||||||
size = len - offset;
|
|
||||||
memcpy(buf, hello_str + offset, size);
|
|
||||||
} else
|
|
||||||
size = 0;
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
#ifndef FUSE_LOCAL_H
|
|
||||||
#define FUSE_LOCAL_H
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
135
main.c
135
main.c
|
@ -1,33 +1,128 @@
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
|
||||||
void link_test()
|
/* must be included before including <fuse.h> */
|
||||||
{
|
#define FUSE_USE_VERSION 26
|
||||||
printf("--- start of link_test ---\n");
|
#include <fuse.h>
|
||||||
LinkTable_print(ROOT_LINK_TBL);
|
|
||||||
Link *link = path_to_Link("6/6.txt", ROOT_LINK_TBL);
|
#include <errno.h>
|
||||||
Link_download(link, 1, 20);
|
#include <fcntl.h>
|
||||||
printf("downloaded content:\n");
|
#include <stdio.h>
|
||||||
printf(link->body);
|
#include <string.h>
|
||||||
printf("\n--- end of link_test ---\n\n");
|
|
||||||
|
static int fs_getattr(const char *path, struct stat *stbuf);
|
||||||
|
static int fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
||||||
|
off_t offset, struct fuse_file_info *fi);
|
||||||
|
static int fs_open(const char *path, struct fuse_file_info *fi);
|
||||||
|
static int fs_read(const char *path, char *buf, size_t size, off_t offset,
|
||||||
|
struct fuse_file_info *fi);
|
||||||
|
|
||||||
|
static struct fuse_operations fs_oper = {
|
||||||
|
.getattr = fs_getattr,
|
||||||
|
.readdir = fs_readdir,
|
||||||
|
.open = fs_open,
|
||||||
|
.read = fs_read,
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
network_init(argv[1]);
|
||||||
|
return fuse_main(argc - 1, argv + 1, &fs_oper, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init()
|
/** \brief return the attributes for a single file indicated by path */
|
||||||
|
static int fs_getattr(const char *path, struct stat *stbuf)
|
||||||
{
|
{
|
||||||
network_init("http://127.0.0.1/~fangfufu/");
|
int res = 0;
|
||||||
|
memset(stbuf, 0, sizeof(struct stat));
|
||||||
|
|
||||||
|
if (!strcmp(path, "/")) {
|
||||||
|
stbuf->st_mode = S_IFDIR | 0755;
|
||||||
|
stbuf->st_nlink = 1;
|
||||||
|
} else {
|
||||||
|
Link *link = path_to_Link(path);
|
||||||
|
if (!link) {
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
switch (link->type) {
|
||||||
|
case LINK_DIR:
|
||||||
|
stbuf->st_mode = S_IFDIR | 0755;
|
||||||
|
stbuf->st_nlink = 1;
|
||||||
|
break;
|
||||||
|
case LINK_FILE:
|
||||||
|
stbuf->st_mode = S_IFREG | 0444;
|
||||||
|
stbuf->st_nlink = 1;
|
||||||
|
stbuf->st_size = link->content_length;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
/** \brief read the directory indicated by the path*/
|
||||||
|
static int fs_readdir(const char *path, void *buf, fuse_fill_dir_t dir_add,
|
||||||
|
off_t offset, struct fuse_file_info *fi)
|
||||||
{
|
{
|
||||||
(void) argc;
|
(void) offset;
|
||||||
(void) argv;
|
(void) fi;
|
||||||
|
|
||||||
init();
|
Link *link;
|
||||||
|
LinkTable *linktbl;
|
||||||
|
|
||||||
link_test();
|
|
||||||
|
if (!strcmp(path, "/")) {
|
||||||
|
linktbl = ROOT_LINK_TBL;
|
||||||
|
} else {
|
||||||
|
link = path_to_Link(path);
|
||||||
|
if (!link) {
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
linktbl = link->next_table;
|
||||||
|
if (!linktbl) {
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* start adding the links */
|
||||||
|
dir_add(buf, ".", NULL, 0);
|
||||||
|
dir_add(buf, "..", NULL, 0);
|
||||||
|
for (int i = 1; i < linktbl->num; i++) {
|
||||||
|
link = linktbl->links[i];
|
||||||
|
dir_add(buf, link->p_url, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief open a file indicated by the path */
|
||||||
|
static int fs_open(const char *path, struct fuse_file_info *fi)
|
||||||
|
{
|
||||||
|
if (!path_to_Link(path)) {
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fi->flags & 3) != O_RDONLY) {
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \brief read a file */
|
||||||
|
static int fs_read(const char *path, char *buf, size_t size, off_t offset,
|
||||||
|
struct fuse_file_info *fi)
|
||||||
|
{
|
||||||
|
(void) fi;
|
||||||
|
Link *link;
|
||||||
|
link = path_to_Link(path);
|
||||||
|
|
||||||
|
if (!link) {
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bytes_downloaded = Link_download(link, offset, size);
|
||||||
|
memcpy(buf, link->body, bytes_downloaded);
|
||||||
|
|
||||||
|
return bytes_downloaded;
|
||||||
|
}
|
||||||
|
|
23
network.c
23
network.c
|
@ -200,8 +200,10 @@ static void Link_free(Link *link)
|
||||||
link = NULL;
|
link = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Link_download(Link *link, size_t start, size_t end)
|
size_t Link_download(Link *link, off_t offset, size_t size)
|
||||||
{
|
{
|
||||||
|
size_t start = offset;
|
||||||
|
size_t end = start + size;
|
||||||
CURL *curl = link->curl;
|
CURL *curl = link->curl;
|
||||||
char range_str[64];
|
char range_str[64];
|
||||||
snprintf(range_str, sizeof(range_str), "%lu-%lu", start, end);
|
snprintf(range_str, sizeof(range_str), "%lu-%lu", start, end);
|
||||||
|
@ -212,7 +214,16 @@ int Link_download(Link *link, size_t start, size_t end)
|
||||||
|
|
||||||
long http_resp;
|
long http_resp;
|
||||||
curl_easy_getinfo(link->curl, CURLINFO_RESPONSE_CODE, &http_resp);
|
curl_easy_getinfo(link->curl, CURLINFO_RESPONSE_CODE, &http_resp);
|
||||||
return http_resp;
|
if (http_resp != HTTP_OK) {
|
||||||
|
fprintf(stderr, "Link_download(): Could not download %s, HTTP %ld",
|
||||||
|
link->f_url, http_resp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double dl;
|
||||||
|
curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &dl);
|
||||||
|
size_t s = dl;
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LinkTable *LinkTable_new(const char *url)
|
static LinkTable *LinkTable_new(const char *url)
|
||||||
|
@ -233,7 +244,7 @@ static LinkTable *LinkTable_new(const char *url)
|
||||||
curl_easy_getinfo(head_link->curl, CURLINFO_RESPONSE_CODE, &http_resp);
|
curl_easy_getinfo(head_link->curl, CURLINFO_RESPONSE_CODE, &http_resp);
|
||||||
if (http_resp != HTTP_OK) {
|
if (http_resp != HTTP_OK) {
|
||||||
fprintf(stderr, "link.c: LinkTable_new() cannot retrive the base URL, \
|
fprintf(stderr, "link.c: LinkTable_new() cannot retrive the base URL, \
|
||||||
URL: %s, HTTP response: %ld\n", url, http_resp);
|
URL: %s, HTTP %ld\n", url, http_resp);
|
||||||
LinkTable_free(linktbl);
|
LinkTable_free(linktbl);
|
||||||
linktbl = NULL;
|
linktbl = NULL;
|
||||||
return linktbl;
|
return linktbl;
|
||||||
|
@ -404,7 +415,7 @@ static Link *path_to_Link_recursive(char *path, LinkTable *linktbl)
|
||||||
if (!(next_table)) {
|
if (!(next_table)) {
|
||||||
next_table = LinkTable_new(linktbl->links[i]->f_url);
|
next_table = LinkTable_new(linktbl->links[i]->f_url);
|
||||||
}
|
}
|
||||||
return path_to_Link(next_path, next_table);
|
return path_to_Link_recursive(next_path, next_table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,10 +423,10 @@ static Link *path_to_Link_recursive(char *path, LinkTable *linktbl)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Link *path_to_Link(const char *path, LinkTable *linktbl)
|
Link *path_to_Link(const char *path)
|
||||||
{
|
{
|
||||||
char *new_path = strndup(path, URL_LEN_MAX);
|
char *new_path = strndup(path, URL_LEN_MAX);
|
||||||
return path_to_Link_recursive(new_path, linktbl);
|
return path_to_Link_recursive(new_path, ROOT_LINK_TBL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
12
network.h
12
network.h
|
@ -5,19 +5,19 @@
|
||||||
|
|
||||||
#include <gumbo.h>
|
#include <gumbo.h>
|
||||||
|
|
||||||
/** \brief root link table */
|
|
||||||
extern LinkTable *ROOT_LINK_TBL;
|
|
||||||
|
|
||||||
/** \brief Initialise the network module */
|
/** \brief Initialise the network module */
|
||||||
void network_init(const char *url);
|
void network_init(const char *url);
|
||||||
|
|
||||||
/** \brief download a link */
|
/**
|
||||||
int Link_download(Link *link, size_t start, size_t end);
|
* \brief download a link */
|
||||||
|
/* \return the number of bytes downloaded
|
||||||
|
*/
|
||||||
|
size_t Link_download(Link *link, off_t offset, size_t size);
|
||||||
|
|
||||||
/** \brief print a LinkTable */
|
/** \brief print a LinkTable */
|
||||||
void LinkTable_print(LinkTable *linktbl);
|
void LinkTable_print(LinkTable *linktbl);
|
||||||
|
|
||||||
/** \brief find the link associated with a path */
|
/** \brief find the link associated with a path */
|
||||||
Link *path_to_Link(const char *path, LinkTable *linktbl);
|
Link *path_to_Link(const char *path);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue