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:
57
ftpfs.c
57
ftpfs.c
@@ -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
10
ftpfs.h
@@ -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)
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user