Merge branch 'dev' into master

This commit is contained in:
Fufu Fang 2021-08-05 00:42:00 +01:00 committed by GitHub
commit 9365dd18a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 244 additions and 125 deletions

14
.gitignore vendored
View File

@ -1,7 +1,15 @@
*.o
*.kate-swp
# Binaries
httpdirfs
sonicfs
# Intermediates
*.o
.depend
doc/html
# Documentation
doc
# Editor related
.vscode
httpdirfs.code-workspace
*.kate-swp

View File

@ -4,9 +4,16 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.3.0]
### Changed
Now generate separate binaries
- ``HTTDirFS`` for mounting HTTP directory listings.
- ``SonicFS`` for mounting Airsonic / Subsonic server.
### Fixed
- macOS uninstallation in Makefile.
## [1.2.1] - 2021-05-27
### Added
- macOS compilation support
- macOS compilation support.
## [1.2.0] - 2019-11-01
### Added
@ -177,8 +184,9 @@ ${XDG_CONFIG_HOME}/httpdirfs, rather than ${HOME}/.httpdirfs
## [1.0] - 2018-08-22
- Initial release, everything works correctly, as far as I know.
[Unreleased]: https://github.com/fangfufu/httpdirfs/compare/Unreleased...1.2.1
[1.2.1]: https://github.com/fangfufu/httpdirfs/compare/Unreleased...1.2.0
[Unreleased]: https://github.com/fangfufu/httpdirfs/compare/Unreleased...1.3.0
[1.3.0]: https://github.com/fangfufu/httpdirfs/compare/1.3.0...1.2.1
[1.2.1]: https://github.com/fangfufu/httpdirfs/compare/1.2.1...1.2.0
[1.2.0]: https://github.com/fangfufu/httpdirfs/compare/1.2.0...1.1.10
[1.1.10]: https://github.com/fangfufu/httpdirfs/compare/1.1.9...1.1.10
[1.1.9]: https://github.com/fangfufu/httpdirfs/compare/1.1.8...1.1.9

View File

@ -901,7 +901,7 @@ EXCLUDE_PATTERNS =
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories use the pattern */test/*
EXCLUDE_SYMBOLS =
EXCLUDE_SYMBOLS = CALLOC exit_failure
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
# that contain example code fragments that are included (see the \include

View File

@ -1,4 +1,4 @@
VERSION = 1.2.1
VERSION = 1.3.0
CFLAGS += -O2 -Wall -Wextra -Wshadow -rdynamic -D_GNU_SOURCE\
-D_FILE_OFFSET_BITS=64 -DVERSION=\"$(VERSION)\"\
@ -23,57 +23,81 @@ endif
prefix ?= /usr/local
all: httpdirfs
all: httpdirfs sonicfs
%.o: src/%.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -c -o $@ $<
httpdirfs: $(COBJS)
httpdirfs: httpdirfs.o $(COBJS)
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
install:
sonicfs: sonicfs.o $(COBJS)
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
install: all
ifeq ($(OS),Linux)
install -m 755 -D httpdirfs \
$(DESTDIR)$(prefix)/bin/httpdirfs
install -m 644 -D doc/man/httpdirfs.1 \
$(DESTDIR)$(prefix)/share/man/man1/httpdirfs.1
install -m 755 -D sonicfs \
$(DESTDIR)$(prefix)/bin/sonicfs
install -m 644 -D doc/man/sonicfs.1 \
$(DESTDIR)$(prefix)/share/man/man1/sonicfs.1
endif
ifeq ($(OS),FreeBSD)
install -m 755 httpdirfs \
install -m 755 httpdirfs\
$(DESTDIR)$(prefix)/bin/httpdirfs
gzip -f -k doc/man/httpdirfs.1
install -m 644 doc/man/httpdirfs.1.gz \
$(DESTDIR)$(prefix)/man/man1/httpdirfs.1.gz
install -m 755 sonicfs\
$(DESTDIR)$(prefix)/bin/sonicfs
gzip -f -k doc/man/sonicfs.1
install -m 644 doc/man/sonicfs.1.gz \
$(DESTDIR)$(prefix)/man/man1/sonicfs.1.gz
endif
ifeq ($(OS),Darwin)
install -d $(DESTDIR)$(prefix)/bin
install -m 755 httpdirfs \
install -m 755 httpdirfs\
$(DESTDIR)$(prefix)/bin/httpdirfs
install -m 755 sonicfs\
$(DESTDIR)$(prefix)/bin/sonicfs
install -d $(DESTDIR)$(prefix)/share/man/man1
install -m 644 doc/man/httpdirfs.1 \
$(DESTDIR)$(prefix)/share/man/man1/httpdirfs.1
install -m 644 doc/man/sonicfs.1 \
$(DESTDIR)$(prefix)/share/man/man1/sonicfs.1
endif
doc:
doxygen Doxyfile
man: all
help2man --no-discard-stderr ./httpdirfs > doc/man/httpdirfs.1
help2man --no-discard-stderr ./sonicfs > doc/man/sonicfs.1
clean:
-rm -f *.o
-rm -f httpdirfs
-rm -rf doc/html
-rm -f httpdirfs sonicfs
distclean: clean
-rm -rf doc/html
uninstall:
-rm -f $(DESTDIR)$(prefix)/bin/httpdirfs
-rm -f $(DESTDIR)$(prefix)/bin/sonicfs
ifeq ($(OS),Linux)
-rm -f $(DESTDIR)$(prefix)/share/man/man1/httpdirfs.1
-rm -f $(DESTDIR)$(prefix)/share/man/man1/sonicfs.1
endif
ifeq ($(OS),FreeBSD)
-rm -f $(DESTDIR)$(prefix)/man/man1/httpdirfs.1.gz
-rm -f $(DESTDIR)$(prefix)/man/man1/sonicfs.1.gz
endif
ifeq ($(OS),Darwin)
-rm -f $(DESTDIR)$(prefix)/share/man/man1/httpdirfs.1
-rm -f $(DESTDIR)$(prefix)/share/man/man1/sonicfs.1
endif
depend: .depend
@ -82,4 +106,4 @@ depend: .depend
$(CC) $(CFLAGS) -MM $^ -MF ./.depend;
include .depend
.PHONY: all doc install clean distclean uninstall depend
.PHONY: all doc man install clean distclean uninstall depend

6
TODO.md Normal file
View File

@ -0,0 +1,6 @@
## Todo
- [ ] Improve debug functions
- [ ] Automatic generation of man page with proper description
- [ ] Update change log
- [ ] Create a new release
- [ ] Contact maintainer for a new Debian package

View File

@ -113,14 +113,23 @@ static int fs_open(const char *path, struct fuse_file_info *fi)
return 0;
}
/** \brief read the directory indicated by the path*/
/**
* \brief read the directory indicated by the path
* \note
* - releasedir() is not implemented, because I don't see why anybody want
* the LinkTables to be evicted from the memory during the runtime of this
* program. If you want to evict LinkTables, just unmount the filesystem.
* - There is no real need to associate the LinkTable with the fi of each
* directory data structure. If you want a deep level directory, you need to
* generate the LinkTables for previous level directories. We might
* as well maintain our own tree structure.
*/
static int fs_readdir(const char *path, void *buf, fuse_fill_dir_t dir_add,
off_t offset, struct fuse_file_info *fi)
{
(void) offset;
(void) fi;
Link *link;
LinkTable *linktbl;
if (!strcmp(path, "/")) {
@ -136,7 +145,7 @@ static int fs_readdir(const char *path, void *buf, fuse_fill_dir_t dir_add,
dir_add(buf, ".", NULL, 0);
dir_add(buf, "..", NULL, 0);
for (int i = 1; i < linktbl->num; i++) {
link = linktbl->links[i];
Link *link = linktbl->links[i];
if (link->type != LINK_INVALID) {
dir_add(buf, link->linkname, NULL, 0);
}

6
src/httpdirfs.c Normal file
View File

@ -0,0 +1,6 @@
#include "main.h"
int main(int argc, char **argv)
{
return common_main(&argc, &argv);
}

View File

@ -1,3 +1,5 @@
#include "main.h"
#include "cache.h"
#include "fuse_local.h"
#include "network.h"
@ -6,92 +8,7 @@
#include <stdlib.h>
#include <string.h>
void add_arg(char ***fuse_argv_ptr, int *fuse_argc, char *opt_string);
static void print_help(char *program_name, int long_help);
static void print_version();
static void print_long_help();
static int
parse_arg_list(int argc, char **argv, char ***fuse_argv, int *fuse_argc);
void parse_config_file(char ***argv, int *argc);
static char *config_path = NULL;
int main(int argc, char **argv)
{
/* Automatically print help if not enough arguments are supplied */
if (argc < 2) {
print_help(argv[0], 0);
fprintf(stderr, "For more information, run \"%s --help.\"\n", argv[0]);
exit(EXIT_FAILURE);
}
/* These are passed into fuse initialiser */
char **fuse_argv = NULL;
int fuse_argc = 0;
/* These are the combined argument with the config file */
char **all_argv = NULL;
int all_argc = 0;
/*--- Add the program's name to the combined argument list ---*/
add_arg(&all_argv, &all_argc, argv[0]);
/*--- FUSE expects the first initialisation to be the program's name ---*/
add_arg(&fuse_argv, &fuse_argc, argv[0]);
/* initialise network configuration struct */
Config_init();
/* initialise network subsystem */
NetworkSystem_init();
/* Copy the command line argument list to the combined argument list */
for (int i = 1; i < argc; i++) {
add_arg(&all_argv, &all_argc, argv[i]);
if (!strcmp(argv[i], "--config")) {
config_path = strdup(argv[i+1]);
}
}
/* parse the config file, if it exists, store it in all_argv and all_argc */
parse_config_file(&all_argv, &all_argc);
/* parse the combined argument list */
if (parse_arg_list(all_argc, all_argv, &fuse_argv, &fuse_argc)) {
/*
* The user basically didn't supply enough arguments, if we reach here
* The point is to print some error messages
*/
goto fuse_start;
}
/*--- Add the last remaining argument, which is the mountpoint ---*/
add_arg(&fuse_argv, &fuse_argc, argv[argc-1]);
/* The second last remaining argument is the URL */
char *base_url = argv[argc-2];
if (strncmp(base_url, "http://", 7) && strncmp(base_url, "https://", 8)) {
fprintf(stderr, "Error: Please supply a valid URL.\n");
print_help(argv[0], 0);
exit(EXIT_FAILURE);
} else {
if (CONFIG.sonic_username && CONFIG.sonic_password) {
CONFIG.sonic_mode = 1;
} else if (CONFIG.sonic_username || CONFIG.sonic_password) {
fprintf(stderr,
"Error: You have to supply both username and password to \
activate Sonic mode.\n");
exit(EXIT_FAILURE);
}
if(!LinkSystem_init(base_url)) {
fprintf(stderr, "Error: Network initialisation failed.\n");
exit(EXIT_FAILURE);
}
}
fuse_start:
fuse_local_init(fuse_argc, fuse_argv);
return 0;
}
char *config_path = NULL;
void parse_config_file(char ***argv, int *argc)
{
@ -136,8 +53,7 @@ void parse_config_file(char ***argv, int *argc)
}
}
static int
parse_arg_list(int argc, char **argv, char ***fuse_argv, int *fuse_argc)
int parse_arg_list(int argc, char **argv, char ***fuse_argv, int *fuse_argc)
{
char c;
int long_index = 0;
@ -267,10 +183,6 @@ parse_arg_list(int argc, char **argv, char ***fuse_argv, int *fuse_argc)
return 0;
}
/**
* \brief add an argument to an argv array
* \details This is basically how you add a string to an array of string
*/
void add_arg(char ***fuse_argv_ptr, int *fuse_argc, char *opt_string)
{
(*fuse_argc)++;
@ -279,7 +191,7 @@ void add_arg(char ***fuse_argv_ptr, int *fuse_argc, char *opt_string)
fuse_argv[*fuse_argc - 1] = strdup(opt_string);
}
static void print_help(char *program_name, int long_help)
void print_help(char *program_name, int long_help)
{
fprintf(stderr,
"usage: %s [options] URL mountpoint\n", program_name);
@ -288,19 +200,25 @@ static void print_help(char *program_name, int long_help)
}
}
static void print_version()
void print_version()
{
fprintf(stderr, "HTTPDirFS version " VERSION "\n");
char *fs_name;
if (!CONFIG.sonic_mode) {
fs_name = "HTTPDirFS";
} else {
fs_name = "SonicFS";
}
fprintf(stderr, "%s version " VERSION "\n", fs_name);
/* --------- Print off SSL engine version --------- */
curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
fprintf(stderr, "libcurl SSL engine: %s\n", data->ssl_version);
}
static void print_long_help()
void print_long_help()
{
fprintf(stderr,
"\n\
general options:\n\
General options:\n\
--config Specify a configuration file \n\
-o opt,[opt...] Mount options\n\
-h --help Print help\n\
@ -333,8 +251,17 @@ HTTPDirFS options:\n\
for HTTP range requests\n\
--insecure_tls Disable licurl TLS certificate verification by\n\
setting CURLOPT_SSL_VERIFYHOST to 0\n\
\n\
For mounting a Airsonic / Subsonic server:\n\
\n");
if (CONFIG.sonic_mode) {
print_sonic_help();
}
}
void print_sonic_help()
{
fprintf(stderr,
"\n\
Airsonic / Subsonic server specific options:\n\
--sonic-username The username for your Airsonic / Subsonic server\n\
--sonic-password The password for your Airsonic / Subsonic server\n\
--sonic-id3 Enable ID3 mode - this present the server content in\n\
@ -344,3 +271,83 @@ HTTPDirFS options:\n\
scheme\n\
\n");
}
int common_main(int *argc_in, char ***argv_in)
{
int argc = *argc_in;
char **argv = *argv_in;
/* Automatically print help if not enough arguments are supplied */
if (argc < 2) {
print_help(argv[0], 0);
fprintf(stderr, "For more information, run \"%s --help.\"\n", argv[0]);
exit(EXIT_FAILURE);
}
/* These are passed into fuse initialiser */
char **fuse_argv = NULL;
int fuse_argc = 0;
/* These are the combined argument with the config file */
char **all_argv = NULL;
int all_argc = 0;
/*--- Add the program's name to the combined argument list ---*/
add_arg(&all_argv, &all_argc, argv[0]);
/*--- FUSE expects the first initialisation to be the program's name ---*/
add_arg(&fuse_argv, &fuse_argc, argv[0]);
/* initialise network configuration struct */
Config_init();
/* initialise network subsystem */
NetworkSystem_init();
/* Copy the command line argument list to the combined argument list */
for (int i = 1; i < argc; i++) {
add_arg(&all_argv, &all_argc, argv[i]);
if (!strcmp(argv[i], "--config")) {
config_path = strdup(argv[i+1]);
}
}
/* parse the config file, if it exists, store it in all_argv and all_argc */
parse_config_file(&all_argv, &all_argc);
/* parse the combined argument list */
if (parse_arg_list(all_argc, all_argv, &fuse_argv, &fuse_argc)) {
/*
* The user basically didn't supply enough arguments, if we reach here
* The point is to print some error messages
*/
goto fuse_start;
}
/*--- Add the last remaining argument, which is the mountpoint ---*/
add_arg(&fuse_argv, &fuse_argc, argv[argc-1]);
/* The second last remaining argument is the URL */
char *base_url = argv[argc-2];
if (strncmp(base_url, "http://", 7) && strncmp(base_url, "https://", 8)) {
fprintf(stderr, "Error: Please supply a valid URL.\n");
print_help(argv[0], 0);
exit(EXIT_FAILURE);
}
if (CONFIG.sonic_mode &&
!(CONFIG.sonic_username && CONFIG.sonic_password)) {
fprintf(stderr,
"Error: You have to supply both username and password for your\
Sonic server account.\n");
exit(EXIT_FAILURE);
}
if(!LinkSystem_init(base_url)) {
fprintf(stderr, "Error: Network initialisation failed.\n");
exit(EXIT_FAILURE);
}
fuse_start:
fuse_local_init(fuse_argc, fuse_argv);
return 0;
}

49
src/main.h Normal file
View File

@ -0,0 +1,49 @@
#ifndef MAIN_H
#define MAIN_H
/**
* \brief Configuration path
*/
extern char *config_path;
/**
* \brief Parse the configuration file
*/
void parse_config_file(char ***argv, int *argc);
/**
* \brief Parse argument list
*/
int parse_arg_list(int argc, char **argv, char ***fuse_argv, int *fuse_argc);
/**
* \brief Add an argument to an argv array
* \details This is basically how you add a string to an array of string
*/
void add_arg(char ***fuse_argv_ptr, int *fuse_argc, char *opt_string);
/**
* \brief Print short help information
*/
void print_help(char *program_name, int long_help);
/**
* \brief Print version number
*/
void print_version();
/**
* \brief Print long help information
*/
void print_long_help();
/**
* \brief Print Sonic server related help information
*/
void print_sonic_help();
/**
* @brief The old main function that is common to both HTTPDirFS and SonicFS
*/
int common_main(int *argc_in, char ***argv_in);
#endif

9
src/sonicfs.c Normal file
View File

@ -0,0 +1,9 @@
#include "main.h"
#include "util.h"
int main(int argc, char **argv)
{
CONFIG.sonic_mode = 1;
return common_main(&argc, &argv);
}

View File

@ -86,8 +86,6 @@ void Config_init(void)
CONFIG.max_segbc = DEFAULT_MAX_SEGBC;
/*-------------- Sonic related -------------*/
CONFIG.sonic_mode = 0;
CONFIG.sonic_username = NULL;
CONFIG.sonic_password = NULL;

View File

@ -26,11 +26,6 @@
*/
#define DEFAULT_USER_AGENT "HTTPDirFS-" VERSION
/**
* \brief configuration data structure
* \note The opening curly bracket should be at line 39, so the code belong