new options: stderr_fd, stderr_path

the mount subsystem is screwy and lots of things will eat logs, so it's nice to be able to directly log to a path
This commit is contained in:
2024-10-11 23:47:56 +00:00
parent a02006d8ec
commit ff6f1a45dd
3 changed files with 46 additions and 29 deletions

57
ftpfs.c
View File

@@ -72,7 +72,7 @@ static int buf_resize(struct buffer *buf, size_t len)
buf->size = (buf->len + len + 63) & ~31; buf->size = (buf->len + len + 63) & ~31;
buf->p = (uint8_t *) realloc(buf->p, buf->size); buf->p = (uint8_t *) realloc(buf->p, buf->size);
if (!buf->p) { if (!buf->p) {
fprintf(stderr, "ftpfs: memory allocation failed\n"); dprintf(ftpfs.stderr_fd, "ftpfs: memory allocation failed\n");
return -1; return -1;
} }
return 0; return 0;
@@ -129,6 +129,8 @@ enum {
static struct fuse_opt ftpfs_opts[] = { static struct fuse_opt ftpfs_opts[] = {
FTPFS_OPT("ftpfs_debug=%u", debug, 0), FTPFS_OPT("ftpfs_debug=%u", debug, 0),
FTPFS_OPT("stderr_path=%s", stderr_path, 0),
FTPFS_OPT("stderr_fd=%u", stderr_fd, 2),
FTPFS_OPT("transform_symlinks", transform_symlinks, 1), FTPFS_OPT("transform_symlinks", transform_symlinks, 1),
FTPFS_OPT("disable_epsv", disable_epsv, 1), FTPFS_OPT("disable_epsv", disable_epsv, 1),
FTPFS_OPT("enable_epsv", disable_epsv, 0), FTPFS_OPT("enable_epsv", disable_epsv, 0),
@@ -209,7 +211,7 @@ static void cancel_previous_multi()
CURLMcode curlMCode = curl_multi_remove_handle(ftpfs.multi, ftpfs.connection); CURLMcode curlMCode = curl_multi_remove_handle(ftpfs.multi, ftpfs.connection);
if (curlMCode != CURLE_OK) if (curlMCode != CURLE_OK)
{ {
fprintf(stderr, "curl_multi_remove_handle problem: %d\n", curlMCode); dprintf(ftpfs.stderr_fd, "curl_multi_remove_handle problem: %d\n", curlMCode);
exit(1); exit(1);
} }
ftpfs.attached_to_multi = 0; ftpfs.attached_to_multi = 0;
@@ -222,7 +224,7 @@ static int op_return(int err, char * operation)
DEBUG(2, "%s successful\n", operation); DEBUG(2, "%s successful\n", operation);
return 0; return 0;
} }
fprintf(stderr, "ftpfs: operation %s failed because %s\n", operation, strerror(-err)); dprintf(ftpfs.stderr_fd, "ftpfs: operation %s failed because %s\n", operation, strerror(-err));
if (strstr(error_buf, "timed out") != NULL if (strstr(error_buf, "timed out") != NULL
|| strstr(error_buf, "timeout") != NULL || strstr(error_buf, "timeout") != NULL
|| strstr(error_buf, "time-out") != NULL) { || strstr(error_buf, "time-out") != NULL) {
@@ -262,7 +264,7 @@ static size_t read_data(void *ptr, size_t size, size_t nmemb, void *data) {
do {\ do {\
CURLcode res = curl_easy_setopt(handle, option, __VA_ARGS__);\ CURLcode res = curl_easy_setopt(handle, option, __VA_ARGS__);\
if (res != CURLE_OK) {\ if (res != CURLE_OK) {\
fprintf(stderr, "Error setting curl option %d: %s\n", option, error_buf);\ dprintf(ftpfs.stderr_fd, "Error setting curl option %d: %s\n", option, error_buf);\
exit(1);\ exit(1);\
}\ }\
}while(0) }while(0)
@@ -385,7 +387,7 @@ static size_t ftpfs_read_chunk(const char* full_path, char* rbuf,
CURLMcode curlMCode = curl_multi_add_handle(ftpfs.multi, ftpfs.connection); CURLMcode curlMCode = curl_multi_add_handle(ftpfs.multi, ftpfs.connection);
if (curlMCode != CURLE_OK) if (curlMCode != CURLE_OK)
{ {
fprintf(stderr, "curl_multi_add_handle problem: %d\n", curlMCode); dprintf(ftpfs.stderr_fd, "curl_multi_add_handle problem: %d\n", curlMCode);
exit(1); exit(1);
} }
ftpfs.attached_to_multi = 1; ftpfs.attached_to_multi = 1;
@@ -568,7 +570,7 @@ static int start_write_thread(struct ftpfs_file *fh)
{ {
if (fh->write_conn != NULL) if (fh->write_conn != NULL)
{ {
fprintf(stderr, "assert fh->write_conn == NULL failed!\n"); dprintf(ftpfs.stderr_fd, "assert fh->write_conn == NULL failed!\n");
exit(1); exit(1);
} }
@@ -582,14 +584,14 @@ static int start_write_thread(struct ftpfs_file *fh)
fh->write_conn = curl_easy_init(); fh->write_conn = curl_easy_init();
if (fh->write_conn == NULL) { if (fh->write_conn == NULL) {
fprintf(stderr, "Error initializing libcurl\n"); dprintf(ftpfs.stderr_fd, "Error initializing libcurl\n");
return 0; return 0;
} else { } else {
int err; int err;
set_common_curl_stuff(fh->write_conn); set_common_curl_stuff(fh->write_conn);
err = pthread_create(&fh->thread_id, NULL, ftpfs_write_thread, fh); err = pthread_create(&fh->thread_id, NULL, ftpfs_write_thread, fh);
if (err) { if (err) {
fprintf(stderr, "failed to create thread: %s\n", strerror(err)); dprintf(ftpfs.stderr_fd, "failed to create thread: %s\n", strerror(err));
/* FIXME: destroy curl_easy */ /* FIXME: destroy curl_easy */
return 0; return 0;
} }
@@ -846,7 +848,7 @@ static int ftpfs_read(const char* path, char* rbuf, size_t size, off_t offset,
if (fh->pos>0 || fh->write_conn!=NULL) if (fh->pos>0 || fh->write_conn!=NULL)
{ {
fprintf(stderr, "in read/write mode we cannot read from a file that has already been written to\n"); dprintf(ftpfs.stderr_fd, "in read/write mode we cannot read from a file that has already been written to\n");
return op_return(-EIO, "ftpfs_read"); return op_return(-EIO, "ftpfs_read");
} }
@@ -1147,7 +1149,7 @@ static int ftpfs_write(const char *path, const char *wbuf, size_t size,
long long size = (long long int)test_size(path); long long size = (long long int)test_size(path);
if (size != 0) if (size != 0)
{ {
fprintf(stderr, "ftpfs_write: start writing with no previous truncate not allowed! size check rval=%lld\n", size); dprintf(ftpfs.stderr_fd, "ftpfs_write: start writing with no previous truncate not allowed! size check rval=%lld\n", size);
return op_return(-EIO, "ftpfs_write"); return op_return(-EIO, "ftpfs_write");
} }
} }
@@ -1233,7 +1235,7 @@ static int ftpfs_flush(const char *path, struct fuse_file_info *fi) {
if (sbuf.st_size != fh->pos) if (sbuf.st_size != fh->pos)
{ {
fh->write_fail_cause = -999; fh->write_fail_cause = -999;
fprintf(stderr, "ftpfs_flush: check filesize problem: size=%lld expected=%lld\n", sbuf.st_size, fh->pos); dprintf(ftpfs.stderr_fd, "ftpfs_flush: check filesize problem: size=%lld expected=%lld\n", sbuf.st_size, fh->pos);
return op_return(-EIO, "ftpfs_flush"); return op_return(-EIO, "ftpfs_flush");
} }
@@ -1436,7 +1438,7 @@ static int ftpfs_opt_proc(void* data, const char* arg, int key,
ftpfs.verbose = 1; ftpfs.verbose = 1;
return 0; return 0;
case KEY_VERSION: case KEY_VERSION:
fprintf(stderr, "curlftpfs %s libcurl/%s fuse/%u.%u\n", dprintf(ftpfs.stderr_fd, "curlftpfs %s libcurl/%s fuse/%u.%u\n",
VERSION, VERSION,
ftpfs.curl_version->version, ftpfs.curl_version->version,
FUSE_MAJOR_VERSION, FUSE_MAJOR_VERSION,
@@ -1459,6 +1461,8 @@ static void usage(const char* progname) {
"\n" "\n"
"FTP options:\n" "FTP options:\n"
" ftpfs_debug print some debugging information\n" " ftpfs_debug print some debugging information\n"
" stderr_path=STR log stderr to path\n"
" stderr_fd=N log stderr to file descriptor\n"
" transform_symlinks prepend mountpoint to absolute symlink targets\n" " transform_symlinks prepend mountpoint to absolute symlink targets\n"
" disable_epsv use PASV, without trying EPSV first (default)\n" " disable_epsv use PASV, without trying EPSV first (default)\n"
" enable_epsv try EPSV before reverting to PASV\n" " enable_epsv try EPSV before reverting to PASV\n"
@@ -1589,7 +1593,7 @@ static void set_common_curl_stuff(CURL* easy) {
* with version 7.15.4 */ * with version 7.15.4 */
if (ftpfs.use_ssl > CURLFTPSSL_TRY && if (ftpfs.use_ssl > CURLFTPSSL_TRY &&
ftpfs.curl_version->version_num <= CURLFTPFS_BAD_SSL) { ftpfs.curl_version->version_num <= CURLFTPFS_BAD_SSL) {
fprintf(stderr, dprintf(ftpfs.stderr_fd,
"WARNING: you are using libcurl %s.\n" "WARNING: you are using libcurl %s.\n"
"This version of libcurl does not respect the mandatory SSL flag.\n" "This version of libcurl does not respect the mandatory SSL flag.\n"
"It will try to send the user and password even if the server doesn't support\n" "It will try to send the user and password even if the server doesn't support\n"
@@ -1599,10 +1603,10 @@ static void set_common_curl_stuff(CURL* easy) {
int i; int i;
const int time_to_wait = 10; const int time_to_wait = 10;
for (i = 0; i < time_to_wait; i++) { for (i = 0; i < time_to_wait; i++) {
fprintf(stderr, "%d.. ", time_to_wait - i); dprintf(ftpfs.stderr_fd, "%d.. ", time_to_wait - i);
sleep(1); sleep(1);
} }
fprintf(stderr, "\n"); dprintf(ftpfs.stderr_fd, "\n");
} }
curl_easy_setopt_or_die(easy, CURLOPT_FTP_SSL, ftpfs.use_ssl); curl_easy_setopt_or_die(easy, CURLOPT_FTP_SSL, ftpfs.use_ssl);
@@ -1738,9 +1742,20 @@ int main(int argc, char** argv) {
if (fuse_opt_parse(&args, &ftpfs, ftpfs_opts, ftpfs_opt_proc) == -1) if (fuse_opt_parse(&args, &ftpfs, ftpfs_opts, ftpfs_opt_proc) == -1)
exit(1); exit(1);
if (ftpfs.stderr_path)
ftpfs.stderr_fd = open(ftpfs.stderr_path, O_RDWR|O_CREAT|O_APPEND, 0644);
if (ftpfs.stderr_fd == -1) {
fprintf(stderr, "failed to open stderr\n");
exit(1);
}
if (ftpfs.debug)
dprintf(ftpfs.stderr_fd, "logging configured\n");
if (!ftpfs.host) { if (!ftpfs.host) {
fprintf(stderr, "missing host\n"); dprintf(ftpfs.stderr_fd, "missing host\n");
fprintf(stderr, "see `%s -h' for usage\n", argv[0]); dprintf(ftpfs.stderr_fd, "see `%s -h' for usage\n", argv[0]);
exit(1); exit(1);
} }
@@ -1754,7 +1769,7 @@ int main(int argc, char** argv) {
easy = curl_easy_init(); easy = curl_easy_init();
if (easy == NULL) { if (easy == NULL) {
fprintf(stderr, "Error initializing libcurl\n"); dprintf(ftpfs.stderr_fd, "Error initializing libcurl\n");
exit(1); exit(1);
} }
@@ -1766,7 +1781,7 @@ int main(int argc, char** argv) {
checkpasswd("proxy", &ftpfs.proxy_user); checkpasswd("proxy", &ftpfs.proxy_user);
if (ftpfs.transform_symlinks && !ftpfs.mountpoint) { if (ftpfs.transform_symlinks && !ftpfs.mountpoint) {
fprintf(stderr, "cannot transform symlinks: no mountpoint given\n"); dprintf(ftpfs.stderr_fd, "cannot transform symlinks: no mountpoint given\n");
exit(1); exit(1);
} }
if (!ftpfs.transform_symlinks) if (!ftpfs.transform_symlinks)
@@ -1783,14 +1798,14 @@ int main(int argc, char** argv) {
curl_easy_setopt_or_die(easy, CURLOPT_NOBODY, ftpfs.safe_nobody); curl_easy_setopt_or_die(easy, CURLOPT_NOBODY, ftpfs.safe_nobody);
curl_res = curl_easy_perform(easy); curl_res = curl_easy_perform(easy);
if (curl_res != 0) { if (curl_res != 0) {
fprintf(stderr, "Error connecting to ftp: %s\n", error_buf); dprintf(ftpfs.stderr_fd, "Error connecting to ftp: %s\n", error_buf);
exit(1); exit(1);
} }
curl_easy_setopt_or_die(easy, CURLOPT_NOBODY, 0); curl_easy_setopt_or_die(easy, CURLOPT_NOBODY, 0);
ftpfs.multi = curl_multi_init(); ftpfs.multi = curl_multi_init();
if (ftpfs.multi == NULL) { if (ftpfs.multi == NULL) {
fprintf(stderr, "Error initializing libcurl multi\n"); dprintf(ftpfs.stderr_fd, "Error initializing libcurl multi\n");
exit(1); exit(1);
} }

10
ftpfs.h
View File

@@ -25,6 +25,8 @@ struct ftpfs {
unsigned blksize; unsigned blksize;
int verbose; int verbose;
int debug; int debug;
char *stderr_path;
int stderr_fd;
int transform_symlinks; int transform_symlinks;
int disable_epsv; int disable_epsv;
int skip_pasv_ip; int skip_pasv_ip;
@@ -75,10 +77,10 @@ extern struct ftpfs ftpfs;
#define DEBUG(level, args...) \ #define DEBUG(level, args...) \
do { if (level <= ftpfs.debug) {\ do { if (level <= ftpfs.debug) {\
int i = 0; \ int i = 0; \
while (++i < level) fprintf(stderr, " "); \ while (++i < level) dprintf(ftpfs.stderr_fd, " "); \
fprintf(stderr, "%ld ", time(NULL));\ dprintf(ftpfs.stderr_fd, "%ld ", time(NULL));\
fprintf(stderr, __FILE__ ":%d ", __LINE__);\ dprintf(ftpfs.stderr_fd, __FILE__ ":%d ", __LINE__);\
fprintf(stderr, args);\ dprintf(ftpfs.stderr_fd, args);\
}\ }\
} while(0) } while(0)

View File

@@ -5038,7 +5038,7 @@ EOF
/* -DDEBUG is fairly common in CFLAGS. */ /* -DDEBUG is fairly common in CFLAGS. */
#undef DEBUG #undef DEBUG
#if defined DEBUGWRAPPER #if defined DEBUGWRAPPER
# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__) # define DEBUG(format, ...) dprintf(ftpfs.stderr_fd, format, __VA_ARGS__)
#else #else
# define DEBUG(format, ...) # define DEBUG(format, ...)
#endif #endif
@@ -5291,9 +5291,9 @@ static void
lt_error_core (int exit_status, const char * mode, lt_error_core (int exit_status, const char * mode,
const char * message, va_list ap) const char * message, va_list ap)
{ {
fprintf (stderr, "%s: %s: ", program_name, mode); dprintf (ftpfs.stderr_fd, "%s: %s: ", program_name, mode);
vfprintf (stderr, message, ap); vdprintf (ftpfs.stderr_fd, message, ap);
fprintf (stderr, ".\n"); dprintf (ftpfs.stderr_fd, ".\n");
if (exit_status >= 0) if (exit_status >= 0)
exit (exit_status); exit (exit_status);