ARB
names.cxx
Go to the documentation of this file.
1 // ============================================================= //
2 // //
3 // File : names.cxx //
4 // Purpose : //
5 // //
6 // Institute of Microbiology (Technical University Munich) //
7 // http://www.arb-home.de/ //
8 // //
9 // ============================================================= //
10 
11 #include <names_server.h>
12 #include <names_client.h>
13 #include "names.h"
14 
15 #include <arbdb.h>
16 #include <arb_file.h>
17 #include <arb_sleep.h>
18 
19 #include <names_prototypes.h>
20 #include <server.h>
21 #include <client.h>
22 #include <servercntrl.h>
23 #include <struct_man.h>
24 
25 #include <unistd.h>
26 #include <cctype>
27 #include <list>
28 #include <string>
29 
30 #define na_assert(cond) arb_assert(cond)
31 
32 #define FULLNAME_LEN_MAX 64
33 #define NAME_LEN_MIN 2
34 
35 using namespace std;
36 
37 // --------------------------------------------------------------------------------
38 
39 // overloaded functions to avoid problems with type-punning:
40 inline long aisc_find_lib(dll_public *dll, char *key) { return aisc_find_lib(reinterpret_cast<dllpublic_ext*>(dll), key); }
41 
42 inline void aisc_link(dll_public *dll, AN_shorts *shorts) { aisc_link(reinterpret_cast<dllpublic_ext*>(dll), reinterpret_cast<dllheader_ext*>(shorts)); }
43 inline void aisc_link(dll_public *dll, AN_revers *revers) { aisc_link(reinterpret_cast<dllpublic_ext*>(dll), reinterpret_cast<dllheader_ext*>(revers)); }
44 
45 // --------------------------------------------------------------------------------
46 
47 #if defined(DEBUG)
48 // #define DUMP_NAME_CREATION
49 #endif // DEBUG
50 
51 #define UPPERCASE(c) do { (c) = toupper(c); } while (0)
52 
53 // --------------------------------------------------------------------------------
54 
55 struct AN_gl_struct {
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
65 
66 const int SERVER_VERSION = 5;
67 
68 // --------------------------------------------------------------------------------
69 
70 inline char *an_strlwr(char *str) {
71  for (int i = 0; str[i]; i++) {
72  str[i] = tolower(str[i]);
73  }
74  return str;
75 }
76 
77 inline int an_strnicmp(const char *s1, const char *s2, int len) {
78  int cmp = 0;
79 
80  for (int i = 0; i<len; i++) {
81  cmp = tolower(s1[i])-tolower(s2[i]);
82  if (cmp || !s1[i]) break; // different or string-end reached in both strings
83  }
84 
85  return cmp;
86 }
87 
88 inline int an_stricmp(const char *s1, const char *s2) {
89  int cmp = 0;
90 
91  for (int i = 0; ; i++) {
92  cmp = tolower(s1[i])-tolower(s2[i]);
93  if (cmp || !s1[i]) break; // different or string-end reached in both strings
94  }
95 
96  return cmp;
97 }
98 
99 
100 static AN_revers *lookup_an_revers(AN_main *main, const char *shortname) {
101  char *key = an_strlwr(ARB_strdup(shortname));
102  AN_revers *an_reverse = (AN_revers*)aisc_find_lib(&main->prevers, key);
103 
104  free(key);
105 
106  return an_reverse;
107 }
108 
109 static AN_shorts *lookup_an_shorts(AN_main *main, const char *identifier) {
110  // 'identifier' is either '*acc*add_id' or 'name1*name2*S' (see get_short() for details)
111  // 'add_id' is the value of an additional DB field and may be empty.
112 
113  char *key = an_strlwr(ARB_strdup(identifier));
114  AN_shorts *an_shorts = (AN_shorts*)aisc_find_lib(&main->pnames, key);
115 
116  free(key);
117 
118  return an_shorts;
119 }
120 
121 // ----------------------------------------
122 // prefix hash
123 
124 static size_t an_shorts_elems(AN_shorts *sin) {
125  size_t count = 0;
126  while (sin) {
127  sin = sin->next;
128  count++;
129  }
130  return count;
131 }
132 
133 #define PREFIXLEN 3
134 
136  if (!aisc_main->prefix_hash) {
137  AN_shorts *sin = aisc_main->shorts1;
138  size_t elems = an_shorts_elems(sin);
139  if (elems<100) elems = 100;
140 
142 
143  while (sin) {
144  GBS_write_hash_no_strdup(hash, ARB_strndup(sin->shrt, PREFIXLEN), (long)sin);
145  sin = sin->next;
146  }
147 
148  aisc_main->prefix_hash = (long)hash;
149  }
150  return (GB_HASH*)aisc_main->prefix_hash;
151 }
152 
153 static const char *an_make_prefix(const char *str) {
154  static char buf[] = "xxx";
155 
156  buf[0] = str[0];
157  buf[1] = str[1];
158  buf[2] = str[2];
159 
160  return buf;
161 }
162 
163 static AN_shorts *an_find_shrt_prefix(const char *search) {
164  return (AN_shorts*)GBS_read_hash(an_get_prefix_hash(), an_make_prefix(search));
165 }
166 
167 // ----------------------------------------
168 
169 static void an_add_short(const AN_local */*locs*/, const char *new_name,
170  const char *parsed_name, const char *parsed_sym,
171  const char *shrt, const char *acc, const char *add_id)
172 {
173  AN_shorts *an_shorts;
174  AN_revers *an_revers;
175  char *full_name;
176 
177  if (strlen(parsed_sym)) {
178  ARB_calloc(full_name, strlen(parsed_name) + strlen(" sym")+1);
179  sprintf(full_name, "%s sym", parsed_name);
180  }
181  else {
182  full_name = ARB_strdup(parsed_name);
183  }
184 
185  an_shorts = create_AN_shorts();
186  an_revers = create_AN_revers();
187 
188  an_shorts->mh.ident = an_strlwr(ARB_strdup(new_name));
189  an_shorts->shrt = ARB_strdup(shrt);
190  an_shorts->full_name = ARB_strdup(full_name);
191  an_shorts->acc = ARB_strdup(acc);
192  an_shorts->add_id = ARB_strdup(add_id);
193 
194  aisc_link(&aisc_main->pnames, an_shorts);
195 
196  an_revers->mh.ident = an_strlwr(ARB_strdup(shrt));
197  an_revers->full_name = full_name;
198  an_revers->acc = ARB_strdup(acc);
199  an_revers->add_id = ARB_strdup(add_id);
200 
201  aisc_link(&aisc_main->prevers, an_revers);
202 
203  GB_HASH *phash = an_get_prefix_hash();
204  GBS_write_hash(phash, an_make_prefix(an_shorts->shrt), (long)an_shorts); // add an_shorts to hash
205  GBS_optimize_hash(phash);
206 
207  aisc_main->touched = 1;
208 }
209 
210 static void an_remove_short(AN_shorts *an_shorts) {
211  /* this should only be used to remove illegal entries from name-server.
212  normally removing names does make problems - so use it very rarely */
213 
214  GBS_write_hash(an_get_prefix_hash(), an_make_prefix(an_shorts->shrt), 0); // delete an_shorts from hash
215 
216  AN_revers *an_revers = lookup_an_revers(aisc_main, an_shorts->shrt);
217 
218  if (an_revers) {
219  aisc_unlink((dllheader_ext*)an_revers);
220 
221  free(an_revers->mh.ident);
222  free(an_revers->full_name);
223  free(an_revers->acc);
224  free(an_revers);
225  }
226 
227  aisc_unlink((dllheader_ext*)an_shorts);
228 
229  free(an_shorts->mh.ident);
230  free(an_shorts->shrt);
231  free(an_shorts->full_name);
232  free(an_shorts->acc);
233  free(an_shorts);
234 }
235 
236 static char *nas_string_2_name(const char *str) {
237  // converts a string to a valid name
238 #if defined(DUMP_NAME_CREATION)
239  const char *org_str = str;
240 #endif // DUMP_NAME_CREATION
241 
242  char buf[FULLNAME_LEN_MAX+1];
243  int i;
244  int c;
245  for (i=0; i<FULLNAME_LEN_MAX;) {
246  c = *(str++);
247  if (!c) break;
248  if (isalpha(c)) buf[i++] = c;
249  }
250  for (; i<NAME_LEN_MIN; i++) buf[i] = '0';
251  buf[i] = 0;
252 #if defined(DUMP_NAME_CREATION)
253  printf("nas_string_2_name('%s') = '%s'\n", org_str, buf);
254 #endif // DUMP_NAME_CREATION
255  return ARB_strdup(buf);
256 }
257 
258 static char *nas_remove_small_vocals(const char *str) {
259 #if defined(DUMP_NAME_CREATION)
260  const char *org_str = str;
261 #endif // DUMP_NAME_CREATION
262  char buf[FULLNAME_LEN_MAX+1];
263  int i;
264  int c;
265 
266  for (i=0; i<FULLNAME_LEN_MAX;) {
267  c = *str++;
268  if (!c) break;
269  if (!strchr("aeiouy", c)) {
270  buf[i++] = c;
271  }
272  }
273  for (; i<NAME_LEN_MIN; i++) buf[i] = '0';
274  buf[i] = 0;
275 #if defined(DUMP_NAME_CREATION)
276  printf("nas_remove_small_vocals('%s') = '%s'\n", org_str, buf);
277 #endif // DUMP_NAME_CREATION
278  return ARB_strdup(buf);
279 }
280 
281 static void an_complete_shrt(char *shrt, const char *rest_of_full) {
282  int len = strlen(shrt);
283 
284  while (len<5) {
285  char c = *rest_of_full++;
286 
287  if (!c) break;
288  shrt[len++] = c;
289  }
290 
291  while (len<NAME_LEN_MIN) {
292  shrt[len++] = '0';
293  }
294 
295  shrt[len] = 0;
296 }
297 
298 static void an_autocaps(char *str) {
299  // automatically capitalizes a string if it is completely up- or downcase
300 
301  bool is_single_case = true;
302  {
303  bool seen_upper_case = false;
304  bool seen_lower_case = false;
305  for (int i = 0; str[i] && is_single_case; i++) {
306  char c = str[i];
307  if (isalpha(c)) {
308  if (islower(c)) seen_lower_case = true;
309  else seen_upper_case = true;
310 
311  if (seen_lower_case == seen_upper_case) { // both cases occurred
312  is_single_case = false;
313  }
314  }
315  }
316  }
317 
318  if (is_single_case) {
319  bool next_is_capital = true;
320 
321  for (int i = 0; str[i]; i++) {
322  char c = str[i];
323  if (isalnum(c)) {
324  if (next_is_capital) {
325  str[i] = toupper(c);
326  next_is_capital = false;
327  }
328  else {
329  str[i] = tolower(c);
330  }
331  }
332  else {
333  next_is_capital = true;
334  }
335  }
336  }
337 }
338 
339 static char *an_get_short(AN_shorts *IF_ASSERTION_USED(shorts), dll_public *parent, const char *full) {
340  AN_shorts *look;
341 
342  na_assert(full);
343  na_assert(shorts == aisc_main->shorts1); // otherwise prefix_hash does not work!
344 
345  if (full[0]==0) return ARB_strdup("ZZZ");
346 
347  const char *result = NULp;
348  char *full1 = ARB_strdup(full);
349  an_autocaps(full1);
350 
351  char *full2 = nas_string_2_name(full1);
352 
353  look = (AN_shorts *)aisc_find_lib((dllpublic_ext*)parent, full2);
354  if (look) { // name is already known
355  free(full2);
356  free(full1);
357  return ARB_strdup(look->shrt);
358  }
359 
360  char *full3 = NULp;
361  char shrt[10];
362  int len2, len3;
363  int p1, p2, p3;
364 
365  // try first three letters:
366 
367  strncpy(shrt, full2, 3);
368  UPPERCASE(shrt[0]);
369  shrt[3] = 0;
370 
371  look = an_find_shrt_prefix(shrt);
372  if (!look) {
373  len2 = strlen(full2);
374  an_complete_shrt(shrt, len2>=3 ? full2+3 : "");
375  goto found_short;
376  }
377 
378  // generate names from first char + consonants:
379 
380  full3 = nas_remove_small_vocals(full2);
381  len3 = strlen(full3);
382 
383  for (p1=1; p1<(len3-1); p1++) {
384  shrt[1] = full3[p1];
385  for (p2=p1+1; p2<len3; p2++) {
386  shrt[2] = full3[p2];
387  look = an_find_shrt_prefix(shrt);
388  if (!look) {
389  an_complete_shrt(shrt, full3+p2+1);
390  goto found_short;
391  }
392  }
393  }
394 
395  // generate names from first char + rest characters:
396 
397  len2 = strlen(full2);
398  for (p1=1; p1<(len2-1); p1++) {
399  shrt[1] = full2[p1];
400  for (p2=p1+1; p2<len2; p2++) {
401  shrt[2] = full2[p2];
402  look = an_find_shrt_prefix(shrt);
403  if (!look) {
404  an_complete_shrt(shrt, full2+p2+1);
405  goto found_short;
406  }
407  }
408  }
409 
410  // generate names containing first char + character from name + one digit:
411 
412  for (p1=1; p1<len2; p1++) {
413  shrt[1] = full2[p1];
414  for (p2=0; p2<=9; p2++) {
415  shrt[2] = '0'+p2;
416  look = an_find_shrt_prefix(shrt);
417  if (!look) {
418  an_complete_shrt(shrt, full2+p1+1);
419  goto found_short;
420  }
421  }
422  }
423 
424  // generate names containing first char + two digits:
425 
426  for (p1=1; p1<=99; p1++) {
427  shrt[1] = '0'+(p1/10);
428  shrt[2] = '0'+(p1%10);
429  look = an_find_shrt_prefix(shrt);
430  if (!look) {
431  an_complete_shrt(shrt, full2+1);
432  goto found_short;
433  }
434  }
435 
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
460 
461  found_short :
462  result = shrt;
463 
464  if (result && result[0]) {
465 #if defined(DUMP_NAME_CREATION)
466  if (isdigit(result[0]) || isdigit(result[1])) {
467  printf("generated new short-name '%s' for full-name '%s' full2='%s' full3='%s'\n", shrt, full, full2, full3);
468  }
469 #endif // DUMP_NAME_CREATION
470 
471  look = create_AN_shorts();
472  look->mh.ident = ARB_strdup(full2);
473  look->shrt = ARB_strdup(result);
474  aisc_link((dllpublic_ext*)parent, (dllheader_ext*)look);
475 
476  aisc_main->touched = 1;
477  }
478  else {
479  result = "ZZZ";
480 #if defined(DEBUG)
481  printf("ARB_name_server: Failed to find a unique short prefix for word '%s' (using '%s')\n", full, result);
482 #endif
483  }
484 
485  free(full3);
486  free(full2);
487  free(full1);
488 
489  return ARB_strdup(result);
490 }
491 
492 // --------------------------------------------------------------------------------
493 
494 static const char *default_full_name = "No name";
495 
496 class NameInformation : virtual Noncopyable {
497  const char *full_name;
498 
499  char *parsed_name;
500  char *parsed_sym;
501  char *parsed_acc;
502  char *parsed_add_id;
503 
504  char *first_name;
505  char *rest_of_name;
506 
507  char *id;
508 
509 public:
510  NameInformation(const AN_local *locs);
511  ~NameInformation();
512 
513  const char *get_id() const { return id; }
514  const char *get_full_name() const { return full_name; }
515  const char *get_first_name() const { return first_name; }
516  const char *get_rest_of_name() const { return rest_of_name; }
517 
518  void add_short(const AN_local *locs, const char *shrt) const {
519  an_add_short(locs, id, parsed_name, parsed_sym, shrt, parsed_acc, parsed_add_id);
520  }
521 };
522 
523 static bool contains_non_alphanumeric(const char *str) {
524  bool nonalnum = false;
525  for (char c = *str++; c; c = *str++) {
526  if (!isalnum(c)) {
527  nonalnum = true;
528  break;
529  }
530  }
531  return nonalnum;
532 }
533 
534 static char *make_alnum(const char *str) {
535  // returns a heap-copy containing all alphanumeric characters of 'str'
536 
537  char *newStr = ARB_alloc<char>(strlen(str)+1);
538  int n = 0;
539 
540  for (int p = 0; str[p]; ++p) {
541  if (isalnum(str[p])) newStr[n++] = str[p];
542  }
543  newStr[n] = 0;
544  return newStr;
545 }
546 static char *make_alpha(const char *str) {
547  // returns a heap-copy containing all alpha characters of 'str'
548 
549  char *newStr = ARB_alloc<char>(strlen(str)+1);
550  int n = 0;
551 
552  for (int p = 0; str[p]; ++p) {
553  if (isalpha(str[p])) newStr[n++] = str[p];
554  }
555  newStr[n] = 0;
556  return newStr;
557 }
558 
559 #if defined(DEBUG)
560 #define assert_alphanumeric(s) na_assert(!contains_non_alphanumeric(s))
561 #else
562 #define assert_alphanumeric(s)
563 #endif // DEBUG
564 
566  full_name = locs->full_name;
567  if (!full_name || !full_name[0]) full_name = default_full_name;
568 
569  parsed_name = GBS_string_eval(full_name,
570  "\t= :\"= :'= :" // replace TABs and quotes by space
571  "sp.=species:spec.=species:SP.=SPECIES:SPEC.=SPECIES:" // replace common abbreviations of 'species'
572  ".= :" // replace dots by spaces
573  " = :"); // multiple spaces -> 1 space
574 
575  {
576  int leading_spaces = strspn(parsed_name, " ");
577  int len = strlen(parsed_name)-leading_spaces;
578  memmove(parsed_name, parsed_name+leading_spaces, len);
579 
580  char *first_space = strchr(parsed_name, ' ');
581  if (first_space) {
582  char *second_space = strchr(first_space+1, ' ');
583  if (second_space) {
584  second_space[0] = 0; // skip all beyond 2nd word
585  }
586  }
587  }
588 
589  an_autocaps(parsed_name);
590 
591  parsed_sym = GBS_string_eval(full_name, "\t= :* * *sym*=S");
592  if (strlen(parsed_sym)>1) freedup(parsed_sym, "");
593 
594  const char *add_id = locs->add_id[0] ? locs->add_id : aisc_main->add_field_default;
595 
596  parsed_acc = make_alnum(locs->acc);
597  parsed_add_id = make_alnum(add_id);
598  first_name = GBS_string_eval(parsed_name, "* *=*1");
599  rest_of_name = make_alnum(parsed_name+strlen(first_name));
600 
601  freeset(first_name, make_alnum(first_name));
602 
603  assert_alphanumeric(parsed_acc);
604  assert_alphanumeric(first_name);
605  assert_alphanumeric(rest_of_name);
606 
607  UPPERCASE(rest_of_name[0]);
608 
609  // build id
610 
611  id = (strlen(parsed_acc)+strlen(parsed_add_id))
612  ? GBS_global_string_copy("*%s*%s", parsed_acc, parsed_add_id)
613  : GBS_global_string_copy("%s*%s*%s", first_name, rest_of_name, parsed_sym);
614 }
615 
617  free(id);
618 
619  free(rest_of_name);
620  free(first_name);
621 
622  free(parsed_add_id);
623  free(parsed_acc);
624  free(parsed_sym);
625  free(parsed_name);
626 }
627 
628 // --------------------------------------------------------------------------------
629 // AISC functions
630 
631 int del_short(const AN_local *locs) {
632  // forget about a short name
633  NameInformation info(locs);
634  int removed = 0;
635  AN_shorts *an_shorts = lookup_an_shorts(aisc_main, info.get_id());
636 
637  if (an_shorts) {
638  an_remove_short(an_shorts);
639  removed = 1;
640  }
641 
642  return removed;
643 }
644 
645 static GB_HASH *nameModHash = NULp; // key = default name; value = max. counter tested
646 
647 aisc_string get_short(const AN_local *locs) {
648  // get the short name from the previously set names
649  static char *shrt = NULp;
650 
651  freenull(shrt);
652 
653  NameInformation info(locs);
654  AN_shorts *an_shorts = lookup_an_shorts(aisc_main, info.get_id());
655 
656  if (an_shorts) { // we already have a short name
657  bool recreate = false;
658 
659  if (contains_non_alphanumeric(an_shorts->shrt)) {
660  recreate = true;
661  }
662  else if (strcmp(an_shorts->full_name, default_full_name) == 0 && // fullname in name server is default_full_name
663  strcmp(info.get_full_name(), an_shorts->full_name) != 0) // and differs from current
664  {
665  recreate = true;
666  }
667  if (recreate) {
668  an_remove_short(an_shorts);
669  an_shorts = NULp;
670  }
671  else {
672  shrt = ARB_strdup(an_shorts->shrt);
673  }
674  }
675  if (!shrt) { // now there is no short name (or an illegal one)
676  char *first_advice = NULp;
677  char *second_advice = NULp;
678 
679  if (locs->advice[0] && contains_non_alphanumeric(locs->advice)) { // bad advice
680  locs->advice[0] = 0; // delete it
681  }
682 
683  if (locs->advice[0]) {
684  char *advice = make_alpha(locs->advice);
685 
686  first_advice = ARB_strdup(advice);
687  if (strlen(advice) > 3) {
688  second_advice = ARB_strdup(advice+3);
689  first_advice[3] = 0;
690  }
691  }
692 
693  if (!first_advice) first_advice = ARB_strdup("ZZZ");
694  if (!second_advice) second_advice = ARB_strdup("ZZZZZ");
695 
696  char *first_short;
697  int first_len;
698  {
699  const char *first_name = info.get_first_name();
700  first_short = first_name[0]
701  ? an_get_short(aisc_main->shorts1, &(aisc_main->pshorts1), first_name)
702  : ARB_strdup(first_advice);
703 
704  na_assert(first_short);
705 
706  if (first_short[0] == 0) { // empty?
707  freedup(first_short, "ZZZ");
708  }
709  first_len = strlen(first_short);
710  }
711 
712  char *second_short = ARB_calloc<char>(10);
713  int second_len;
714  {
715  const char *rest_of_name = info.get_rest_of_name();
716  int restlen = strlen(rest_of_name);
717 
718  if (!restlen) {
719  rest_of_name = second_advice;
720  restlen = strlen(rest_of_name);
721  if (!restlen) {
722  rest_of_name = "ZZZZZ";
723  restlen = 5;
724  }
725  }
726 
727  second_short[0] = 0;
728 
729  if (restlen<5 && first_len>3) {
730  strcpy(second_short, first_short+3); // take additional characters from first_short
731  second_short[5-restlen] = 0; // but not too many
732  }
733 
734  char *strend = strchr(second_short, 0);
735  strncpy(strend, rest_of_name, 8);
736  second_len = strlen(second_short);
737  }
738 
739  if (first_len>3) {
740  first_short[3] = 0;
741  first_len = 3;
742  }
743 
744  int both_len = first_len+second_len;
745  if (both_len<8) {
746  freeset(second_short, GBS_global_string_copy("%s00000000", second_short));
747  second_len += 8;
748  both_len += 8;
749  }
750 
751  if (both_len>8) {
752  second_len = 8-first_len;
753  second_short[second_len] = 0;
754  both_len = 8;
755  }
756 
757  char test_short[9];
758  sprintf(test_short, "%s%s", first_short, second_short);
759 
760  na_assert(size_t(both_len) == strlen(test_short));
761  na_assert(second_len>=5 && second_len <= 8);
762 
763  if (lookup_an_revers(aisc_main, test_short)) {
764  if (!nameModHash) nameModHash = GBS_create_hash(100, GB_IGNORE_CASE);
765 
766  char *test_short_dup = ARB_strdup(test_short);
767 
768  long count = 2; // start numbering with 'SomName2' (not 'SomName1')
769  test_short[7] = 0; // store, max. 7 chars in nameModHash (at least one digit is used)
770  count = std::max(count, GBS_read_hash(nameModHash, test_short));
771 
772  const long NUMBERS = 100000;
773 
774  int printOffset = both_len;
775  bool foundUnused = false;
776 
777  // first attempt to create alternate name using 1-5 digits at the end of the name
778  if (count<NUMBERS) {
779  int digLimit[6] = { 0, 9, 99, 999, 9999, 99999 };
780  for (int digits = 1; !foundUnused && digits <= 5; ++digits) {
781  int maxOffset = 8-digits;
782  int limit = digLimit[digits];
783 
784  if (printOffset>maxOffset) printOffset = maxOffset;
785 
786  char *printAt = test_short+printOffset;
787  if (digits>1) {
788  printAt[0] = 0;
789  count = std::max(count, GBS_read_hash(nameModHash, test_short)); // check shorter prefix
790  }
791 
792  for (; !foundUnused && count <= limit; ++count) {
793  IF_ASSERTION_USED(int printed =) sprintf(printAt, "%li", count);
794  na_assert((printed+printOffset) <= 8);
795  if (!lookup_an_revers(aisc_main, test_short)) foundUnused = true; // name does not exist
796  }
797  }
798  }
799  else {
800  test_short[3] = 0;
801  count = std::max(count, GBS_read_hash(nameModHash, test_short)); // check prefix with len==3
802  }
803 
804  const long base36_limit5 = 60466176; // 60466176 = 36^5 (while using 3-letter-prefix)
805  const int64_t base36_limit7 = 78364164096LL; // 78364164096 = 36^7 (while using 1-letter-prefix)
806 
807  bool store_in_nameModHash = true;
808 
809  // if no unused name found, create one with mixed alphanumeric-chars (last 5 characters of the name)
810  if (!foundUnused) {
811  strcpy(test_short, test_short_dup);
812 
813  long count2 = count-NUMBERS; // 100000 numbers were used above
814  char *printAt = test_short+3;
815  const char *base36 = "0123456789abcdefghijklmnopqrstuvwxyz";
816 
817  printAt[5] = 0;
818 
819  for (; !foundUnused && count2<base36_limit5; ++count2) {
820  // now print count2 converted to base 36
821 
822  long c = count2;
823  for (int pos = 0; pos<5; ++pos) {
824  long nextc = c/36;
825  int rest = c-36*nextc;
826 
827  printAt[4-pos] = base36[rest];
828  c = nextc;
829 
830  na_assert(pos != 4 || c == 0);
831  }
832 
833  if (!lookup_an_revers(aisc_main, test_short)) foundUnused = true; // name does not exist
834  }
835 
836  if (!foundUnused) {
837  // loop over ALL possible short-name (=1-letter-prefix + 7-letter-alnum-suffix)
838  na_assert(count2>base36_limit5);
839  store_in_nameModHash = false; // is directly stored for each 1-letter-prefix
840 
841  // @@@ try original starting character first?
842 
843  for (int pc = 'a'; pc<='z' && !foundUnused; ++pc) {
844  char key[2] = { char(pc), 0 };
845 
846  int64_t count3 = GBS_read_hash(nameModHash, key);
847 
848  test_short[0] = pc;
849  printAt = test_short+1;
850 
851  for (; !foundUnused && count3<base36_limit7; ++count3) {
852  // now print count3 converted to base 36
853 
854  int64_t c = count3;
855  for (int pos = 0; pos<7; ++pos) {
856  int64_t nextc = c/36;
857  int rest = c-36*nextc;
858 
859  printAt[6-pos] = base36[rest];
860  c = nextc;
861 
862  na_assert(pos != 6 || c == 0);
863  }
864 
865  if (!lookup_an_revers(aisc_main, test_short)) foundUnused = true; // name does not exist
866  }
867 
868  GBS_write_hash(nameModHash, key, count3);
869  }
870 
871  if (!foundUnused) {
872  const int64_t names_limit = 26*base36_limit7;
873  GBK_terminatef("Fatal error: reached short-name-limit ("
874 #if defined(ARB_64)
875  "%li"
876 #else // !defined(ARB_64)
877  "%lli"
878 #endif
879  ")", names_limit);
880  }
881  }
882  count = count2+NUMBERS;
883  }
884 
885  na_assert(foundUnused);
886 
887  if (store_in_nameModHash) {
888  test_short_dup[7] = 0;
889  GBS_write_hash(nameModHash, test_short_dup, count);
890  if (count>9) {
891  test_short_dup[6] = 0;
892  GBS_write_hash(nameModHash, test_short_dup, count);
893  if (count>99) {
894  test_short_dup[5] = 0;
895  GBS_write_hash(nameModHash, test_short_dup, count);
896  if (count>999) {
897  test_short_dup[4] = 0;
898  GBS_write_hash(nameModHash, test_short_dup, count);
899  if (count>9999) {
900  test_short_dup[3] = 0;
901  GBS_write_hash(nameModHash, test_short_dup, count);
902  }
903  }
904  }
905  }
906  }
907 
908  free(test_short_dup);
909  GBS_optimize_hash(nameModHash);
910  }
911 
912  assert_alphanumeric(test_short);
913 
914  shrt = ARB_strdup(test_short);
915  info.add_short(locs, shrt);
916 
917  free(first_short);
918  free(second_short);
919  free(first_advice);
920  free(second_advice);
921  }
922 
923  assert_alphanumeric(shrt);
924  return shrt;
925 }
926 
927 int server_save(AN_main *main, int) {
928  if (main->touched) {
929  int server_date = GB_time_of_file(main->server_file);
930  if (server_date>main->server_filedate) {
931  printf("Another nameserver changed '%s' - your changes are lost.\n", main->server_file);
932  }
933  else {
934  char *sec_name = ARB_calloc<char>(strlen(main->server_file)+2);
935  sprintf(sec_name, "%s%%", main->server_file);
936  printf("Saving '%s'..\n", main->server_file);
937 
938  FILE *file = fopen(sec_name, "w");
939  if (!file) {
940  fprintf(stderr, "ERROR cannot save file '%s'\n", sec_name);
941  }
942  else {
943  save_AN_main(main, file);
944  if (fclose(file) == 0) {
945  GB_ERROR mv_error = GB_move_file(sec_name, main->server_file);
946  if (mv_error) GB_warning(mv_error);
947  else main->touched = 0;
948  }
949  else {
950  GB_ERROR save_error = GB_IO_error("saving", sec_name);
951  fprintf(stderr, "Error: %s\n", save_error);
952  unlink(sec_name);
953  }
954  }
955  free(sec_name);
956  main->server_filedate = GB_time_of_file(main->server_file);
957  }
958  }
959  else {
960  printf("No changes to ARB_name_server data.\n");
961  }
962 
963  return 0;
964 }
965 
966 #if defined(DEBUG) && 0
967 static void check_list(AN_shorts *start) {
968  int count = 0;
969  while (++count) {
970  start = start->next;
971  if (!start) {
972  fprintf(stderr, "<list has %i elements>\n", count);
973  return;
974  }
975  }
976 
977  fprintf(stderr, "<ERROR - list is looped>\n");
978  na_assert(0);
979 }
980 #endif // DEBUG
981 
982 static void check_for_case_error(AN_main *main) {
983  // test for duplicated names or name parts (only differing in case)
984  // such names were created by old name server versions
985 
986  bool case_error_occurred = false;
987  int idents_changed = 0;
988  // first check name parts
989  for (AN_shorts *shrt = main->shorts1; shrt;) {
990  AN_shorts *next = shrt->next;
991  AN_shorts *found = an_find_shrt_prefix(shrt->shrt);
992  if (found != shrt) {
993  fprintf(stderr, "- Correcting error in name-database: '%s' equals '%s'\n",
994  found->shrt, shrt->shrt);
995  an_remove_short(shrt);
996  case_error_occurred = true;
997  }
998  shrt = next;
999  }
1000 
1001  // then check full short-names
1002  for (AN_shorts *shrt = main->names; shrt;) {
1003  AN_shorts *next = shrt->next;
1004  AN_revers *found = lookup_an_revers(main, shrt->shrt);
1005 
1006  if (found && (shrt->acc && found->acc && an_stricmp(shrt->acc, found->acc) != 0)) {
1007  fprintf(stderr, "- Correcting error in name-database: '%s' equals '%s' (but acc differs)\n",
1008  found->mh.ident, shrt->shrt);
1009 
1010  an_remove_short(shrt);
1011  case_error_occurred = true;
1012  }
1013  else if (found && (shrt->add_id && found->add_id && an_stricmp(shrt->add_id, found->add_id) != 0)) {
1014  fprintf(stderr, "- Correcting error in name-database: '%s' equals '%s' (but add_id differs)\n",
1015  found->mh.ident, shrt->shrt);
1016 
1017  an_remove_short(shrt);
1018  case_error_occurred = true;
1019  }
1020  else {
1021  AN_shorts *self_find = lookup_an_shorts(main, shrt->mh.ident);
1022  if (!self_find) { // stored with wrong key (not lowercase)
1023  aisc_unlink((dllheader_ext*)shrt);
1024  an_strlwr(shrt->mh.ident);
1025  aisc_link(&main->pnames, shrt);
1026  main->touched = 1;
1027 
1028  case_error_occurred = true;
1029  idents_changed++;
1030  }
1031  else if (self_find != shrt) {
1032  fprintf(stderr, "- Correcting error in name-database: '%s' equals '%s' (case-difference in full_name or acc)\n",
1033  shrt->mh.ident, self_find->mh.ident);
1034  an_remove_short(shrt);
1035  case_error_occurred = true;
1036  }
1037  }
1038 
1039  shrt = next;
1040  }
1041 
1042  if (case_error_occurred) {
1043  int regen_name_parts = 0;
1044  int deleted_names = 0;
1045 
1046  // now capitalize all name parts
1047  {
1048  list<string> idents_to_recreate;
1049 
1050  for (AN_shorts *shrt = main->shorts1; shrt;) {
1051  char *cap_name = ARB_strdup(shrt->shrt);
1052  an_autocaps(cap_name);
1053 
1054  if (strcmp(cap_name, shrt->shrt) != 0) {
1055  idents_to_recreate.push_back(shrt->mh.ident);
1056  }
1057  free(cap_name);
1058 
1059  AN_shorts *next = shrt->next;
1060  an_remove_short(shrt);
1061  shrt = next;
1062  }
1063 
1064  list<string>::const_iterator end = idents_to_recreate.end();
1065  for (list<string>::const_iterator i = idents_to_recreate.begin(); i != end; ++i) {
1066  const char *ident = i->c_str();
1067  free(an_get_short(main->shorts1, &(main->pshorts1), ident));
1068  regen_name_parts++;
1069  }
1070  }
1071 
1072  // now capitalize all short names
1073  for (AN_shorts *shrt = main->names; shrt;) {
1074  AN_shorts *next = shrt->next;
1075  char *cap_name = ARB_strdup(shrt->shrt);
1076  an_autocaps(cap_name);
1077 
1078  if (strcmp(cap_name, shrt->shrt) != 0) {
1079  an_remove_short(shrt);
1080  deleted_names++;
1081  }
1082  shrt = next;
1083  free(cap_name);
1084  }
1085 
1086  if (idents_changed) fprintf(stderr, "* Changed case of %i identifiers.\n", idents_changed);
1087  if (regen_name_parts) fprintf(stderr, "* Regenerated %i prefix names.\n", regen_name_parts);
1088  if (deleted_names) fprintf(stderr, "* Removed %i names with wrong case.\n"
1089  "=> This leads to name changes when generating new names (which is recommended now).\n", deleted_names);
1090  }
1091 }
1092 
1093 static void check_for_illegal_chars(AN_main *main) {
1094  // test for names containing illegal characters
1095  int illegal_names = 0;
1096 
1097  // first check name parts
1098  for (AN_shorts *shrt = main->shorts1; shrt;) {
1099  AN_shorts *next = shrt->next;
1100  if (contains_non_alphanumeric(shrt->shrt)) {
1101  fprintf(stderr, "- Fixing illegal chars in '%s'\n", shrt->shrt);
1102  an_remove_short(shrt);
1103  illegal_names++;
1104  }
1105  shrt = next;
1106  }
1107  // then check full short-names
1108  for (AN_shorts *shrt = main->names; shrt;) {
1109  AN_shorts *next = shrt->next;
1110  if (contains_non_alphanumeric(shrt->shrt)) {
1111  fprintf(stderr, "- Fixing illegal chars in '%s'\n", shrt->shrt);
1112  an_remove_short(shrt);
1113  illegal_names++;
1114  }
1115  shrt = next;
1116  }
1117 
1118  if (illegal_names>0) {
1119  fprintf(stderr, "* Removed %i names containing illegal characters.\n"
1120  "=> This leads to name changes when generating new names (which is recommended now).\n", illegal_names);
1121  }
1122 }
1123 
1124 static void set_empty_addids(AN_main *main) {
1125  // fill all empty add.ids with default value
1126 
1127  if (main->add_field_default[0]) {
1128  // if we use a non-empty default, old entries need to be changed
1129  // (empty default was old behavior)
1130 
1131  long count = 0;
1132  for (AN_shorts *shrt = main->names; shrt;) {
1133  AN_shorts *next = shrt->next;
1134  if (!shrt->add_id[0]) {
1135  aisc_unlink((dllheader_ext*)shrt);
1136 
1137  freedup(shrt->add_id, main->add_field_default);
1138  na_assert(strchr(shrt->mh.ident, 0)[-1] == '*');
1139  freeset(shrt->mh.ident, GBS_global_string_copy("%s%s", shrt->mh.ident, main->add_field_default));
1140 
1141  aisc_link(&main->pnames, shrt);
1142 
1143  count++;
1144  }
1145  shrt = next;
1146  }
1147  if (count>0) {
1148  printf(" Filled in default value '%s' for %li names\n", main->add_field_default, count);
1149  main->touched = 1;
1150  }
1151  }
1152 }
1153 
1154 static GB_ERROR server_load(AN_main *main) {
1155  FILE *file;
1156  GB_ERROR error = NULp;
1157  AN_shorts *shrt;
1158  AN_revers *revers;
1159 
1160  fprintf(stderr, "Starting ARB_name_server..\n");
1161 
1162  file = fopen(main->server_file, "r");
1163  if (!file) {
1164  error = GBS_global_string("No such file '%s'", main->server_file);
1165  }
1166  else {
1167  fprintf(stderr, "* Loading %s\n", main->server_file);
1168  int err_code = load_AN_main(main, file);
1169  if (err_code) {
1170  error = GBS_global_string("Error #%i while loading '%s'", err_code, main->server_file);
1171  }
1172  }
1173 
1174  if (!error) {
1175  fprintf(stderr, "* Parsing data\n");
1176  long nameCount = 0;
1177  for (shrt = main->names; shrt; shrt = shrt->next) {
1178  revers = create_AN_revers();
1179  revers->mh.ident = an_strlwr(ARB_strdup(shrt->shrt));
1180  revers->full_name = ARB_strdup(shrt->full_name);
1181  revers->acc = ARB_strdup(shrt->acc);
1182  revers->add_id = shrt->add_id ? ARB_strdup(shrt->add_id) : NULp;
1183  aisc_link(&main->prevers, revers);
1184  nameCount++;
1185  }
1186 
1187  int namesDBversion = main->dbversion; // version used to save names.dat
1188  fprintf(stderr, "* Loaded NAMEDB v%i (contains %li names)\n", namesDBversion, nameCount);
1189 
1190  if (namesDBversion < SERVER_VERSION) {
1191  if (namesDBversion<4) {
1192  fprintf(stderr, "* Checking for case-errors\n");
1193  check_for_case_error(main);
1194 
1195  fprintf(stderr, "* Checking for illegal characters\n");
1197  }
1198 
1199  fprintf(stderr, "* NAMEDB version upgrade %i -> %i\n", namesDBversion, SERVER_VERSION);
1200  main->dbversion = SERVER_VERSION;
1201  main->touched = 1; // force save
1202  }
1203  if (namesDBversion > SERVER_VERSION) {
1204  error = GBS_global_string("NAMEDB is from version %i, but your nameserver can only handle version %i",
1205  namesDBversion, SERVER_VERSION);
1206  }
1207  else {
1208  fprintf(stderr, "ARB_name_server is up.\n");
1209  main->server_filedate = GB_time_of_file(main->server_file);
1210  }
1211  }
1212  else {
1213  main->server_filedate = -1;
1214  }
1215  return error;
1216 }
1217 
1219  server_save(aisc_main, 0);
1220  return 0;
1221 }
1222 
1223 int server_shutdown(AN_main */*pm*/, aisc_string passwd) {
1224  // password check
1225  bool authorized = strcmp(passwd, "ldfiojkherjkh") == 0;
1226  free(passwd);
1227  if (!authorized) return 1;
1228 
1229  fflush(stderr); fflush(stdout);
1230  printf("\narb_name_server: I got the shutdown message.\n");
1231 
1232  // shutdown clients
1233  aisc_broadcast(AN_global.server_communication, 0, "Used nameserver has been shut down");
1234 
1235  // shutdown server
1236  printf("ARB_name_server: server shutdown by administrator\n");
1238  exit(EXIT_SUCCESS);
1239 
1240  return 0;
1241 }
1242 
1243 static int usage(const char *exeName, const char *err) {
1244  printf("ARB nameserver v%i\n"
1245  "Usage: %s command server-parameters\n"
1246  "command = -boot\n"
1247  " -kill\n"
1248  " -look\n"
1249  , SERVER_VERSION, exeName);
1251  if (err) printf("Error: %s\n", err);
1252  return EXIT_FAILURE;
1253 }
1254 
1255 int ARB_main(int argc, char *argv[]) {
1256  char *name;
1257  int i;
1258  Hs_struct *so;
1259  arb_params *params;
1260 
1261  params = arb_trace_argv(&argc, (const char **)argv);
1262  const char *executable = argv[0];
1263 
1264  if (!params->default_file) {
1265  return usage(executable, "Missing default file");
1266  }
1267 
1268  if (argc==1) { // default command is '-look'
1269  char flag[]="-look";
1270  argv[1] = flag;
1271  argc = 2;
1272  }
1273 
1274  if (argc!=2) {
1275  return usage(executable, "Too many parameters");
1276  }
1277 
1278  aisc_main = create_AN_main();
1279 
1280  // try to open com with running name server
1281  if (params->tcp) {
1282  name = params->tcp;
1283  }
1284  else {
1285  const char *cname = GBS_read_arb_tcp(GBS_nameserver_tag(NULp));
1286 
1287  if (!cname) {
1288  GB_print_error();
1289  return EXIT_FAILURE;
1290  }
1291  name = ARB_strdup(cname);
1292  }
1293 
1294  GB_ERROR error = NULp;
1296 
1297  if (AN_global.cl_link) {
1298  if (!strcmp(argv[1], "-look")) {
1299  printf("ARB_name_server: No client - terminating.\n");
1302  return EXIT_SUCCESS;
1303  }
1304 
1305  printf("There is another active nameserver. I try to kill it..\n");
1307  MAIN_SHUTDOWN, "ldfiojkherjkh",
1308  NULp);
1311  ARB_sleep(1, SEC);
1312  }
1313 
1314  if (error) {
1315  printf("ARB_name_server: %s\n", error);
1316  return EXIT_FAILURE;
1317  }
1318 
1319  if (((strcmp(argv[1], "-kill") == 0)) ||
1320  ((argc==3) && (strcmp(argv[2], "-kill")==0))) {
1321  printf("ARB_name_server: Now I kill myself!\n");
1322  return EXIT_SUCCESS;
1323  }
1324  for (i=0, so=NULp; (i<MAX_TRY) && (!so); i++) {
1325  so = open_aisc_server(name, NAME_SERVER_SLEEP*1000L, 0);
1326  if (!so) ARB_sleep(RETRY_SLEEP, SEC);
1327  }
1328  if (!so) {
1329  printf("AN_SERVER: Gave up on opening the communication socket!\n");
1330  return EXIT_FAILURE;
1331  }
1333 
1334  aisc_main->server_file = ARB_strdup(params->default_file);
1335  aisc_main->server_filedate = GB_time_of_file(aisc_main->server_file);
1336 
1337  error = server_load(aisc_main);
1338 
1339  if (!error) {
1340  const char *field = params->field;
1341  const char *field_default = params->field_default;
1342 
1343  if (!field) {
1344  field = ""; // default to no field
1345  field_default = "";
1346  }
1347  else {
1348  if (!params->field_default) {
1349  error = GBS_global_string("Missing default value for add.field (option has to be -f%s=defaultValue)", field);
1350  }
1351  }
1352 
1353  if (!error) {
1354  if (!aisc_main->add_field) { // add. field was not defined yet
1355  if (field[0]) {
1356  printf("* add. field not defined yet -> using '%s'\n", field);
1357  }
1358  else {
1359  fputs("* using no add. field\n", stdout);
1360  }
1361  aisc_main->add_field = ARB_strdup(field);
1362  aisc_main->touched = 1;
1363  }
1364  else {
1365  if (strcmp(aisc_main->add_field, field) != 0) { // add. field changed
1366  if (aisc_main->add_field[0]) {
1367  error = GBS_global_string("This names-DB has to be started with -f%s", aisc_main->add_field);
1368  }
1369  else {
1370  error = "This names-DB has to be started w/o -f option";
1371  }
1372  }
1373  }
1374  }
1375 
1376  if (!error) {
1377  char *field_default_alnum = make_alnum(field_default);
1378 
1379  if (!aisc_main->add_field_default) { // previously no default was defined for add.field
1380  reassign(aisc_main->add_field_default, field_default_alnum);
1382  aisc_main->touched = 1;
1383  }
1384  else {
1385  if (strcmp(aisc_main->add_field_default, field_default_alnum) != 0) {
1386  error = GBS_global_string("Default for add.field previously was '%s' (called with '%s')\n"
1387  "If you really need to change this - delete the names DB",
1388  aisc_main->add_field_default, field_default_alnum);
1389  }
1390  }
1391  free(field_default_alnum);
1392  }
1393  }
1394 
1395  long accept_calls_init = NAME_SERVER_TIMEOUT/long(NAME_SERVER_SLEEP);
1396  long accept_calls = accept_calls_init;
1397  bool isTimeout = true;
1398 
1399  if (!error && aisc_main->touched) server_save(aisc_main, 0);
1400 
1401 
1402  while (!error && accept_calls>0) {
1403  aisc_accept_calls(so);
1404 
1405  if (aisc_main->ploc_st.cnt <= 0) { // timeout passed and no clients
1406  accept_calls--;
1407 
1408  long server_date = GB_time_of_file(aisc_main->server_file);
1409  if (server_date == 0 && aisc_main->server_filedate != 0) {
1410  fprintf(stderr, "ARB_name_server data has been deleted.\n");
1411  accept_calls = 0;
1412  isTimeout = false;
1413  }
1414  if (server_date>aisc_main->server_filedate) {
1415  fprintf(stderr, "ARB_name_server data changed on disc.\n");
1416  accept_calls = 0;
1417  isTimeout = false;
1418  }
1419  else if (aisc_main->touched) {
1420  server_save(aisc_main, 0);
1421  accept_calls = accept_calls_init;
1422  }
1423  }
1424  else { // got a client
1425  accept_calls = accept_calls_init;
1426  }
1427  }
1428 
1429  if (error) {
1430  char *fullErrorMsg = GBS_global_string_copy("Error in ARB_name_server: %s", error);
1431  char *quotedErrorMsg = GBK_singlequote(fullErrorMsg);
1432 
1433  fprintf(stderr, "%s\n", fullErrorMsg); // log error to console
1434  error = GBK_system(GBS_global_string("arb_message %s &", quotedErrorMsg)); // send async to avoid deadlock
1435  if (error) fprintf(stderr, "Error: %s\n", error);
1436  free(quotedErrorMsg);
1437  free(fullErrorMsg);
1438  }
1439  else if (accept_calls == 0) {
1440  if (isTimeout) {
1441  fprintf(stderr, "Been idle for %i minutes.\n", int(NAME_SERVER_TIMEOUT/60));
1442  }
1443  }
1444 
1445  printf("ARB_name_server terminating...\n");
1446  if (nameModHash) GBS_free_hash(nameModHash);
1448  int exitcode = error ? EXIT_FAILURE : EXIT_SUCCESS;
1449  printf("Server terminates with code %i.\n", exitcode);
1450  return exitcode;
1451 }
long aisc_find_lib(dll_public *dll, char *key)
Definition: names.cxx:40
const char * aisc_unlink(dllheader_ext *object)
Definition: struct_man.c:185
GB_ERROR GBK_system(const char *system_command)
Definition: arb_msg.cxx:571
#define FULLNAME_LEN_MAX
Definition: names.cxx:32
const char * GB_ERROR
Definition: arb_core.h:25
string result
void GB_warning(const char *message)
Definition: arb_msg.cxx:530
const char * id
Definition: AliAdmin.cxx:17
static const char * an_make_prefix(const char *str)
Definition: names.cxx:153
int an_strnicmp(const char *s1, const char *s2, int len)
Definition: names.cxx:77
void add_short(const AN_local *locs, const char *shrt) const
Definition: names.cxx:518
long GBS_write_hash(GB_HASH *hs, const char *key, long val)
Definition: adhash.cxx:454
static const char * default_full_name
Definition: names.cxx:494
const char * get_first_name() const
Definition: names.cxx:515
Hs_struct * open_aisc_server(const char *path, int timeout, int fork)
Definition: server.c:235
static GB_ERROR server_load(AN_main *main)
Definition: names.cxx:1154
char * an_strlwr(char *str)
Definition: names.cxx:70
void aisc_server_shutdown(Hs_struct *&hs)
Definition: server.c:1134
int aisc_close(aisc_com *link, AISC_Object &object)
Definition: client.c:249
static char * nas_remove_small_vocals(const char *str)
Definition: names.cxx:258
int main(int argc, char **argv)
Definition: aisc.c:359
void aisc_link(dll_public *dll, AN_shorts *shorts)
Definition: names.cxx:42
long
Definition: AW_awar.cxx:152
T_AN_MAIN cl_main
Definition: names.cxx:58
int names_server_save()
Definition: names.cxx:1218
char * field
Definition: servercntrl.h:20
GB_ERROR GB_IO_error(const char *action, const char *filename)
Definition: arb_msg.cxx:285
char * ARB_strdup(const char *str)
Definition: arb_string.h:27
AN_main * aisc_main
Definition: names.cxx:64
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:203
static GB_HASH * an_get_prefix_hash()
Definition: names.cxx:135
int aisc_nput(aisc_com *link, int o_type, const AISC_Object &object,...)
Definition: client.c:564
static char * make_alnum(const char *str)
Definition: names.cxx:534
static void an_complete_shrt(char *shrt, const char *rest_of_full)
Definition: names.cxx:281
void GBK_terminatef(const char *templat,...)
Definition: arb_msg.cxx:523
STL namespace.
char * GBS_string_eval(const char *insource, const char *icommand)
Definition: admatch.cxx:699
int del_short(const AN_local *locs)
Definition: names.cxx:631
void GBS_free_hash(GB_HASH *hs)
Definition: adhash.cxx:538
static int usage(const char *exeName, const char *err)
Definition: names.cxx:1243
#define UPPERCASE(c)
Definition: names.cxx:51
#define EXIT_SUCCESS
Definition: arb_a2ps.c:154
long GBS_write_hash_no_strdup(GB_HASH *hs, char *key, long val)
Definition: adhash.cxx:459
int server_shutdown(AN_main *, aisc_string passwd)
Definition: names.cxx:1223
NameInformation(const AN_local *locs)
Definition: names.cxx:565
arb_params * arb_trace_argv(int *argc, const char **argv)
Hs_struct * server_communication
Definition: names.cxx:57
static HelixNrInfo * start
static char * nas_string_2_name(const char *str)
Definition: names.cxx:236
int an_stricmp(const char *s1, const char *s2)
Definition: names.cxx:88
void arb_print_server_params()
fflush(stdout)
const char * GBS_read_arb_tcp(const char *env)
Definition: adtcp.cxx:325
static char * an_get_short(AN_shorts *shorts, dll_public *parent, const char *full)
Definition: names.cxx:339
CONSTEXPR_INLINE int digits(int parts)
int ARB_main(int argc, char *argv[])
Definition: names.cxx:1255
unsigned long GB_time_of_file(const char *path)
Definition: arb_file.cxx:44
static struct AN_gl_struct AN_global
Definition: names.cxx:63
static void an_add_short(const AN_local *, const char *new_name, const char *parsed_name, const char *parsed_sym, const char *shrt, const char *acc, const char *add_id)
Definition: names.cxx:169
GB_ERROR GB_move_file(const char *oldpath, const char *newpath)
Definition: arb_file.cxx:284
static void error(const char *msg)
Definition: mkptypes.cxx:96
char * tcp
Definition: servercntrl.h:30
static GB_HASH * nameModHash
Definition: names.cxx:645
char * str
Definition: defines.h:20
#define cmp(h1, h2)
Definition: admap.cxx:50
const char * field_default
Definition: servercntrl.h:21
static int base36(int ch)
#define na_assert(cond)
Definition: names.cxx:30
void ARB_sleep(int amount, TimeUnit tu)
Definition: arb_sleep.h:32
int aisc_broadcast(Hs_struct *hs, int message_type, const char *message)
Definition: server.c:912
static bool contains_non_alphanumeric(const char *str)
Definition: names.cxx:523
#define EXIT_FAILURE
Definition: arb_a2ps.c:157
#define NAME_SERVER_TIMEOUT
Definition: names.h:10
char * server_name
Definition: names.cxx:59
GB_ERROR GB_print_error()
Definition: arb_msg.cxx:324
aisc_com * cl_link
Definition: names.cxx:56
long int flag
Definition: f2c.h:39
#define AISC_MAGIC_NUMBER
Definition: client_privat.h:51
fputs(TRACE_PREFIX, stderr)
const char * get_rest_of_name() const
Definition: names.cxx:516
TYPE * ARB_calloc(size_t nelem)
Definition: arb_mem.h:81
#define IF_ASSERTION_USED(x)
Definition: arb_assert.h:308
#define RETRY_SLEEP
Definition: names.h:3
const int SERVER_VERSION
Definition: names.cxx:66
char * GBK_singlequote(const char *arg)
Definition: arb_msg.cxx:599
T_PT_LOCS locs
char * ARB_strndup(const char *start, int len)
Definition: arb_string.h:83
const char * GBS_nameserver_tag(const char *add_field)
Definition: adtcp.cxx:303
static size_t an_shorts_elems(AN_shorts *sin)
Definition: names.cxx:124
static void check_for_case_error(AN_main *main)
Definition: names.cxx:982
static void an_remove_short(AN_shorts *an_shorts)
Definition: names.cxx:210
static void check_for_illegal_chars(AN_main *main)
Definition: names.cxx:1093
aisc_com * aisc_open(const char *path, AISC_Object &main_obj, long magic, GB_ERROR *error)
Definition: client.c:205
static AN_revers * lookup_an_revers(AN_main *main, const char *shortname)
Definition: names.cxx:100
static AN_shorts * an_find_shrt_prefix(const char *search)
Definition: names.cxx:163
#define MAX_TRY
Definition: names.h:2
const char * get_full_name() const
Definition: names.cxx:514
const char * get_id() const
Definition: names.cxx:513
#define NAME_SERVER_SLEEP
Definition: names.h:14
#define NULp
Definition: cxxforward.h:116
#define PREFIXLEN
Definition: names.cxx:133
static void set_empty_addids(AN_main *main)
Definition: names.cxx:1124
int server_save(AN_main *main, int)
Definition: names.cxx:927
char * default_file
Definition: servercntrl.h:19
aisc_string get_short(const AN_local *locs)
Definition: names.cxx:647
static AN_shorts * lookup_an_shorts(AN_main *main, const char *identifier)
Definition: names.cxx:109
static int info[maxsites+1]
Definition: arb_sleep.h:30
Hs_struct * aisc_accept_calls(Hs_struct *hs)
Definition: server.c:1026
#define assert_alphanumeric(s)
Definition: names.cxx:562
long GBS_read_hash(const GB_HASH *hs, const char *key)
Definition: adhash.cxx:392
static char * make_alpha(const char *str)
Definition: names.cxx:546
char * GBS_global_string_copy(const char *templat,...)
Definition: arb_msg.cxx:194
void GBS_optimize_hash(const GB_HASH *hs)
Definition: adhash.cxx:316
GB_HASH * GBS_create_hash(long estimated_elements, GB_CASE case_sens)
Definition: adhash.cxx:253
#define NAME_LEN_MIN
Definition: names.cxx:33
static void an_autocaps(char *str)
Definition: names.cxx:298
#define max(a, b)
Definition: f2c.h:154