Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 230553 Details for
Bug 162828
net-p2p/microdc2-0.15.6 100% CPU usage
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
slavemode patch missing in net-p2p/microdc2-0.15.6-r2
slavemode.patch (text/plain), 27.42 KB, created by
Nebojsa Trpkovic
on 2010-05-06 00:41:04 UTC
(
hide
)
Description:
slavemode patch missing in net-p2p/microdc2-0.15.6-r2
Filename:
MIME Type:
Creator:
Nebojsa Trpkovic
Created:
2010-05-06 00:41:04 UTC
Size:
27.42 KB
patch
obsolete
>by Andrew Zabolotny: > >This patch implements a "slave mode". What it does is that it allows >two microdc2's to run with the same database of shared files. Right now >microdc2 supports connecting just to one hub at a time, so this patch >helps overcome this limit. > >To use it, just launch a second copy of microdc2 and set >filelist_refresh_interval to 0. This will tell microdc2 to not refresh >the file list, but rather to check the last modification time on file >~/.microdc2/filelist. When it changes (supposedly re-written by a >"master" microdc2 process), it is re-read by the slave processes. > >3. Another small patch is that I've added - the -c switch now accepts >filenames without path, in which case they are looked for in the >~/.microdc2/ directory. For example, you can have two config files - >config.hub1 and config.hub2 in that directory, then you just can run: >"microdc2 -c config.hub1" rather than "microdc2 -c /home/user/config.hub1". > >4. Also the later patch incorporates a important bugfix (I haven't >separated it from the slave mode patch, my bad, but it's completely >contained in the subdiff for the file main.c). While having microdc2 >running for a couple of days I have observed that sometimes it goes in >a tight loop in the master process (the one that manipulates the >children) doing select() which quits immediately without sleeping >inbetween. This causes 100% CPU load on the server which is a pretty >bad thing. > >Some research has shown that sometimes (very seldom) client processes >are left running although all the relevant structures in the main >process (in the user_conns hashmap) are cleaned up, but their file >handle is left in the read_fds/write_fds set. Since these strcutures >are persistent for the lifetime of the master process, as soon as these >handles becomes ready the master process won't be able to sleep in >select() anymore, but still it won't do anything about these "orphan" >handles. > >The 'bugfix' is rather a dirty workaround, but it works and it could be >helpful at least in debug mode (when/if the real bug will be fixed). >What it does is that it checks that all handles signalled as ready in >the res_read_fds/res_write_fds filesets are processed. If there are >handles left unprocessed at the end of loop, it emits a warning and >closes those handles, then clears them from read_fds/write_fds. > > >diff -ur orig/src/filelist-in.c src/filelist-in.c >--- orig/src/filelist-in.c 2006-11-28 15:49:09.000000000 +0300 >+++ src/filelist-in.c 2007-03-20 00:06:00.000000000 +0300 >@@ -334,6 +334,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 >diff -ur orig/src/hash.c src/hash.c >--- orig/src/hash.c 2006-11-16 14:21:43.000000000 +0300 >+++ src/hash.c 2007-03-20 00:04:46.000000000 +0300 >@@ -58,6 +58,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 >diff -ur orig/src/local_flist.c src/local_flist.c >--- orig/src/local_flist.c 2006-12-09 12:01:22.000000000 +0300 >+++ src/local_flist.c 2007-03-29 23:00:38.000000000 +0400 >@@ -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; > } >diff -ur orig/src/lookup.c src/lookup.c >--- orig/src/lookup.c 2006-11-16 11:18:14.000000000 +0300 >+++ src/lookup.c 2007-03-20 00:09:05.000000000 +0300 >@@ -170,6 +170,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 >diff -ur orig/src/main.c src/main.c >--- orig/src/main.c 2006-12-24 21:23:51.000000000 +0300 >+++ src/main.c 2007-03-31 17:26:33.000000000 +0400 >@@ -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 >@@ -489,7 +498,8 @@ > > FD_CLR(uc->get_mq->fd, &read_fds); > FD_CLR(uc->put_mq->fd, &write_fds); >- if (close(uc->get_mq->fd) != 0 || close(uc->put_mq->fd) != 0) >+ // using (close || close) here could cause one of close() to be skipped >+ if ((close(uc->get_mq->fd) | close(uc->put_mq->fd)) != 0) > warn(_("Cannot close pipe - %s\n"), errstr); > msgq_free(uc->get_mq); > uc->get_mq = NULL; >@@ -1109,9 +1119,11 @@ > } > /* Start of disable_search. */ > if (search_socket >= 0) { >- if (close(search_socket) < 0) >+ if (close(search_socket) < 0) > warn(_("Cannot close socket - %s\n"), errstr); >- search_socket = -1; >+ FD_CLR(search_socket, &read_fds); >+ FD_CLR(search_socket, &write_fds); >+ search_socket = -1; > } > /* End of disable_search. */ > enable_search(); >@@ -1170,6 +1182,11 @@ > custom_config = true; > free(config_file); > config_file = xstrdup(optarg); >+ /* Check if file exists: if not consider it is a file name in package dir */ >+ if (strchr (config_file, '/') == NULL && access (config_file, R_OK) != 0) { >+ free(config_file); >+ get_package_file(optarg, &config_file); >+ } > break; > case 'n': /* --no-config */ > free(config_file); >@@ -1178,6 +1195,7 @@ > case HELP_OPT: /* --help */ > printf(_("Usage: %s [OPTION]...\n"), quotearg(argv[0])); > puts(_("Start microdc, a command-line based Direct Connect client.\n")); >+ printf(_(" -c, --config=FILE use a custom config file\n")); > printf(_(" -n, --no-config do not read config file on startup\n")); > printf(_(" --help display this help and exit\n")); > printf(_(" --version output version information and exit\n")); >@@ -1306,34 +1324,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 +1385,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: > >@@ -1365,6 +1432,9 @@ > > byteq_free(search_recvq); > >+ /* Do this before freeing user_conn_unknown_free otherwise we crash */ >+ hmap_foreach_value(user_conns, user_conn_cancel); >+ > ptrv_foreach(user_conn_unknown_free, free); > ptrv_free(user_conn_unknown_free); > >@@ -1374,7 +1444,6 @@ > ptrv_foreach(our_searches, (PtrVForeachCallback) free_search_request); > ptrv_free(our_searches); > >- hmap_foreach_value(user_conns, user_conn_cancel); > /* XXX: follow up and wait for user connections to die? */ > hmap_free(user_conns); > >diff -ur orig/src/microdc.1 src/microdc.1 >--- orig/src/microdc.1 2006-10-22 12:35:50.000000000 +0400 >+++ src/microdc.1 2007-03-17 11:16:33.000000000 +0300 >@@ -34,6 +34,8 @@ > .TP > \fB\-c, \-\-config\fR=\fIFILE\fR > Read configuration script from FILE rather than ~/.microdc/config. >+If FILE doees not exist and its name doesn't contain any slashes, >+program will look for given file in ~/.microdc/. > .TP > \fB\-n, \-\-no\-config\fR > Do not read config file on startup. >@@ -43,6 +45,69 @@ > .TP > \fB\-\-version\fR > Output version information and exit. >+.SH SETTINGS >+Most important options can be changed only by using the microdc \fBset\fR command. >+.TP >+\fBactive\fR=\fIon|1|off|0\fR >+Enable if listening for remote connections. Uses the setting \fBlistenport\fR >+for incoming connection port number. >+.TP >+\fBauto_reconnect\fR=\fIon|1|off|0\fR >+Enable automatic reconnect to the last connected hub >+.TP >+\fBdescription\fR=\fISTRING\fR >+This is the description which is visible to other users of the hub. >+.TP >+\fBdisplay\fR=\fIconnections{,debug,download,joinpart,publicchat,searchresults,upload}\fR >+Types of messages to display on screen. >+.TP >+\fBdownloaddir\fR=\fISTRING\fR >+Directory which files are downloaded to. >+.TP >+\fBemail\fR=\fISTRING\fR >+The e-mail visible to other users of the hub. >+.TP >+\fBfilelist_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. >+.TP >+\fBfilesystem_charset\fR=\fICHARSET\fR >+Character set used for chat on the hub. >+.TP >+\fBlistenaddr\fR=\fIHOST\fR >+Address to send to clients. >+.TP >+\fBlistenport\fR=\fINUMBER\fR >+Port to listen on for connections. >+.TP >+\fBlistingdir\fR=\fISTRING\fR >+Directory where file listings are kept. If you set this, this makes startup faster. >+.TP >+\fBlog\fR=\fIconnections{,debug,download,joinpart,publicchat,searchresults,upload}\fR >+Types of messages to log (if logfile set). >+.TP >+\fBlog_charset\fR=\fICHARSET\fR >+Log charset (if it differs from local charset). >+.TP >+\fBlogfile\fR=\fIFILE\fR >+File to log screen messages to (will be appeneded). >+.TP >+\fBnick\fR=\fISTRING\fR >+This is the desired (but not necessarily the current) nick name. >+.TP >+\fBpassword\fR=\fISTRING\fR >+The optional password to pass to the hub on connect. >+.TP >+\fBslots\fR=\fINUMBER\fR >+Number of open upload slots. >+.TP >+\fBspeed\fR=\fISTRING\fR >+The speed visible to other users of the hub. >+.TP >+\fBtag\fR=\fISTRING\fR >+The user agent tag the hub uses to detect features > .SH FILES > The following files are used by microdc (~ represents the current user's home directory): > .TP >diff -ur orig/src/microdc.h src/microdc.h >--- orig/src/microdc.h 2006-12-24 21:27:15.000000000 +0300 >+++ src/microdc.h 2007-03-17 13:36:26.000000000 +0300 >@@ -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); >diff -ur orig/src/user.c src/user.c >--- orig/src/user.c 2006-11-30 13:00:40.000000000 +0300 >+++ src/user.c 2007-03-22 11:10:49.000000000 +0300 >@@ -604,7 +604,7 @@ > ucl->share_file/*UL*/ = share_file; > } else { > free(share_file); >- ucl->share_file = xstrdup(base_name(local_file)); >+ ucl->share_file = xstrdup(local_file ? base_name(local_file) : ""); > } > ucl->local_file/*UL*/ = local_file; > } else { >@@ -612,7 +612,7 @@ > } > > if (ucl->local_file/*UL*/ == NULL) { >- flag_putf(DC_DF_CONNECTIONS, _("%s: File Not Available\n"), quotearg(ucl->local_file/*UL*/)); >+ flag_putf(DC_DF_CONNECTIONS, _("Non-existent file requested: Not Available\n")); > user_putf(ucl, "$Error File Not Available|"); > end_upload(ucl, false, _("no such shared file")); > return -4; >diff -ur orig/src/variables.c src/variables.c >--- orig/src/variables.c 2006-12-24 21:42:07.000000000 +0300 >+++ src/variables.c 2007-03-17 13:39:15.000000000 +0300 >@@ -313,10 +313,27 @@ > static void > charset_completion_generator(DCCompletionInfo *ci) > { >- /* FIXME: NYI */ >- /*run the command 'iconv --list' to get a list of completion alternatives >- fork(); >- exec('iconv', 'iconv', '--list');*/ >+ size_t wlen; >+ char line [100]; >+ FILE *f = popen ("iconv --list", "r"); >+ if (!f) >+ return; >+ >+ wlen = strlen(ci->word); >+ >+ // iconv detects when stdout is not a tty, and prints the list >+ // in a special format: CHARSET// >+ while (fgets (line, sizeof (line), f)) { >+ char *slash = strchr (line, '/'); >+ if (!slash) >+ continue; >+ *slash = 0; >+ >+ if (slash - line >= wlen && memcmp(ci->word, line, wlen) == 0) >+ ptrv_append(ci->results, new_completion_entry(xstrndup(line, slash - line), NULL)); >+ } >+ pclose (f); >+ ptrv_sort(ci->results, completion_entry_display_compare); > } > >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 162828
:
202605
| 230553 |
262125