Statistics
| Revision:

root / trunk / base / utils.c @ 1913

History | View | Annotate | Download (21 KB)

1
/* 
2
    Copyright (C) 2005-2010  Erik van Pienbroek
3

                
4
    This program is free software; you can redistribute it and/or modify
5
    it under the terms of the GNU General Public License as published by
6
    the Free Software Foundation; either version 2 of the License, or
7
    (at your option) any later version.
8

                
9
    This program is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU General Public License for more details.
13

                
14
    You should have received a copy of the GNU General Public License
15
    along with this program; if not, write to the Free Software
16
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
*/
18

                
19
#include 
20
#include 
21
#include 
22
#include 
23

                
24
#ifndef _MSC_VER
25
#include 
26
#endif
27

                
28
#ifdef WIN32
29
#include 
30
#include 
31
#include 
32
#include 
33
#include 
34
#else
35
#include 
36
#include 
37
#include 
38
#include 
39
#endif
40

                
41
#include 
42
#include 
43
#include "nntpgrab_utils.h"
44
#include "nntpgrab_types.h"
45

                
46
#ifdef WIN32
47
#define CLOSE(x)    closesocket(x)
48
#else
49
#define CLOSE(x)    close(x)
50
#endif
51

                
52
ngboolean
53
nntpgrab_utils_strip_subject(const char *subject, char **subject_without_partnum, int *file_num, int *total_files, char **filename, char **extension, NNTPFileType *file_type, int *par2_startnum, int *num_par2_blocks, int *part_num, int *total_parts)
54
{
55
    const char **values;
56
    static NGRegex *re_filename_and_extension = NULL;
57
    static NGRegex *re_subject_without_partnum = NULL;
58
    NNTPFileType type;
59

                
60
    if (!re_filename_and_extension) {
61
        re_filename_and_extension = nntpgrab_utils_regex_compile("((?:.*[\"']|[^ ]+ |^)(.+(?:\"|'|)\\.([fF][lL][aA][cC]|[pP][aA][rR]2|[xX][lL][sS][xX]|[a-zA-Z0-9]{3}|[tT][sS]))[\"'\\] ].*)\\(([0-9]+)/([0-9]+)\\).*$");
62
    }
63

                
64
    if (!re_subject_without_partnum) {
65
        re_subject_without_partnum = nntpgrab_utils_regex_compile("(.*)\\(([0-9]+)/([0-9]+)\\).*$");
66
    }
67

                
68
    // If the user only wants to know the subject without part numbers, use a more simple regex
69
    if (!(file_num || total_files || filename || extension || file_type || par2_startnum || num_par2_blocks)) {
70
        values = nntpgrab_utils_regex_match(re_subject_without_partnum, subject);
71
        if (values == NULL) {
72
            return FALSE;
73
        }
74

                
75
        if (subject_without_partnum) {
76
            *subject_without_partnum = g_strdup(values[1]);
77
        }
78

                
79
        if (part_num) {
80
            *part_num = atoi(values[2]);
81
        }
82

                
83
        if (total_parts) {
84
            *total_parts = atoi(values[3]);
85
        }
86

                
87
        nntpgrab_utils_regex_matches_free(values);
88

                
89
        return TRUE;
90
    }
91

                
92
    values = nntpgrab_utils_regex_match(re_filename_and_extension, subject);
93
    if (values == NULL) {
94
        return FALSE;
95
    }
96

                
97
    if (subject_without_partnum) {
98
        *subject_without_partnum = g_strdup(values[1]);
99
    }
100

                
101
    if (filename) {
102
        *filename = g_strdup(values[2]);
103
    }
104

                
105
    if (extension) {
106
        *extension = g_strdup(values[3]);
107
    }
108

                
109
    if (file_type || par2_startnum || num_par2_blocks) {
110
        if (!g_strcasecmp(values[3], "rar")) {
111
            type = NNTP_FILE_TYPE_RAR;
112
        } else if (!g_strcasecmp(values[3], "par2")) {
113
            type = NNTP_FILE_TYPE_PAR2;
114
        } else if (!g_strcasecmp(values[3], "par")) {
115
            type = NNTP_FILE_TYPE_PAR;
116
        } else if (!g_strcasecmp(values[3], "sfv")) {
117
            type = NNTP_FILE_TYPE_SFV;
118
        } else if (!g_strcasecmp(values[3], "nfo")) {
119
            type = NNTP_FILE_TYPE_NFO;
120
        } else if (!g_strcasecmp(values[3], "nzb")) {
121
            type = NNTP_FILE_TYPE_NZB;
122
        } else {
123
            type = NNTP_FILE_TYPE_OTHER;
124
        }
125

                
126
        if (file_type) {
127
            *file_type = type;
128
        }
129

                
130
        if (par2_startnum || num_par2_blocks) {
131
            if (par2_startnum) {
132
                *par2_startnum = -1;
133
            }
134

                
135
            if (num_par2_blocks) {
136
                *num_par2_blocks = -1;
137
            }
138

                
139
            if (type == NNTP_FILE_TYPE_PAR2) {
140
                // Find out the block numbers of this PAR2 file.
141
                // FIXME: This should be integrated in the main regexp
142
                static NGRegex *re_par2_blocknumbers = NULL;
143
                const char **values_par2;
144

                
145
                if (!re_par2_blocknumbers) {
146
                    re_par2_blocknumbers = nntpgrab_utils_regex_compile(".*\\.[vV][oO][lL](\\d+)\\+(\\d+)\\.[pP][aA][rR]2$");
147
                }
148

                
149
                values_par2 = nntpgrab_utils_regex_match(re_par2_blocknumbers, values[2]);
150
                if (values_par2 && values_par2[0] && values_par2[1] && values_par2[2]) {
151
                    if (par2_startnum) {
152
                        *par2_startnum = atoi(values_par2[1]);
153
                    }
154

                
155
                    if (num_par2_blocks) {
156
                        *num_par2_blocks = atoi(values_par2[2]);
157
                    }
158

                
159
                    nntpgrab_utils_regex_matches_free(values_par2);
160
                }
161
            }
162
        }
163
    }
164

                
165
    if (part_num) {
166
        *part_num = atoi(values[4]);
167
    }
168

                
169
    if (total_parts) {
170
        *total_parts = atoi(values[5]);
171
    }
172

                
173
    nntpgrab_utils_regex_matches_free(values);
174

                
175
    return TRUE;
176
}
177

                
178
NNTPFileType
179
nntpgrab_utils_get_file_type_of_filename(const char *filename)
180
{
181
    char *filename_tmp = g_strdup_printf("%s.", filename);
182
    char *ptr = g_strrstr(filename_tmp, ".");
183
    NNTPFileType type = NNTP_FILE_TYPE_UNKNOWN;
184

                
185
    while (ptr) {
186
        if (!g_strncasecmp(ptr + 1, "rar.", 4)) {
187
            type = NNTP_FILE_TYPE_RAR;
188
            break;
189
        } else if (!g_strncasecmp(ptr + 1, "par2.", 5)) {
190
            type = NNTP_FILE_TYPE_PAR2;
191
            break;
192
        } else if (!g_strncasecmp(ptr + 1, "par.", 4)) {
193
            type = NNTP_FILE_TYPE_PAR;
194
            break;
195
        } else if (!g_strncasecmp(ptr + 1, "sfv.", 4)) {
196
            type = NNTP_FILE_TYPE_SFV;
197
            break;
198
        } else if (!g_strncasecmp(ptr + 1, "nfo.", 4)) {
199
            type = NNTP_FILE_TYPE_NFO;
200
            break;
201
        } else if (!g_strncasecmp(ptr + 1, "nzb.", 4)) {
202
            type = NNTP_FILE_TYPE_NZB;
203
            break;
204
        }
205

                
206
        ptr = g_strrstr_len(filename_tmp, ptr - filename_tmp - 1, ".");
207
    }
208

                
209
    g_free(filename_tmp);
210

                
211
    return type;
212
}
213

                
214
void
215
nntpgrab_utils_calculate_file_size(nguint64 file_size, char *file_size_str, int file_size_str_len)
216
{
217
    double d_file_size;
218

                
219
    d_file_size = (double) file_size;
220
    if (d_file_size < 1024) {
221
        snprintf(file_size_str, file_size_str_len, "%.1f bytes", d_file_size);
222
        return;
223
    }
224

                
225
    d_file_size /= 1024;
226
    if (d_file_size < 1024) {
227
        snprintf(file_size_str, file_size_str_len, "%.1f KB", d_file_size);
228
        return;
229
    }
230

                
231
    d_file_size /= 1024;
232
    if (d_file_size < 1024) {
233
        snprintf(file_size_str, file_size_str_len, "%.1f MB", d_file_size);
234
        return;
235
    }
236

                
237
    d_file_size /= 1024;
238
    snprintf(file_size_str, file_size_str_len, "%.1f GB", d_file_size);
239
}
240

                
241
int
242
nntpgrab_utils_calculate_estimated_time_remaining(int bytes_received1, int bytes_received2, int bytes_received3, int bytes_received4, int bytes_received5, int bytes_received6, int bytes_received7, int bytes_received8, int bytes_received9, int bytes_received10, nguint64 file_size)
243
{
244
    int bytes_per_sec_avg;
245
    guint64 ret;
246

                
247
    // calculate the average speed of the last 10 seconds
248
    bytes_per_sec_avg  = bytes_received1;
249
    bytes_per_sec_avg += bytes_received2;
250
    bytes_per_sec_avg += bytes_received3;
251
    bytes_per_sec_avg += bytes_received4;
252
    bytes_per_sec_avg += bytes_received5;
253
    bytes_per_sec_avg += bytes_received6;
254
    bytes_per_sec_avg += bytes_received7;
255
    bytes_per_sec_avg += bytes_received8;
256
    bytes_per_sec_avg += bytes_received9;
257
    bytes_per_sec_avg += bytes_received10;
258
    bytes_per_sec_avg /= 10;
259

                
260
    // Is there any data received in the last 10 seconds?
261
    if (bytes_per_sec_avg == 0) {
262
        return -1;
263
    }
264

                
265
    // Don't make an estimation when there hasn't been much data seen in the last 10 seconds
266
    if (bytes_per_sec_avg < 2048) {
267
        return -1;
268
    }
269

                
270
    ret = file_size / bytes_per_sec_avg;
271

                
272
    return (int) ret;
273
}
274

                
275
void
276
nntpgrab_utils_get_readable_time_remaining(int estimated_time_remaining, char *time_remaining_str, int time_remaining_str_len)
277
{
278
    int num_days;
279
    int num_hours;
280
    int num_minutes;
281
    int num_seconds;
282
    int left;
283
    char days[64];
284
    char hours[64];
285
    char minutes[64];
286
    char seconds[64];
287

                
288
    if (estimated_time_remaining <= 0) {
289
        time_remaining_str[0] = '\0';
290
        return;
291
    }
292

                
293
    memset(&days, 0, sizeof(days));
294
    memset(&hours, 0, sizeof(hours));
295
    memset(&minutes, 0, sizeof(minutes));
296
    memset(&seconds, 0, sizeof(seconds));
297

                
298
    num_days = estimated_time_remaining / 86400;
299
    left = estimated_time_remaining % 86400;
300

                
301
    num_hours = left / 3600;
302
    left %= 3600;
303

                
304
    num_minutes = left / 60;
305
    num_seconds = left % 60;
306

                
307
    if (num_days == 0) {
308
        /* Do nothing */
309
    } else if (num_days == 1) {
310
        snprintf(days, sizeof(days) - 1, _("%i day"), num_days);
311
    } else  {
312
        snprintf(days, sizeof(days) - 1, _("%i days"), num_days);
313
    }
314

                
315
    if (num_hours == 1) {
316
        snprintf(hours, sizeof(hours) - 1, _("1 hour"));
317
    } else {
318
        snprintf(hours, sizeof(hours) - 1, _("%i hours"), num_hours);
319
    }
320

                
321
    if (num_minutes == 1) {
322
        snprintf(minutes, sizeof(minutes) - 1, _("1 minute"));
323
    } else {
324
        snprintf(minutes, sizeof(minutes) - 1, _("%i minutes"), num_minutes);
325
    }
326

                
327
    if (num_seconds == 0 || num_days > 0) {
328
        /* Do nothing */
329
    } else if (num_seconds == 1) {
330
        snprintf(seconds, sizeof(seconds) - 1, _("1 second"));
331
    } else {
332
        snprintf(seconds, sizeof(seconds) - 1, _("%i seconds"), num_seconds);
333
    }
334

                
335
    if (num_days > 0) {
336
        snprintf(time_remaining_str, time_remaining_str_len, "%s %s %s", days, hours, minutes);
337
    } else {
338
        if (num_hours == 0) {
339
            if (num_seconds == 0) {
340
                snprintf(time_remaining_str, time_remaining_str_len, "%s", minutes);
341
            } else {
342
                snprintf(time_remaining_str, time_remaining_str_len, "%s %s", minutes, seconds);
343
            }
344
        } else {
345
            if (num_seconds == 0) {
346
                snprintf(time_remaining_str, time_remaining_str_len, "%s %s", hours, minutes);
347
            } else {
348
                snprintf(time_remaining_str, time_remaining_str_len, "%s %s %s", hours, minutes, seconds);
349
            }
350
        }
351
    }
352
}
353

                
354
void
355
nntpgrab_utils_get_readable_finished_time(int estimated_time_remaining, char *time_remaining_str, int time_remaining_str_len)
356
{
357
    struct tm *now;
358
    time_t stamp;
359
    static int nugrft_once = 0;
360

                
361
    if (estimated_time_remaining <= 0) {
362
        time_remaining_str[0] = '\0';
363
        return;
364
    }
365

                
366
    stamp = time(NULL) + estimated_time_remaining;
367

                
368
    if ((now = localtime(&stamp)) == NULL) {
369
        // Date could not be parsed
370
        time_remaining_str[0] = '\0';
371
        return;
372
    }
373

                
374
    if (strftime(time_remaining_str, time_remaining_str_len, "%c", now) == 0) {
375
        if (!nugrft_once) {
376
            g_error(__FILE__ ":%i buffer too small", __LINE__);
377
            nugrft_once = 1;
378
        }
379
    }
380
}
381

                
382
void
383
nntpgrab_utils_get_readable_time_stamp(time_t stamp, char *stamp_str, int stamp_str_len)
384
{
385
    struct tm *now;
386
    static int nugrft_once = 0;
387

                
388
    if (stamp <= 0) {
389
        stamp_str[0] = '\0';
390
        return;
391
    }
392

                
393
    if ((now = localtime(&stamp)) == NULL) {
394
        // Date could not be parsed
395
        stamp_str[0] = '\0';
396
        return;
397
    }
398

                
399
    if (strftime(stamp_str, stamp_str_len, "%c", now) == 0) {
400
        if (!nugrft_once) {
401
            g_error(__FILE__ ":%i buffer too small", __LINE__);
402
            nugrft_once = 1;
403
        }
404
    }
405
}
406

                
407
static gint
408
sort_folders_func(gconstpointer a, gconstpointer b)
409
{
410
    const NNTPGrabFolder *folderA = a;
411
    const NNTPGrabFolder *folderB = b;
412

                
413
    if (a == NULL) {
414
        return 1;
415
    }
416

                
417
    if (b == NULL) {
418
        return 1;
419
    }
420

                
421
    return g_strcasecmp(folderA->folder, folderB->folder);
422
}
423

                
424
/** 
425
 * Retrieve all the folders which belong to path
426
 *
427
 * @param parent        The path whose belonging folders should be looked up. If NULL, all the drive letters will be returned (on Win32) or "/" is returned (*nix/osx)
428
 * @param folders       Return address for a list containing g_slice_new'ed ConfigFolder structures containing the requested info
429
 *
430
 * @return              FALSE when the given parent is invalid
431
 */
432
ngboolean
433
nntpgrab_utils_get_folder_listing(const char *parent, NGList **folders)
434
{
435
    GDir *dir;
436
    const char *filename;
437
#ifdef WIN32
438
    char *tmp;
439
#endif
440

                
441
    g_assert(folders);
442

                
443
    *folders = NULL;
444

                
445
    if (!parent) {
446
#ifdef WIN32
447
        DWORD logicalDrives = GetLogicalDrives() << 1;
448
        int i = 1;
449
        char driveLetter = 'A';
450

                
451
        while(driveLetter <= 'Z') {
452
            char *path;
453

                
454
            if(logicalDrives & (int)pow(2,i)) {
455
                GDir *dir;
456
                NNTPGrabFolder *folder = g_slice_new0(NNTPGrabFolder);
457

                
458
                path = g_strdup_printf("%c:\\", driveLetter);
459

                
460
#ifdef WIN32
461
                // Prevent the message 'No disk in drive' by checking via another method if
462
                // the given path is reachable
463
                if (!PathFileExistsA(path)) {
464
                    i++;
465
                    driveLetter++;
466
                    g_slice_free(NNTPGrabFolder, folder);
467
                    g_free(path);
468
                    continue;
469
                }
470
#endif
471

                
472
                dir = g_dir_open(path, 0, NULL);
473

                
474
                folder->has_subfolders = FALSE;
475

                
476
                if (dir) {
477
                    const char *filename;
478
                    while ((filename = g_dir_read_name(dir))) {
479
                        char *path2 = g_build_filename(path, filename, NULL);
480
                        if (g_file_test(path2, G_FILE_TEST_IS_DIR)) {
481
                            folder->has_subfolders = TRUE;
482
                        }
483
                        g_free(path2);
484
                    }
485
                    g_dir_close(dir);
486
                }
487

                
488
                // Strip the \ character from the path
489
                path[strlen(path) - 1] = '\0';
490
                strncpy(folder->folder, path, sizeof(folder->folder) - 1);
491

                
492
                *folders = ng_list_append(*folders, folder);
493

                
494
                g_free(path);
495
            }
496

                
497
            i++;
498
            driveLetter++;
499
        }
500

                
501
        return TRUE;
502
#else
503
        NNTPGrabFolder *folder = g_slice_new0(NNTPGrabFolder);
504
        folder->has_subfolders = TRUE;      // There's no need to test this as there is always a root directory containing subdirectories
505
        folder->folder[0] = '/';
506
        folder->folder[1] = '\0';
507
        *folders = ng_list_append(*folders, folder);
508
        return TRUE;
509
#endif
510
    }
511

                
512
#ifdef WIN32
513
    if (strlen(parent) == 2) {
514
        tmp = g_strdup_printf("%s\\", parent);
515
    } else {
516
        tmp = g_strdup(parent);
517
    }
518
    dir = g_dir_open(tmp, 0, NULL);
519
    g_free(tmp);
520
#else
521
    dir = g_dir_open(parent, 0, NULL);
522
#endif
523
    if (!dir) {
524
        return FALSE;
525
    }
526

                
527
    while ((filename = g_dir_read_name(dir))) {
528
        // Is this a directory ?
529
        char *path = g_build_filename(parent, filename, NULL);
530
        if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
531
            GDir *dir2 = g_dir_open(path, 0, NULL);
532
            if (dir2) {
533
                NNTPGrabFolder *folder = g_slice_new0(NNTPGrabFolder);
534
                const char *filename2;
535

                
536
                folder->has_subfolders = FALSE;
537
                while ((filename2 = g_dir_read_name(dir2))) {
538
                    char *path2 = g_build_filename(parent, filename, filename2, NULL);
539
                    if (g_file_test(path2, G_FILE_TEST_IS_DIR)) {
540
                        folder->has_subfolders = TRUE;
541
                        g_free(path2);
542
                        break;
543
                    }
544
                    g_free(path2);
545
                }
546
                g_dir_close(dir2);
547

                
548
                strncpy(folder->folder, filename, sizeof(folder->folder) - 1);
549

                
550
                *folders = ng_list_append(*folders, folder);
551
            }
552
        }
553
        g_free(path);
554
    }
555

                
556
    g_dir_close(dir);
557

                
558
    *folders = (NGList*) g_list_sort((GList*) *folders, sort_folders_func);
559

                
560
    return TRUE;
561
}
562

                
563
void
564
nntpgrab_utils_free_folder_listing(NGList *folders)
565
{
566
    NGList *list = folders;
567
    while (list) {
568
        g_slice_free(NNTPGrabFolder, list->data);
569
        list = ng_list_next(list);
570
    }
571
    ng_list_free(folders);
572
}
573

                
574
void
575
nntpgrab_utils_sanitize_text(char *text, int length)
576
{
577
    char *ptr = text;
578
    char *end = NULL;
579

                
580
    while (!g_utf8_validate(ptr, length, (const char**) &end)) {
581
        // Invalid character found, replace it with an ' '
582
        *end = ' ';
583
        length = length - (end - ptr) - 1;
584
        ptr = end + 1;
585
    }
586
}
587

                
588
void
589
nntpgrab_utils_sanitize_collection_name(char *collection_name)
590
{
591
    // Strip out any of the following characters from the collection_name: *!"'()/\[] and the tab character
592
    char *ptr = collection_name;
593
    while ((ptr = strstr(ptr, "*"))) {
594
        *ptr = ' ';
595
        ptr++;
596
    }
597
    ptr = collection_name;
598
    while ((ptr = strstr(ptr, "!"))) {
599
        *ptr = ' ';
600
        ptr++;
601
    }
602
    ptr = collection_name;
603
    while ((ptr = strstr(ptr, "\""))) {
604
        *ptr = ' ';
605
        ptr++;
606
    }
607
    ptr = collection_name;
608
    while ((ptr = strstr(ptr, "/"))) {
609
        *ptr = ' ';
610
        ptr++;
611
    }
612
    ptr = collection_name;
613
    while ((ptr = strstr(ptr, "\\"))) {
614
        *ptr = ' ';
615
        ptr++;
616
    }
617
    ptr = collection_name;
618
    while ((ptr = strstr(ptr, "'"))) {
619
        *ptr = ' ';
620
        ptr++;
621
    }
622
    ptr = collection_name;
623
    while ((ptr = strstr(ptr, "("))) {
624
        *ptr = ' ';
625
        ptr++;
626
    }
627
    ptr = collection_name;
628
    while ((ptr = strstr(ptr, ")"))) {
629
        *ptr = ' ';
630
        ptr++;
631
    }
632
    ptr = collection_name;
633
    while ((ptr = strstr(ptr, ":"))) {
634
        *ptr = ' ';
635
        ptr++;
636
    }
637
    ptr = collection_name;
638
    while ((ptr = strstr(ptr, "["))) {
639
        *ptr = ' ';
640
        ptr++;
641
    }
642
    ptr = collection_name;
643
    while ((ptr = strstr(ptr, "]"))) {
644
        *ptr = ' ';
645
        ptr++;
646
    }
647
    ptr = collection_name;
648
    while ((ptr = strstr(ptr, "<"))) {
649
        *ptr = ' ';
650
        ptr++;
651
    }
652
    ptr = collection_name;
653
    while ((ptr = strstr(ptr, ">"))) {
654
        *ptr = ' ';
655
        ptr++;
656
    }
657
    ptr = collection_name;
658
    while ((ptr = strstr(ptr, "\t"))) {
659
        *ptr = ' ';
660
        ptr++;
661
    }
662

                
663
    // Strip any whitespace at the beginning and end
664
    g_strstrip(collection_name);
665
}
666

                
667
void
668
nntpgrab_utils_strip_nzb_extension(char *filename)
669
{
670
    char *tmp;
671

                
672
    tmp = strstr(filename, ".nzb");
673
    if (tmp) {
674
        tmp[0] = '\0';
675
    }
676

                
677
    tmp = strstr(filename, ".NZB");
678
    if (tmp) {
679
        tmp[0] = '\0';
680
    }
681
}
682

                
683
ngboolean
684
nntpgrab_utils_extract_par2set_name_from_par2_filename(const char *par2filename, char *par2set, int par2set_length)
685
{
686
    static NGRegex *re_par2_filename = NULL;
687
    const char **values_par2;
688

                
689
    g_return_val_if_fail(par2filename != NULL, FALSE);
690
    g_return_val_if_fail(par2set != NULL, FALSE);
691
    g_return_val_if_fail(par2set_length > 0, FALSE);
692

                
693
    if (!re_par2_filename) {
694
        re_par2_filename = nntpgrab_utils_regex_compile("(.*?)(\\.[vV][oO][lL]\\d+\\+\\d+)?\\.[pP][aA][rR]2$");
695
    }
696

                
697
    values_par2 = nntpgrab_utils_regex_match(re_par2_filename, par2filename);
698
    if (!(values_par2 && values_par2[0] && values_par2[1])) {
699
        if (values_par2) {
700
            nntpgrab_utils_regex_matches_free(values_par2);
701
        }
702

                
703
        return FALSE;
704
    }
705

                
706
    strncpy(par2set, values_par2[1], par2set_length);
707
    nntpgrab_utils_regex_matches_free(values_par2);
708

                
709
    return TRUE;
710
}
711

                
712
ngboolean
713
nntpgrab_utils_test_is_server_already_running(void)
714
{
715
    int sock = -1;
716
    char *str_port;
717
    struct addrinfo hints, *res, *ressave;
718
    int n;
719

                
720
    memset(&hints, 0, sizeof(struct addrinfo));
721

                
722
    hints.ai_family = AF_UNSPEC;
723
    hints.ai_socktype = SOCK_STREAM;
724

                
725
    str_port = g_strdup_printf("%i", 5423);
726
    n = getaddrinfo("localhost", str_port, &hints, &res);
727
    g_free(str_port);
728

                
729
    /* If 'localhost' could not be resolved, something is wrong with the user's network configuration */
730
    if (n < 0) {
731
        fprintf(stderr,
732
                "getaddrinfo error:: [%s]\n",
733
#ifdef WIN32
734
                WSAGetLastError());
735
#else
736
                gai_strerror(n));
737
#endif
738
        g_return_val_if_fail(n == 0, FALSE);    /* This always fails */
739
    }
740

                
741
    ressave = res;
742

                
743
    while (res) {
744
        sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
745

                
746
#ifdef WIN32
747
        if ((sock == INVALID_SOCKET)) {
748
#else
749
        if ((sock == -1)) {
750
#endif
751
            // The socket couldn't be created
752
            res = res->ai_next;
753
            continue;
754
        }
755

                
756
        if (connect(sock, res->ai_addr, (int) res->ai_addrlen) == 0) {
757
            // Connection succesfull
758
            break;
759
        }
760

                
761
        CLOSE(sock);
762
        sock = -1;
763

                
764
        res = res->ai_next;
765
    }
766

                
767
    if (sock == -1) {
768
        freeaddrinfo(ressave);
769

                
770
        return FALSE;
771
    }
772

                
773
    freeaddrinfo(ressave);
774

                
775
    CLOSE(sock);
776

                
777
    return TRUE;
778
}