1 | #include <stdio.h> |
---|
2 | #include <string.h> |
---|
3 | #include <stdlib.h> |
---|
4 | #include <unistd.h> |
---|
5 | #include <ctype.h> |
---|
6 | |
---|
7 | #include <names_server.h> |
---|
8 | #include <names_client.h> |
---|
9 | #include "names.h" |
---|
10 | #include <arbdb.h> |
---|
11 | #include <names_prototypes.h> |
---|
12 | #include <server.h> |
---|
13 | #include <client.h> |
---|
14 | #include <servercntrl.h> |
---|
15 | #include <struct_man.h> |
---|
16 | |
---|
17 | |
---|
18 | #define UPPERCASE(c) if ( (c>='a') && (c<='z')) c+= 'A'-'a' |
---|
19 | |
---|
20 | struct AN_gl_struct AN_global; |
---|
21 | AN_main *aisc_main; /* muss so heissen */ |
---|
22 | |
---|
23 | void an_add_short(AN_local *locs,char *new_name, char *parsed_name,char *parsed_sym,char *shrt,char *acc) |
---|
24 | { |
---|
25 | AN_shorts *an_shorts; |
---|
26 | AN_revers *an_revers; |
---|
27 | char *full_name; |
---|
28 | locs = locs; |
---|
29 | |
---|
30 | if (strlen(parsed_sym)){ |
---|
31 | full_name = (char *)calloc(sizeof(char), |
---|
32 | strlen(parsed_name) + strlen(" sym")+1); |
---|
33 | sprintf(full_name,"%s sym",parsed_name); |
---|
34 | }else{ |
---|
35 | full_name = strdup(parsed_name); |
---|
36 | } |
---|
37 | |
---|
38 | an_shorts = create_AN_shorts(); |
---|
39 | an_revers = create_AN_revers(); |
---|
40 | |
---|
41 | an_shorts->mh.ident = strdup(new_name); |
---|
42 | an_shorts->shrt = strdup(shrt); |
---|
43 | an_shorts->full_name = strdup(full_name); |
---|
44 | an_shorts->acc = strdup(acc); |
---|
45 | aisc_link((struct_dllpublic_ext*)&(aisc_main->pnames),(struct_dllheader_ext*)an_shorts); |
---|
46 | |
---|
47 | an_revers->mh.ident = strdup(shrt); |
---|
48 | an_revers->full_name = full_name; |
---|
49 | an_revers->acc = strdup(acc); |
---|
50 | aisc_link((struct_dllpublic_ext*)&(aisc_main->prevers),(struct_dllheader_ext*)an_revers); |
---|
51 | aisc_main->touched = 1; |
---|
52 | } |
---|
53 | |
---|
54 | |
---|
55 | AN_shorts *an_find_shrt(AN_shorts *sin,char *search) |
---|
56 | { |
---|
57 | while (sin) { |
---|
58 | if (!strncmp(sin->shrt,search,3)) { |
---|
59 | return sin; |
---|
60 | } |
---|
61 | sin = sin->next; |
---|
62 | } |
---|
63 | return 0; |
---|
64 | } |
---|
65 | |
---|
66 | /* searches for an already defined short, |
---|
67 | if found then return found |
---|
68 | else if fullname == 0 return advice |
---|
69 | else if |advice| >=3 try advice first |
---|
70 | else try first 3 characters of full |
---|
71 | else try |
---|
72 | */ |
---|
73 | char *nas_string_2_key(const char *str) /* converts any string to a valid key */ |
---|
74 | { |
---|
75 | char buf[GB_KEY_LEN_MAX+1]; |
---|
76 | int i; |
---|
77 | int c; |
---|
78 | for (i=0;i<GB_KEY_LEN_MAX;) { |
---|
79 | c= *(str++); |
---|
80 | if (!c) break; |
---|
81 | if (isalpha(c)) buf[i++] = c; |
---|
82 | else if (c==' ' || c=='_') buf[i++] = '_'; |
---|
83 | } |
---|
84 | for (;i<GB_KEY_LEN_MIN;i++) buf[i] = '_'; |
---|
85 | buf[i] = 0; |
---|
86 | #if defined(DUMP_NAME_CREATION) |
---|
87 | printf("nas_string_2_key('%s') = '%s'\n", str, buf); |
---|
88 | #endif // DUMP_NAME_CREATION |
---|
89 | return strdup(buf); |
---|
90 | } |
---|
91 | |
---|
92 | char *nas_remove_small_vocals(const char *str) { |
---|
93 | char buf[GB_KEY_LEN_MAX+1]; |
---|
94 | int i; |
---|
95 | int c; |
---|
96 | |
---|
97 | for (i=0; i<GB_KEY_LEN_MAX; ) { |
---|
98 | c = *str++; |
---|
99 | if (!c) break; |
---|
100 | if (strchr("aeiouy", c)==0) { |
---|
101 | buf[i++] = c; |
---|
102 | } |
---|
103 | } |
---|
104 | for (; i<GB_KEY_LEN_MIN; i++) buf[i] = '_'; |
---|
105 | buf[i] = 0; |
---|
106 | #if defined(DUMP_NAME_CREATION) |
---|
107 | printf("nas_remove_small_vocals('%s') = '%s'\n", str, buf); |
---|
108 | #endif // DUMP_NAME_CREATION |
---|
109 | return strdup(buf); |
---|
110 | } |
---|
111 | |
---|
112 | void an_complete_shrt(char *shrt, const char *rest_of_full) { |
---|
113 | int len = strlen(shrt); |
---|
114 | |
---|
115 | while (len<5) { |
---|
116 | char c = *rest_of_full++; |
---|
117 | |
---|
118 | if (!c) break; |
---|
119 | shrt[len++] = c; |
---|
120 | } |
---|
121 | |
---|
122 | while (len<GB_KEY_LEN_MIN) { |
---|
123 | shrt[len++] = '_'; |
---|
124 | } |
---|
125 | |
---|
126 | shrt[len] = 0; |
---|
127 | } |
---|
128 | |
---|
129 | char *an_get_short(AN_shorts *shorts,dll_public *parent,char *full){ |
---|
130 | AN_shorts *look; |
---|
131 | // int search_pos; |
---|
132 | // int c_pos; |
---|
133 | // int end_pos; |
---|
134 | // char *p; |
---|
135 | |
---|
136 | if (strlen(full) == 0) { |
---|
137 | return strdup("Xxx"); |
---|
138 | } |
---|
139 | |
---|
140 | look = (AN_shorts *)aisc_find_lib((struct_dllpublic_ext*)parent,full); |
---|
141 | if (look) { /* hurra hurra , schon gefunden */ |
---|
142 | return strdup(look->shrt); |
---|
143 | } |
---|
144 | |
---|
145 | char *full2 = nas_string_2_key(full); |
---|
146 | char *full3 = 0; |
---|
147 | char shrt[10]; |
---|
148 | int len2, len3; |
---|
149 | int p1, p2; |
---|
150 | |
---|
151 | // try first three letters: |
---|
152 | |
---|
153 | strncpy(shrt,full2,3); |
---|
154 | UPPERCASE(shrt[0]); |
---|
155 | shrt[3] = 0; |
---|
156 | |
---|
157 | look = an_find_shrt(shorts,shrt); |
---|
158 | if (!look) { |
---|
159 | an_complete_shrt(shrt, full2+3); |
---|
160 | goto insert_shrt; |
---|
161 | } |
---|
162 | |
---|
163 | // generate names from consonants: |
---|
164 | |
---|
165 | full3 = nas_remove_small_vocals(full2); |
---|
166 | len3 = strlen(full3); |
---|
167 | |
---|
168 | for (p1=3; p1<(len3-1); p1++) { |
---|
169 | shrt[1] = full3[p1]; |
---|
170 | for (p2=p1+1; p2<len3; p2++) { |
---|
171 | shrt[2] = full3[p2]; |
---|
172 | look = an_find_shrt(shorts, shrt); |
---|
173 | if (!look) { |
---|
174 | an_complete_shrt(shrt, full3+p2+1); |
---|
175 | goto insert_shrt; |
---|
176 | } |
---|
177 | } |
---|
178 | } |
---|
179 | |
---|
180 | // generate names from all characters: |
---|
181 | |
---|
182 | len2 = strlen(full2); |
---|
183 | for (p1=3; p1<(len2-1); p1++) { |
---|
184 | shrt[1] = full2[p1]; |
---|
185 | for (p2=p1+1; p2<len2; p2++) { |
---|
186 | shrt[2] = full2[p2]; |
---|
187 | look = an_find_shrt(shorts, shrt); |
---|
188 | if (!look) { |
---|
189 | an_complete_shrt(shrt, full2+p2+1); |
---|
190 | goto insert_shrt; |
---|
191 | } |
---|
192 | } |
---|
193 | } |
---|
194 | |
---|
195 | // generate names containing two characters and one digit: |
---|
196 | |
---|
197 | for (p1=2; p1<len2; p1++) { |
---|
198 | shrt[1] = full2[p1]; |
---|
199 | for (p2=0; p2<=9; p2++) { |
---|
200 | shrt[2] = '0'+p2; |
---|
201 | look = an_find_shrt(shorts, shrt); |
---|
202 | if (!look) { |
---|
203 | an_complete_shrt(shrt, full2+p1+1); |
---|
204 | goto insert_shrt; |
---|
205 | } |
---|
206 | } |
---|
207 | } |
---|
208 | |
---|
209 | // generate names containing one characters and two digits: |
---|
210 | |
---|
211 | for (p1=0; p1<=99; p1++) { |
---|
212 | shrt[1] = '0'+(p1/10); |
---|
213 | shrt[2] = '0'+(p1%10); |
---|
214 | look = an_find_shrt(shorts, shrt); |
---|
215 | if (!look) { |
---|
216 | an_complete_shrt(shrt, full2+1); |
---|
217 | goto insert_shrt; |
---|
218 | } |
---|
219 | } |
---|
220 | |
---|
221 | free(full3); |
---|
222 | free(full2); |
---|
223 | |
---|
224 | return 0; |
---|
225 | |
---|
226 | /* ---------------------------------------- */ |
---|
227 | |
---|
228 | insert_shrt: |
---|
229 | |
---|
230 | #if defined(DUMP_NAME_CREATION) |
---|
231 | if (isdigit(shrt[0]) || isdigit(shrt[1])) { |
---|
232 | printf("generated new short-name '%s' for full-name '%s' full2='%s' full3='%s'\n", shrt, full, full2, full3); |
---|
233 | } |
---|
234 | #endif // DUMP_NAME_CREATION |
---|
235 | |
---|
236 | look = create_AN_shorts(); |
---|
237 | look->mh.ident = strdup(full2); |
---|
238 | look->shrt = strdup(shrt); |
---|
239 | aisc_link((struct_dllpublic_ext*)parent,(struct_dllheader_ext*)look); |
---|
240 | aisc_main->touched = 1; |
---|
241 | |
---|
242 | free(full3); |
---|
243 | free(full2); |
---|
244 | |
---|
245 | return strdup(shrt); |
---|
246 | } |
---|
247 | |
---|
248 | extern "C" aisc_string get_short(AN_local *locs) |
---|
249 | /* get the short name from the previously set |
---|
250 | names */ |
---|
251 | { |
---|
252 | char *parsed_name; |
---|
253 | char *parsed_sym; |
---|
254 | char *parsed_acc; |
---|
255 | char *new_name; |
---|
256 | char *first; |
---|
257 | char *second; |
---|
258 | char *p; |
---|
259 | static char *shrt=0; |
---|
260 | AN_shorts *an_shorts; |
---|
261 | int shortlen; |
---|
262 | |
---|
263 | if(shrt) free(shrt); |
---|
264 | shrt = 0; |
---|
265 | |
---|
266 | parsed_name = GBS_string_eval(locs->full_name, |
---|
267 | "\t= :\"=:'=:* * *=*1 *2:sp.=species:spec.=species:.=",0); |
---|
268 | /* delete ' " \t and more than two words */ |
---|
269 | parsed_sym = GBS_string_eval(locs->full_name, |
---|
270 | "\t= :* * *sym*=S",0); |
---|
271 | if (strlen(parsed_sym)>1) { |
---|
272 | free(parsed_sym); |
---|
273 | parsed_sym = strdup(""); |
---|
274 | } |
---|
275 | parsed_acc = GBS_string_eval(locs->acc,";=:\t=: =:\"=:,=",0); |
---|
276 | /* delete spaces and more */ |
---|
277 | first = GBS_string_eval(parsed_name,"* *=*1",0); |
---|
278 | p = strdup(parsed_name+strlen(first)); |
---|
279 | second = GBS_string_eval(p," =:\t=",0); |
---|
280 | UPPERCASE(second[0]); |
---|
281 | free(p); |
---|
282 | |
---|
283 | new_name = (char *)calloc(sizeof(char), |
---|
284 | strlen(first)+strlen(second)+strlen(parsed_acc)+4); |
---|
285 | |
---|
286 | if (strlen(parsed_acc)){ |
---|
287 | sprintf(new_name,"*%s",parsed_acc); |
---|
288 | }else{ |
---|
289 | sprintf(new_name,"%s*%s*%s",first,second,parsed_sym); |
---|
290 | } |
---|
291 | |
---|
292 | an_shorts = (AN_shorts *)aisc_find_lib((struct_dllpublic_ext*)&(aisc_main->pnames),new_name); |
---|
293 | if (!an_shorts){ /* now there is no short name */ |
---|
294 | char *first_short,*second_short; |
---|
295 | char *first_advice,*second_advice; |
---|
296 | int count; |
---|
297 | char test_short[256]; |
---|
298 | |
---|
299 | if (strlen(locs->advice) ) { |
---|
300 | first_advice = GBS_string_eval(locs->advice, |
---|
301 | "???*=?1?2?3:0=:1=:2=:3=:4=:5=:6=:7=:8=:9=",0); |
---|
302 | }else{ |
---|
303 | first_advice = strdup("Xxx"); |
---|
304 | } |
---|
305 | |
---|
306 | if (strlen(locs->advice) > 3) { |
---|
307 | second_advice = GBS_string_eval(locs->advice+3, |
---|
308 | " =:\t=:,=:;=",0); |
---|
309 | }else{ |
---|
310 | second_advice = strdup("Yyyyy"); |
---|
311 | } |
---|
312 | |
---|
313 | if (strlen(first)) { |
---|
314 | first_short = an_get_short( aisc_main->shorts1, |
---|
315 | &(aisc_main->pshorts1),first); |
---|
316 | }else{ |
---|
317 | first_short = strdup(first_advice); |
---|
318 | } |
---|
319 | first_short = (char *)realloc(first_short,strlen(first_short)+3); |
---|
320 | |
---|
321 | if (!strlen(first_short)) { |
---|
322 | sprintf(first_short,"Xxx"); |
---|
323 | } |
---|
324 | |
---|
325 | |
---|
326 | shortlen = 5; |
---|
327 | second_short = (char *)calloc(sizeof(char), 10); |
---|
328 | if (strlen(second)) { |
---|
329 | strncpy(second_short,second,shortlen); |
---|
330 | }else if (strlen(first_short) > 3) { |
---|
331 | strncpy(second_short,first_short+3,shortlen); |
---|
332 | }else if (strlen(second_advice) ) { |
---|
333 | strncpy(second_short,second_advice,shortlen); |
---|
334 | UPPERCASE(second_short[0]); |
---|
335 | }else{ |
---|
336 | strncpy(second_short,"Yyyyy",shortlen); |
---|
337 | } |
---|
338 | |
---|
339 | first_short[3] = 0; /* 3 characters for the first word */ |
---|
340 | |
---|
341 | sprintf(test_short,"%s%s", |
---|
342 | first_short,second_short); |
---|
343 | |
---|
344 | if (aisc_find_lib((struct_dllpublic_ext*)&(aisc_main->prevers),test_short)) { |
---|
345 | second_short[shortlen-1] = 0; |
---|
346 | for (count = 2; count <100000; count++) { |
---|
347 | if (count>=10){ |
---|
348 | second_short[shortlen-2] = 0; |
---|
349 | } |
---|
350 | if (count>=100){ |
---|
351 | second_short[shortlen-3] = 0; |
---|
352 | } |
---|
353 | sprintf(test_short,"%s%s%i",first_short,second_short,count); |
---|
354 | if (!aisc_find_lib((struct_dllpublic_ext*)&(aisc_main->prevers),test_short)) break; |
---|
355 | } |
---|
356 | } |
---|
357 | shrt = strdup(test_short); |
---|
358 | if (strlen(parsed_name) >3) { |
---|
359 | an_add_short(locs,new_name,parsed_name,parsed_sym,shrt,parsed_acc); |
---|
360 | /* add the newly created short to list */ |
---|
361 | } |
---|
362 | free(first_short); |
---|
363 | free(second_short); |
---|
364 | free(first_advice); |
---|
365 | free(second_advice); |
---|
366 | }else{ |
---|
367 | shrt = strdup(an_shorts->shrt); |
---|
368 | } |
---|
369 | free(first);free(second);free(parsed_name);free(parsed_sym); |
---|
370 | free(parsed_acc); free(new_name); |
---|
371 | return shrt; |
---|
372 | } |
---|
373 | |
---|
374 | extern "C" int server_save(AN_main *main, int dummy) |
---|
375 | { |
---|
376 | FILE *file; |
---|
377 | int error; |
---|
378 | char *sec_name; |
---|
379 | dummy = dummy; |
---|
380 | if (main->touched) { |
---|
381 | |
---|
382 | sec_name = (char *)calloc(sizeof(char),strlen(aisc_main->server_file)+2); |
---|
383 | sprintf(sec_name,"%s%%",aisc_main->server_file); |
---|
384 | file = fopen(sec_name,"w"); |
---|
385 | if (!file) { |
---|
386 | fprintf(stderr,"ERROR cannot save file %s\n",sec_name); |
---|
387 | }else{ |
---|
388 | error = save_AN_main(aisc_main,file); |
---|
389 | fclose(file); |
---|
390 | if (!error) { |
---|
391 | if (GB_rename(sec_name,aisc_main->server_file)) { |
---|
392 | GB_print_error(); |
---|
393 | fprintf(stderr,"ERROR cannot rename file %s %s\n", |
---|
394 | sec_name,aisc_main->server_file); |
---|
395 | }else{ |
---|
396 | main->touched = 0; |
---|
397 | } |
---|
398 | } |
---|
399 | } |
---|
400 | free(sec_name); |
---|
401 | } |
---|
402 | return 0; |
---|
403 | } |
---|
404 | |
---|
405 | int server_load(AN_main *main) |
---|
406 | { |
---|
407 | FILE *file; |
---|
408 | int error=0; |
---|
409 | char *sec_name = main->server_file; |
---|
410 | AN_shorts *shrt; |
---|
411 | AN_revers *revers; |
---|
412 | |
---|
413 | file = fopen(sec_name,"r"); |
---|
414 | if (!file) { |
---|
415 | fprintf(stderr,"ERROR cannot load file %s\n",sec_name); |
---|
416 | }else{ |
---|
417 | error = load_AN_main(main,file); |
---|
418 | } |
---|
419 | for (shrt = main->names; shrt; shrt = shrt->next) { |
---|
420 | revers = create_AN_revers(); |
---|
421 | revers->mh.ident = strdup(shrt->shrt); |
---|
422 | revers->full_name = strdup(shrt->full_name); |
---|
423 | revers->acc = strdup(shrt->acc); |
---|
424 | aisc_link((struct_dllpublic_ext*)&(main->prevers),(struct_dllheader_ext*)revers); |
---|
425 | } |
---|
426 | return error; |
---|
427 | } |
---|
428 | |
---|
429 | int names_server_shutdown(void) |
---|
430 | { |
---|
431 | /* server_save(aisc_main,0); */ |
---|
432 | aisc_server_shutdown(AN_global.server_communication); |
---|
433 | return 0; |
---|
434 | } |
---|
435 | |
---|
436 | |
---|
437 | extern "C" int server_shutdown(AN_main *pm,aisc_string passwd){ |
---|
438 | /** passwdcheck **/ |
---|
439 | if( strcmp(passwd, "ldfiojkherjkh") ) return 1; |
---|
440 | printf("\nI got the shutdown message.\n"); |
---|
441 | |
---|
442 | /** shoot clients **/ |
---|
443 | aisc_broadcast(AN_global.server_communication, 0, |
---|
444 | "SERVER SHUTDOWN BY ADMINISTRATOR!\n"); |
---|
445 | |
---|
446 | /** shutdown **/ |
---|
447 | names_server_shutdown(); |
---|
448 | exit(0); |
---|
449 | pm = pm; |
---|
450 | return 0; /* Never Reached */ |
---|
451 | } |
---|
452 | |
---|
453 | int main(int argc,char **argv) |
---|
454 | { |
---|
455 | char *name; |
---|
456 | int i; |
---|
457 | struct Hs_struct *so; |
---|
458 | struct arb_params *params; |
---|
459 | |
---|
460 | params = arb_trace_argv(&argc,argv); |
---|
461 | if (!params->default_file) { |
---|
462 | printf("No file: Syntax: %s -boot/-kill/-look -dfile\n",argv[0]); |
---|
463 | exit(-1); |
---|
464 | } |
---|
465 | |
---|
466 | if (argc ==1) { |
---|
467 | char flag[]="-look"; |
---|
468 | argv[1] = flag; |
---|
469 | argc = 2; |
---|
470 | } |
---|
471 | |
---|
472 | if (argc!=2) { |
---|
473 | printf("Wrong Parameters %i Syntax: %s -boot/-kill/-look -dfile\n",argc,argv[0]); |
---|
474 | exit(-1); |
---|
475 | } |
---|
476 | |
---|
477 | aisc_main = create_AN_main(); |
---|
478 | /***** try to open com with any other pb server ******/ |
---|
479 | if (params->tcp) { |
---|
480 | name = params->tcp; |
---|
481 | }else{ |
---|
482 | if( !(name=(char *)GBS_read_arb_tcp("ARB_NAME_SERVER")) ){ |
---|
483 | GB_print_error(); |
---|
484 | exit(-1); |
---|
485 | }else{ |
---|
486 | name=strdup(name); |
---|
487 | } |
---|
488 | } |
---|
489 | |
---|
490 | AN_global.cl_link = (aisc_com *)aisc_open(name, |
---|
491 | (long *)&AN_global.cl_main,AISC_MAGIC_NUMBER); |
---|
492 | |
---|
493 | if (AN_global.cl_link) { |
---|
494 | if( !strcmp(argv[1],"-look")) { |
---|
495 | aisc_close(AN_global.cl_link);AN_global.cl_link=0; |
---|
496 | exit(0); |
---|
497 | } |
---|
498 | |
---|
499 | printf("There is another activ server. I try to kill him...\n"); |
---|
500 | aisc_nput(AN_global.cl_link, AN_MAIN, AN_global.cl_main, |
---|
501 | MAIN_SHUTDOWN, "ldfiojkherjkh", |
---|
502 | NULL); |
---|
503 | aisc_close(AN_global.cl_link);AN_global.cl_link=0; |
---|
504 | sleep(1); |
---|
505 | } |
---|
506 | if( ((strcmp(argv[1],"-kill")==0)) || |
---|
507 | ((argc==3) && (strcmp(argv[2],"-kill")==0))){ |
---|
508 | printf("Now I kill myself!\n"); |
---|
509 | exit(0); |
---|
510 | } |
---|
511 | for(i=0, so=0; (i<MAX_TRY) && (!so); i++){ |
---|
512 | so = open_aisc_server(name, TIME_OUT,0); |
---|
513 | if(!so) sleep(10); |
---|
514 | } |
---|
515 | if(!so){ |
---|
516 | printf("AN_SERVER: Gave up on opening the communication socket!\n"); |
---|
517 | exit(0); |
---|
518 | } |
---|
519 | AN_global.server_communication = so; |
---|
520 | |
---|
521 | aisc_main->server_file = strdup(params->default_file); |
---|
522 | server_load(aisc_main); |
---|
523 | |
---|
524 | while (i == i) { |
---|
525 | aisc_accept_calls(so); |
---|
526 | if (aisc_main->ploc_st.cnt <=0) { |
---|
527 | server_save(aisc_main,0); |
---|
528 | names_server_shutdown(); |
---|
529 | exit(0); |
---|
530 | } |
---|
531 | } |
---|
532 | |
---|
533 | return 0; |
---|
534 | } |
---|