Created
July 17, 2018 20:10
-
-
Save 19h/510e0965c2040568d737623001d19a18 to your computer and use it in GitHub Desktop.
microdc2-ubuntu-patches <891113>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
unchanged: | |
--- microdc2-0.15.6/configure.ac 2010-01-17 04:44:54.000000000 +0000 | |
+++ microdc2-0.15.6/configure.ac 2010-01-20 23:57:34.000000000 +0000 | |
@@ -47,12 +47,12 @@ | |
#AH_TEMPLATE([XML_SAVE_FORMAT], [1], [Define if libxml2 has no such option for xmlSave- functions]) | |
AC_PATH_PROG(XML_CONFIG, xml2-config) | |
AC_PATH_PROG(TR, tr) | |
-if test -n "$XML_CONFIG" && test -n "$TR"; then | |
- LIBXML2_VERSION=`$XML_CONFIG --version | $TR -d "."` | |
- if test $LIBXML2_VERSION -eq 2616; then | |
- AC_DEFINE([XML_SAVE_FORMAT], [1], [The libxml2 version 2.6.16 has no such option defined in the library headers]) | |
- fi | |
- if test $LIBXML2_VERSION -ge 2616; then | |
+#if test -n "$XML_CONFIG" && test -n "$TR"; then | |
+# LIBXML2_VERSION=`$XML_CONFIG --version | $TR -d "."` | |
+# if test $LIBXML2_VERSION -eq 2616; then | |
+# AC_DEFINE([XML_SAVE_FORMAT], [1], [The libxml2 version 2.6.16 has no such option defined in the library headers]) | |
+# fi | |
+# if test $LIBXML2_VERSION -ge 2616; then | |
AC_DEFINE([HAVE_LIBXML2]) | |
LIBXML2_LIBS="`$XML_CONFIG --libs`" | |
LIBXML2_CFLAGS="`$XML_CONFIG --cflags`" | |
@@ -60,10 +60,11 @@ | |
AC_SUBST(LIBXML2_CFLAGS) | |
# LIBS="$LIBS $LIBXML2_LIBS" | |
# CFLAGS="$CFLAGS $LIBXML2_CFLAGS" | |
- else | |
- AC_MSG_WARN([XML libxml2 library version 2.6.16 or later is required to support XML filelists]) | |
- fi | |
-fi | |
+# else | |
+# AC_MSG_WARN([XML libxml2 library version 2.6.16 or later is required to support XML filelists]) | |
+# fi | |
+#fi | |
+AC_CHECK_LIB(bz2, BZ2_bzRead,, AC_MSG_ERROR([Missing bz2 library])) | |
# Checks for header files | |
@@ -80,7 +81,6 @@ | |
lib/Makefile | |
src/Makefile | |
src/common/Makefile | |
- src/bzip2/Makefile | |
src/tth/Makefile | |
rpm/microdc.spec]) | |
AC_CONFIG_FILES([slackware/microdc.SlackBuild], | |
unchanged: | |
--- microdc2-0.15.6.orig/Makefile.am 2010-01-17 04:55:33.000000000 +0000 | |
+++ microdc2-0.15.6/Makefile.am 2010-01-17 04:55:16.000000000 +0000 | |
@@ -25,9 +25,6 @@ | |
clean-local: | |
-rm -f build-stamp configure-stamp stamp-h1 | |
- -rm -f debian/compat debian/files debian/@[email protected] | |
- -rm -f debian/stamp-* | |
- -rm -rf debian/@PACKAGE@ | |
# This macro is useful until gnulib-tool is incorporated into autoreconf. | |
# Unfortunately the ./configure script is first run if configure.ac is | |
unchanged: | |
--- microdc2-0.15.6/src/Makefile.am 2010-01-17 21:30:47.000000000 +0000 | |
+++ microdc2-0.15.6/src/Makefile.am 2010-01-20 23:57:20.000000000 +0000 | |
@@ -1,4 +1,4 @@ | |
-SUBDIRS = common bzip2 tth | |
+SUBDIRS = common tth | |
AM_CFLAGS = \ | |
-Wall \ | |
@@ -8,7 +8,7 @@ | |
-I$(top_builddir)/lib \ | |
-I$(top_srcdir)/lib | |
-bin_PROGRAMS = microdc2 tthsum | |
+bin_PROGRAMS = microdc2 | |
microdc2_SOURCES = \ | |
command.c \ | |
@@ -33,9 +33,6 @@ | |
charsets.h \ | |
microdc.h | |
-tthsum_SOURCES = \ | |
- tth.c | |
- | |
#microdc_tth_SOURCES = \ | |
# tth_file.c \ | |
# tth_file.h \ | |
@@ -43,7 +40,6 @@ | |
microdc2_LDADD = \ | |
common/libcommon.a \ | |
- bzip2/libbzip2.a \ | |
tth/libtth.a \ | |
../lib/libgnu.a \ | |
$(READLINE_LIBS) \ | |
@@ -52,20 +48,13 @@ | |
$(LIBXML2_LIBS) | |
-tthsum_LDADD = \ | |
- tth/libtth.a \ | |
- ../lib/libgnu.a \ | |
- $(LIBINTL) | |
- | |
#microdc_tth_LDADD = \ | |
# tth/libtth.a \ | |
# ../lib/libgnu.a | |
# $(LIBICONV) - not yet used | |
-man_MANS = \ | |
- microdc.1 \ | |
- microdc.pl.1 | |
+man_MANS = microdc2.1 | |
EXTRA_DIST = \ | |
$(man_MANS) | |
unchanged: | |
--- microdc2-0.15.6.orig/src/microdc.1 2010-01-17 21:07:10.000000000 +0000 | |
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000 | |
@@ -1,64 +0,0 @@ | |
-.\" -*- nroff -*- | |
-.\" microdc.1 - Manual page for microdc. | |
-.\" | |
-.\" Copyright (C) 2004, 2005 Oskar Liljeblad | |
-.\" | |
-.\" This program is free software; you can redistribute it and/or modify | |
-.\" it under the terms of the GNU General Public License as published by | |
-.\" the Free Software Foundation; either version 2 of the License, or | |
-.\" (at your option) any later version. | |
-.\" | |
-.\" This program is distributed in the hope that it will be useful, | |
-.\" but WITHOUT ANY WARRANTY; without even the implied warranty of | |
-.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
-.\" GNU Library General Public License for more details. | |
-.\" | |
-.\" You should have received a copy of the GNU General Public License along | |
-.\" with this program; if not, write to the Free Software Foundation, | |
-.\" Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
-.\" | |
-.TH MICRODC "1" "September 17, 2005" "microdc" | |
-.SH NAME | |
-microdc - A command-line based Direct Connect client | |
-.SH SYNOPSIS | |
-.B microdc | |
-.RI [ OPTION ]... | |
-.SH DESCRIPTION | |
-microdc is a command-line based Direct Connect client that uses the GNU | |
-Readline library for user interaction. It was developed from ground up and | |
-does not depend on any other program. Despite the command-line user | |
-interface, microdc was designed to be user friendly and simple to use. | |
-.SH OPTIONS | |
-This program follows the usual GNU command line syntax, with long | |
-options starting with two dashes (`--'). | |
-.TP | |
-\fB\-c, \-\-config\fR=\fIFILE\fR | |
-Read configuration script from FILE rather than ~/.microdc/config. | |
-.TP | |
-\fB\-n, \-\-no\-config\fR | |
-Do not read config file on startup. | |
-.TP | |
-\fB\-\-help\fR | |
-Show summary of options. | |
-.TP | |
-\fB\-\-version\fR | |
-Output version information and exit. | |
-.SH FILES | |
-The following files are used by microdc (~ represents the current user's home directory): | |
-.TP | |
-\fB~/.microdc/config\fR | |
-This file is loaded on startup. It contains commands, one per line, that will be executed | |
-on startup. You can override loading of this file with --config and --no-config. | |
-.TP | |
-\fB~/.microdc/history\fR | |
-This is the command history file. It contains a list of commands that were typed and | |
-executed from the microdc prompt. It can safely be removed. | |
-.SH REPORTING BUGS | |
-Report bugs to <\[email protected]\fP>. | |
-.SH AUTHOR | |
-The author of \fBmicrodc\fP and this manual page is Oskar Liljeblad <\[email protected]\fP>. | |
-.SH COPYRIGHT | |
-Copyright \(co 2004, 2005 Oskar Liljeblad | |
- | |
-This is free software; see the source for copying conditions. There is NO | |
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
unchanged: | |
--- microdc2-0.15.6/src/microdc2.1 2006-10-22 08:35:50.000000000 +0000 | |
+++ microdc2-0.15.6/src/microdc2.1 2011-02-11 02:58:55.453480003 +0100 | |
@@ -0,0 +1,70 @@ | |
+.\" -*- nroff -*- | |
+.\" microdc.1 - Manual page for microdc. | |
+.\" | |
+.\" Copyright (C) 2004, 2005 Oskar Liljeblad | |
+.\" | |
+.\" This program is free software; you can redistribute it and/or modify | |
+.\" it under the terms of the GNU General Public License as published by | |
+.\" the Free Software Foundation; either version 2 of the License, or | |
+.\" (at your option) any later version. | |
+.\" | |
+.\" This program is distributed in the hope that it will be useful, | |
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of | |
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
+.\" GNU Library General Public License for more details. | |
+.\" | |
+.\" You should have received a copy of the GNU General Public License along | |
+.\" with this program; if not, write to the Free Software Foundation, | |
+.\" Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
+.\" | |
+.TH MICRODC "1" "September 17, 2005" "microdc" | |
+.SH NAME | |
+microdc - A command-line based Direct Connect client | |
+.SH SYNOPSIS | |
+.B microdc | |
+.RI [ OPTION ]... | |
+.SH DESCRIPTION | |
+microdc is a command-line based Direct Connect client that uses the GNU | |
+Readline library for user interaction. It was developed from ground up and | |
+does not depend on any other program. Despite the command-line user | |
+interface, microdc was designed to be user friendly and simple to use. | |
+.SH OPTIONS | |
+This program follows the usual GNU command line syntax, with long | |
+options starting with two dashes (`--'). | |
+.TP | |
+\fB\-c, \-\-config\fR=\fIFILE\fR | |
+Read configuration script from FILE rather than ~/.microdc/config. | |
+.TP | |
+\fB\-n, \-\-no\-config\fR | |
+Do not read config file on startup. | |
+.TP | |
+\fB\-\-help\fR | |
+Show summary of options. | |
+.TP | |
+\fB\-\-version\fR | |
+Output version information and exit. | |
+.TP | |
+\fB\-\-filelist_refresh_interval\fR=\fINUMBER\fR | |
+Local filelist refresh interval (in seconds). If set to zero, program runs in a | |
+special \fIslave\fR mode: it never updates the file list, just checks every minute | |
+if the filelist changes, and if so - reads it. This is pretty useful if you connect | |
+to several hubs and use same filelist. | |
+.SH FILES | |
+The following files are used by microdc (~ represents the current user's home directory): | |
+.TP | |
+\fB~/.microdc/config\fR | |
+This file is loaded on startup. It contains commands, one per line, that will be executed | |
+on startup. You can override loading of this file with --config and --no-config. | |
+.TP | |
+\fB~/.microdc/history\fR | |
+This is the command history file. It contains a list of commands that were typed and | |
+executed from the microdc prompt. It can safely be removed. | |
+.SH REPORTING BUGS | |
+Report bugs to <\[email protected]\fP>. | |
+.SH AUTHOR | |
+The author of \fBmicrodc\fP and this manual page is Oskar Liljeblad <\[email protected]\fP>. | |
+.SH COPYRIGHT | |
+Copyright \(co 2004, 2005 Oskar Liljeblad | |
+ | |
+This is free software; see the source for copying conditions. There is NO | |
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
unchanged: | |
--- microdc2-0.15.6.orig/src/main.c 2011-02-11 02:36:28.353479995 +0100 | |
+++ microdc2-0.15.6/src/main.c 2011-02-11 02:37:22.823479996 +0100 | |
@@ -55,6 +55,15 @@ | |
#include "common/msgq.h" | |
#include "microdc.h" | |
+/* Define the macro below for orphan handle checking (useful for debugging) */ | |
+#define CHECK_ORPHAN_HANDLES | |
+ | |
+#ifdef CHECK_ORPHAN_HANDLES | |
+#define IF_ORPHAN_HANDLES(x) x | |
+#else | |
+#define IF_ORPHAN_HANDLES(x) | |
+#endif | |
+ | |
enum { | |
VERSION_OPT = 256, | |
HELP_OPT | |
@@ -1306,34 +1315,60 @@ | |
break; | |
} | |
- if (running && FD_ISSET(signal_pipe[0], &res_read_fds)) | |
- read_signal_input(); | |
- if (running && FD_ISSET(STDIN_FILENO, &res_read_fds)) | |
+ if (running && FD_ISSET(signal_pipe[0], &res_read_fds)) { | |
+ FD_CLR(signal_pipe[0], &res_read_fds); | |
+ read_signal_input(); | |
+ } | |
+ if (running && FD_ISSET(STDIN_FILENO, &res_read_fds)) { | |
+ IF_ORPHAN_HANDLES (FD_CLR(STDIN_FILENO, &res_read_fds)); | |
screen_read_input(); | |
- if (running && listen_socket >= 0 && FD_ISSET(listen_socket, &res_read_fds)) | |
+ } | |
+ if (running && listen_socket >= 0 && FD_ISSET(listen_socket, &res_read_fds)) { | |
+ IF_ORPHAN_HANDLES (FD_CLR(listen_socket, &res_read_fds)); | |
handle_listen_connection(); | |
- if (running && hub_socket >= 0 && FD_ISSET(hub_socket, &res_read_fds)) | |
+ } | |
+ if (running && hub_socket >= 0 && FD_ISSET(hub_socket, &res_read_fds)) { | |
+ IF_ORPHAN_HANDLES (FD_CLR(hub_socket, &res_read_fds)); | |
hub_input_available(); | |
- if (running && hub_socket >= 0 && FD_ISSET(hub_socket, &res_write_fds)) | |
+ } | |
+ if (running && hub_socket >= 0 && FD_ISSET(hub_socket, &res_write_fds)) { | |
+ IF_ORPHAN_HANDLES (FD_CLR(hub_socket, &res_write_fds)); | |
hub_now_writable(); | |
+ } | |
if (running) | |
check_hub_activity(); | |
- if (running && search_socket >= 0 && FD_ISSET(search_socket, &res_read_fds)) | |
+ if (running && search_socket >= 0 && FD_ISSET(search_socket, &res_read_fds)) { | |
+ IF_ORPHAN_HANDLES (FD_CLR(search_socket, &res_read_fds)); | |
search_input_available(); | |
- if (running && search_socket >= 0 && FD_ISSET(search_socket, &res_write_fds)) | |
+ } | |
+ if (running && search_socket >= 0 && FD_ISSET(search_socket, &res_write_fds)) { | |
+ IF_ORPHAN_HANDLES (FD_CLR(search_socket, &res_write_fds)); | |
search_now_writable(); | |
- if (running && FD_ISSET(lookup_request_mq->fd, &res_write_fds)) | |
+ } | |
+ if (running && FD_ISSET(lookup_request_mq->fd, &res_write_fds)) { | |
+ IF_ORPHAN_HANDLES (FD_CLR(lookup_request_mq->fd, &res_write_fds)); | |
lookup_request_fd_writable(); | |
- if (running && FD_ISSET(lookup_result_mq->fd, &res_read_fds)) | |
+ } | |
+ if (running && FD_ISSET(lookup_result_mq->fd, &res_read_fds)) { | |
+ IF_ORPHAN_HANDLES (FD_CLR(lookup_result_mq->fd, &res_read_fds)); | |
lookup_result_fd_readable(); | |
- if (running && FD_ISSET(parse_request_mq->fd, &res_write_fds)) | |
+ } | |
+ if (running && FD_ISSET(parse_request_mq->fd, &res_write_fds)) { | |
+ IF_ORPHAN_HANDLES (FD_CLR(parse_request_mq->fd, &res_write_fds)); | |
parse_request_fd_writable(); | |
- if (running && FD_ISSET(parse_result_mq->fd, &res_read_fds)) | |
+ } | |
+ if (running && FD_ISSET(parse_result_mq->fd, &res_read_fds)) { | |
+ IF_ORPHAN_HANDLES (FD_CLR(parse_result_mq->fd, &res_read_fds)); | |
parse_result_fd_readable(); | |
- if (running && FD_ISSET(update_request_mq->fd, &res_write_fds)) | |
+ } | |
+ if (running && FD_ISSET(update_request_mq->fd, &res_write_fds)) { | |
+ IF_ORPHAN_HANDLES (FD_CLR(update_request_mq->fd, &res_write_fds)); | |
update_request_fd_writable(); | |
- if (running && FD_ISSET(update_result_mq->fd, &res_read_fds)) | |
+ } | |
+ if (running && FD_ISSET(update_result_mq->fd, &res_read_fds)) { | |
+ IF_ORPHAN_HANDLES (FD_CLR(update_result_mq->fd, &res_read_fds)); | |
update_result_fd_readable(); | |
+ } | |
if (running) { | |
HMapIterator it; | |
@@ -1341,13 +1376,36 @@ | |
hmap_iterator(user_conns, &it); | |
while (running && it.has_next(&it)) { | |
DCUserConn *uc = it.next(&it); | |
- if (uc->put_mq != NULL && FD_ISSET(uc->put_mq->fd, &res_write_fds)) | |
+ if (uc->put_mq != NULL && FD_ISSET(uc->put_mq->fd, &res_write_fds)) { | |
+ IF_ORPHAN_HANDLES (FD_CLR(uc->put_mq->fd, &res_write_fds)); | |
user_request_fd_writable(uc); | |
- if (uc->get_mq != NULL && FD_ISSET(uc->get_mq->fd, &res_read_fds)) | |
- user_result_fd_readable(uc); | |
+ } | |
+ if (uc->get_mq != NULL && FD_ISSET(uc->get_mq->fd, &res_read_fds)) { | |
+ IF_ORPHAN_HANDLES (FD_CLR(uc->get_mq->fd, &res_read_fds)); | |
+ user_result_fd_readable(uc); | |
+ } | |
} | |
} | |
- } | |
+ | |
+#ifdef CHECK_ORPHAN_HANDLES | |
+ /* Check for orphan file handles */ | |
+ { | |
+ int i; | |
+ for (i = 0; i < FD_SETSIZE; i++) { | |
+ if (FD_ISSET (i, &res_read_fds)) { | |
+ warn(_("Orphan READ file handle %d, closing\n"), i); | |
+ close (i); | |
+ FD_CLR (i, &read_fds); | |
+ } | |
+ if (FD_ISSET (i, &res_write_fds)) { | |
+ warn(_("Orphan WRITE file handle %d, closing\n"), i); | |
+ close (i); | |
+ FD_CLR (i, &write_fds); | |
+ } | |
+ } | |
+ } | |
+#endif | |
+ } | |
cleanup: | |
unchanged: | |
--- a/src/command.c | |
+++ b/src/command.c | |
@@ -65,6 +65,7 @@ | |
static void cmd_help(int argc, char **argv); | |
static void cmd_exit(int argc, char **argv); | |
static void cmd_say(int argc, char **argv); | |
+static void cmd_rehash(int argc, char **argv); | |
static void cmd_msg(int argc, char **argv); | |
static void cmd_raw(int argc, char **argv); | |
static void cmd_disconnect(int argc, char **argv); | |
@@ -268,6 +269,9 @@ | |
"\n" | |
"Example:\n" | |
" say \"hi everyone!\"\n")); | |
+ add_builtin_command("rehash", cmd_rehash, NULL, | |
+ _("rehash"), | |
+ _("Refresh share.\n")); | |
add_builtin_command("search", cmd_search, NULL, | |
_("search WORD..."), | |
_("Issue a search for the specified search words.\n")); | |
@@ -874,6 +878,12 @@ | |
} | |
static void | |
+cmd_rehash(int argc, char **argv) | |
+{ | |
+ local_file_list_update_init(); | |
+} | |
+ | |
+static void | |
cmd_msg(int argc, char **argv) | |
{ | |
char *t1; | |
unchanged: | |
--- a/src/screen.c Fri Jan 25 18:46:56 2008 +0200 | |
+++ b/src/screen.c Sat Jan 26 01:28:53 2008 +0200 | |
@@ -228,10 +228,29 @@ static void | |
static void | |
flag_vputf(DCDisplayFlag flag, const char *format, va_list args) | |
{ | |
- //va_list args2; | |
+ if (log_fh != NULL && log_flags & flag) { | |
+ char c_time[1024]; | |
+ time_t now = time(NULL); | |
+ struct tm _tm = {0}; | |
+ va_list args_dup; | |
- //va_copy(args2, args); | |
+ if (NULL != localtime_r(&now, &_tm) && 0 != strftime(c_time, 1023, "%d.%m.%Y %H:%M:%S", &_tm)) { | |
+ fprintf(log_fh, "%s ", c_time); | |
+ } | |
+ // args would become undefined after xvasprintf() call, so make a copy | |
+ // of args to use it later below. | |
+ va_copy(args_dup, args); | |
+ char* msg = xvasprintf(format, args_dup); | |
+ va_end(args_dup); | |
+ | |
+ char* log_msg = main_to_log_string(msg); | |
+ free(msg); | |
+ fprintf(log_fh, log_msg); | |
+ free(log_msg); | |
+ fflush(log_fh); | |
+ } | |
+ | |
if (display_flags & flag) { | |
if (screen_state == SCREEN_SUSPENDED) { | |
ptrv_append(suspend_msgs, xvasprintf(format, args)); | |
@@ -243,21 +262,6 @@ flag_vputf(DCDisplayFlag flag, const cha | |
vprintf(format, args); | |
fflush(stdout); | |
} | |
- } | |
- if (log_fh != NULL && log_flags & flag) { | |
- char c_time[1024]; | |
- time_t now = time(NULL); | |
- struct tm _tm = {0}; | |
- if (NULL != localtime_r(&now, &_tm) && 0 != strftime(c_time, 1023, "%d.%m.%Y %H:%M:%S", &_tm)) { | |
- fprintf(log_fh, "%s ", c_time); | |
- } | |
- char* msg = xvasprintf(format, args); | |
- //va_end(args2); | |
- char* log_msg = main_to_log_string(msg); | |
- free(msg); | |
- fprintf(log_fh, log_msg); | |
- free(log_msg); | |
- fflush(log_fh); | |
} | |
} | |
--- microdc2-0.15.6.orig/src/local_flist.c 2011-02-11 02:56:18.543479994 +0100 | |
+++ microdc2-0.15.6/src/local_flist.c 2011-02-11 02:59:20.533480000 +0100 | |
@@ -66,6 +66,7 @@ | |
pid_t update_child; | |
int incoming_update_type = -1; | |
char* update_status = NULL; | |
+time_t filelist_mtime = 0; | |
static const char* filelist_name = "filelist"; | |
static const char* new_filelist_name = "new-filelist"; | |
@@ -78,6 +79,8 @@ | |
#define ENOTFILELIST (1 << 16) | |
#define EWRONGVERSION (ENOTFILELIST + 1) | |
+bool report_error(MsgQ* status_mq, const char* fmt, ...); | |
+ | |
int compare_pointers(void* p1, void* p2) | |
{ | |
return p1 != p2; | |
@@ -119,20 +122,61 @@ | |
return is_already_shared_inode(root, st.st_dev, st.st_ino); | |
} | |
-DCFileList* read_local_file_list(const char* path) | |
+void lock_file (const char* path) | |
+{ | |
+ int fd, timeout = 20; | |
+ char fn [300]; | |
+ snprintf (fn, sizeof (fn), "%s.lock", path); | |
+ while ((fd = open (fn, O_RDONLY | O_CREAT | O_EXCL, 0600) < 0)) { | |
+ if (errno != EEXIST) { | |
+ /* It seems there's no way to report an error from here to parent? */ | |
+ /*report_error(result_mq, _("%s: Failed to create filelist lock, filelist will be not multiprocess-safe\n"), fn);*/ | |
+ break; | |
+ } | |
+ /* Wait some time for the lock to be released */ | |
+ sleep (1); | |
+ if (!--timeout) { | |
+ /*report_error(result_mq, _("%s: Filelist semaphore locked, but owner seems dead, breaking lock\n"), fn);*/ | |
+ break; | |
+ } | |
+ } | |
+ if (fd >= 0) | |
+ close (fd); | |
+} | |
+ | |
+void unlock_file (const char* path) | |
+{ | |
+ char fn [300]; | |
+ snprintf (fn, sizeof (fn), "%s.lock", path); | |
+ unlink (fn); | |
+} | |
+ | |
+/* if old_root is not NULL, rereads the file list only if file changed */ | |
+DCFileList* read_local_file_list(const char* path, DCFileList *old_root) | |
{ | |
struct stat st; | |
DCFileList *root = NULL; | |
+ /* First of all, check if filelist is not locked by other process */ | |
+ lock_file (path); | |
+ | |
if (stat(path, &st) < 0) { | |
if (errno != ENOENT) { | |
TRACE(("cannot stat %s: %d, %s\n", path, errno, errstr)); | |
+ unlock_file (path); | |
return NULL; | |
} | |
} else if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) { | |
+ unlock_file (path); | |
return NULL; | |
} | |
+ if (old_root && filelist_mtime == st.st_mtime) { | |
+ unlock_file (path); | |
+ return old_root; | |
+ } | |
+ filelist_mtime = st.st_mtime; | |
+ | |
int fd = open(path, O_RDONLY); | |
if (fd >= 0) { | |
void* mapped = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); | |
@@ -158,12 +202,22 @@ | |
root = new_file_node("", DC_TYPE_DIR, NULL); | |
} | |
+ unlock_file (path); | |
+ | |
+ if (old_root) | |
+ filelist_free (old_root); | |
+ | |
return root; | |
} | |
bool write_local_file_list(const char* path, DCFileList* root) | |
{ | |
bool result = false; | |
+ struct stat st; | |
+ | |
+ /* Check if filelist is not locked by other process */ | |
+ lock_file (path); | |
+ | |
int fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); | |
if (fd >= 0) { | |
unsigned char* data = NULL; | |
@@ -194,8 +248,14 @@ | |
result = (size == data_size); | |
cleanup: | |
+ /* Update filelist mtime */ | |
+ if (stat(path, &st) == 0) | |
+ filelist_mtime = st.st_mtime; | |
+ | |
close(fd); | |
} | |
+ | |
+ unlock_file (path); | |
return result; | |
} | |
@@ -487,6 +547,7 @@ | |
/* Inability to register these signals is not a fatal error. */ | |
sigact.sa_flags = SA_RESTART; | |
sigact.sa_handler = SIG_IGN; | |
+ sigemptyset (&sigact.sa_mask); | |
#ifdef HAVE_STRUCT_SIGACTION_SA_RESTORER | |
sigact.sa_restorer = NULL; | |
#endif | |
@@ -503,7 +564,7 @@ | |
goto cleanup; | |
} | |
- if (NULL == (root = read_local_file_list(flist_filename))) { | |
+ if (NULL == (root = read_local_file_list(flist_filename, NULL))) { | |
if (errno == ENOTFILELIST) { | |
report_error(result_mq, "Cannot load FileList - %s: Invalid file format\n", flist_filename); | |
} else if (errno == EWRONGVERSION) { | |
@@ -527,7 +588,7 @@ | |
max_fd = MAX(hash_result_mq->fd, max_fd); | |
while (true) { | |
- tv.tv_sec = filelist_refresh_timeout; | |
+ tv.tv_sec = FILELIST_SLAVE_MODE ? 60 : filelist_refresh_timeout; | |
tv.tv_usec = 0; | |
fd_set r_ready = readable, w_ready = writable; | |
@@ -577,13 +638,19 @@ | |
fflush(stderr); | |
*/ | |
} | |
+ | |
+ if (FILELIST_SLAVE_MODE && update_hash) { | |
+ /* Unexpected hash update received while in slave filelist mode */ | |
+ update_hash = false; | |
+ } | |
+ | |
time_t now = time(NULL); | |
if (update_hash && ((hashing == NULL && hash_files->cur == 0) || (now - hash_start) > filelist_hash_refresh_timeout)) { | |
hash_start = now; | |
if (write_local_file_list(new_flist_filename, root)) { | |
rename(new_flist_filename, flist_filename); | |
} else { | |
- unlink(new_filelist_name); | |
+ unlink(new_flist_filename); | |
} | |
if (!send_filelist(result_mq, root)) { | |
@@ -607,11 +674,7 @@ | |
msgq_get(request_mq, MSGQ_INT, &update_type, MSGQ_END); | |
} else { | |
if (update_type == FILELIST_UPDATE_REFRESH_INTERVAL) { | |
- time_t interval = 0; | |
- msgq_get(request_mq, MSGQ_INT, &interval, MSGQ_END); | |
- if (interval != 0) { | |
- filelist_refresh_timeout = interval; | |
- } | |
+ msgq_get(request_mq, MSGQ_INT, &filelist_refresh_timeout, MSGQ_END); | |
} else { | |
char *name; | |
int len = 0; | |
@@ -626,13 +689,15 @@ | |
case FILELIST_UPDATE_ADD_DIR_NAME: | |
if (is_already_shared(root, name)) { | |
// report error here | |
- report_error(result_mq, "%s directory is already shared as subfolder of existing shared tree\n", name); | |
- } else { | |
+ report_error(result_mq, _("%s directory is already shared as subfolder of existing shared tree\n"), name); | |
+ } else if (FILELIST_SLAVE_MODE) | |
+ report_error(result_mq, _("Cannot add directory %s to share list while in slave filelist mode\n"), name); | |
+ else { | |
char* bname = xstrdup(base_name(name)); | |
if (hmap_contains_key(root->dir.children, bname)) { | |
/* we already have the shared directory with the same name */ | |
- report_error(result_mq, "%s directory cannot be shared as %s because there is already shared directory with the same name\n", name, bname); | |
+ report_error(result_mq, _("%s directory cannot be shared as %s because there is already shared directory with the same name\n"), name, bname); | |
} else { | |
DCFileList* node = new_file_node(bname, DC_TYPE_DIR, root); | |
node->dir.real_path = xstrdup(name); | |
@@ -642,28 +707,30 @@ | |
} | |
break; | |
case FILELIST_UPDATE_DEL_DIR_NAME: | |
- //selected = 0; | |
{ | |
char* bname = xstrdup(base_name(name)); | |
DCFileList* node = hmap_get(root->dir.children, bname); | |
- if (node != NULL && node->type == DC_TYPE_DIR) { | |
- if (strcmp(node->dir.real_path, name) == 0) { | |
+ if (node != NULL && node->type == DC_TYPE_DIR && | |
+ strcmp(node->dir.real_path, name) == 0) { | |
+ if (FILELIST_SLAVE_MODE) | |
+ report_error(result_mq, _("Cannot remove directory %s from share list while in slave filelist mode\n"), name); | |
+ else { | |
node = hmap_remove(root->dir.children, bname); | |
filelist_free(node); | |
if (write_local_file_list(new_flist_filename, root)) { | |
rename(new_flist_filename, flist_filename); | |
} else { | |
- unlink(new_filelist_name); | |
+ unlink(new_flist_filename); | |
} | |
if (!send_filelist(result_mq, root)) { | |
goto cleanup; | |
} | |
- } else { | |
- report_error(result_mq, "%s directory is not shared\n"); | |
} | |
} | |
+ else | |
+ report_error(result_mq, _("%s directory is not shared\n"), name); | |
free(bname); | |
} | |
break; | |
@@ -703,18 +770,27 @@ | |
} | |
} | |
} | |
- if (selected == 0) { | |
+ | |
+ if (FILELIST_SLAVE_MODE && selected >= 0) { | |
+ // Check if filelist has been changed since we last read it | |
+ DCFileList *new_root = read_local_file_list(flist_filename, root); | |
+ if (new_root != root) { | |
+ root = new_root; | |
+ send_filelist(result_mq, root); | |
+ } | |
+ } | |
+ else if (selected == 0) { | |
// just look through shared directories for new or deleted files | |
if (hashing == NULL && !initial) | |
- report_status(result_mq, "Refreshing FileList"); | |
+ report_status(result_mq, _("Refreshing FileList")); | |
if (lookup_filelist_changes(root, hash_files)) { | |
if (write_local_file_list(new_flist_filename, root)) { | |
rename(new_flist_filename, flist_filename); | |
} else { | |
- unlink(new_filelist_name); | |
+ unlink(new_flist_filename); | |
} | |
- | |
+ | |
if (!send_filelist(result_mq, root)) { | |
break; | |
} | |
unchanged: | |
--- microdc2-0.15.6.orig/src/microdc.h 2011-02-11 02:56:29.033479994 +0100 | |
+++ microdc2-0.15.6/src/microdc.h 2011-02-11 02:57:37.883479998 +0100 | |
@@ -596,6 +596,7 @@ | |
extern pid_t update_child; | |
extern char* update_status; | |
extern time_t filelist_refresh_timeout; | |
+#define FILELIST_SLAVE_MODE (filelist_refresh_timeout <= 0) | |
bool local_file_list_update_init(void); | |
bool local_file_list_init(void); | |
void local_file_list_update_finish(void); | |
unchanged: | |
--- microdc2-0.15.6.orig/src/variables.c | |
+++ microdc2-0.15.6/src/variables.c | |
@@ -252,7 +252,7 @@ static DCVariable variables[] = { | |
var_get_string, var_set_log_file, &log_filename, | |
local_path_completion_generator, | |
NULL, | |
- "File to log screen messages to (will be appeneded)" | |
+ "File to log screen messages to (will be appended)" | |
}, | |
{ | |
"nick", | |
unchanged: | |
--- microdc2-0.15.6.orig/src/local_flist.c | |
+++ microdc2-0.15.6/src/local_flist.c | |
@@ -992,7 +992,7 @@ bool local_file_list_init(void) | |
screen_putf(_("%s\n"), msg); | |
free(msg); | |
} else { | |
- warn(_("unknown messge\n")); | |
+ warn(_("unknown message\n")); | |
} | |
return false; | |
} | |
only in patch2: | |
unchanged: | |
--- microdc2-0.15.6.orig/src/screen.c | |
+++ microdc2-0.15.6/src/screen.c | |
@@ -246,7 +246,7 @@ flag_vputf(DCDisplayFlag flag, const cha | |
char* log_msg = main_to_log_string(msg); | |
free(msg); | |
- fprintf(log_fh, log_msg); | |
+ fprintf(log_fh, "%s", log_msg); | |
free(log_msg); | |
fflush(log_fh); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment