source: branches/port5/PROBE/PT_main.cxx

Last change on this file was 6419, checked in by westram, 15 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.9 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <string.h>
5#include <sys/stat.h>
6#include <PT_server.h>
7#include <PT_server_prototypes.h>
8#include "probe.h"
9#include "pt_prototypes.h"
10#include <arbdbt.h>
11#include <servercntrl.h>
12#include <server.h>
13#include <client.h>
14#include <struct_man.h>
15#define MAX_TRY 10
16#define TIME_OUT 1000*60*60*24
17
18struct probe_struct_global  psg;
19char                       *pt_error_buffer = new char[1024];
20ULONG                       physical_memory = 0;
21
22// globals of gene-pt-server
23int gene_flag = 0;
24
25gene_struct_list           all_gene_structs; // stores all gene_structs
26gene_struct_index_arb      gene_struct_arb2internal; // sorted by arb speces+gene name
27gene_struct_index_internal gene_struct_internal2arb; // sorted by internal name
28
29// list<gene_struct *>  names_list_idp;
30// GBDATA *map_ptr_idp;
31
32/*****************************************************************************
33        Communication
34*******************************************************************************/
35char *pt_init_main_struct(PT_main *main, char *filename)
36{
37    main               = main;
38    probe_read_data_base(filename);
39    GB_begin_transaction(psg.gb_main);
40    psg.alignment_name = GBT_get_default_alignment(psg.gb_main);
41    GB_commit_transaction(psg.gb_main);
42    printf("Building PT-Server for alignment '%s'...\n", psg.alignment_name);
43    probe_read_alignments();
44    PT_build_species_hash();
45    return 0;
46}
47PT_main *aisc_main; /* muss so heissen */
48
49extern "C" int server_shutdown(PT_main *pm,aisc_string passwd){
50    /** passwdcheck **/
51    pm = pm;
52    if( strcmp(passwd, "47@#34543df43%&3667gh") ) return 1;
53    printf("\nI got the shutdown message.\n");
54    /** shoot clients **/
55    aisc_broadcast(psg.com_so, 0,
56                   "SERVER UPDATE BY ADMINISTRATOR!\nYou'll get the latest version. Your screen information will be lost, sorry!");
57    /** shutdown **/
58    aisc_server_shutdown_and_exit(psg.com_so, EXIT_SUCCESS); // never returns
59    return 0;
60}
61extern "C" int broadcast(PT_main *main, int dummy )
62{
63    aisc_broadcast(psg.com_so, main->m_type, main->m_text);
64    dummy = dummy;
65    return 0;
66}
67
68void PT_init_psg(){
69    memset((char *)&psg,0,sizeof(psg));
70    int i;
71    for (i=0;i<256;i++){
72        psg.complement[i] = PT_complement(i);
73    }
74}
75
76// ------------------------------------------------------------------------------ name mapping
77// the mapping is generated in ../TOOLS/arb_gene_probe.cxx
78
79inline const char *find_sep(const char *str, char sep) {
80    // sep may occur escaped (by \)
81    const char *found = strchr(str, sep);
82    while (found) {
83        if (found>str && found[-1] == '\\') { // escaped separator
84            found = strchr(found+1, sep);
85        }
86        else {
87            break;              // non-escaped -> report
88        }
89    }
90    return found;
91}
92
93inline bool copy_to_buf(const char *start, const char *behindEnd, int MAXLEN, char *destBuf) {
94    int len = behindEnd-start;
95    if (len>MAXLEN) {
96        return false;
97    }
98    memcpy(destBuf, start, len);
99    destBuf[len] = 0;
100    return true;
101}
102
103static void parse_names_into_gene_struct(const char *map_str, gene_struct_list& listOfGenes) {
104#define MAX_INAME_LEN 30
105#define MAX_ONAME_LEN 30
106#define MAX_GNAME_LEN 1024
107
108    char iname[MAX_INAME_LEN+1]; // internal name
109    char oname[MAX_ONAME_LEN+1]; // organism name
110    char gname[MAX_GNAME_LEN+1]; // gene name
111
112    const char *err = 0;
113
114    while (*map_str) {
115        const char *sep1 = strchr(map_str, ';');
116        const char *sep2 = sep1 ? strchr(sep1+1, ';') : 0;
117        const char *sep3 = sep2 ? find_sep(sep2+1, ';') :  0;
118
119        if (sep3) {
120            bool ok = copy_to_buf(map_str, sep1, MAX_INAME_LEN, iname);
121            ok = ok && copy_to_buf(sep1+1, sep2, MAX_ONAME_LEN, oname);
122            ok = ok && copy_to_buf(sep2+1, sep3, MAX_GNAME_LEN, gname);
123
124            if (ok) {
125                char *unesc               = GBS_unescape_string(gname, ";", '\\');
126                listOfGenes.push_back(gene_struct(iname, oname, unesc));
127                free(unesc);
128            }
129            else {
130                err = "buffer overflow (some name too long)";
131                break;
132            }
133        }
134        else {
135            err = GBS_global_string("expected at least 3 ';' in '%s'", map_str);
136            break;
137        }
138        map_str = sep3+1;
139    }
140
141    if (err) {
142        printf("Error parsing name-mapping (%s)\n", err);
143        exit(EXIT_FAILURE);
144    }
145
146}
147
148void PT_init_map(){
149    GB_push_transaction(psg.gb_main);
150    GBDATA *map_ptr_idp = GB_entry(psg.gb_main,"gene_map");
151
152    if (map_ptr_idp != NULL) {
153        gene_flag               = 1;
154        GBDATA     *map_ptr_str = GB_entry(map_ptr_idp,"map_string");
155        const char *map_str     = GB_read_char_pntr(map_ptr_str);
156
157        parse_names_into_gene_struct(map_str, all_gene_structs);
158
159        // build indices :
160        gene_struct_list::const_iterator end = all_gene_structs.end();
161
162        for (gene_struct_list::const_iterator gs = all_gene_structs.begin(); gs != end; ++gs) {
163            if (gene_struct_internal2arb.find(&*gs) != gene_struct_internal2arb.end()) {
164                fprintf(stderr, "  Duplicated internal entry for '%s'\n", gs->get_internal_gene_name());
165            }
166            gene_struct_internal2arb.insert(&*gs);
167            if (gene_struct_arb2internal.find(&*gs) != gene_struct_arb2internal.end()) {
168                fprintf(stderr, "  Duplicated entry for '%s/%s'\n", gs->get_arb_species_name(), gs->get_arb_gene_name());
169            }
170            gene_struct_arb2internal.insert(&*gs);
171        }
172
173        size_t list_size = all_gene_structs.size();
174        bool   err       = false;
175        if (list_size == 0) {
176            fprintf(stderr, "Internal error - empty name map.\n");
177            err = true;
178        }
179        else {
180            fprintf(stderr, "Name map size = %zu\n", list_size);
181        }
182        if (gene_struct_arb2internal.size() != list_size) {
183            fprintf(stderr, "Internal error - detected %zi duplicated 'species/gene' combinations in name mapping.\n",
184                    list_size-gene_struct_arb2internal.size());
185            err = true;
186        }
187        if (gene_struct_internal2arb.size() != list_size) {
188            fprintf(stderr, "Internal error - detected %zi duplicated internal gene name in name mapping.\n",
189                    list_size-gene_struct_internal2arb.size());
190            err = true;
191        }
192        if (err) {
193            fprintf(stderr, "Sorry - PT server cannot start.\n");
194            exit(EXIT_FAILURE);
195        }
196    }
197    else {
198        gene_flag = 0;
199    }
200    GB_pop_transaction(psg.gb_main);
201}
202
203extern int aisc_core_on_error;
204
205int main(int argc, char **argv)
206{
207    int                i;
208    struct Hs_struct  *so;
209    const char        *name;
210    char              *error;
211    char              *aname,*tname;
212    struct stat        s_source,s_dest;
213    int                build_flag;
214    struct arb_params *params;
215    char              *command_flag;
216
217    params             = arb_trace_argv(&argc,argv);
218    PT_init_psg();
219    GB_install_pid(0);          /* not arb_clean able */
220    aisc_core_on_error = 0;
221    physical_memory    = GB_get_physical_memory();
222#if defined(DEBUG)
223    printf("physical_memory=%lu k (%lu Mb)\n", physical_memory, physical_memory/1024UL);
224#endif // DEBUG
225
226    /***** try to open com with any other pb server ******/
227    if ((argc>2)                         ||
228        ((argc<2) && !params->db_server) ||
229        (argc >= 2 && strcmp(argv[1], "--help") == 0))
230    {
231        printf("Syntax: %s [-look/-build/-kill/-QUERY] -Dfile.arb -TSocketid\n",argv[0]);
232        exit(EXIT_FAILURE);
233    }
234    if (argc==2) {
235        command_flag = argv[1];
236    }
237    else {
238        static char flag[] = "-boot";
239        command_flag = flag;
240    }
241
242    if (!(name = params->tcp)) {
243        if( !(name=GBS_read_arb_tcp("ARB_PT_SERVER0")) ){
244            GB_print_error();
245            exit(EXIT_FAILURE);
246        }
247    }
248
249    aisc_main = create_PT_main();
250   
251    aname = params->db_server;
252    tname = GBS_global_string_copy("%s.pt", aname);
253
254    if (!strcmp(command_flag, "-build")) {  /* build command */
255        if (( error = pt_init_main_struct(aisc_main, params->db_server) ))
256        {
257            printf("PT_SERVER: Gave up:\nERROR: %s\n", error);
258            exit(EXIT_FAILURE);
259        }
260        enter_stage_1_build_tree(aisc_main,tname);
261
262        {
263            char *msg = GBS_global_string_copy("PT_SERVER database \"%s\" has been created.", params->db_server);
264            puts(msg);
265            GBS_add_ptserver_logentry(msg);
266
267            char *command = GBS_global_string_copy("arb_message '%s'", msg);
268
269            if (system(command) != 0) {
270                fprintf(stderr, "Failed to run '%s'\n", command);
271            }
272            free(command);
273            free(msg);
274        }
275
276        exit(EXIT_SUCCESS);
277    }
278    if (!strcmp(command_flag, "-QUERY")) {
279        if (( error = pt_init_main_struct(aisc_main, params->db_server) ))
280        {
281            printf("PT_SERVER: Gave up:\nERROR: %s\n", error);
282            exit(EXIT_FAILURE);
283        }
284        enter_stage_3_load_tree(aisc_main,tname); /* now stage 3 */
285        printf("Tree loaded - performing checks..\n");
286        PT_debug_tree();
287        printf("Checks done");
288        exit(EXIT_SUCCESS);
289    }
290    psg.link = (aisc_com *) aisc_open(name, &psg.main, AISC_MAGIC_NUMBER);
291    if (psg.link) {
292        if (strcmp(command_flag, "-look") == 0) {
293            exit(EXIT_SUCCESS); /* already another server */
294        }
295        printf("There is another activ server. I try to kill him...\n");
296        aisc_nput(psg.link, PT_MAIN, psg.main,
297                  MAIN_SHUTDOWN, "47@#34543df43%&3667gh",
298                  NULL);
299        aisc_close(psg.link); psg.link      = 0;
300    }
301    if (strcmp(command_flag, "-kill") == 0) {
302        exit(EXIT_SUCCESS);
303    }
304    printf("\nTUM POS_TREE SERVER (Oliver Strunk) V 1.0 (C) 1993 \ninitializing:\n");
305    printf("open connection...\n");
306    sleep(1);
307    for (i = 0, so = 0; (i < MAX_TRY) && (!so); i++) {
308        so = open_aisc_server(name, TIME_OUT,0);
309        if (!so)
310            sleep(10);
311    }
312    if (!so) {
313        printf("PT_SERVER: Gave up on opening the communication socket!\n");
314        exit(EXIT_FAILURE);
315    }
316    psg.com_so = so;
317    /**** init server main struct ****/
318    printf("Init internal structs...\n");
319
320    /****** all ok: main'loop' ********/
321    if (stat(aname,&s_source)) {
322        printf("PT_SERVER error while stat source %s\n",aname);
323        aisc_server_shutdown_and_exit(so, EXIT_FAILURE); // never returns
324    }
325    build_flag = 0;
326    if (stat(tname,&s_dest)) {
327        build_flag = 1;
328    }
329    else {
330        if ( (s_source.st_mtime>s_dest.st_mtime) || (s_dest.st_size == 0)) {
331            printf("PT_SERVER: Source %s has been modified more recently than %s\n",aname,tname);
332            build_flag = 1;
333        }
334    }
335    if (build_flag) {
336        char buf[256];
337        sprintf(buf,"%s -build -D%s",argv[0],params->db_server);
338        printf("Executing '%s'\n", buf);
339        if (system(buf) != 0) {
340            printf("Error building pt-server.\n");
341            exit(EXIT_FAILURE);
342        }
343    }
344
345    {
346        void *reserved_for_mmap = NULL;
347        long  size_of_file      = GB_size_of_file(tname);
348        if(size_of_file > 0) {
349            reserved_for_mmap = malloc(size_of_file);
350            if (!reserved_for_mmap) {
351                printf("Can't reserve enough memory to map pt file!\n");
352                exit(EXIT_FAILURE);
353            }
354        }
355   
356        if (( error = pt_init_main_struct(aisc_main, params->db_server) ))
357        {
358            printf("PT_SERVER: Gave up:\nERROR: %s\n", error);
359            aisc_server_shutdown_and_exit(so, EXIT_FAILURE); // never returns
360        }
361        if(reserved_for_mmap) free(reserved_for_mmap);
362    }
363    enter_stage_3_load_tree(aisc_main,tname);
364
365    PT_init_map();
366
367    printf("ok, server is running.\n"); // do NOT change or remove! others depend on it
368    fflush(stdout);
369    aisc_accept_calls(so);
370    aisc_server_shutdown_and_exit(so, EXIT_SUCCESS); // never returns
371}
Note: See TracBrowser for help on using the repository browser.