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->p = (uint8_t *) realloc(buf->p, buf->size);
if (!buf->p) {
fprintf(stderr, "ftpfs: memory allocation failed\n");
dprintf(ftpfs.stderr_fd, "ftpfs: memory allocation failed\n");
return -1;
}
return 0;
@@ -129,6 +129,8 @@ enum {
static struct fuse_opt ftpfs_opts[] = {
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("disable_epsv", disable_epsv, 1),
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);
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);
}
ftpfs.attached_to_multi = 0;
@@ -222,7 +224,7 @@ static int op_return(int err, char * operation)
DEBUG(2, "%s successful\n", operation);
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
|| strstr(error_buf, "timeout") != 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 {\
CURLcode res = curl_easy_setopt(handle, option, __VA_ARGS__);\
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);\
}\
}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);
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);
}
ftpfs.attached_to_multi = 1;
@@ -568,7 +570,7 @@ static int start_write_thread(struct ftpfs_file *fh)
{
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);
}
@@ -582,14 +584,14 @@ static int start_write_thread(struct ftpfs_file *fh)
fh->write_conn = curl_easy_init();
if (fh->write_conn == NULL) {
fprintf(stderr, "Error initializing libcurl\n");
dprintf(ftpfs.stderr_fd, "Error initializing libcurl\n");
return 0;
} else {
int err;
set_common_curl_stuff(fh->write_conn);
err = pthread_create(&fh->thread_id, NULL, ftpfs_write_thread, fh);
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 */
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)
{
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");
}
@@ -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);
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");
}
}
@@ -1233,7 +1235,7 @@ static int ftpfs_flush(const char *path, struct fuse_file_info *fi) {
if (sbuf.st_size != fh->pos)
{
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");
}
@@ -1436,7 +1438,7 @@ static int ftpfs_opt_proc(void* data, const char* arg, int key,
ftpfs.verbose = 1;
return 0;
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,
ftpfs.curl_version->version,
FUSE_MAJOR_VERSION,
@@ -1459,6 +1461,8 @@ static void usage(const char* progname) {
"\n"
"FTP options:\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"
" disable_epsv use PASV, without trying EPSV first (default)\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 */
if (ftpfs.use_ssl > CURLFTPSSL_TRY &&
ftpfs.curl_version->version_num <= CURLFTPFS_BAD_SSL) {
fprintf(stderr,
dprintf(ftpfs.stderr_fd,
"WARNING: you are using libcurl %s.\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"
@@ -1599,10 +1603,10 @@ static void set_common_curl_stuff(CURL* easy) {
int i;
const int time_to_wait = 10;
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);
}
fprintf(stderr, "\n");
dprintf(ftpfs.stderr_fd, "\n");
}
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)
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) {
fprintf(stderr, "missing host\n");
fprintf(stderr, "see `%s -h' for usage\n", argv[0]);
dprintf(ftpfs.stderr_fd, "missing host\n");
dprintf(ftpfs.stderr_fd, "see `%s -h' for usage\n", argv[0]);
exit(1);
}
@@ -1754,7 +1769,7 @@ int main(int argc, char** argv) {
easy = curl_easy_init();
if (easy == NULL) {
fprintf(stderr, "Error initializing libcurl\n");
dprintf(ftpfs.stderr_fd, "Error initializing libcurl\n");
exit(1);
}
@@ -1766,7 +1781,7 @@ int main(int argc, char** argv) {
checkpasswd("proxy", &ftpfs.proxy_user);
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);
}
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_res = curl_easy_perform(easy);
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);
}
curl_easy_setopt_or_die(easy, CURLOPT_NOBODY, 0);
ftpfs.multi = curl_multi_init();
if (ftpfs.multi == NULL) {
fprintf(stderr, "Error initializing libcurl multi\n");
dprintf(ftpfs.stderr_fd, "Error initializing libcurl multi\n");
exit(1);
}

10
ftpfs.h
View File

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

View File

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