~ubuntu-branches/debian/jessie/arb/jessie

« back to all changes in this revision

Viewing changes to NAMES/names.cxx

  • Committer: Package Import Robot
  • Author(s): Elmar Pruesse, Andreas Tille, Elmar Pruesse
  • Date: 2014-09-02 15:15:06 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20140902151506-jihq58b3iz342wif
Tags: 6.0.2-1
[ Andreas Tille ]
* New upstream version
  Closes: #741890
* debian/upstream -> debian/upstream/metadata
* debian/control:
   - Build-Depends: added libglib2.0-dev
   - Depends: added mafft, mrbayes
* debian/rules
   - Add explicite --remove-section=.comment option to manual strip call
* cme fix dpkg-control
* arb-common.dirs: Do not create unneeded lintian dir
* Add turkish debconf translation (thanks for the patch to Mert Dirik
  <mertdirik@gmail.com>)
  Closes: #757497

[ Elmar Pruesse ]
* patches removed:
   - 10_config.makefiles.patch,
     80_no_GL.patch
       removed in favor of creating file from config.makefile.template via 
       sed in debian/control
   - 20_Makefile_main.patch
       merged upstream
   - 21_Makefiles.patch
       no longer needed
   - 30_tmpfile_CVE-2008-5378.patch: 
       merged upstream
   - 50_fix_gcc-4.8.patch:
       merged upstream
   - 40_add_libGLU.patch:
       libGLU not needed for arb_ntree)
   - 60_use_debian_packaged_raxml.patch:
       merged upstream
   - 70_hardening.patch
       merged upstream
   - 72_add_math_lib_to_linker.patch
       does not appear to be needed
* patches added:
   - 10_upstream_r12793__show_db_load_progress:
       backported patch showing progress while ARB is loading a database
       (needed as indicator/splash screen while ARB is launching)
   - 20_upstream_r12794__socket_permissions:
       backported security fix
   - 30_upstream_r12814__desktop_keywords:
       backported add keywords to desktop (fixes lintian warning)
   - 40_upstream_r12815__lintian_spelling:
       backported fix for lintian reported spelling errors
   - 50_private_nameservers
       change configuration to put nameservers into users home dirs
       (avoids need for shared writeable directory)
   - 60_use_debian_phyml
       use phyml from debian package for both interfaces in ARB
* debian/rules:
   - create config.makefile from override_dh_configure target
   - use "make tarfile" in override_dh_install
   - remove extra cleaning not needed for ARB 6
   - use "dh_install --list-missing" to avoid missing files
   - added override_dh_fixperms target
* debian/control:
   - added libarb-dev package
   - Depends: added phyml, xdg-utils
   - Suggests: removed phyml
   - fix lintian duplicate-short-description (new descriptions)
* debian/*.install:
   - "unrolled" confusing globbing to select files
   - pick files from debian/tmp
   - moved all config files to /etc/arb
* debian/arb-common.templates: updated
* scripts:
   - removed arb-add-pt-server
   - launch-wrapper: 
     - only add demo.arb to newly created $ARBUSERDATA
     - pass commandline arguments through bin/arb wrapper
   - preinst: removing old PT server index files on upgrade from 5.5*
   - postinst: set setgid on shared PT dir
* rewrote arb.1 manfile
* added file icon for ARB databases
* using upstream arb_tcp.dat

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <stdio.h>
2
 
#include <string.h>
3
 
#include <stdlib.h>
4
 
#include <unistd.h>
5
 
#include <ctype.h>
 
1
// ============================================================= //
 
2
//                                                               //
 
3
//   File      : names.cxx                                       //
 
4
//   Purpose   :                                                 //
 
5
//                                                               //
 
6
//   Institute of Microbiology (Technical University Munich)     //
 
7
//   http://www.arb-home.de/                                     //
 
8
//                                                               //
 
9
// ============================================================= //
6
10
 
7
11
#include <names_server.h>
8
12
#include <names_client.h>
9
13
#include "names.h"
 
14
 
10
15
#include <arbdb.h>
 
16
#include <arb_file.h>
 
17
#include <arb_sleep.h>
 
18
 
11
19
#include <names_prototypes.h>
12
20
#include <server.h>
13
21
#include <client.h>
14
22
#include <servercntrl.h>
15
23
#include <struct_man.h>
16
24
 
 
25
#include <unistd.h>
 
26
#include <cctype>
17
27
#include <list>
18
28
#include <string>
19
29
 
 
30
#define na_assert(cond) arb_assert(cond)
 
31
 
 
32
#define FULLNAME_LEN_MAX 64
 
33
#define NAME_LEN_MIN 2
 
34
 
20
35
using namespace std;
21
36
 
22
37
// --------------------------------------------------------------------------------
33
48
// #define DUMP_NAME_CREATION
34
49
#endif // DEBUG
35
50
 
36
 
#define UPPERCASE(c) do{ (c) = toupper(c); }while(0)
 
51
#define UPPERCASE(c) do { (c) = toupper(c); } while (0)
37
52
 
38
53
// --------------------------------------------------------------------------------
39
54
 
40
 
struct AN_gl_struct  AN_global;
41
 
AN_main             *aisc_main; /* muss so heissen */
 
55
struct AN_gl_struct {
 
56
    aisc_com  *cl_link;
 
57
    Hs_struct *server_communication;
 
58
    T_AN_MAIN  cl_main;
 
59
    char      *server_name;
 
60
};
 
61
 
 
62
 
 
63
static struct AN_gl_struct  AN_global;
 
64
AN_main             *aisc_main; // muss so heissen
42
65
 
43
66
const int SERVER_VERSION = 5;
44
67
 
77
100
static AN_revers *lookup_an_revers(AN_main *main, const char *shortname) {
78
101
    char      *key        = an_strlwr(strdup(shortname));
79
102
    AN_revers *an_reverse = (AN_revers*)aisc_find_lib(&main->prevers, key);
80
 
    
 
103
 
81
104
    free(key);
82
105
 
83
106
    return an_reverse;
114
137
        AN_shorts *sin       = aisc_main->shorts1;
115
138
        size_t     elems     = an_shorts_elems(sin);
116
139
        if (elems<100) elems = 100;
117
 
        
118
 
        GB_HASH *hash = GBS_create_hash(2*elems, GB_IGNORE_CASE);
 
140
 
 
141
        GB_HASH *hash = GBS_create_hash(elems, GB_IGNORE_CASE);
119
142
 
120
143
        while (sin) {
121
144
            GBS_write_hash_no_strdup(hash, GB_strndup(sin->shrt, PREFIXLEN), (long)sin);
133
156
    buf[0] = str[0];
134
157
    buf[1] = str[1];
135
158
    buf[2] = str[2];
136
 
    
 
159
 
137
160
    return buf;
138
161
}
139
162
 
143
166
 
144
167
// ----------------------------------------
145
168
 
146
 
static void an_add_short(AN_local *locs, const char *new_name,
 
169
static void an_add_short(const AN_local */*locs*/, const char *new_name,
147
170
                         const char *parsed_name, const char *parsed_sym,
148
171
                         const char *shrt, const char *acc, const char *add_id)
149
172
{
150
173
    AN_shorts *an_shorts;
151
174
    AN_revers *an_revers;
152
175
    char      *full_name;
153
 
    locs = locs;
154
176
 
155
 
    if (strlen(parsed_sym)){
 
177
    if (strlen(parsed_sym)) {
156
178
        full_name = (char *)calloc(sizeof(char), strlen(parsed_name) + strlen(" sym")+1);
157
 
        sprintf(full_name,"%s sym",parsed_name);
 
179
        sprintf(full_name, "%s sym", parsed_name);
158
180
    }
159
181
    else {
160
182
        full_name = strdup(parsed_name);
190
212
       normally removing names does make problems - so use it very rarely */
191
213
 
192
214
    GBS_write_hash(an_get_prefix_hash(), an_make_prefix(an_shorts->shrt), 0); // delete an_shorts from hash
193
 
    
 
215
 
194
216
    AN_revers *an_revers = lookup_an_revers(aisc_main, an_shorts->shrt);
195
217
 
196
218
    if (an_revers) {
197
 
        aisc_unlink((struct_dllheader_ext*)an_revers);
 
219
        aisc_unlink((dllheader_ext*)an_revers);
198
220
 
199
221
        free(an_revers->mh.ident);
200
222
        free(an_revers->full_name);
202
224
        free(an_revers);
203
225
    }
204
226
 
205
 
    aisc_unlink((struct_dllheader_ext*)an_shorts);
 
227
    aisc_unlink((dllheader_ext*)an_shorts);
206
228
 
207
229
    free(an_shorts->mh.ident);
208
230
    free(an_shorts->shrt);
211
233
    free(an_shorts);
212
234
}
213
235
 
214
 
static char *nas_string_2_key(const char *str)
215
 
// converts any string to a valid key
216
 
{
 
236
static char *nas_string_2_name(const char *str) {
 
237
    // converts a string to a valid name
217
238
#if defined(DUMP_NAME_CREATION)
218
239
    const char *org_str = str;
219
240
#endif // DUMP_NAME_CREATION
220
 
    
221
 
    char buf[GB_KEY_LEN_MAX+1];
 
241
 
 
242
    char buf[FULLNAME_LEN_MAX+1];
222
243
    int  i;
223
244
    int  c;
224
 
    for (i=0;i<GB_KEY_LEN_MAX;) {
 
245
    for (i=0; i<FULLNAME_LEN_MAX;) {
225
246
        c                        = *(str++);
226
247
        if (!c) break;
227
248
        if (isalpha(c)) buf[i++] = c;
228
 
        // name should not contain _'s (not compatible with FastDNAml)
229
 
        //else if (c==' ' || c=='_') buf[i++] = '_';
230
249
    }
231
 
    for (;i<GB_KEY_LEN_MIN;i++) buf[i] = '0';
 
250
    for (; i<NAME_LEN_MIN; i++) buf[i] = '0';
232
251
    buf[i] = 0;
233
252
#if defined(DUMP_NAME_CREATION)
234
 
    printf("nas_string_2_key('%s') = '%s'\n", org_str, buf);
 
253
    printf("nas_string_2_name('%s') = '%s'\n", org_str, buf);
235
254
#endif // DUMP_NAME_CREATION
236
255
    return strdup(buf);
237
256
}
240
259
#if defined(DUMP_NAME_CREATION)
241
260
    const char *org_str = str;
242
261
#endif // DUMP_NAME_CREATION
243
 
    char buf[GB_KEY_LEN_MAX+1];
 
262
    char buf[FULLNAME_LEN_MAX+1];
244
263
    int i;
245
264
    int c;
246
265
 
247
 
    for (i=0; i<GB_KEY_LEN_MAX; ) {
 
266
    for (i=0; i<FULLNAME_LEN_MAX;) {
248
267
        c = *str++;
249
268
        if (!c) break;
250
269
        if (strchr("aeiouy", c)==0) {
251
270
            buf[i++] = c;
252
271
        }
253
272
    }
254
 
    for (; i<GB_KEY_LEN_MIN; i++) buf[i] = '0';
 
273
    for (; i<NAME_LEN_MIN; i++) buf[i] = '0';
255
274
    buf[i] = 0;
256
275
#if defined(DUMP_NAME_CREATION)
257
276
    printf("nas_remove_small_vocals('%s') = '%s'\n", org_str, buf);
269
288
        shrt[len++] = c;
270
289
    }
271
290
 
272
 
    while (len<GB_KEY_LEN_MIN) {
 
291
    while (len<NAME_LEN_MIN) {
273
292
        shrt[len++] = '0';
274
293
    }
275
294
 
317
336
    }
318
337
}
319
338
 
320
 
static char *an_get_short(AN_shorts *IF_DEBUG(shorts), dll_public *parent, const char *full){
 
339
static char *an_get_short(AN_shorts *IF_ASSERTION_USED(shorts), dll_public *parent, const char *full) {
321
340
    AN_shorts *look;
322
341
 
323
 
    gb_assert(full);
324
 
    gb_assert(shorts == aisc_main->shorts1); // otherwise prefix_hash does not work!
325
 
 
326
 
    if (full[0]==0) {
327
 
        return strdup("Xxx");
328
 
    }
329
 
 
330
 
    char *result = 0;
 
342
    na_assert(full);
 
343
    na_assert(shorts == aisc_main->shorts1); // otherwise prefix_hash does not work!
 
344
 
 
345
    if (full[0]==0) return strdup("ZZZ");
 
346
 
 
347
    const char *result = 0;
331
348
    char *full1  = strdup(full);
332
349
    an_autocaps(full1);
333
350
 
334
 
    char *full2 = nas_string_2_key(full1);
 
351
    char *full2 = nas_string_2_name(full1);
335
352
 
336
 
    look = (AN_shorts *)aisc_find_lib((struct_dllpublic_ext*)parent, full2);
337
 
    if (look) {                 /* name is already known */
 
353
    look = (AN_shorts *)aisc_find_lib((dllpublic_ext*)parent, full2);
 
354
    if (look) {                 // name is already known
338
355
        free(full2);
339
356
        free(full1);
340
357
        return strdup(look->shrt);
347
364
 
348
365
    // try first three letters:
349
366
 
350
 
    strncpy(shrt,full2,3);
 
367
    strncpy(shrt, full2, 3);
351
368
    UPPERCASE(shrt[0]);
352
369
    shrt[3] = 0;
353
370
 
375
392
        }
376
393
    }
377
394
 
378
 
    // generate names from first char + all characters:
 
395
    // generate names from first char + rest characters:
379
396
 
380
397
    len2 = strlen(full2);
381
398
    for (p1=1; p1<(len2-1); p1++) {
390
407
        }
391
408
    }
392
409
 
393
 
    // generate names containing first char + characters from name + one digit:
 
410
    // generate names containing first char + character from name + one digit:
394
411
 
395
412
    for (p1=1; p1<len2; p1++) {
396
413
        shrt[1] = full2[p1];
416
433
        }
417
434
    }
418
435
 
419
 
    // generate names containing 1 random character + 2 digits:
420
 
 
421
 
    for (p1='A'; p1<='Z'; p1++) {
422
 
        shrt[0] = p1;
423
 
        for (p2=0; p2<=99; p2++) {
424
 
            shrt[1] = '0'+(p2/10);
425
 
            shrt[2] = '0'+(p2%10);
426
 
            look = an_find_shrt_prefix(shrt);
427
 
            if (!look) {
428
 
                an_complete_shrt(shrt, full2);
429
 
                goto found_short;
430
 
            }
431
 
        }
432
 
    }
433
 
 
434
 
    // generate names containing 2 random characters + 1 digit:
435
 
 
436
 
    for (p1='A'; p1<='Z'; p1++) {
437
 
        shrt[0] = p1;
438
 
        for (p2='a'; p2<='z'; p2++) {
439
 
            shrt[1] = p2;
440
 
            for (p3=0; p3<=9; p3++) {
441
 
                shrt[2] = '0'+p3;
442
 
                look = an_find_shrt_prefix(shrt);
443
 
                if (!look) {
444
 
                    an_complete_shrt(shrt, full2);
445
 
                    goto found_short;
446
 
                }
447
 
            }
448
 
        }
449
 
    }
450
 
 
451
 
    // generate names containing 3 random characters:
452
 
 
453
 
    for (p1='A'; p1<='Z'; p1++) {
454
 
        shrt[0] = p1;
455
 
        for (p2='a'; p2<='z'; p2++) {
456
 
            shrt[1] = p2;
457
 
            for (p3='a'; p3<='z'; p3++) {
458
 
                shrt[2] = p3;
459
 
                look = an_find_shrt_prefix(shrt);
460
 
                if (!look) {
461
 
                    an_complete_shrt(shrt, full2);
462
 
                found_short:
463
 
                    result = shrt;
464
 
                    goto done;
465
 
                }
466
 
            }
467
 
        }
468
 
    }
469
 
 
470
 
 done: 
 
436
    // failed to produce sth with given name, generate something random now
 
437
 
 
438
    {
 
439
        // use digits first, then use upper-case alpha (methods above use lower-case alpha)
 
440
        const char *allowed = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
441
        const int   len     = 36;
 
442
 
 
443
        for (p1='A'; p1<='Z'; p1++) { // first character has to be alpha
 
444
            shrt[0] = p1;
 
445
            for (p2 = 0; p2<len; p2++) {
 
446
                shrt[1] = allowed[p2];
 
447
                for (p3 = 0; p3<len; p3++) {
 
448
                    shrt[2] = allowed[p3];
 
449
                    look = an_find_shrt_prefix(shrt);
 
450
                    if (!look) {
 
451
                        an_complete_shrt(shrt, full2);
 
452
                        goto found_short;
 
453
                    }
 
454
                }
 
455
            }
 
456
        }
 
457
    }
 
458
 
 
459
    shrt[0] = 0; // erase result
471
460
    
472
 
    if (result) {
 
461
 found_short :
 
462
    result = shrt;
 
463
 
 
464
    if (result && result[0]) {
473
465
#if defined(DUMP_NAME_CREATION)
474
466
        if (isdigit(result[0]) || isdigit(result[1])) {
475
467
            printf("generated new short-name '%s' for full-name '%s' full2='%s' full3='%s'\n", shrt, full, full2, full3);
479
471
        look           = create_AN_shorts();
480
472
        look->mh.ident = strdup(full2);
481
473
        look->shrt     = strdup(result);
482
 
        aisc_link((struct_dllpublic_ext*)parent,(struct_dllheader_ext*)look);
483
 
        
 
474
        aisc_link((dllpublic_ext*)parent, (dllheader_ext*)look);
 
475
 
484
476
        aisc_main->touched = 1;
485
477
    }
486
478
    else {
487
479
        printf("ARB_name_server: Failed to make a short-name for '%s'\n", full);
 
480
        result = "ZZZ";
488
481
    }
489
482
 
490
483
    free(full3);
498
491
 
499
492
static const char *default_full_name = "No name";
500
493
 
501
 
class NameInformation {
 
494
class NameInformation : virtual Noncopyable {
502
495
    const char *full_name;
503
496
 
504
497
    char *parsed_name;
512
505
    char *id;
513
506
 
514
507
public:
515
 
    NameInformation(AN_local *locs);
 
508
    NameInformation(const AN_local *locs);
516
509
    ~NameInformation();
517
510
 
518
511
    const char *get_id() const { return id; }
520
513
    const char *get_first_name() const { return first_name; }
521
514
    const char *get_rest_of_name() const { return rest_of_name; }
522
515
 
523
 
    void add_short(AN_local *locs, const char *shrt) const {
524
 
        if (strlen(parsed_name)>3) {
525
 
            an_add_short(locs, id, parsed_name, parsed_sym, shrt, parsed_acc, parsed_add_id);
526
 
        }
 
516
    void add_short(const AN_local *locs, const char *shrt) const {
 
517
        an_add_short(locs, id, parsed_name, parsed_sym, shrt, parsed_acc, parsed_add_id);
527
518
    }
528
519
};
529
520
 
564
555
}
565
556
 
566
557
#if defined(DEBUG)
567
 
#define assert_alnum(s) gb_assert(stralnum(s))
 
558
#define assert_alnum(s) na_assert(stralnum(s))
568
559
#else
569
560
#define assert_alnum(s)
570
561
#endif // DEBUG
571
562
 
572
 
NameInformation::NameInformation(AN_local *locs) {
 
563
NameInformation::NameInformation(const AN_local *locs) {
573
564
    full_name = locs->full_name;
574
565
    if (!full_name || !full_name[0]) full_name = default_full_name;
575
566
 
576
567
    parsed_name = GBS_string_eval(full_name,
577
568
                                  "\t= :\"= :'= :" // replace TABs and quotes by space
578
 
                                  "sp.=species:spec.=species:SP.=SPECIES:SPEC.=SPECIES:" // replace common abbreviations of 'species' 
 
569
                                  "sp.=species:spec.=species:SP.=SPECIES:SPEC.=SPECIES:" // replace common abbreviations of 'species'
579
570
                                  ".= :" // replace dots by spaces
580
571
                                  "  = :" // multiple spaces -> 1 space
581
 
                                  "* * *=*1 *2" // skip all beyond 2nd word
582
 
                                  ,0);
 
572
                                  , 0);
 
573
 
 
574
    {
 
575
        int leading_spaces = strspn(parsed_name, " ");
 
576
        int len            = strlen(parsed_name)-leading_spaces;
 
577
        memmove(parsed_name, parsed_name+leading_spaces, len);
 
578
 
 
579
        char *first_space = strchr(parsed_name, ' ');
 
580
        if (first_space) {
 
581
            char *second_space = strchr(first_space+1, ' ');
 
582
            if (second_space) {
 
583
                second_space[0] = 0; // skip all beyond 2nd word
 
584
            }
 
585
        }
 
586
    }
 
587
 
583
588
    an_autocaps(parsed_name);
584
589
 
585
 
    parsed_sym = GBS_string_eval(full_name, "\t= :* * *sym*=S",0);
 
590
    parsed_sym = GBS_string_eval(full_name, "\t= :* * *sym*=S", 0);
586
591
    if (strlen(parsed_sym)>1) freedup(parsed_sym, "");
587
592
 
588
593
    const char *add_id = locs->add_id[0] ? locs->add_id : aisc_main->add_field_default;
589
594
 
590
595
    parsed_acc    = make_alnum(locs->acc);
591
596
    parsed_add_id = make_alnum(add_id);
592
 
    first_name    = GBS_string_eval(parsed_name,"* *=*1",0);
 
597
    first_name    = GBS_string_eval(parsed_name, "* *=*1", 0);
593
598
    rest_of_name  = make_alnum(parsed_name+strlen(first_name));
594
599
 
595
600
    freeset(first_name, make_alnum(first_name));
609
614
 
610
615
NameInformation::~NameInformation() {
611
616
    free(id);
612
 
    
 
617
 
613
618
    free(rest_of_name);
614
619
    free(first_name);
615
620
 
622
627
// --------------------------------------------------------------------------------
623
628
// AISC functions
624
629
 
625
 
extern "C" int del_short(AN_local *locs)
626
 
/* forget about a short name */
627
 
{
 
630
int del_short(const AN_local *locs) {
 
631
    // forget about a short name
628
632
    NameInformation  info(locs);
629
633
    int              removed   = 0;
630
634
    AN_shorts       *an_shorts = lookup_an_shorts(aisc_main, info.get_id());
639
643
 
640
644
static GB_HASH *nameModHash = 0; // key = default name; value = max. counter tested
641
645
 
642
 
extern "C" aisc_string get_short(AN_local *locs)
643
 
/* get the short name from the previously set names */
644
 
{
 
646
aisc_string get_short(const AN_local *locs) {
 
647
    // get the short name from the previously set names
645
648
    static char *shrt = 0;
646
649
 
647
 
    freeset(shrt, 0);
 
650
    freenull(shrt);
648
651
 
649
652
    NameInformation  info(locs);
650
653
    AN_shorts       *an_shorts = lookup_an_shorts(aisc_main, info.get_id());
668
671
            shrt = strdup(an_shorts->shrt);
669
672
        }
670
673
    }
671
 
    if (!shrt) { /* now there is no short name (or an illegal one) */
672
 
        char *first_advice=0,*second_advice=0;
 
674
    if (!shrt) { // now there is no short name (or an illegal one)
 
675
        char *first_advice=0, *second_advice=0;
673
676
 
674
 
        if (locs->advice[0] && !stralnum(locs->advice)) { // bad advice 
 
677
        if (locs->advice[0] && !stralnum(locs->advice)) { // bad advice
675
678
            locs->advice[0] = 0; // delete it
676
679
        }
677
680
 
685
688
            }
686
689
        }
687
690
 
688
 
        if (!first_advice) first_advice = strdup("Xxx");
689
 
        if (!second_advice) second_advice = strdup("Yyyyy");
 
691
        if (!first_advice) first_advice = strdup("ZZZ");
 
692
        if (!second_advice) second_advice = strdup("ZZZZZ");
690
693
 
691
694
        char *first_short;
692
695
        int   first_len;
696
699
                ? an_get_short(aisc_main->shorts1, &(aisc_main->pshorts1), first_name)
697
700
                : strdup(first_advice);
698
701
 
699
 
            gb_assert(first_short);
 
702
            na_assert(first_short);
700
703
            if (first_short[0] == 0) { // empty?
701
 
                freedup(first_short, "Xxx");
 
704
                freedup(first_short, "ZZZ");
702
705
            }
703
706
            first_len = strlen(first_short);
704
707
        }
713
716
                rest_of_name = second_advice;
714
717
                restlen      = strlen(rest_of_name);
715
718
                if (!restlen) {
716
 
                    rest_of_name = "Yyyyy";
 
719
                    rest_of_name = "ZZZZZ";
717
720
                    restlen      = 5;
718
721
                }
719
722
            }
732
735
 
733
736
        if (first_len>3) {
734
737
            first_short[3] = 0;
735
 
            first_len      = 3;;
 
738
            first_len      = 3;
736
739
        }
737
740
 
738
741
        int both_len = first_len+second_len;
749
752
        }
750
753
 
751
754
        char test_short[9];
752
 
        sprintf(test_short,"%s%s", first_short, second_short);
753
 
        
754
 
        gb_assert(size_t(both_len) == strlen(test_short));
755
 
        gb_assert(second_len>=5 && second_len <= 8);
 
755
        sprintf(test_short, "%s%s", first_short, second_short);
 
756
 
 
757
        na_assert(size_t(both_len) == strlen(test_short));
 
758
        na_assert(second_len>=5 && second_len <= 8);
756
759
 
757
760
        if (lookup_an_revers(aisc_main, test_short)) {
758
761
            if (!nameModHash) nameModHash = GBS_create_hash(100, GB_IGNORE_CASE);
772
775
                    int limit     = digLimit[digits];
773
776
 
774
777
                    if (printOffset>maxOffset) printOffset = maxOffset;
775
 
                
 
778
 
776
779
                    char *printAt = test_short+printOffset;
777
780
 
778
781
                    for (; !foundUnused && count <= limit; ++count) {
779
 
                        IF_DEBUG(int printed =) sprintf(printAt, "%li", count);
780
 
                        gb_assert((printed+printOffset) <= 8);
 
782
                        IF_ASSERTION_USED(int printed =) sprintf(printAt, "%li", count);
 
783
                        na_assert((printed+printOffset) <= 8);
781
784
                        if (!lookup_an_revers(aisc_main, test_short)) foundUnused = true; // name does not exist
782
785
                    }
783
786
                }
804
807
                        printAt[4-pos] = base36[rest];
805
808
                        c              = nextc;
806
809
 
807
 
                        gb_assert(pos != 4 || c == 0);
 
810
                        na_assert(pos != 4 || c == 0);
808
811
                    }
809
812
 
810
813
                    if (!lookup_an_revers(aisc_main, test_short)) foundUnused = true; // name does not exist
813
816
                count = count2+100000;
814
817
            }
815
818
 
816
 
            gb_assert(foundUnused);
 
819
            na_assert(foundUnused);
817
820
            GBS_write_hash(nameModHash, test_short_dup, count);
818
821
            GBS_optimize_hash(nameModHash);
819
822
 
835
838
    return shrt;
836
839
}
837
840
 
838
 
extern "C" int server_save(AN_main *main, int dummy)
839
 
{
840
 
    FILE        *file;
841
 
    int error;
842
 
    char        *sec_name;
843
 
    dummy = dummy;
 
841
int server_save(AN_main *main, int) {
844
842
    if (main->touched) {
845
843
        int server_date = GB_time_of_file(main->server_file);
846
844
        if (server_date>main->server_filedate) {
847
845
            printf("Another nameserver changed '%s' - your changes are lost.\n", main->server_file);
848
846
        }
849
847
        else {
850
 
            sec_name = (char *)calloc(sizeof(char), strlen(main->server_file)+2);
851
 
            sprintf(sec_name,"%s%%", main->server_file);
 
848
            char *sec_name = (char *)calloc(sizeof(char), strlen(main->server_file)+2);
 
849
            sprintf(sec_name, "%s%%", main->server_file);
852
850
            printf("Saving '%s'..\n", main->server_file);
853
 
            file     = fopen(sec_name,"w");
 
851
 
 
852
            FILE *file = fopen(sec_name, "w");
854
853
            if (!file) {
855
 
                fprintf(stderr,"ERROR cannot save file '%s'\n",sec_name);
 
854
                fprintf(stderr, "ERROR cannot save file '%s'\n", sec_name);
856
855
            }
857
 
            else { 
858
 
                error = save_AN_main(main,file);
859
 
                fclose(file);
860
 
                if (!error) {
861
 
                    if (GB_rename_file(sec_name, main->server_file)) {
862
 
                        GB_print_error();
863
 
                    }
864
 
                    else {
865
 
                        main->touched = 0;
866
 
                    }
 
856
            else {
 
857
                save_AN_main(main, file);
 
858
                if (fclose(file) == 0) {
 
859
                    GB_ERROR mv_error = GB_rename_file(sec_name, main->server_file);
 
860
                    if (mv_error) GB_warning(mv_error);
 
861
                    else main->touched = 0;
 
862
                }
 
863
                else {
 
864
                    GB_ERROR save_error = GB_IO_error("saving", sec_name);
 
865
                    fprintf(stderr, "Error: %s\n", save_error);
 
866
                    unlink(sec_name);
867
867
                }
868
868
            }
869
869
            free(sec_name);
870
870
            main->server_filedate = GB_time_of_file(main->server_file);
871
 
        }        
 
871
        }
872
872
    }
873
873
    else {
874
874
        printf("No changes to ARB_name_server data.\n");
889
889
    }
890
890
 
891
891
    fprintf(stderr, "<ERROR - list is looped>\n");
892
 
    gb_assert(0);
 
892
    na_assert(0);
893
893
}
894
894
#endif // DEBUG
895
895
 
900
900
    bool case_error_occurred = false;
901
901
    int  idents_changed      = 0;
902
902
    // first check name parts
903
 
    for (AN_shorts *shrt = main->shorts1; shrt; ) {
 
903
    for (AN_shorts *shrt = main->shorts1; shrt;) {
904
904
        AN_shorts *next  = shrt->next;
905
905
        AN_shorts *found = an_find_shrt_prefix(shrt->shrt);
906
906
        if (found != shrt) {
913
913
    }
914
914
 
915
915
    // then check full short-names
916
 
    for (AN_shorts *shrt = main->names; shrt; ) {
 
916
    for (AN_shorts *shrt = main->names; shrt;) {
917
917
        AN_shorts *next  = shrt->next;
918
918
        AN_revers *found = lookup_an_revers(main, shrt->shrt);
919
919
 
934
934
        else {
935
935
            AN_shorts *self_find = lookup_an_shorts(main, shrt->mh.ident);
936
936
            if (!self_find) { // stored with wrong key (not lowercase)
937
 
                aisc_unlink((struct_dllheader_ext*)shrt);
 
937
                aisc_unlink((dllheader_ext*)shrt);
938
938
                an_strlwr(shrt->mh.ident);
939
939
                aisc_link(&main->pnames, shrt);
940
940
                main->touched = 1;
961
961
        {
962
962
            list<string> idents_to_recreate;
963
963
 
964
 
            for (AN_shorts *shrt =  main->shorts1; shrt; ) {
 
964
            for (AN_shorts *shrt =  main->shorts1; shrt;) {
965
965
                char      *cap_name = strdup(shrt->shrt);
966
966
                an_autocaps(cap_name);
967
967
 
969
969
                    idents_to_recreate.push_back(shrt->mh.ident);
970
970
                }
971
971
                free(cap_name);
972
 
                
 
972
 
973
973
                AN_shorts *next = shrt->next;
974
974
                an_remove_short(shrt);
975
975
                shrt = next;
978
978
            list<string>::const_iterator end = idents_to_recreate.end();
979
979
            for (list<string>::const_iterator i = idents_to_recreate.begin(); i != end; ++i) {
980
980
                const char *ident = i->c_str();
981
 
                an_get_short(main->shorts1, &(main->pshorts1), ident);
 
981
                free(an_get_short(main->shorts1, &(main->pshorts1), ident));
982
982
                regen_name_parts++;
983
983
            }
984
984
        }
985
985
 
986
986
        // now capitalize all short names
987
 
        for (AN_shorts *shrt =  main->names; shrt; ) {
 
987
        for (AN_shorts *shrt =  main->names; shrt;) {
988
988
            AN_shorts *next     = shrt->next;
989
989
            char      *cap_name = strdup(shrt->shrt);
990
990
            an_autocaps(cap_name);
991
991
 
992
992
            if (strcmp(cap_name, shrt->shrt) != 0) {
993
 
                // fprintf(stderr, "Deleting entry '%s'\n", shrt->shrt);
994
993
                an_remove_short(shrt);
995
994
                deleted_names++;
996
995
            }
1010
1009
    int illegal_names = 0;
1011
1010
 
1012
1011
    // first check name parts
1013
 
    for (AN_shorts *shrt = main->shorts1; shrt; ) {
 
1012
    for (AN_shorts *shrt = main->shorts1; shrt;) {
1014
1013
        AN_shorts *next = shrt->next;
1015
1014
        if (!stralnum(shrt->shrt)) {
1016
1015
            fprintf(stderr, "- Fixing illegal chars in '%s'\n", shrt->shrt);
1020
1019
        shrt = next;
1021
1020
    }
1022
1021
    // then check full short-names
1023
 
    for (AN_shorts *shrt = main->names; shrt; ) {
 
1022
    for (AN_shorts *shrt = main->names; shrt;) {
1024
1023
        AN_shorts *next  = shrt->next;
1025
1024
        if (!stralnum(shrt->shrt)) {
1026
1025
            fprintf(stderr, "- Fixing illegal chars in '%s'\n", shrt->shrt);
1029
1028
        }
1030
1029
        shrt = next;
1031
1030
    }
1032
 
    
 
1031
 
1033
1032
    if (illegal_names>0) {
1034
1033
        fprintf(stderr, "* Removed %i names containing illegal characters.\n"
1035
1034
                "=> This leads to name changes when generating new names (which is recommended now).\n", illegal_names);
1044
1043
        // (empty default was old behavior)
1045
1044
 
1046
1045
        long count = 0;
1047
 
        for (AN_shorts *shrt = main->names; shrt; ) {
 
1046
        for (AN_shorts *shrt = main->names; shrt;) {
1048
1047
            AN_shorts *next  = shrt->next;
1049
1048
            if (!shrt->add_id[0]) {
1050
 
                aisc_unlink((struct_dllheader_ext*)shrt);
 
1049
                aisc_unlink((dllheader_ext*)shrt);
1051
1050
 
1052
1051
                freedup(shrt->add_id, main->add_field_default);
1053
 
                gb_assert(strchr(shrt->mh.ident, 0)[-1] == '*');
 
1052
                na_assert(strchr(shrt->mh.ident, 0)[-1] == '*');
1054
1053
                freeset(shrt->mh.ident, GBS_global_string_copy("%s%s", shrt->mh.ident, main->add_field_default));
1055
 
            
 
1054
 
1056
1055
                aisc_link(&main->pnames, shrt);
1057
1056
 
1058
1057
                count++;
1075
1074
 
1076
1075
    fprintf(stderr, "Starting ARB_name_server..\n");
1077
1076
 
1078
 
    file = fopen(main->server_file,"r");
 
1077
    file = fopen(main->server_file, "r");
1079
1078
    if (!file) {
1080
1079
        error = GBS_global_string("No such file '%s'", main->server_file);
1081
1080
    }
1082
1081
    else {
1083
1082
        fprintf(stderr, "* Loading %s\n", main->server_file);
1084
 
        int err_code = load_AN_main(main,file);
 
1083
        int err_code = load_AN_main(main, file);
1085
1084
        if (err_code) {
1086
1085
            error = GBS_global_string("Error #%i while loading '%s'", err_code, main->server_file);
1087
1086
        }
1131
1130
    return error;
1132
1131
}
1133
1132
 
1134
 
void names_server_shutdown(int exitcode) __ATTR__NORETURN;
1135
 
void names_server_shutdown(int exitcode) {
 
1133
__ATTR__NORETURN static void names_server_shutdown(int exitcode) {
1136
1134
    aisc_server_shutdown_and_exit(AN_global.server_communication, exitcode); // never returns
1137
1135
}
1138
1136
 
1139
 
int names_server_save(void) {
 
1137
int names_server_save() {
1140
1138
    server_save(aisc_main, 0);
1141
1139
    return 0;
1142
1140
}
1143
1141
 
1144
 
extern "C" int server_shutdown(AN_main *pm, aisc_string passwd){
1145
 
    /** passwdcheck **/
1146
 
    if( strcmp(passwd, "ldfiojkherjkh") ) return 1;
 
1142
int server_shutdown(AN_main */*pm*/, aisc_string passwd) {
 
1143
    // password check
 
1144
    if (strcmp(passwd, "ldfiojkherjkh")) return 1;
1147
1145
    printf("\narb_name_server: I got the shutdown message.\n");
1148
1146
 
1149
 
    /** shoot clients **/
 
1147
    // shutdown clients
1150
1148
    aisc_broadcast(AN_global.server_communication, 0,
1151
1149
                   "SERVER SHUTDOWN BY ADMINISTRATOR!\n");
1152
1150
 
1153
 
    /** shutdown **/
 
1151
    // shutdown server
1154
1152
    printf("ARB_name_server: server shutdown by administrator\n");
1155
1153
    names_server_shutdown(0);   // never returns!
1156
 
    pm = pm;
1157
1154
    return 0;
1158
1155
}
1159
1156
 
1167
1164
           , SERVER_VERSION, exeName);
1168
1165
    arb_print_server_params();
1169
1166
    if (err) printf("Error: %s\n", err);
1170
 
    exit(-1);
 
1167
    exit(EXIT_FAILURE);
1171
1168
}
1172
1169
 
1173
 
int main(int argc,char **argv)
1174
 
{
1175
 
    char              *name;
1176
 
    int                i;
1177
 
    struct Hs_struct  *so;
1178
 
    struct arb_params *params;
 
1170
int ARB_main(int argc, char *argv[]) {
 
1171
    char       *name;
 
1172
    int         i;
 
1173
    Hs_struct  *so;
 
1174
    arb_params *params;
1179
1175
 
1180
 
    params                 = arb_trace_argv(&argc,argv);
 
1176
    params                 = arb_trace_argv(&argc, (const char **)argv);
1181
1177
    const char *executable = argv[0];
1182
1178
 
1183
1179
    if (!params->default_file) usage(executable, "Missing default file");
1191
1187
    if (argc!=2) usage(executable, "Too many parameters");
1192
1188
 
1193
1189
    aisc_main = create_AN_main();
1194
 
    /***** try to open com with any other pb server ******/
 
1190
 
 
1191
    // try to open com with running name server
1195
1192
    if (params->tcp) {
1196
1193
        name = params->tcp;
1197
1194
    }
1198
1195
    else {
1199
 
        const char *cname = GBS_read_arb_tcp("ARB_NAME_SERVER");
 
1196
        const char *cname = GBS_read_arb_tcp(GBS_nameserver_tag(NULL));
1200
1197
 
1201
1198
        if (!cname) {
1202
1199
            GB_print_error();
1203
 
            exit(-1);
 
1200
            exit(EXIT_FAILURE);
1204
1201
        }
1205
1202
        name = strdup(cname);
1206
1203
    }
1207
1204
 
1208
 
    AN_global.cl_link = (aisc_com *)aisc_open(name, (long *)&AN_global.cl_main,AISC_MAGIC_NUMBER);
 
1205
    GB_ERROR error    = NULL;
 
1206
    AN_global.cl_link = aisc_open(name, AN_global.cl_main, AISC_MAGIC_NUMBER, &error);
1209
1207
 
1210
1208
    if (AN_global.cl_link) {
1211
 
        if( !strcmp(argv[1],"-look")) {
 
1209
        if (!strcmp(argv[1], "-look")) {
1212
1210
            printf("ARB_name_server: No client - terminating.\n");
1213
 
            aisc_close(AN_global.cl_link);AN_global.cl_link = 0;
1214
 
            exit(0);
 
1211
            aisc_close(AN_global.cl_link, AN_global.cl_main); AN_global.cl_link = 0;
 
1212
            exit(EXIT_SUCCESS);
1215
1213
        }
1216
1214
 
1217
1215
        printf("There is another active nameserver. I try to kill it..\n");
1218
1216
        aisc_nput(AN_global.cl_link, AN_MAIN, AN_global.cl_main,
1219
1217
                  MAIN_SHUTDOWN, "ldfiojkherjkh",
1220
1218
                  NULL);
1221
 
        aisc_close(AN_global.cl_link);AN_global.cl_link=0;
1222
 
        sleep(1);
1223
 
    }
1224
 
    if( ((strcmp(argv[1],"-kill")==0)) ||
1225
 
        ((argc==3) && (strcmp(argv[2],"-kill")==0))){
 
1219
        aisc_close(AN_global.cl_link, AN_global.cl_main); AN_global.cl_link=0;
 
1220
        GB_sleep(1, SEC);
 
1221
    }
 
1222
 
 
1223
    if (error) {
 
1224
        printf("ARB_name_server: %s\n", error);
 
1225
        exit(EXIT_FAILURE);
 
1226
    }
 
1227
 
 
1228
    if (((strcmp(argv[1], "-kill") == 0)) ||
 
1229
        ((argc==3) && (strcmp(argv[2], "-kill")==0))) {
1226
1230
        printf("ARB_name_server: Now I kill myself!\n");
1227
 
        exit(0);
 
1231
        exit(EXIT_SUCCESS);
1228
1232
    }
1229
 
    for (i=0, so=0; (i<MAX_TRY) && (!so); i++){
1230
 
        so = open_aisc_server(name, NAME_SERVER_SLEEP*1000L ,0);
1231
 
        if (!so) sleep(RETRY_SLEEP);
 
1233
    for (i=0, so=0; (i<MAX_TRY) && (!so); i++) {
 
1234
        so = open_aisc_server(name, NAME_SERVER_SLEEP*1000L, 0);
 
1235
        if (!so) GB_sleep(RETRY_SLEEP, SEC);
1232
1236
    }
1233
1237
    if (!so) {
1234
1238
        printf("AN_SERVER: Gave up on opening the communication socket!\n");
1235
 
        exit(0);
 
1239
        exit(EXIT_FAILURE);
1236
1240
    }
1237
1241
    AN_global.server_communication = so;
1238
1242
 
1239
1243
    aisc_main->server_file     = strdup(params->default_file);
1240
1244
    aisc_main->server_filedate = GB_time_of_file(aisc_main->server_file);
1241
1245
 
1242
 
    GB_ERROR error = server_load(aisc_main);
 
1246
    error = server_load(aisc_main);
1243
1247
 
1244
1248
    if (!error) {
1245
1249
        const char *field         = params->field;
1303
1307
 
1304
1308
    if (!error && aisc_main->touched) server_save(aisc_main, 0);
1305
1309
 
 
1310
 
1306
1311
    while (!error && accept_calls>0) {
1307
1312
        aisc_accept_calls(so);
1308
1313
 
1309
 
        if (aisc_main->ploc_st.cnt <=0) { // timeout passed and no clients
 
1314
        if (aisc_main->ploc_st.cnt <= 0) { // timeout passed and no clients
1310
1315
            accept_calls--;
1311
1316
 
1312
1317
            long server_date = GB_time_of_file(aisc_main->server_file);
1321
1326
                isTimeout    = false;
1322
1327
            }
1323
1328
            else if (aisc_main->touched) {
1324
 
                server_save(aisc_main,0);
 
1329
                server_save(aisc_main, 0);
1325
1330
                accept_calls = accept_calls_init;
1326
1331
            }
1327
1332
        }