Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 162828 | Differences between
and this patch

Collapse All | Expand All

(-)orig/src/filelist-in.c (+1 lines)
Lines 334-339 Link Here
334
    /* Inability to register these signals is not a fatal error. */
334
    /* Inability to register these signals is not a fatal error. */
335
    sigact.sa_flags = SA_RESTART;
335
    sigact.sa_flags = SA_RESTART;
336
    sigact.sa_handler = SIG_IGN;
336
    sigact.sa_handler = SIG_IGN;
337
    sigemptyset (&sigact.sa_mask);
337
#ifdef HAVE_STRUCT_SIGACTION_SA_RESTORER
338
#ifdef HAVE_STRUCT_SIGACTION_SA_RESTORER
338
    sigact.sa_restorer = NULL;
339
    sigact.sa_restorer = NULL;
339
#endif
340
#endif
(-)orig/src/hash.c (+1 lines)
Lines 58-63 Link Here
58
    /* Inability to register these signals is not a fatal error. */
58
    /* Inability to register these signals is not a fatal error. */
59
    sigact.sa_flags = SA_RESTART;
59
    sigact.sa_flags = SA_RESTART;
60
    sigact.sa_handler = SIG_IGN;
60
    sigact.sa_handler = SIG_IGN;
61
    sigemptyset (&sigact.sa_mask);
61
#ifdef HAVE_STRUCT_SIGACTION_SA_RESTORER
62
#ifdef HAVE_STRUCT_SIGACTION_SA_RESTORER
62
    sigact.sa_restorer = NULL;
63
    sigact.sa_restorer = NULL;
63
#endif
64
#endif
(-)orig/src/local_flist.c (-22 / +98 lines)
Lines 66-71 Link Here
66
pid_t update_child;
66
pid_t update_child;
67
int   incoming_update_type = -1;
67
int   incoming_update_type = -1;
68
char* update_status = NULL;
68
char* update_status = NULL;
69
time_t filelist_mtime = 0;
69
70
70
static const char* filelist_name = "filelist";
71
static const char* filelist_name = "filelist";
71
static const char* new_filelist_name = "new-filelist";
72
static const char* new_filelist_name = "new-filelist";
Lines 78-83 Link Here
78
#define ENOTFILELIST    (1 << 16)
79
#define ENOTFILELIST    (1 << 16)
79
#define EWRONGVERSION   (ENOTFILELIST + 1)
80
#define EWRONGVERSION   (ENOTFILELIST + 1)
80
81
82
bool report_error(MsgQ* status_mq, const char* fmt, ...);
83
81
int compare_pointers(void* p1, void* p2)
84
int compare_pointers(void* p1, void* p2)
82
{
85
{
83
    return p1 != p2;
86
    return p1 != p2;
Lines 119-138 Link Here
119
    return is_already_shared_inode(root, st.st_dev, st.st_ino);
122
    return is_already_shared_inode(root, st.st_dev, st.st_ino);
120
}
123
}
121
124
122
DCFileList* read_local_file_list(const char* path)
125
void lock_file (const char* path)
126
{
127
    int fd, timeout = 20;
128
    char fn [300];
129
    snprintf (fn, sizeof (fn), "%s.lock", path);
130
    while ((fd = open (fn, O_RDONLY | O_CREAT | O_EXCL, 0600) < 0)) {
131
        if (errno != EEXIST) {
132
            /* It seems there's no way to report an error from here to parent? */
133
            /*report_error(result_mq, _("%s: Failed to create filelist lock, filelist will be not multiprocess-safe\n"), fn);*/
134
            break;
135
        }
136
        /* Wait some time for the lock to be released */
137
        sleep (1);
138
        if (!--timeout) {
139
            /*report_error(result_mq, _("%s: Filelist semaphore locked, but owner seems dead, breaking lock\n"), fn);*/
140
            break;
141
        }
142
    }
143
    if (fd >= 0)
144
        close (fd);
145
}
146
147
void unlock_file (const char* path)
148
{
149
    char fn [300];
150
    snprintf (fn, sizeof (fn), "%s.lock", path);
151
    unlink (fn);
152
}
153
154
/* if old_root is not NULL, rereads the file list only if file changed */
155
DCFileList* read_local_file_list(const char* path, DCFileList *old_root)
123
{
156
{
124
    struct stat st;
157
    struct stat st;
125
    DCFileList *root = NULL;
158
    DCFileList *root = NULL;
126
159
160
    /* First of all, check if filelist is not locked by other process */
161
    lock_file (path);
162
127
    if (stat(path, &st) < 0) {
163
    if (stat(path, &st) < 0) {
128
        if (errno != ENOENT) {
164
        if (errno != ENOENT) {
129
            TRACE(("cannot stat %s: %d, %s\n", path, errno, errstr));
165
            TRACE(("cannot stat %s: %d, %s\n", path, errno, errstr));
166
            unlock_file (path);
130
            return NULL;
167
            return NULL;
131
        }
168
        }
132
    } else if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) {
169
    } else if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) {
170
        unlock_file (path);
133
        return NULL;
171
        return NULL;
134
    }
172
    }
135
173
174
    if (old_root && filelist_mtime == st.st_mtime) {
175
        unlock_file (path);
176
        return old_root;
177
    }
178
    filelist_mtime = st.st_mtime;
179
136
    int fd = open(path, O_RDONLY);
180
    int fd = open(path, O_RDONLY);
137
    if (fd >= 0) {
181
    if (fd >= 0) {
138
        void* mapped = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
182
        void* mapped = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
Lines 158-169 Link Here
158
        root = new_file_node("", DC_TYPE_DIR, NULL);
202
        root = new_file_node("", DC_TYPE_DIR, NULL);
159
    }
203
    }
160
204
205
    unlock_file (path);
206
207
    if (old_root)
208
        filelist_free (old_root);
209
161
    return root;
210
    return root;
162
}
211
}
163
212
164
bool write_local_file_list(const char* path, DCFileList* root)
213
bool write_local_file_list(const char* path, DCFileList* root)
165
{
214
{
166
    bool result = false;
215
    bool result = false;
216
    struct stat st;
217
218
    /* Check if filelist is not locked by other process */
219
    lock_file (path);
220
167
    int fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
221
    int fd = open(path, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
168
    if (fd >= 0) {
222
    if (fd >= 0) {
169
        unsigned char* data = NULL;
223
        unsigned char* data = NULL;
Lines 194-201 Link Here
194
        result = (size == data_size);
248
        result = (size == data_size);
195
249
196
cleanup:
250
cleanup:
251
        /* Update filelist mtime */
252
        if (stat(path, &st) == 0)
253
            filelist_mtime = st.st_mtime;
254
197
        close(fd);
255
        close(fd);
198
    }
256
    }
257
258
    unlock_file (path);
199
    return result;
259
    return result;
200
}
260
}
201
261
Lines 487-492 Link Here
487
    /* Inability to register these signals is not a fatal error. */
547
    /* Inability to register these signals is not a fatal error. */
488
    sigact.sa_flags = SA_RESTART;
548
    sigact.sa_flags = SA_RESTART;
489
    sigact.sa_handler = SIG_IGN;
549
    sigact.sa_handler = SIG_IGN;
550
    sigemptyset (&sigact.sa_mask);
490
#ifdef HAVE_STRUCT_SIGACTION_SA_RESTORER
551
#ifdef HAVE_STRUCT_SIGACTION_SA_RESTORER
491
    sigact.sa_restorer = NULL;
552
    sigact.sa_restorer = NULL;
492
#endif
553
#endif
Lines 503-509 Link Here
503
        goto cleanup;
564
        goto cleanup;
504
    }
565
    }
505
566
506
    if (NULL == (root = read_local_file_list(flist_filename))) {
567
    if (NULL == (root = read_local_file_list(flist_filename, NULL))) {
507
        if (errno == ENOTFILELIST) {
568
        if (errno == ENOTFILELIST) {
508
            report_error(result_mq, "Cannot load FileList - %s: Invalid file format\n", flist_filename);
569
            report_error(result_mq, "Cannot load FileList - %s: Invalid file format\n", flist_filename);
509
        } else if (errno == EWRONGVERSION) {
570
        } else if (errno == EWRONGVERSION) {
Lines 527-533 Link Here
527
    max_fd = MAX(hash_result_mq->fd, max_fd);
588
    max_fd = MAX(hash_result_mq->fd, max_fd);
528
589
529
    while (true) {
590
    while (true) {
530
        tv.tv_sec   = filelist_refresh_timeout;
591
        tv.tv_sec   = FILELIST_SLAVE_MODE ? 60 : filelist_refresh_timeout;
531
        tv.tv_usec  = 0;
592
        tv.tv_usec  = 0;
532
593
533
        fd_set r_ready = readable, w_ready = writable;
594
        fd_set r_ready = readable, w_ready = writable;
Lines 577-589 Link Here
577
                        fflush(stderr);
638
                        fflush(stderr);
578
                        */
639
                        */
579
                    }
640
                    }
641
642
                    if (FILELIST_SLAVE_MODE && update_hash) {
643
                        /* Unexpected hash update received while in slave filelist mode */
644
                        update_hash = false;
645
                    }
646
580
                    time_t now = time(NULL);
647
                    time_t now = time(NULL);
581
                    if (update_hash && ((hashing == NULL && hash_files->cur == 0) || (now - hash_start) > filelist_hash_refresh_timeout)) {
648
                    if (update_hash && ((hashing == NULL && hash_files->cur == 0) || (now - hash_start) > filelist_hash_refresh_timeout)) {
582
                        hash_start = now;
649
                        hash_start = now;
583
                        if (write_local_file_list(new_flist_filename, root)) {
650
                        if (write_local_file_list(new_flist_filename, root)) {
584
                            rename(new_flist_filename, flist_filename);
651
                            rename(new_flist_filename, flist_filename);
585
                        } else {
652
                        } else {
586
                            unlink(new_filelist_name);
653
                            unlink(new_flist_filename);
587
                        }
654
                        }
588
655
589
                        if (!send_filelist(result_mq, root)) {
656
                        if (!send_filelist(result_mq, root)) {
Lines 607-617 Link Here
607
                        msgq_get(request_mq, MSGQ_INT, &update_type, MSGQ_END);
674
                        msgq_get(request_mq, MSGQ_INT, &update_type, MSGQ_END);
608
                    } else {
675
                    } else {
609
                        if (update_type == FILELIST_UPDATE_REFRESH_INTERVAL) {
676
                        if (update_type == FILELIST_UPDATE_REFRESH_INTERVAL) {
610
                            time_t interval = 0;
677
                            msgq_get(request_mq, MSGQ_INT, &filelist_refresh_timeout, MSGQ_END);
611
                            msgq_get(request_mq, MSGQ_INT, &interval, MSGQ_END);
612
                            if (interval != 0) {
613
                                filelist_refresh_timeout = interval;
614
                            }
615
                        } else {
678
                        } else {
616
                            char *name;
679
                            char *name;
617
                            int len = 0;
680
                            int len = 0;
Lines 626-638 Link Here
626
                            case FILELIST_UPDATE_ADD_DIR_NAME:
689
                            case FILELIST_UPDATE_ADD_DIR_NAME:
627
                                if (is_already_shared(root, name)) {
690
                                if (is_already_shared(root, name)) {
628
                                    // report error here
691
                                    // report error here
629
                                    report_error(result_mq, "%s directory is already shared as subfolder of existing shared tree\n", name);
692
                                    report_error(result_mq, _("%s directory is already shared as subfolder of existing shared tree\n"), name);
630
                                } else {
693
                                } else if (FILELIST_SLAVE_MODE)
694
                                    report_error(result_mq, _("Cannot add directory %s to share list while in slave filelist mode\n"), name);
695
                                else {
631
                                    char* bname = xstrdup(base_name(name));
696
                                    char* bname = xstrdup(base_name(name));
632
697
633
                                    if (hmap_contains_key(root->dir.children, bname)) {
698
                                    if (hmap_contains_key(root->dir.children, bname)) {
634
                                        /* we already have the shared directory with the same name */
699
                                        /* we already have the shared directory with the same name */
635
                                        report_error(result_mq, "%s directory cannot be shared as %s because there is already shared directory with the same name\n", name, bname);
700
                                        report_error(result_mq, _("%s directory cannot be shared as %s because there is already shared directory with the same name\n"), name, bname);
636
                                    } else {
701
                                    } else {
637
                                        DCFileList* node = new_file_node(bname, DC_TYPE_DIR, root);
702
                                        DCFileList* node = new_file_node(bname, DC_TYPE_DIR, root);
638
                                        node->dir.real_path = xstrdup(name);
703
                                        node->dir.real_path = xstrdup(name);
Lines 642-669 Link Here
642
                                }
707
                                }
643
                                break;
708
                                break;
644
                            case FILELIST_UPDATE_DEL_DIR_NAME:
709
                            case FILELIST_UPDATE_DEL_DIR_NAME:
645
                                //selected = 0;
646
                                {
710
                                {
647
                                    char* bname = xstrdup(base_name(name));
711
                                    char* bname = xstrdup(base_name(name));
648
712
649
                                    DCFileList* node = hmap_get(root->dir.children, bname);
713
                                    DCFileList* node = hmap_get(root->dir.children, bname);
650
                                    if (node != NULL && node->type == DC_TYPE_DIR) {
714
                                    if (node != NULL && node->type == DC_TYPE_DIR &&
651
                                        if (strcmp(node->dir.real_path, name) == 0) {
715
                                        strcmp(node->dir.real_path, name) == 0) {
716
                                        if (FILELIST_SLAVE_MODE)
717
                                            report_error(result_mq, _("Cannot remove directory %s from share list while in slave filelist mode\n"), name);
718
                                        else {
652
                                            node = hmap_remove(root->dir.children, bname);
719
                                            node = hmap_remove(root->dir.children, bname);
653
                                            filelist_free(node);
720
                                            filelist_free(node);
654
                                            if (write_local_file_list(new_flist_filename, root)) {
721
                                            if (write_local_file_list(new_flist_filename, root)) {
655
                                                rename(new_flist_filename, flist_filename);
722
                                                rename(new_flist_filename, flist_filename);
656
                                            } else {
723
                                            } else {
657
                                                unlink(new_filelist_name);
724
                                                unlink(new_flist_filename);
658
                                            }
725
                                            }
659
726
660
                                            if (!send_filelist(result_mq, root)) {
727
                                            if (!send_filelist(result_mq, root)) {
661
                                                goto cleanup;
728
                                                goto cleanup;
662
                                            }
729
                                            }
663
                                        } else {
664
                                            report_error(result_mq, "%s directory is not shared\n");
665
                                        }
730
                                        }
666
                                    }
731
                                    }
732
                                    else
733
                                        report_error(result_mq, _("%s directory is not shared\n"), name);
667
                                    free(bname);
734
                                    free(bname);
668
                                }
735
                                }
669
                                break;
736
                                break;
Lines 703-720 Link Here
703
                }
770
                }
704
            }
771
            }
705
        }
772
        }
706
        if (selected == 0) {
773
774
        if (FILELIST_SLAVE_MODE && selected >= 0) {
775
            // Check if filelist has been changed since we last read it
776
            DCFileList *new_root = read_local_file_list(flist_filename, root);
777
            if (new_root != root) {
778
                root = new_root;
779
                send_filelist(result_mq, root);
780
            }
781
        }
782
        else if (selected == 0) {
707
            // just look through shared directories for new or deleted files
783
            // just look through shared directories for new or deleted files
708
            if (hashing == NULL && !initial)
784
            if (hashing == NULL && !initial)
709
                report_status(result_mq, "Refreshing FileList");
785
                report_status(result_mq, _("Refreshing FileList"));
710
786
711
            if (lookup_filelist_changes(root, hash_files)) {
787
            if (lookup_filelist_changes(root, hash_files)) {
712
                if (write_local_file_list(new_flist_filename, root)) {
788
                if (write_local_file_list(new_flist_filename, root)) {
713
                    rename(new_flist_filename, flist_filename);
789
                    rename(new_flist_filename, flist_filename);
714
                } else {
790
                } else {
715
                    unlink(new_filelist_name);
791
                    unlink(new_flist_filename);
716
                }
792
                }
717
793
    
718
                if (!send_filelist(result_mq, root)) {
794
                if (!send_filelist(result_mq, root)) {
719
                    break;
795
                    break;
720
                }
796
                }
(-)orig/src/lookup.c (+1 lines)
Lines 170-175 Link Here
170
    /* Inability to register these signals is not a fatal error. */
170
    /* Inability to register these signals is not a fatal error. */
171
    sigact.sa_flags = SA_RESTART;
171
    sigact.sa_flags = SA_RESTART;
172
    sigact.sa_handler = SIG_IGN;
172
    sigact.sa_handler = SIG_IGN;
173
    sigemptyset (&sigact.sa_mask);
173
#ifdef HAVE_STRUCT_SIGACTION_SA_RESTORER
174
#ifdef HAVE_STRUCT_SIGACTION_SA_RESTORER
174
    sigact.sa_restorer = NULL;
175
    sigact.sa_restorer = NULL;
175
#endif
176
#endif
(-)orig/src/main.c (-22 / +91 lines)
Lines 55-60 Link Here
55
#include "common/msgq.h"
55
#include "common/msgq.h"
56
#include "microdc.h"
56
#include "microdc.h"
57
57
58
/* Define the macro below for orphan handle checking (useful for debugging) */
59
#define CHECK_ORPHAN_HANDLES
60
61
#ifdef CHECK_ORPHAN_HANDLES
62
#define IF_ORPHAN_HANDLES(x) x
63
#else
64
#define IF_ORPHAN_HANDLES(x)
65
#endif
66
58
enum {
67
enum {
59
    VERSION_OPT = 256,
68
    VERSION_OPT = 256,
60
    HELP_OPT
69
    HELP_OPT
Lines 489-495 Link Here
489
498
490
    FD_CLR(uc->get_mq->fd, &read_fds);
499
    FD_CLR(uc->get_mq->fd, &read_fds);
491
    FD_CLR(uc->put_mq->fd, &write_fds);
500
    FD_CLR(uc->put_mq->fd, &write_fds);
492
    if (close(uc->get_mq->fd) != 0 || close(uc->put_mq->fd) != 0)
501
    // using (close || close) here could cause one of close() to be skipped
502
    if ((close(uc->get_mq->fd) | close(uc->put_mq->fd)) != 0)
493
	warn(_("Cannot close pipe - %s\n"), errstr);
503
	warn(_("Cannot close pipe - %s\n"), errstr);
494
    msgq_free(uc->get_mq);
504
    msgq_free(uc->get_mq);
495
    uc->get_mq = NULL;
505
    uc->get_mq = NULL;
Lines 1109-1117 Link Here
1109
    }
1119
    }
1110
    /* Start of disable_search. */
1120
    /* Start of disable_search. */
1111
    if (search_socket >= 0) {
1121
    if (search_socket >= 0) {
1112
	    if (close(search_socket) < 0)
1122
	if (close(search_socket) < 0)
1113
            warn(_("Cannot close socket - %s\n"), errstr);
1123
            warn(_("Cannot close socket - %s\n"), errstr);
1114
	    search_socket = -1;
1124
	FD_CLR(search_socket, &read_fds);
1125
	FD_CLR(search_socket, &write_fds);
1126
	search_socket = -1;
1115
    }
1127
    }
1116
    /* End of disable_search. */
1128
    /* End of disable_search. */
1117
    enable_search();
1129
    enable_search();
Lines 1170-1175 Link Here
1170
	        custom_config = true;
1182
	        custom_config = true;
1171
	        free(config_file);
1183
	        free(config_file);
1172
	        config_file = xstrdup(optarg);
1184
	        config_file = xstrdup(optarg);
1185
            /* Check if file exists: if not consider it is a file name in package dir */
1186
            if (strchr (config_file, '/') == NULL && access (config_file, R_OK) != 0) {
1187
                free(config_file);
1188
                get_package_file(optarg, &config_file);
1189
            }
1173
	        break;
1190
	        break;
1174
	    case 'n': /* --no-config */
1191
	    case 'n': /* --no-config */
1175
	        free(config_file);
1192
	        free(config_file);
Lines 1178-1183 Link Here
1178
	    case HELP_OPT: /* --help */
1195
	    case HELP_OPT: /* --help */
1179
	        printf(_("Usage: %s [OPTION]...\n"), quotearg(argv[0]));
1196
	        printf(_("Usage: %s [OPTION]...\n"), quotearg(argv[0]));
1180
	        puts(_("Start microdc, a command-line based Direct Connect client.\n"));
1197
	        puts(_("Start microdc, a command-line based Direct Connect client.\n"));
1198
	        printf(_("  -c, --config=FILE use a custom config file\n"));
1181
	        printf(_("  -n, --no-config  do not read config file on startup\n"));
1199
	        printf(_("  -n, --no-config  do not read config file on startup\n"));
1182
	        printf(_("      --help       display this help and exit\n"));
1200
	        printf(_("      --help       display this help and exit\n"));
1183
	        printf(_("      --version    output version information and exit\n"));
1201
	        printf(_("      --version    output version information and exit\n"));
Lines 1306-1339 Link Here
1306
	        break;
1324
	        break;
1307
	    }
1325
	    }
1308
1326
1309
    	if (running && FD_ISSET(signal_pipe[0], &res_read_fds))
1327
    	if (running && FD_ISSET(signal_pipe[0], &res_read_fds)) {
1310
	        read_signal_input();
1328
            FD_CLR(signal_pipe[0], &res_read_fds);
1311
    	if (running && FD_ISSET(STDIN_FILENO, &res_read_fds))
1329
            read_signal_input();
1330
	    }
1331
    	if (running && FD_ISSET(STDIN_FILENO, &res_read_fds)) {
1332
            IF_ORPHAN_HANDLES (FD_CLR(STDIN_FILENO, &res_read_fds));
1312
    	    screen_read_input();
1333
    	    screen_read_input();
1313
    	if (running && listen_socket >= 0 && FD_ISSET(listen_socket, &res_read_fds))
1334
	    }
1335
    	if (running && listen_socket >= 0 && FD_ISSET(listen_socket, &res_read_fds)) {
1336
	        IF_ORPHAN_HANDLES (FD_CLR(listen_socket, &res_read_fds));
1314
	        handle_listen_connection();
1337
	        handle_listen_connection();
1315
	    if (running && hub_socket >= 0 && FD_ISSET(hub_socket, &res_read_fds))
1338
	    }
1339
	    if (running && hub_socket >= 0 && FD_ISSET(hub_socket, &res_read_fds)) {
1340
	        IF_ORPHAN_HANDLES (FD_CLR(hub_socket, &res_read_fds));
1316
	        hub_input_available();
1341
	        hub_input_available();
1317
	    if (running && hub_socket >= 0 && FD_ISSET(hub_socket, &res_write_fds))
1342
	    }
1343
	    if (running && hub_socket >= 0 && FD_ISSET(hub_socket, &res_write_fds)) {
1344
	        IF_ORPHAN_HANDLES (FD_CLR(hub_socket, &res_write_fds));
1318
	        hub_now_writable();
1345
	        hub_now_writable();
1346
	    }
1319
        if (running)
1347
        if (running)
1320
            check_hub_activity();
1348
            check_hub_activity();
1321
	    if (running && search_socket >= 0 && FD_ISSET(search_socket, &res_read_fds))
1349
	    if (running && search_socket >= 0 && FD_ISSET(search_socket, &res_read_fds)) {
1350
    	    IF_ORPHAN_HANDLES (FD_CLR(search_socket, &res_read_fds));
1322
    	    search_input_available();
1351
    	    search_input_available();
1323
	    if (running && search_socket >= 0 && FD_ISSET(search_socket, &res_write_fds))
1352
	    }
1353
	    if (running && search_socket >= 0 && FD_ISSET(search_socket, &res_write_fds)) {
1354
	        IF_ORPHAN_HANDLES (FD_CLR(search_socket, &res_write_fds));
1324
	        search_now_writable();
1355
	        search_now_writable();
1325
        if (running && FD_ISSET(lookup_request_mq->fd, &res_write_fds))
1356
	    }
1357
        if (running && FD_ISSET(lookup_request_mq->fd, &res_write_fds)) {
1358
            IF_ORPHAN_HANDLES (FD_CLR(lookup_request_mq->fd, &res_write_fds));
1326
            lookup_request_fd_writable();
1359
            lookup_request_fd_writable();
1327
        if (running && FD_ISSET(lookup_result_mq->fd, &res_read_fds))
1360
	    }
1361
        if (running && FD_ISSET(lookup_result_mq->fd, &res_read_fds)) {
1362
            IF_ORPHAN_HANDLES (FD_CLR(lookup_result_mq->fd, &res_read_fds));
1328
            lookup_result_fd_readable();
1363
            lookup_result_fd_readable();
1329
        if (running && FD_ISSET(parse_request_mq->fd, &res_write_fds))
1364
	    }
1365
        if (running && FD_ISSET(parse_request_mq->fd, &res_write_fds)) {
1366
            IF_ORPHAN_HANDLES (FD_CLR(parse_request_mq->fd, &res_write_fds));
1330
            parse_request_fd_writable();
1367
            parse_request_fd_writable();
1331
        if (running && FD_ISSET(parse_result_mq->fd, &res_read_fds))
1368
	    }
1369
        if (running && FD_ISSET(parse_result_mq->fd, &res_read_fds)) {
1370
            IF_ORPHAN_HANDLES (FD_CLR(parse_result_mq->fd, &res_read_fds));
1332
            parse_result_fd_readable();
1371
            parse_result_fd_readable();
1333
        if (running && FD_ISSET(update_request_mq->fd, &res_write_fds))
1372
	    }
1373
        if (running && FD_ISSET(update_request_mq->fd, &res_write_fds)) {
1374
            IF_ORPHAN_HANDLES (FD_CLR(update_request_mq->fd, &res_write_fds));
1334
            update_request_fd_writable();
1375
            update_request_fd_writable();
1335
        if (running && FD_ISSET(update_result_mq->fd, &res_read_fds))
1376
	    }
1377
        if (running && FD_ISSET(update_result_mq->fd, &res_read_fds)) {
1378
            IF_ORPHAN_HANDLES (FD_CLR(update_result_mq->fd, &res_read_fds));
1336
            update_result_fd_readable();
1379
            update_result_fd_readable();
1380
	    }
1337
1381
1338
	    if (running) {
1382
	    if (running) {
1339
	        HMapIterator it;
1383
	        HMapIterator it;
Lines 1341-1353 Link Here
1341
	        hmap_iterator(user_conns, &it);
1385
	        hmap_iterator(user_conns, &it);
1342
	        while (running && it.has_next(&it)) {
1386
	        while (running && it.has_next(&it)) {
1343
	    	    DCUserConn *uc = it.next(&it);
1387
	    	    DCUserConn *uc = it.next(&it);
1344
	    	    if (uc->put_mq != NULL && FD_ISSET(uc->put_mq->fd, &res_write_fds))
1388
	    	    if (uc->put_mq != NULL && FD_ISSET(uc->put_mq->fd, &res_write_fds)) {
1389
	    	        IF_ORPHAN_HANDLES (FD_CLR(uc->put_mq->fd, &res_write_fds));
1345
	    	        user_request_fd_writable(uc);
1390
	    	        user_request_fd_writable(uc);
1346
                    if (uc->get_mq != NULL && FD_ISSET(uc->get_mq->fd, &res_read_fds))
1391
	            }
1347
                        user_result_fd_readable(uc);
1392
	            if (uc->get_mq != NULL && FD_ISSET(uc->get_mq->fd, &res_read_fds)) {
1393
	                IF_ORPHAN_HANDLES (FD_CLR(uc->get_mq->fd, &res_read_fds));
1394
	                user_result_fd_readable(uc);
1395
	            }
1348
	        }
1396
	        }
1349
	    }
1397
	    }
1350
    }
1398
1399
#ifdef CHECK_ORPHAN_HANDLES
1400
        /* Check for orphan file handles */
1401
        {
1402
            int i;
1403
            for (i = 0; i < FD_SETSIZE; i++) {
1404
                if (FD_ISSET (i, &res_read_fds)) {
1405
                    warn(_("Orphan READ file handle %d, closing\n"), i);
1406
                    close (i);
1407
                    FD_CLR (i, &read_fds);
1408
                }
1409
                if (FD_ISSET (i, &res_write_fds)) {
1410
                    warn(_("Orphan WRITE file handle %d, closing\n"), i);
1411
                    close (i);
1412
                    FD_CLR (i, &write_fds);
1413
                }
1414
            }
1415
        }
1416
#endif
1417
	}
1351
1418
1352
cleanup:
1419
cleanup:
1353
1420
Lines 1365-1370 Link Here
1365
1432
1366
    byteq_free(search_recvq);
1433
    byteq_free(search_recvq);
1367
1434
1435
    /* Do this before freeing user_conn_unknown_free otherwise we crash */
1436
    hmap_foreach_value(user_conns, user_conn_cancel);
1437
1368
    ptrv_foreach(user_conn_unknown_free, free);
1438
    ptrv_foreach(user_conn_unknown_free, free);
1369
    ptrv_free(user_conn_unknown_free);
1439
    ptrv_free(user_conn_unknown_free);
1370
1440
Lines 1374-1380 Link Here
1374
    ptrv_foreach(our_searches, (PtrVForeachCallback) free_search_request);
1444
    ptrv_foreach(our_searches, (PtrVForeachCallback) free_search_request);
1375
    ptrv_free(our_searches);
1445
    ptrv_free(our_searches);
1376
1446
1377
    hmap_foreach_value(user_conns, user_conn_cancel);
1378
    /* XXX: follow up and wait for user connections to die? */
1447
    /* XXX: follow up and wait for user connections to die? */
1379
    hmap_free(user_conns);
1448
    hmap_free(user_conns);
1380
1449
(-)orig/src/microdc.1 (+65 lines)
Lines 34-39 Link Here
34
.TP
34
.TP
35
\fB\-c, \-\-config\fR=\fIFILE\fR
35
\fB\-c, \-\-config\fR=\fIFILE\fR
36
Read configuration script from FILE rather than ~/.microdc/config.
36
Read configuration script from FILE rather than ~/.microdc/config.
37
If FILE doees not exist and its name doesn't contain any slashes,
38
program will look for given file in ~/.microdc/.
37
.TP
39
.TP
38
\fB\-n, \-\-no\-config\fR
40
\fB\-n, \-\-no\-config\fR
39
Do not read config file on startup.
41
Do not read config file on startup.
Lines 43-48 Link Here
43
.TP
45
.TP
44
\fB\-\-version\fR
46
\fB\-\-version\fR
45
Output version information and exit.
47
Output version information and exit.
48
.SH SETTINGS
49
Most important options can be changed only by using the microdc \fBset\fR command.
50
.TP
51
\fBactive\fR=\fIon|1|off|0\fR
52
Enable if listening for remote connections. Uses the setting \fBlistenport\fR
53
for incoming connection port number.
54
.TP
55
\fBauto_reconnect\fR=\fIon|1|off|0\fR
56
Enable automatic reconnect to the last connected hub
57
.TP
58
\fBdescription\fR=\fISTRING\fR
59
This is the description which is visible to other users of the hub.
60
.TP
61
\fBdisplay\fR=\fIconnections{,debug,download,joinpart,publicchat,searchresults,upload}\fR
62
Types of messages to display on screen.
63
.TP
64
\fBdownloaddir\fR=\fISTRING\fR
65
Directory which files are downloaded to.
66
.TP
67
\fBemail\fR=\fISTRING\fR
68
The e-mail visible to other users of the hub.
69
.TP
70
\fBfilelist_refresh_interval\fR=\fINUMBER\fR
71
Local filelist refresh interval (in seconds). If set to zero, program runs in a
72
special \fIslave\fR mode: it never updates the file list, just checks every minute
73
if the filelist changes, and if so - reads it. This is pretty useful if you connect
74
to several hubs and use same filelist.
75
.TP
76
\fBfilesystem_charset\fR=\fICHARSET\fR
77
Character set used for chat on the hub.
78
.TP
79
\fBlistenaddr\fR=\fIHOST\fR
80
Address to send to clients.
81
.TP
82
\fBlistenport\fR=\fINUMBER\fR
83
Port to listen on for connections.
84
.TP
85
\fBlistingdir\fR=\fISTRING\fR
86
Directory where file listings are kept. If you set this, this makes startup faster.
87
.TP
88
\fBlog\fR=\fIconnections{,debug,download,joinpart,publicchat,searchresults,upload}\fR
89
Types of messages to log (if logfile set).
90
.TP
91
\fBlog_charset\fR=\fICHARSET\fR
92
Log charset (if it differs from local charset).
93
.TP
94
\fBlogfile\fR=\fIFILE\fR
95
File to log screen messages to (will be appeneded).
96
.TP
97
\fBnick\fR=\fISTRING\fR
98
This is the desired (but not necessarily the current) nick name.
99
.TP
100
\fBpassword\fR=\fISTRING\fR
101
The optional password to pass to the hub on connect.
102
.TP
103
\fBslots\fR=\fINUMBER\fR
104
Number of open upload slots.
105
.TP
106
\fBspeed\fR=\fISTRING\fR
107
The speed visible to other users of the hub.
108
.TP
109
\fBtag\fR=\fISTRING\fR
110
The user agent tag the hub uses to detect features
46
.SH FILES
111
.SH FILES
47
The following files are used by microdc (~ represents the current user's home directory):
112
The following files are used by microdc (~ represents the current user's home directory):
48
.TP
113
.TP
(-)orig/src/microdc.h (+1 lines)
Lines 596-601 Link Here
596
extern pid_t update_child;
596
extern pid_t update_child;
597
extern char* update_status;
597
extern char* update_status;
598
extern time_t filelist_refresh_timeout;
598
extern time_t filelist_refresh_timeout;
599
#define FILELIST_SLAVE_MODE (filelist_refresh_timeout <= 0)
599
bool local_file_list_update_init(void);
600
bool local_file_list_update_init(void);
600
bool local_file_list_init(void);
601
bool local_file_list_init(void);
601
void local_file_list_update_finish(void);
602
void local_file_list_update_finish(void);
(-)orig/src/user.c (-2 / +2 lines)
Lines 604-610 Link Here
604
            ucl->share_file/*UL*/ = share_file;
604
            ucl->share_file/*UL*/ = share_file;
605
        } else {
605
        } else {
606
            free(share_file);
606
            free(share_file);
607
            ucl->share_file = xstrdup(base_name(local_file));
607
            ucl->share_file = xstrdup(local_file ? base_name(local_file) : "");
608
        }
608
        }
609
        ucl->local_file/*UL*/ = local_file;
609
        ucl->local_file/*UL*/ = local_file;
610
    } else {
610
    } else {
Lines 612-618 Link Here
612
    }
612
    }
613
613
614
    if (ucl->local_file/*UL*/ == NULL) {
614
    if (ucl->local_file/*UL*/ == NULL) {
615
        flag_putf(DC_DF_CONNECTIONS, _("%s: File Not Available\n"), quotearg(ucl->local_file/*UL*/));
615
        flag_putf(DC_DF_CONNECTIONS, _("Non-existent file requested: Not Available\n"));
616
        user_putf(ucl, "$Error File Not Available|");
616
        user_putf(ucl, "$Error File Not Available|");
617
        end_upload(ucl, false, _("no such shared file"));
617
        end_upload(ucl, false, _("no such shared file"));
618
        return -4;
618
        return -4;
(-)orig/src/variables.c (-4 / +21 lines)
Lines 313-322 Link Here
313
static void
313
static void
314
charset_completion_generator(DCCompletionInfo *ci)
314
charset_completion_generator(DCCompletionInfo *ci)
315
{
315
{
316
    /* FIXME: NYI */
316
    size_t wlen;
317
    /*run the command  'iconv --list' to get a list of completion alternatives
317
    char line [100];
318
    fork();
318
    FILE *f = popen ("iconv --list", "r");
319
    exec('iconv', 'iconv', '--list');*/
319
    if (!f)
320
        return;
321
322
    wlen = strlen(ci->word);
323
324
    // iconv detects when stdout is not a tty, and prints the list
325
    // in a special format: CHARSET//
326
    while (fgets (line, sizeof (line), f)) {
327
        char *slash = strchr (line, '/');
328
        if (!slash)
329
            continue;
330
        *slash = 0;
331
332
        if (slash - line >= wlen && memcmp(ci->word, line, wlen) == 0)
333
            ptrv_append(ci->results, new_completion_entry(xstrndup(line, slash - line), NULL));
334
    }
335
    pclose (f);
336
    ptrv_sort(ci->results, completion_entry_display_compare);
320
}
337
}
321
338
322
339

Return to bug 162828