source: branches/port5/ARBDB/adcomm.c

Last change on this file was 6143, checked in by westram, 15 years ago
  • backport [6141] (parts changing code, but only strings and comments)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 70.1 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include <sys/uio.h>
6#include <errno.h>
7/*#include "arbdb.h"*/
8#include "adlocal.h"
9
10#include <sys/types.h>
11#include <sys/socket.h>
12#include <sys/un.h>
13#include <netinet/in.h>
14#include <netinet/tcp.h>
15#include <arpa/inet.h>
16#include <netdb.h>
17#include <signal.h>
18#include <time.h>
19#include <sys/time.h>
20
21#if defined(SUN4) || defined(SUN5)
22# ifndef __cplusplus
23#  define SIG_PF void (*)()
24# else
25#  include <sysent.h>   /* c++ only for sun */
26# endif
27#else
28# define SIG_PF void (*)(int )
29#endif
30
31#define FD_SET_TYPE
32
33#define debug_printf(a,b)
34
35#define GBCMS_TRANSACTION_TIMEOUT 60*60
36/* one hour timeout */
37#define MAX_QUEUE_LEN             5
38
39#define GBCM_COMMAND_UNFOLD             (GBTUM_MAGIC_NUMBER)
40#define GBCM_COMMAND_GET_UPDATA         (GBTUM_MAGIC_NUMBER+1)
41#define GBCM_COMMAND_PUT_UPDATE         (GBTUM_MAGIC_NUMBER+2)
42#define GBCM_COMMAND_UPDATED            (GBTUM_MAGIC_NUMBER+3)
43#define GBCM_COMMAND_BEGIN_TRANSACTION  (GBTUM_MAGIC_NUMBER+4)
44#define GBCM_COMMAND_COMMIT_TRANSACTION (GBTUM_MAGIC_NUMBER+5)
45#define GBCM_COMMAND_ABORT_TRANSACTION  (GBTUM_MAGIC_NUMBER+6)
46#define GBCM_COMMAND_INIT_TRANSACTION   (GBTUM_MAGIC_NUMBER+7)
47#define GBCM_COMMAND_FIND               (GBTUM_MAGIC_NUMBER+8)
48#define GBCM_COMMAND_CLOSE              (GBTUM_MAGIC_NUMBER+9)
49#define GBCM_COMMAND_SYSTEM             (GBTUM_MAGIC_NUMBER+10)
50#define GBCM_COMMAND_KEY_ALLOC          (GBTUM_MAGIC_NUMBER+11)
51#define GBCM_COMMAND_UNDO               (GBTUM_MAGIC_NUMBER+12)
52#define GBCM_COMMAND_DONT_WAIT          (GBTUM_MAGIC_NUMBER+13)
53
54#define GBCM_COMMAND_SEND               (GBTUM_MAGIC_NUMBER+0x1000)
55#define GBCM_COMMAND_SEND_COUNT         (GBTUM_MAGIC_NUMBER+0x2000)
56#define GBCM_COMMAND_SETDEEP            (GBTUM_MAGIC_NUMBER+0x3000)
57#define GBCM_COMMAND_SETINDEX           (GBTUM_MAGIC_NUMBER+0x4000)
58#define GBCM_COMMAND_PUT_UPDATE_KEYS    (GBTUM_MAGIC_NUMBER+0x5000)
59#define GBCM_COMMAND_PUT_UPDATE_CREATE  (GBTUM_MAGIC_NUMBER+0x6000)
60#define GBCM_COMMAND_PUT_UPDATE_DELETE  (GBTUM_MAGIC_NUMBER+0x7000)
61#define GBCM_COMMAND_PUT_UPDATE_UPDATE  (GBTUM_MAGIC_NUMBER+0x8000)
62#define GBCM_COMMAND_PUT_UPDATE_END     (GBTUM_MAGIC_NUMBER+0x9000)
63#define GBCM_COMMAND_TRANSACTION_RETURN (GBTUM_MAGIC_NUMBER+0x100000)
64#define GBCM_COMMAND_FIND_ERG           (GBTUM_MAGIC_NUMBER+0x108000)
65#define GBCM_COMMAND_KEY_ALLOC_RES      (GBTUM_MAGIC_NUMBER+0x10b000)
66#define GBCM_COMMAND_SYSTEM_RETURN      (GBTUM_MAGIC_NUMBER+0x10a0000)
67#define GBCM_COMMAND_UNDO_CMD           (GBTUM_MAGIC_NUMBER+0x10a0001)
68
69/*********************************** some structures *************************************/
70/** Store all deleted items in a list */
71struct gbcms_delete_list {
72    struct gbcms_delete_list *next;
73    long            creation_date;
74    long            update_date;
75    GBDATA          *gbd;
76};
77
78struct Socinf {
79    struct Socinf *next;
80    int socket;
81    struct  gbcms_delete_list   *dl;    /* point to last deleted item that is sent to
82                                           this client */
83    char    *username;
84};
85
86void g_bcms_delete_Socinf(struct Socinf *THIS){
87    freeset(THIS->username, NULL);
88    THIS->next = 0;
89    free(THIS);
90}
91
92struct Hs_struct {
93    int hso;
94    char    *unix_name;
95    struct Socinf *soci;
96    long nsoc;
97    long timeout;
98    GBDATA *gb_main;
99    int     wait_for_new_request;
100    struct gbcms_delete_list    *del_first; /* All deleted items, that are yet
101                                               unknown to at least one client */
102    struct gbcms_delete_list    *del_last;
103};
104
105
106
107struct gbcms_create_struct {
108    struct gbcms_create_struct *next;
109    GBDATA  *server_id;
110    GBDATA  *client_id;
111};
112
113
114/* -------------------- */
115/*      Panic save      */
116 
117GBCONTAINER *gbcms_gb_main;
118
119void *gbcms_sighup(void){
120    char *panic_file = 0;                      // hang-up trigger file
121    char *db_panic   = 0;                      // file to save DB to
122    {
123        const char *ap = GB_getenv("ARB_PID");
124        if (!ap) ap    = "";
125
126        FILE *in = GB_fopen_tempfile(GBS_global_string("arb_panic_%s_%s", GB_getenvUSER(), ap), "rt", &panic_file);
127
128        fprintf(stderr,
129                "**** ARB DATABASE SERVER received a HANGUP SIGNAL ****\n"
130                "- Looking for file '%s'\n",
131                panic_file);
132
133        db_panic = GB_read_fp(in);
134        fclose(in);
135    }
136
137    if (!db_panic) {
138        fprintf(stderr,
139                "- Could not read '%s' (Reason: %s)\n"
140                "[maybe retry]\n",
141                panic_file, GB_await_error());
142    }
143    else {
144        char *newline           = strchr(db_panic, '\n');
145        if (newline) newline[0] = 0;
146
147        GB_MAIN_TYPE *Main       = GBCONTAINER_MAIN(gbcms_gb_main);
148        int           translevel = Main->transaction;
149
150        fprintf(stderr, "- Trying to save DATABASE in ASCII mode into file '%s'\n", db_panic);
151
152        Main->transaction = 0;
153        GB_ERROR error    = GB_save_as((GBDATA *) gbcms_gb_main, db_panic, "a");
154       
155        if (error) fprintf(stderr, "Error while saving '%s': %s\n", db_panic, error);
156        else fprintf(stderr, "- DATABASE saved into '%s' (ASCII)\n", db_panic);
157
158        unlink(panic_file);
159        Main->transaction = translevel;
160
161        free(db_panic);
162    }
163
164    return 0;
165}
166
167
168
169/**************************************************************************************
170                server open
171***************************************************************************************/
172
173GB_ERROR GBCMS_open(const char *path, long timeout, GBDATA *gb_main) {
174    GB_MAIN_TYPE *Main  = GB_MAIN(gb_main);
175    GB_ERROR      error = 0;
176
177    if (Main->server_data) {
178        error = "reopen of server not allowed";
179    }
180    else {
181        struct gbcmc_comm *comm = gbcmc_open(path);
182        if (comm) {
183            error = GBS_global_string("Socket '%s' already in use", path);
184            gbcmc_close(comm);
185        }
186        else {
187            int   socket;
188            char *unix_name;
189
190            error = gbcm_open_socket(path, TCP_NODELAY, 0, &socket, &unix_name);
191            if (!error) {
192                signal(SIGPIPE,(SIG_PF)gbcms_sigpipe);
193                signal(SIGHUP,(SIG_PF)gbcms_sighup);
194
195                gbcms_gb_main = (GBCONTAINER *)gb_main;
196
197                if (listen(socket, MAX_QUEUE_LEN) < 0) {
198                    error = GBS_global_string("could not listen (server; errno=%i)", errno);
199                }
200                else {
201                    struct Hs_struct *hs = (struct Hs_struct *)GB_calloc(sizeof(struct Hs_struct),1);
202
203                    hs->timeout   = timeout;
204                    hs->gb_main   = gb_main;
205                    hs->hso       = socket;
206                    hs->unix_name = unix_name;
207
208                    Main->server_data = (void *)hs;
209                }
210            }
211        }
212    }
213
214    if (error) {
215        error = GBS_global_string("ARB_DB_SERVER_ERROR: %s", error);
216        fprintf(stderr, "%s\n", error);
217    }
218    return error;
219}
220
221
222/**************************************************************************************
223                server close
224***************************************************************************************/
225
226void GBCMS_shutdown(GBDATA *gbd) {
227    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
228    if (Main->server_data) {
229        struct Hs_struct *hs = (struct Hs_struct *)Main->server_data;
230        struct Socinf    *si;
231
232        for (si=hs->soci; si; si=si->next) {
233            shutdown(si->socket, 2);  /* 2 = both dir */
234            close(si->socket);
235        }
236        shutdown(hs->hso, 2);
237       
238        if (hs->unix_name){
239            unlink(hs->unix_name);
240            freeset(hs->unix_name, NULL);
241        }
242        close(hs->hso);
243        freeset(Main->server_data, NULL);
244    }
245}
246
247/**************************************************************************************
248                server send deleted and updated
249***************************************************************************************/
250void gbcms_shift_delete_list(void *hsi,void *soi)
251{
252    struct Hs_struct *hs = (struct Hs_struct *)hsi;
253    struct Socinf *socinf   = (struct Socinf *)soi;
254    if (!hs->del_first) return;
255    while ( (!socinf->dl) || (socinf->dl->next) ) {
256        if (!socinf->dl) socinf->dl = hs->del_first;
257        else    socinf->dl = socinf->dl->next;
258    }
259}
260
261/**************************************************************************************
262                server send deleted and updated
263***************************************************************************************/
264int gbcms_write_deleted(int socket,GBDATA *gbd,long hsin,long client_clock, long *buffer)
265{
266    struct Socinf *socinf;
267    struct Hs_struct *hs;
268    struct gbcms_delete_list *dl;
269
270    hs = (struct Hs_struct *)hsin;
271    for (socinf = hs->soci;socinf;socinf=socinf->next){
272        if (socinf->socket == socket) break;
273    }
274    if (!socinf) return 0;
275    if (!hs->del_first) return 0;
276    while (!socinf->dl || (socinf->dl->next) ) {
277        if (!socinf->dl) socinf->dl = hs->del_first;
278        else    socinf->dl = socinf->dl->next;
279        if (socinf->dl->creation_date>client_clock) continue;
280        /* created and deleted object */
281        buffer[0] = GBCM_COMMAND_PUT_UPDATE_DELETE;
282        buffer[1] = (long)socinf->dl->gbd;
283        if (gbcm_write(socket,(const char *)buffer,sizeof(long)*2) ) return GBCM_SERVER_FAULT;
284    }
285    for (socinf = hs->soci;socinf;socinf=socinf->next){
286        if (!socinf->dl) return 0;
287    }
288    while ( (dl = hs->del_first) ) {
289        for (socinf = hs->soci;socinf;socinf=socinf->next){
290            if (socinf->dl == dl) return 0;
291        }
292        hs->del_first = dl->next;
293        gbm_free_mem((char *)dl,sizeof(struct gbcms_delete_list),GBM_CB_INDEX);
294    }
295    gbd = gbd;
296    return 0;
297}
298
299
300
301int gbcms_write_updated(int socket,GBDATA *gbd,long hsin,long client_clock, long *buffer)
302{
303    struct Hs_struct *hs;
304    int send_header = 0;
305
306    if (GB_GET_EXT_UPDATE_DATE(gbd)<=client_clock) return 0;
307    hs = (struct Hs_struct *)hsin;
308    if ( GB_GET_EXT_CREATION_DATE(gbd) > client_clock) {
309        buffer[0] = GBCM_COMMAND_PUT_UPDATE_CREATE;
310        buffer[1] = (long)GB_FATHER(gbd);
311        if (gbcm_write(socket,(const char *)buffer,sizeof(long)*2) ) return GBCM_SERVER_FAULT;
312        gbcm_write_bin(socket,gbd,buffer,1,0,1);
313    }else{      /* send clients first */
314        if (GB_TYPE(gbd) == GB_DB)
315        {
316            GBDATA      *gb2;
317            GBCONTAINER *gbc = ((GBCONTAINER *)gbd);
318            int          index,end;
319
320            end = (int)gbc->d.nheader;
321            if ( gbc->header_update_date > client_clock) send_header = 1;
322
323            buffer[0] = GBCM_COMMAND_PUT_UPDATE_UPDATE;
324            buffer[1] = (long)gbd;
325            if (gbcm_write(socket,(const char *)buffer,sizeof(long)*2) ) return GBCM_SERVER_FAULT;
326            gbcm_write_bin(socket,gbd,buffer,1,0,send_header);
327
328            for (index = 0; index < end; index++) {
329                if ( (gb2 = GBCONTAINER_ELEM(gbc,index)) ) {
330                    if (gbcms_write_updated(socket,gb2,hsin,client_clock,buffer))
331                        return GBCM_SERVER_FAULT;
332                }
333            }
334        }else{
335            buffer[0] = GBCM_COMMAND_PUT_UPDATE_UPDATE;
336            buffer[1] = (long)gbd;
337            if (gbcm_write(socket,(const char *)buffer,sizeof(long)*2) ) return GBCM_SERVER_FAULT;
338            gbcm_write_bin(socket,gbd,buffer,1,0,send_header);
339        }
340    }
341
342    return 0;
343}
344
345int gbcms_write_keys(int socket,GBDATA *gbd)
346{
347    int i;
348    long buffer[4];
349    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
350
351    buffer[0] = GBCM_COMMAND_PUT_UPDATE_KEYS;
352    buffer[1] = (long)gbd;
353    buffer[2] = Main->keycnt;
354    buffer[3] = Main->first_free_key;
355    if (gbcm_write(socket,(const char *)buffer,4*sizeof(long)) ) return GBCM_SERVER_FAULT;
356
357    for (i=1;i<Main->keycnt;i++) {
358        buffer[0] = Main->keys[i].nref;
359        buffer[1] = Main->keys[i].next_free_key;
360        if (gbcm_write(socket,(const char *)buffer,sizeof(long)*2) ) return GBCM_SERVER_FAULT;
361        if (gbcm_write_string(socket,Main->keys[i].key )) return GBCM_SERVER_FAULT;
362    }
363    return 0;
364}
365
366/**************************************************************************************
367                server gbcms_talking_unfold
368                GBCM_COMMAND_UNFOLD
369***************************************************************************************/
370int gbcms_talking_unfold(int socket,long *hsin,void *sin, GBDATA *gb_in)
371{
372    GBCONTAINER *gbc = (GBCONTAINER *)gb_in;
373    GB_ERROR     error;
374    GBDATA      *gb2;
375    char        *buffer;
376    long         deep[1];
377    long         index_pos[1];
378    int          index,start,end;
379
380    GBUSE(hsin);GBUSE(sin);
381    if ( (error = gbcm_test_address((long *)gbc,GBTUM_MAGIC_NUMBER))) {
382        return GBCM_SERVER_FAULT;
383    }
384    if (GB_TYPE(gbc) != GB_DB) return 1;
385    if (gbcm_read_two(socket,GBCM_COMMAND_SETDEEP,0,deep)){
386        return GBCM_SERVER_FAULT;
387    }
388    if (gbcm_read_two(socket,GBCM_COMMAND_SETINDEX,0,index_pos)){
389        return GBCM_SERVER_FAULT;
390    }
391
392    gbcm_read_flush(socket);
393    buffer = GB_give_buffer(1014);
394
395    if (index_pos[0]==-2) {
396        error = gbcm_write_bin(socket,gb_in,(long *)buffer,1,deep[0]+1,1);
397        if (error) {
398            return GBCM_SERVER_FAULT;
399        }
400        gbcm_write_flush(socket);
401        return 0;
402    }
403
404    if (index_pos[0] >= 0) {
405        start  = (int)index_pos[0];
406        end = start + 1;
407        if (gbcm_write_two(socket,GBCM_COMMAND_SEND_COUNT, 1)){
408            return GBCM_SERVER_FAULT;
409        }
410    }else{
411        start = 0;
412        end = gbc->d.nheader;
413        if (gbcm_write_two(socket,GBCM_COMMAND_SEND_COUNT, gbc->d.size)){
414            return GBCM_SERVER_FAULT;
415        }
416    }
417    for (index = start; index < end; index++) {
418        if ( (gb2 = GBCONTAINER_ELEM(gbc,index)) ) {
419            error = gbcm_write_bin(socket,gb2,(long *)buffer,1,deep[0],1);
420            if (error) {
421                return GBCM_SERVER_FAULT;
422            }
423        }
424    }
425
426    gbcm_write_flush(socket);
427    return 0;
428}
429/**************************************************************************************
430                server gbcms_talking_get_update
431***************************************************************************************/
432int gbcms_talking_get_update(int socket,long *hsin,void *sin,GBDATA *gbd)
433{
434    struct Hs_struct *hs = (struct Hs_struct *)hsin;
435    GBUSE(hs);
436    socket = socket;
437    gbd = gbd;
438    sin = sin;
439    return 0;
440}
441/**************************************************************************************
442                server gbcms_talking_put_update
443                GBCM_COMMAND_PUT_UPDATE
444***************************************************************************************/
445int
446gbcms_talking_put_update(int socket, long *hsin, void *sin,GBDATA * gbd_dummy)
447{
448    /* reads the date from a client
449       read all changed data of the client */
450    GB_ERROR       error;
451    long        irror;
452    GBDATA         *gbd;
453    struct gbcms_create_struct *cs[1], *cs_main[1];
454    long            *buffer;
455    GB_BOOL     end;
456    struct Hs_struct *hs = (struct Hs_struct *) hsin;
457    GBUSE(hs); GBUSE(sin);
458    sin = sin;
459    gbd_dummy = gbd_dummy;
460    cs_main[0] = 0;
461    buffer = (long *) GB_give_buffer(1024);
462    end = GB_FALSE;
463    while (!end) {
464        if (gbcm_read(socket, (char *) buffer, sizeof(long) * 3) != sizeof(long) * 3)
465            return GBCM_SERVER_FAULT;
466        gbd = (GBDATA *) buffer[2];
467        if ( (error = gbcm_test_address((long *)gbd,GBTUM_MAGIC_NUMBER))) {
468            GB_export_errorf("address %p not valid 3712",gbd);
469            GB_print_error();
470            return GBCM_SERVER_FAULT;
471        }
472        switch (buffer[0]) {
473            case GBCM_COMMAND_PUT_UPDATE_CREATE:
474                irror = gbcm_read_bin(socket,
475                                      (GBCONTAINER *)gbd, buffer, 1, 0,(void *)cs_main);
476                if (irror) return GBCM_SERVER_FAULT;
477                break;
478            case GBCM_COMMAND_PUT_UPDATE_DELETE:
479                gb_delete_force(gbd);
480                break;
481            case GBCM_COMMAND_PUT_UPDATE_UPDATE:
482                irror = gbcm_read_bin(socket,0,buffer, 1,gbd,0);
483                if (irror) return GBCM_SERVER_FAULT;
484                break;
485            case GBCM_COMMAND_PUT_UPDATE_END:
486                end = GB_TRUE;
487                break;
488            default:
489                return GBCM_SERVER_FAULT;
490        }
491    }
492    gbcm_read_flush(socket);            /* send all id's of newly created
493                            objects */
494    for (cs[0] = cs_main[0];cs[0];cs[0]=cs_main[0]) {
495        cs_main[0] = cs[0]->next;
496        buffer[0] = (long)cs[0]->client_id;
497        buffer[1] = (long)cs[0]->server_id;
498        if (gbcm_write(socket,(const char *)buffer, sizeof(long)*2)) return GBCM_SERVER_FAULT;
499        free((char *)cs[0]);
500    }
501    buffer[0] = 0;
502    if (gbcm_write(socket,(const char *)buffer,sizeof(long)*2)) return GBCM_SERVER_FAULT;
503    gbcm_write_flush(socket);
504    return 0;
505}
506/**************************************************************************************
507                server gbcms_talking_updated
508***************************************************************************************/
509int gbcms_talking_updated(int socket,long *hsin,void *sin, GBDATA *gbd)
510{
511    struct Hs_struct *hs = (struct Hs_struct *)hsin;
512    GBUSE(hs);
513    socket = socket;
514    gbd = gbd;
515    sin = sin;
516    return 0;
517}
518
519/**************************************************************************************
520                server gbcms_talking_begin_transaction
521                GBCM_COMMAND_INIT_TRANSACTION
522***************************************************************************************/
523int gbcms_talking_init_transaction(int socket,long *hsin,void *sin,GBDATA *gb_dummy)
524     /* begin client transaction
525        send        clock
526    */
527{
528    GBDATA *gb_main;
529    GBDATA *gbd;
530    struct Hs_struct *hs = (struct Hs_struct *)hsin;
531    struct Socinf   *si  = (struct Socinf *)sin;
532    long anz;
533    long    *buffer;
534    char    *user;
535    fd_set set;
536    struct timeval timeout;
537    GB_MAIN_TYPE *Main;
538
539    gb_dummy = gb_dummy;
540    gb_main = hs->gb_main;
541    Main = GB_MAIN(gb_main);
542    gbd = gb_main;
543    user = gbcm_read_string(socket);
544    gbcm_read_flush(socket);
545    if (gbcm_login((GBCONTAINER *)gbd,user)) {
546        return GBCM_SERVER_FAULT;
547    }
548    si->username = user;
549
550    gb_local->running_client_transaction = ARB_TRANS;
551
552    if (gbcm_write_two(socket,GBCM_COMMAND_TRANSACTION_RETURN,Main->clock)){
553        return GBCM_SERVER_FAULT;
554    }
555    if (gbcm_write_two(socket,GBCM_COMMAND_TRANSACTION_RETURN,(long)gbd)){
556        return GBCM_SERVER_FAULT;
557    }
558    if (gbcm_write_two(socket,GBCM_COMMAND_TRANSACTION_RETURN,
559                       (long)Main->this_user->userid)){
560        return GBCM_SERVER_FAULT;
561    }
562    gbcms_write_keys(socket,gbd);
563
564    gbcm_write_flush(socket);
565    /* send modified data to client */
566    buffer = (long *)GB_give_buffer(1024);
567
568    GB_begin_transaction(gbd);
569    while (gb_local->running_client_transaction == ARB_TRANS){
570
571        FD_ZERO(&set);
572        FD_SET(socket,&set);
573
574        timeout.tv_sec  = GBCMS_TRANSACTION_TIMEOUT;
575        timeout.tv_usec = 100000;
576
577        anz = select(FD_SETSIZE,FD_SET_TYPE &set,NULL,NULL,&timeout);
578
579        if (anz<0) continue;
580        if (anz==0) {
581            GB_export_errorf("ARB_DB ERROR CLIENT TRANSACTION TIMEOUT, CLIENT DISCONNECTED (I waited %lu seconds)",timeout.tv_sec);
582            GB_print_error();
583            gb_local->running_client_transaction = ARB_ABORT;
584            GB_abort_transaction(gbd);
585            return GBCM_SERVER_FAULT;
586        }
587        if( GBCM_SERVER_OK == gbcms_talking(socket,hsin,sin )) continue;
588        gb_local->running_client_transaction = ARB_ABORT;
589        GB_abort_transaction(gbd);
590        return GBCM_SERVER_FAULT;
591    }
592    if (gb_local->running_client_transaction == ARB_COMMIT) {
593        GB_commit_transaction(gbd);
594        gbcms_shift_delete_list(hsin,sin);
595    }else{
596        GB_abort_transaction(gbd);
597    }
598    return 0;
599}
600/**************************************************************************************
601                server gbcms_talking_begin_transaction
602                GBCM_COMMAND_BEGIN_TRANSACTION
603***************************************************************************************/
604int gbcms_talking_begin_transaction(int socket,long *hsin,void *sin, long client_clock)
605     /* begin client transaction
606        send        clock
607                deleted
608                created+updated
609    */
610{
611    GBDATA *gb_main;
612    GBDATA *gbd;
613    struct Hs_struct *hs = (struct Hs_struct *)hsin;
614    long anz;
615    long    *buffer;
616    fd_set set;
617    struct timeval timeout;
618
619    gb_main = hs->gb_main;
620    gbd = gb_main;
621    gbcm_read_flush(socket);
622    gb_local->running_client_transaction = ARB_TRANS;
623
624    if (gbcm_write_two(socket,GBCM_COMMAND_TRANSACTION_RETURN,GB_MAIN(gbd)->clock)){
625        return GBCM_SERVER_FAULT;
626    }
627
628    /* send modified data to client */
629    buffer = (long *)GB_give_buffer(1024);
630    if (GB_MAIN(gb_main)->key_clock > client_clock) {
631        if (gbcms_write_keys(socket,gbd)) return GBCM_SERVER_FAULT;
632    }
633    if (gbcms_write_deleted(socket,gbd,(long)hs,client_clock,buffer)) return GBCM_SERVER_FAULT;
634    if (gbcms_write_updated(socket,gbd,(long)hs,client_clock,buffer)) return GBCM_SERVER_FAULT;
635    buffer[0] = GBCM_COMMAND_PUT_UPDATE_END;
636    buffer[1] = 0;
637    if (gbcm_write(socket,(const char *)buffer,sizeof(long)*2)) return GBCM_SERVER_FAULT;
638    if (gbcm_write_flush(socket))       return GBCM_SERVER_FAULT;
639
640    GB_begin_transaction(gbd);
641    while (gb_local->running_client_transaction == ARB_TRANS){
642        FD_ZERO(&set);
643        FD_SET(socket,&set);
644
645        timeout.tv_sec  = GBCMS_TRANSACTION_TIMEOUT;
646        timeout.tv_usec = 0;
647
648        anz = select(FD_SETSIZE,FD_SET_TYPE &set,NULL,NULL,&timeout);
649
650        if (anz<0) continue;
651        if (anz==0) {
652            GB_export_errorf("ARB_DB ERROR CLIENT TRANSACTION TIMEOUT, CLIENT DISCONNECTED (I waited %lu seconds)",timeout.tv_sec);
653            GB_print_error();
654            gb_local->running_client_transaction = ARB_ABORT;
655            GB_abort_transaction(gbd);
656            return GBCM_SERVER_FAULT;
657        }
658        if( GBCM_SERVER_OK == gbcms_talking(socket,hsin,sin )) continue;
659        gb_local->running_client_transaction = ARB_ABORT;
660        GB_abort_transaction(gbd);
661        return GBCM_SERVER_FAULT;
662    }
663    if (gb_local->running_client_transaction == ARB_COMMIT) {
664        GB_commit_transaction(gbd);
665        gbcms_shift_delete_list(hsin,sin);
666    }else{
667        GB_abort_transaction(gbd);
668    }
669    return 0;
670}
671/**************************************************************************************
672                server gbcms_talking_commit_transaction
673                GBCM_COMMAND_COMMIT_TRANSACTION
674***************************************************************************************/
675int gbcms_talking_commit_transaction(int socket,long *hsin,void *sin, GBDATA *gbd)
676{
677    GB_ERROR error = 0;
678    struct Hs_struct *hs = (struct Hs_struct *)hsin;
679    GBUSE(hs);
680    sin = sin;
681    if ( (error = gbcm_test_address((long *)gbd,GBTUM_MAGIC_NUMBER)) ) {
682        GB_export_errorf("address %p not valid 4783",gbd);
683        GB_print_error();
684        if (error) return GBCM_SERVER_FAULT;
685        return GBCM_SERVER_OK;
686    }
687    gb_local->running_client_transaction = ARB_COMMIT;
688    gbcm_read_flush(socket);
689    if (gbcm_write_two(socket,GBCM_COMMAND_TRANSACTION_RETURN,0)){
690        return GBCM_SERVER_FAULT;
691    }
692    if (gbcm_write_flush(socket)){
693        return GBCM_SERVER_FAULT;
694    }
695    return GBCM_SERVER_OK;
696}
697/**************************************************************************************
698                server gbcms_talking_abort_transaction
699                GBCM_COMMAND_ABORT_TRANSACTION
700***************************************************************************************/
701int gbcms_talking_abort_transaction(int socket,long *hsin,void *sin, GBDATA *gbd)
702{
703    GB_ERROR error;
704    struct Hs_struct *hs = (struct Hs_struct *)hsin;
705    GBUSE(hs);
706    sin = sin;
707    if ( (error = gbcm_test_address((long *)gbd,GBTUM_MAGIC_NUMBER)) ) {
708        GB_export_errorf("address %p not valid 4356",gbd);
709        GB_print_error();
710        return GBCM_SERVER_FAULT;
711    }
712    gb_local->running_client_transaction = ARB_ABORT;
713    gbcm_read_flush(socket);
714    if (gbcm_write_two(socket,GBCM_COMMAND_TRANSACTION_RETURN,0)){
715        return GBCM_SERVER_FAULT;
716    }
717    if (gbcm_write_flush(socket)){
718        return GBCM_SERVER_FAULT;
719    }
720    return 0;
721}
722/**************************************************************************************
723                gbcms_talking_close
724                GBCM_COMMAND_CLOSE
725***************************************************************************************/
726int gbcms_talking_close(int socket,long *hsin,void *sin,GBDATA *gbd)
727{
728    gbd = gbd;
729    socket = socket;
730    hsin = hsin;
731    sin = sin;
732    return GBCM_SERVER_ABORTED;
733}
734
735/**************************************************************************************
736                gbcms_talking_system
737                GBCM_COMMAND_SYSTEM
738***************************************************************************************/
739int gbcms_talking_system(int socket,long *hsin,void *sin,GBDATA *gbd)
740{
741    char *comm = gbcm_read_string(socket);
742
743    gbcm_read_flush(socket);
744    gbd    = gbd;
745    socket = socket;
746    hsin   = hsin;
747    sin    = sin;
748
749    GB_ERROR error = GB_system(comm);
750    if (error) {
751        GB_warning(error);
752        return GBCM_SERVER_FAULT;
753    }
754
755    if (gbcm_write_two(socket,GBCM_COMMAND_SYSTEM_RETURN,0)){
756        return GBCM_SERVER_FAULT;
757    }
758    if (gbcm_write_flush(socket)){
759        return GBCM_SERVER_FAULT;
760    }
761    return GBCM_SERVER_OK;
762}
763
764/**************************************************************************************
765                gbcms_talking_undo
766                GBCM_COMMAND_UNDO
767***************************************************************************************/
768int gbcms_talking_undo(int socket,long *hsin,void *sin,GBDATA *gbd)
769{
770    long cmd;
771    GB_ERROR result = 0;
772    char *to_free = 0;
773    if (gbcm_read_two(socket, GBCM_COMMAND_UNDO_CMD,0,&cmd)){
774        return GBCM_SERVER_FAULT;
775    }
776    gbcm_read_flush(socket);
777    hsin = hsin;
778    sin = sin;
779    switch (cmd) {
780        case _GBCMC_UNDOCOM_REQUEST_NOUNDO:
781            result = GB_request_undo_type(gbd, GB_UNDO_NONE);
782            break;
783        case _GBCMC_UNDOCOM_REQUEST_NOUNDO_KILL:
784            result = GB_request_undo_type(gbd, GB_UNDO_KILL);
785            break;
786        case _GBCMC_UNDOCOM_REQUEST_UNDO:
787            result = GB_request_undo_type(gbd, GB_UNDO_UNDO);
788            break;
789        case _GBCMC_UNDOCOM_INFO_UNDO:
790            result = to_free = GB_undo_info(gbd, GB_UNDO_UNDO);
791            break;
792        case _GBCMC_UNDOCOM_INFO_REDO:
793            result = to_free = GB_undo_info(gbd, GB_UNDO_REDO);
794            break;
795        case _GBCMC_UNDOCOM_UNDO:
796            result = GB_undo(gbd,GB_UNDO_UNDO);
797            break;
798        case _GBCMC_UNDOCOM_REDO:
799            result = GB_undo(gbd,GB_UNDO_REDO);
800            break;
801        default:    result = GB_set_undo_mem(gbd,cmd);
802    }
803    if (gbcm_write_string(socket,result)){
804        if (to_free) free(to_free);
805        return GBCM_SERVER_FAULT;
806    }
807    if (to_free) free(to_free);
808    if (gbcm_write_flush(socket)){
809        return GBCM_SERVER_FAULT;
810    }
811    return GBCM_SERVER_OK;
812}
813
814/**************************************************************************************
815                do a query in the server
816                GBCM_COMMAND_FIND
817***************************************************************************************/
818int gbcms_talking_find(int socket, long *hsin, void *sin, GBDATA * gbd)
819{
820    GB_ERROR  error;
821    char     *key;
822    char     *val1      = 0;
823    GB_CASE   case_sens = GB_CASE_UNDEFINED;
824    long      val2      = 0;
825    GB_TYPES  type;
826    void     *buffer[2];
827
828    struct Hs_struct *hs = (struct Hs_struct *) hsin;
829    GBUSE(hs);GBUSE(sin);
830
831    if ( (error = gbcm_test_address((long *) gbd, GBTUM_MAGIC_NUMBER)) ) {
832        GB_export_errorf("address %p not valid 8734", gbd);
833        GB_print_error();
834        return GBCM_SERVER_FAULT;
835    }
836
837    key  = gbcm_read_string(socket);
838    type = gbcm_read_long(socket);
839
840    switch (type) {
841        case GB_NONE:
842            break;
843           
844        case GB_STRING:
845            val1      = gbcm_read_string(socket);
846            case_sens = gbcm_read_long(socket);;
847            break;
848
849        case GB_INT:
850            val2 = gbcm_read_long(socket);
851            break;
852           
853        default:
854            gb_assert(0);
855            GB_export_errorf("gbcms_talking_find: illegal data type (%i)", type);
856            GB_print_error();
857            return GBCM_SERVER_FAULT;
858    }
859
860    {
861        enum gb_search_types gbs = gbcm_read_long(socket);
862        gbcm_read_flush(socket);
863
864        if (type == GB_NONE) {
865            gbd = GB_find(gbd, key, gbs);
866        }
867        else if (type == GB_STRING) {
868            gbd = GB_find_string(gbd, key, val1, case_sens, gbs);
869            free(val1);
870        }
871        else if (type == GB_INT) {
872            gbd = GB_find_int(gbd, key, val2, gbs);
873        }
874        else {
875            GB_internal_errorf("Searching DBtype %i not implemented", type);
876        }
877    }
878
879    free(key);
880
881    if (gbcm_write_two(socket, GBCM_COMMAND_FIND_ERG, (long) gbd)) {
882        return GBCM_SERVER_FAULT;
883    }
884    if (gbd) {
885        while (GB_GRANDPA(gbd)) {
886            buffer[0] = (void *)gbd->index;
887            buffer[1] = (void *)GB_FATHER(gbd);
888            gbcm_write(socket, (const char *) buffer, sizeof(long) * 2 );
889            gbd = (GBDATA *)GB_FATHER(gbd);
890        }
891    }
892    buffer[0] = NULL;
893    buffer[1] = NULL;
894    gbcm_write(socket, (const char *) buffer, sizeof(long) * 2);
895
896    if (gbcm_write_flush(socket)) {
897        return GBCM_SERVER_FAULT;
898    }
899    return 0;
900}
901
902/**************************************************************************************
903                do a query in the server
904                GBCM_COMMAND_KEY_ALLOC
905***************************************************************************************/
906int
907gbcms_talking_key_alloc(int socket, long *hsin, void *sin, GBDATA * gbd)
908{
909    GB_ERROR    error;
910    char           *key;
911    long            index;
912    struct Hs_struct *hs = (struct Hs_struct *) hsin;
913    GBUSE(hs);GBUSE(sin);
914
915    if ( (error = gbcm_test_address((long *) gbd, GBTUM_MAGIC_NUMBER))) {
916        GB_export_errorf("address %p not valid 8734", gbd);
917        GB_print_error();
918        return GBCM_SERVER_FAULT;
919    }
920    key = gbcm_read_string(socket);
921    gbcm_read_flush(socket);
922
923    if (key)
924        index = gb_create_key(GB_MAIN(gbd),key,GB_FALSE);
925    else
926        index = 0;
927
928    if (key)
929        free(key);
930
931    if (gbcm_write_two(socket, GBCM_COMMAND_KEY_ALLOC_RES, index)) {
932        return GBCM_SERVER_FAULT;
933    }
934    if (gbcm_write_flush(socket)) {
935        return GBCM_SERVER_FAULT;
936    }
937    return GBCM_SERVER_OK;
938}
939
940int gbcms_talking_disable_wait_for_new_request(int socket, long *hsin, void *sin, GBDATA *gbd){
941    struct Hs_struct *hs = (struct Hs_struct *) hsin;
942    GBUSE(socket);
943    GBUSE(sin);
944    GBUSE(gbd);
945    hs->wait_for_new_request--;
946    return GBCM_SERVER_OK_WAIT;
947}
948/**************************************************************************************
949                server talking
950***************************************************************************************/
951#ifdef __cplusplus
952extern "C" {
953#endif
954    static int (*(aisc_talking_functions[]))(int,long *,void *,GBDATA *) = {
955        gbcms_talking_unfold,   /* GBCM_COMMAND_UNFOLD */
956        gbcms_talking_get_update, /* GBCM_COMMAND_GET_UPDATA */
957        gbcms_talking_put_update, /* GBCM_COMMAND_PUT_UPDATE */
958        gbcms_talking_updated,  /* GBCM_COMMAND_UPDATED */
959        ( int (*)(int , long *, void *,  GBDATA*) )gbcms_talking_begin_transaction, /* GBCM_COMMAND_BEGIN_TRANSACTION */
960        gbcms_talking_commit_transaction, /* GBCM_COMMAND_COMMIT_TRANSACTION */
961        gbcms_talking_abort_transaction, /* GBCM_COMMAND_ABORT_TRANSACTION */
962        gbcms_talking_init_transaction, /* GBCM_COMMAND_INIT_TRANSACTION */
963        gbcms_talking_find,     /* GBCM_COMMAND_FIND */
964        gbcms_talking_close,    /* GBCM_COMMAND_CLOSE */
965        gbcms_talking_system,   /* GBCM_COMMAND_SYSTEM */
966        gbcms_talking_key_alloc, /* GBCM_COMMAND_KEY_ALLOC */
967        gbcms_talking_undo,     /* GBCM_COMMAND_UNDO */
968        gbcms_talking_disable_wait_for_new_request /* GBCM_COMMAND_DONT_WAIT */
969    };
970#ifdef __cplusplus
971}
972#endif
973
974int gbcms_talking(int con,long *hs, void *sin)
975{
976    long      buf[3];
977    long             len,error;
978    long             magic_number;
979    gbcm_read_flush(con);
980 next_command:
981    len = gbcm_read(con, (char *)buf, sizeof(long) * 3);
982    if (len == sizeof(long) * 3) {
983        magic_number = buf[0];
984        if ((magic_number & GBTUM_MAGIC_NUMBER_FILTER) != GBTUM_MAGIC_NUMBER) {
985            gbcm_read_flush(con);
986            fprintf(stderr,"Illegal Access\n");
987            return GBCM_SERVER_FAULT;
988        }
989        magic_number &= ~GBTUM_MAGIC_NUMBER_FILTER;
990        error = (aisc_talking_functions[magic_number])(con,hs,sin,(GBDATA *)buf[2]);
991        if (error == GBCM_SERVER_OK_WAIT){
992            goto next_command;
993        }
994        gbcm_read_flush(con);
995        if (!error) {
996            buf[0] = GBCM_SERVER_OK;
997            return GBCM_SERVER_OK;
998        } else {
999            buf[0] = GBCM_SERVER_FAULT;
1000            return error;
1001        }
1002    } else {
1003        return GBCM_SERVER_FAULT;
1004    }
1005}
1006
1007GB_BOOL GBCMS_accept_calls(GBDATA *gbd,GB_BOOL wait_extra_time) /* returns GB_TRUE if served */
1008{
1009    struct Hs_struct *hs;
1010    int  con;
1011    long anz, i, error = 0;
1012    struct Socinf *si, *si_last, *sinext, *sptr;
1013    fd_set set,setex;
1014    struct timeval timeout;
1015    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1016    long    in_trans = GB_read_transaction(gbd);
1017    if (!Main->server_data) return GB_FALSE;
1018    if (in_trans)       return GB_FALSE;
1019    if (!Main->server_data) return GB_FALSE;
1020
1021    hs = (struct Hs_struct *)Main->server_data;
1022
1023
1024    if (wait_extra_time){
1025        timeout.tv_sec = 0;
1026        timeout.tv_usec = 100000;
1027    }else{
1028        timeout.tv_sec = (int)(hs->timeout / 1000);
1029        timeout.tv_usec = (hs->timeout % 1000) * 1000;
1030    }
1031    if (wait_extra_time){
1032        hs->wait_for_new_request = 1;
1033    }else{
1034        hs->wait_for_new_request = 0;
1035    }
1036    {
1037        FD_ZERO(&set);
1038        FD_ZERO(&setex);
1039        FD_SET(hs->hso,&set);
1040        FD_SET(hs->hso,&setex);
1041
1042        for(si=hs->soci, i=1; si; si=si->next, i++)
1043        {
1044            FD_SET(si->socket,&set);
1045            FD_SET(si->socket,&setex);
1046        }
1047
1048        if ( hs->timeout>=0) {
1049            anz = select(FD_SETSIZE,FD_SET_TYPE &set,NULL,FD_SET_TYPE &setex,&timeout);
1050        }else{
1051            anz = select(FD_SETSIZE,FD_SET_TYPE &set,NULL,FD_SET_TYPE &setex,0);
1052        }
1053
1054        if(anz==-1){
1055            /*printf("ERROR: poll in aisc_accept_calls %i\n",errno);*/
1056            return GB_FALSE;
1057        }
1058        if(!anz){ /* timed out */
1059            return GB_FALSE;
1060        }
1061
1062
1063        if(FD_ISSET(hs->hso,&set)){
1064            con = accept(hs->hso,NULL,0);
1065            if(con>0){
1066                long optval[1];
1067                sptr = (struct Socinf *)GB_calloc(sizeof(struct Socinf),1);
1068                if(!sptr) return 0;
1069                sptr->next = hs->soci;
1070                sptr->socket = con;
1071                hs->soci=sptr;
1072                hs->nsoc++;
1073                optval[0] = 1;
1074                setsockopt(con,IPPROTO_TCP,TCP_NODELAY,(char *)optval,4);
1075            }
1076        }else{
1077            si_last = 0;
1078
1079            for(si=hs->soci; si; si_last=si, si=sinext){
1080                sinext = si->next;
1081
1082                if (FD_ISSET(si->socket,&set)){
1083                    error = gbcms_talking(si->socket,(long *)hs,(void *)si);
1084                    if( GBCM_SERVER_OK == error){
1085                        hs->wait_for_new_request ++;
1086                        continue;
1087                    }
1088                }else if (!FD_ISSET(si->socket,&setex)) continue;
1089
1090                /** kill socket **/
1091
1092                if(close(si->socket)){
1093                    printf("aisc_accept_calls: ");
1094                    printf("couldn't close socket errno = %i!\n",errno);
1095                }
1096
1097                hs->nsoc--;
1098                if(si==hs->soci){ /* first one */
1099                    hs->soci = si->next;
1100                }else{
1101                    si_last->next = si->next;
1102                }
1103                if (si->username){
1104                    gbcm_logout((GBCONTAINER *)hs->gb_main,si->username);
1105                }
1106                g_bcms_delete_Socinf(si);
1107                si = 0;
1108
1109                if (error != GBCM_SERVER_ABORTED) {
1110                    fprintf(stdout,"ARB_DB_SERVER: a client died abnormally\n");
1111                }
1112                break;
1113            }
1114        }
1115
1116    } /* while main loop */
1117    if (hs->wait_for_new_request>0){
1118        return GB_TRUE;
1119    }
1120    return GB_FALSE;
1121}
1122
1123
1124/**************************************************************************************
1125                write an entry
1126***************************************************************************************/
1127GB_ERROR gbcm_write_bin(int socket,GBDATA *gbd, long *buffer, long mode, long deep, int send_headera)
1128     /* mode =1 server  =0 client   */
1129     /* send a database item to client/server
1130        buffer = buffer
1131        deep = 0 -> just send one item   >0 send sub entries too
1132        send_headera = 1 -> if type = GB_DB send flag and key_quark array
1133     */
1134{
1135    GBCONTAINER *gbc;
1136    long         i;
1137
1138    buffer[0] = GBCM_COMMAND_SEND;
1139    i = 2;
1140    buffer[i++] = (long)gbd;
1141    buffer[i++] = gbd->index;
1142    *(struct gb_flag_types *)(&buffer[i++]) = gbd->flags;
1143    if (GB_TYPE(gbd) == GB_DB) {
1144        int end;
1145        int index;
1146        gbc = (GBCONTAINER *)gbd;
1147        end = gbc->d.nheader;
1148        *(struct gb_flag_types3 *)(&buffer[i++]) = gbc->flags3;
1149
1150        if (send_headera) {
1151            buffer[i++] = end;
1152        }else{
1153            buffer[i++] = -1;
1154        }
1155
1156        if (deep){
1157            buffer[i++] = gbc->d.size;
1158        }else{
1159            buffer[i++] = -1;
1160        }
1161        buffer[1] = i;
1162        if (gbcm_write(socket,(const char *)buffer,i* sizeof(long))) {
1163            return GB_export_error("ARB_DB WRITE TO SOCKET FAILED");
1164        }
1165
1166        if (send_headera) {
1167            struct gb_header_list_struct *hdl  = GB_DATA_LIST_HEADER(gbc->d);
1168            struct gb_header_flags       *buf2 = (struct gb_header_flags *)GB_give_buffer2(gbc->d.nheader * sizeof(struct gb_header_flags));
1169
1170            for (index = 0; index < end; index++) {
1171                buf2[index] = hdl[index].flags;
1172            }
1173            if (gbcm_write(socket,(const char *)buf2,end* sizeof(struct gb_header_flags))) {
1174                return GB_export_error("ARB_DB WRITE TO SOCKET FAILED");
1175            }
1176        }
1177
1178        if (deep) {
1179            GBDATA *gb2;
1180            GB_ERROR error;
1181            debug_printf("%i    ",gbc->d.size);
1182
1183            for (index = 0; index < end; index++) {
1184                if (( gb2 = GBCONTAINER_ELEM(gbc,index) )) {
1185                    debug_printf("%i ",index);
1186                    error = gbcm_write_bin(socket,gb2,
1187                                           (long *)buffer,mode,deep-1,send_headera);
1188                    if (error) return error;
1189                }
1190            }
1191            debug_printf("\n",0);
1192        }
1193
1194    }else if ((unsigned int)GB_TYPE(gbd) < (unsigned int)GB_BITS) {
1195        buffer[i++] = gbd->info.i;
1196        buffer[1] = i;
1197        if (gbcm_write(socket,(const char *)buffer,i*sizeof(long)))  {
1198            return GB_export_error("ARB_DB WRITE TO SOCKET FAILED");
1199        }
1200    }else{
1201        long memsize;
1202        buffer[i++] = GB_GETSIZE(gbd);
1203        memsize = buffer[i++] = GB_GETMEMSIZE(gbd);
1204        buffer[1] = i;
1205        if (gbcm_write(socket,(const char *)buffer,i* sizeof(long)))  {
1206            return GB_export_error("ARB_DB WRITE TO SOCKET FAILED");
1207        }
1208        if (gbcm_write(socket,GB_GETDATA(gbd), memsize)){
1209            return GB_export_error("ARB_DB WRITE TO SOCKET FAILED");
1210        }
1211    }
1212    return 0;
1213}
1214/**************************************************************************************
1215                read an entry into gbd
1216***************************************************************************************/
1217long gbcm_read_bin(int socket,GBCONTAINER *gbd, long *buffer, long mode, GBDATA *gb_source,void *cs_main)
1218     /* mode ==  1   server reads data       */
1219     /* mode ==  0  client read all data        */
1220     /* mode == -1  client read but do not read subobjects -> folded cont   */
1221     /* mode == -2  client dummy read       */
1222{
1223    GBDATA *gb2;
1224    long    index_pos;
1225    long    size;
1226    long    id;
1227    long    i;
1228    int     type;
1229
1230    struct gb_flag_types  flags;
1231    struct gb_flag_types3 flags3;
1232
1233    size = gbcm_read(socket, (char *)buffer, sizeof(long) * 3);
1234    if (size != sizeof(long) * 3) {
1235        fprintf(stderr, "receive failed header size\n");
1236        return GBCM_SERVER_FAULT;
1237    }
1238    if (buffer[0] != GBCM_COMMAND_SEND) {
1239        fprintf(stderr, "receive failed wrong command\n");
1240        return GBCM_SERVER_FAULT;
1241    }
1242    id = buffer[2];
1243    i = buffer[1];
1244    i = sizeof(long) * (i - 3);
1245
1246    size = gbcm_read(socket, (char *)buffer, i);
1247    if (size != i) {
1248        GB_internal_error("receive failed DB_NODE\n");
1249        return GBCM_SERVER_FAULT;
1250    }
1251
1252    i = 0;
1253    index_pos = buffer[i++];
1254    if (!gb_source && gbd && index_pos<gbd->d.nheader ) {
1255        gb_source = GBCONTAINER_ELEM(gbd,index_pos);
1256    }
1257    flags = *(struct gb_flag_types *)(&buffer[i++]);
1258    type = flags.type;
1259
1260    if (mode >= -1) {   /* real read data */
1261        if (gb_source) {
1262            int types = GB_TYPE(gb_source);
1263            gb2 = gb_source;
1264            if (types != type) {
1265                GB_internal_error("Type changed in client: Connection aborted\n");
1266                return GBCM_SERVER_FAULT;
1267            }
1268            if (mode>0) {   /* transactions only in server */
1269                if (gbcm_test_address((long *) gb2, GBTUM_MAGIC_NUMBER)) {
1270                    return GBCM_SERVER_FAULT;
1271                }
1272            }
1273            if (types != GB_DB) {
1274                gb_save_extern_data_in_ts(gb2);
1275            }
1276            gb_touch_entry(gb2, gb_changed);
1277        } else {
1278            if (mode==-1) goto dont_create_in_a_folded_container;
1279            if (type == GB_DB) {
1280                gb2 = (GBDATA *)gb_make_container(gbd, 0, index_pos,
1281                                                  GB_DATA_LIST_HEADER(gbd->d)[index_pos].flags.key_quark);
1282            }else{  /* @@@ Header Transaction stimmt nicht */
1283                gb2 = gb_make_entry(gbd, 0, index_pos,
1284                                    GB_DATA_LIST_HEADER(gbd->d)[index_pos].flags.key_quark,(GB_TYPES)type);
1285            }
1286            if (mode>0){    /* transaction only in server */
1287                gb_touch_entry(gb2,gb_created);
1288            }else{
1289                gb2->server_id = id;
1290                GBS_write_hashi(GB_MAIN(gb2)->remote_hash, id, (long) gb2);
1291            }
1292            if (cs_main) {
1293                struct gbcms_create_struct *cs;
1294                cs = (struct gbcms_create_struct *) GB_calloc(sizeof(struct gbcms_create_struct), 1);
1295                cs->next = *((struct gbcms_create_struct **) cs_main);
1296                *((struct gbcms_create_struct **) cs_main) = cs;
1297                cs->server_id = gb2;
1298                cs->client_id = (GBDATA *) id;
1299            }
1300        }
1301        gb2->flags = flags;
1302        if (type == GB_DB) {
1303            ((GBCONTAINER *)gb2)->flags3 =
1304                *((struct gb_flag_types3 *)&(buffer[i++]));
1305        }
1306    } else {
1307    dont_create_in_a_folded_container:
1308        if (type == GB_DB) {
1309            flags3 = *((struct gb_flag_types3 *)&(buffer[i++]));
1310        }
1311        gb2 = 0;
1312    }
1313
1314    if (type == GB_DB) {
1315        long             nitems;
1316        long         nheader;
1317        long             item,irror;
1318        nheader = buffer[i++];
1319        nitems = buffer[i++];
1320
1321        if (nheader > 0) {
1322            long realsize = nheader* sizeof(struct gb_header_flags);
1323            struct gb_header_flags *buffer2;
1324            buffer2 = (struct gb_header_flags *)GB_give_buffer2(realsize);
1325            size = gbcm_read(socket, (char *)buffer2, realsize);
1326            if (size != realsize) {
1327                GB_internal_error("receive failed data\n");
1328                return GBCM_SERVER_FAULT;
1329            }
1330            if (gb2 && mode >= -1) {
1331                GBCONTAINER *gbc = (GBCONTAINER*)gb2;
1332                struct gb_header_list_struct *hdl;
1333                GB_MAIN_TYPE *Main = GBCONTAINER_MAIN(gbc);
1334
1335                gb_create_header_array(gbc,(int)nheader);
1336                if (nheader < gbc->d.nheader) {
1337                    GB_internal_error("Inconsistency Client-Server Cache");
1338                }
1339                gbc->d.nheader = (int)nheader;
1340                hdl = GB_DATA_LIST_HEADER(gbc->d);
1341                for (item = 0; item < nheader; item++) {
1342                    int old_index = hdl->flags.key_quark;
1343                    int new_index = buffer2->key_quark;
1344                    if (new_index && !old_index ) { /* a rename ... */
1345                        gb_write_index_key(gbc,item,new_index);
1346                    }
1347                    if (mode>0) {   /* server read data */
1348
1349
1350                    }else{
1351                        if ((int)buffer2->changed >= gb_deleted) {
1352                            hdl->flags.changed = gb_deleted;
1353                            hdl->flags.ever_changed = 1;
1354                        }
1355                    }
1356                    hdl->flags.flags = buffer2->flags;
1357                    hdl++; buffer2++;
1358                }
1359                if (mode>0){    /* transaction only in server */
1360                    gb_touch_header(gbc);
1361                }else{
1362                    gbc->header_update_date = Main->clock;
1363                }
1364            }
1365        }
1366
1367        if (nitems >= 0) {
1368            long newmod = mode;
1369            if (mode>=0){
1370                if (mode==0 && nitems<=1 ) {        /* only a partial send */
1371                    gb2->flags2.folded_container = 1;
1372                }
1373            }else{
1374                newmod = -2;
1375            }
1376            debug_printf("Client %i \n",nheader);
1377            for (item = 0; item < nitems; item++) {
1378                debug_printf("  Client reading %i\n",item);
1379                irror = gbcm_read_bin(socket, (GBCONTAINER *)gb2, buffer,
1380                                      newmod,0,cs_main);
1381                if (irror) {
1382                    return GBCM_SERVER_FAULT;
1383                }
1384            }
1385            debug_printf("Client done\n",0);
1386        } else {
1387            if ((mode==0) && !gb_source){       /* created GBDATA at client */
1388                gb2->flags2.folded_container = 1;
1389            }
1390        }
1391    } else if (type < GB_BITS) {
1392        if (mode >=0)   gb2->info.i = buffer[i++];
1393    } else {
1394        if (mode >=0) {
1395            long  realsize = buffer[i++];
1396            long  memsize  = buffer[i++];
1397            char *data;
1398            /* GB_FREEDATA(gb2); */
1399            GB_INDEX_CHECK_OUT(gb2);
1400
1401            assert_or_exit(!(gb2->flags2.extern_data && GB_EXTERN_DATA_DATA(gb2->info.ex)));
1402
1403            if (GB_CHECKINTERN(realsize,memsize)) {
1404                GB_SETINTERN(gb2);
1405                data = GB_GETDATA(gb2);
1406            }else{
1407                GB_SETEXTERN(gb2);
1408                data = gbm_get_mem((size_t)memsize,GB_GBM_INDEX(gb2));
1409            }
1410            size = gbcm_read(socket, data, memsize);
1411            if (size != memsize) {
1412                fprintf(stderr, "receive failed data\n");
1413                return GBCM_SERVER_FAULT;
1414            }
1415
1416            GB_SETSMD(gb2,realsize,memsize,data);
1417
1418        } else {            /* dummy read (e.g. updata in server && not cached in client */
1419            long memsize;
1420            char *buffer2;
1421            i++;
1422            memsize = buffer[i++];
1423            buffer2 = GB_give_buffer2(memsize);
1424
1425            size = gbcm_read(socket, buffer2, memsize);
1426            if (size != memsize) {
1427                GB_internal_error("receive failed data\n");
1428                return GBCM_SERVER_FAULT;
1429            }
1430        }
1431    }
1432
1433    return GBCM_SERVER_OK;
1434}
1435/**************************************************************************************
1436                unfold client
1437***************************************************************************************/
1438GB_ERROR gbcm_unfold_client(GBCONTAINER *gbd, long deep, long index_pos)
1439     /* read data from a server
1440        deep = -1   read whole data
1441        deep = 0...n    read to deep
1442        index_pos  == -1 read all clients
1443        index_pos == -2 read all clients + header array
1444    */
1445{
1446    int socket;
1447    long    buffer[256];
1448    long    nitems[1];
1449    long    item;
1450    long    irror=0;
1451
1452    socket = GBCONTAINER_MAIN(gbd)->c_link->socket;
1453    gbcm_read_flush(socket);
1454    if (gbcm_write_two(socket,GBCM_COMMAND_UNFOLD,gbd->server_id)){
1455        return GB_export_error("Cannot send data to Server");
1456    }
1457    if (gbcm_write_two(socket,GBCM_COMMAND_SETDEEP,deep)){
1458        return GB_export_error("Cannot send data to Server");
1459    }
1460    if (gbcm_write_two(socket,GBCM_COMMAND_SETINDEX,index_pos)){
1461        return GB_export_error("Cannot send data to Server");
1462    }
1463    if (gbcm_write_flush(socket)){
1464        return GB_export_error("Cannot send data to Server");
1465    }
1466
1467    if (index_pos == -2){
1468        irror = gbcm_read_bin(socket,0,buffer,0,(GBDATA*)gbd,0);
1469    }else{
1470        if (gbcm_read_two(socket,GBCM_COMMAND_SEND_COUNT,0,nitems)) {
1471            irror = 1;
1472        }else{
1473            for (item=0;item<nitems[0];item++){
1474                irror = gbcm_read_bin(socket,gbd,buffer,0,0,0);
1475                if (irror) break;
1476            }
1477        }
1478    }
1479    if (irror) {
1480        GB_ERROR error;
1481        error = GB_export_errorf("GB_unfold (%s) read error",GB_read_key_pntr((GBDATA*)gbd));
1482        return error;
1483    }
1484
1485    gbcm_read_flush(socket);
1486    if (index_pos < 0){
1487        gbd->flags2.folded_container = 0;
1488    }
1489    return 0;
1490}
1491
1492/**************************************************************************************
1493                send update to server
1494                CLIENT  FUNCTIONS
1495***************************************************************************************/
1496GB_ERROR gbcmc_begin_sendupdate(GBDATA *gbd)
1497{
1498    if (gbcm_write_two(GB_MAIN(gbd)->c_link->socket,GBCM_COMMAND_PUT_UPDATE,gbd->server_id) ) {
1499        return GB_export_errorf("Cannot send '%s' to server",GB_KEY(gbd));
1500    }
1501    return 0;
1502}
1503
1504GB_ERROR gbcmc_end_sendupdate(GBDATA *gbd)
1505{
1506    long    buffer[2];
1507    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1508    int socket = Main->c_link->socket;
1509    if (gbcm_write_two(socket,GBCM_COMMAND_PUT_UPDATE_END,gbd->server_id) ) {
1510        return GB_export_errorf("Cannot send '%s' to server",GB_KEY(gbd));
1511    }
1512    gbcm_write_flush(socket);
1513    while (1) {
1514        if (gbcm_read(socket,(char *)&(buffer[0]),sizeof(long)*2) != sizeof(long)*2){
1515            return GB_export_error("ARB_DB READ ON SOCKET FAILED");
1516        }
1517        gbd = (GBDATA *)buffer[0];
1518        if (!gbd) break;
1519        gbd->server_id = buffer[1];
1520        GBS_write_hashi(Main->remote_hash,gbd->server_id,(long)gbd);
1521    }
1522    gbcm_read_flush(socket);
1523    return 0;
1524}
1525
1526GB_ERROR gbcmc_sendupdate_create(GBDATA *gbd)
1527{
1528    long    *buffer;
1529    GB_ERROR error;
1530    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1531    int socket = Main->c_link->socket;
1532    GBCONTAINER *father = GB_FATHER(gbd);
1533
1534    if (!father) return GB_export_errorf("internal error #2453:%s",GB_KEY(gbd));
1535    if (gbcm_write_two(socket,GBCM_COMMAND_PUT_UPDATE_CREATE,father->server_id) ) {
1536        return GB_export_errorf("Cannot send '%s' to server",GB_KEY(gbd));
1537    }
1538    buffer = (long *)GB_give_buffer(1014);
1539    error = gbcm_write_bin(socket,gbd,buffer,0,-1,1);
1540    if (error) return error;
1541    return 0;
1542}
1543
1544GB_ERROR gbcmc_sendupdate_delete(GBDATA *gbd)
1545{
1546    if (gbcm_write_two( GB_MAIN(gbd)->c_link->socket,
1547                        GBCM_COMMAND_PUT_UPDATE_DELETE,
1548                        gbd->server_id) ) {
1549        return GB_export_errorf("Cannot send '%s' to server",GB_KEY(gbd));
1550    }else{
1551        return 0;
1552    }
1553}
1554
1555GB_ERROR gbcmc_sendupdate_update(GBDATA *gbd, int send_headera)
1556{
1557    long    *buffer;
1558    GB_ERROR error;
1559    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1560
1561    if (!GB_FATHER(gbd)) return GB_export_errorf("internal error #2453 %s",GB_KEY(gbd));
1562    if (gbcm_write_two(Main->c_link->socket,GBCM_COMMAND_PUT_UPDATE_UPDATE,gbd->server_id) ) {
1563        return GB_export_errorf("Cannot send '%s' to server",GB_KEY(gbd));
1564    }
1565    buffer = (long *)GB_give_buffer(1016);
1566    error = gbcm_write_bin(Main->c_link->socket,gbd,buffer,0,0,send_headera);
1567    if (error) return error;
1568    return 0;
1569}
1570
1571GB_ERROR gbcmc_read_keys(int socket,GBDATA *gbd){
1572    long size;
1573    int i;
1574    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1575    char *key;
1576    long buffer[2];
1577
1578    if (gbcm_read(socket,(char *)buffer,sizeof(long)*2) != sizeof(long)*2) {
1579        return GB_export_error("ARB_DB CLIENT ERROR receive failed 6336");
1580    }
1581    size = buffer[0];
1582    Main->first_free_key = buffer[1];
1583    gb_create_key_array(Main,(int)size);
1584    for (i=1;i<size;i++) {
1585        if (gbcm_read(socket,(char *)buffer,sizeof(long)*2) != sizeof(long)*2) {
1586            return GB_export_error("ARB_DB CLIENT ERROR receive failed 6253");
1587        }
1588        Main->keys[i].nref = buffer[0];         /* to control malloc_index */
1589        Main->keys[i].next_free_key = buffer[1];    /* to control malloc_index */
1590        key = gbcm_read_string(socket);
1591        if (key) {
1592            GBS_write_hash(Main->key_2_index_hash,key,i);
1593            if (Main->keys[i].key) free ( Main->keys[i].key );
1594            Main->keys[i].key = key;
1595        }
1596    }
1597    Main->keycnt = (int)size;
1598    return 0;
1599}
1600
1601GB_ERROR gbcmc_begin_transaction(GBDATA *gbd)
1602{
1603    long    *buffer;
1604    long clock[1];
1605    GBDATA  *gb2;
1606    long    d;
1607    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1608    int socket = Main->c_link->socket;
1609    long    mode;
1610    GB_ERROR error;
1611
1612    buffer = (long *)GB_give_buffer(1026);
1613    if (gbcm_write_two(Main->c_link->socket,GBCM_COMMAND_BEGIN_TRANSACTION,Main->clock) ) {
1614        return GB_export_errorf("Cannot send '%s' to server",GB_KEY(gbd));
1615    }
1616    if (gbcm_write_flush(socket)) {
1617        return GB_export_error("ARB_DB CLIENT ERROR send failed 1626");
1618    }
1619    if (gbcm_read_two(socket,GBCM_COMMAND_TRANSACTION_RETURN,0,clock)){
1620        return GB_export_error("ARB_DB CLIENT ERROR receive failed 3656");
1621    };
1622    Main->clock = clock[0];
1623    while (1){
1624        if (gbcm_read(socket,(char *)buffer,sizeof(long)*2) != sizeof(long)*2) {
1625            return GB_export_error("ARB_DB CLIENT ERROR receive failed 6435");
1626        }
1627        d = buffer[1];
1628        gb2 = (GBDATA *)GBS_read_hashi(Main->remote_hash,d);
1629        if (gb2){
1630            if (gb2->flags2.folded_container) {
1631                mode =-1;   /* read container */
1632            }else{
1633                mode = 0;   /* read all */
1634            }
1635        }else{
1636            mode = -2;      /* read nothing */
1637        }
1638        switch(buffer[0]) {
1639            case GBCM_COMMAND_PUT_UPDATE_UPDATE:
1640                if (gbcm_read_bin(socket,0,buffer, mode,gb2,0)){
1641                    return GB_export_error("ARB_DB CLIENT ERROR receive failed 2456");
1642                }
1643                if (gb2 ){
1644                    GB_CREATE_EXT(gb2);
1645                    gb2->ext->update_date = clock[0];
1646                }
1647                break;
1648            case GBCM_COMMAND_PUT_UPDATE_CREATE:
1649                if (gbcm_read_bin(socket, (GBCONTAINER *)gb2, buffer, mode, 0, 0)) {
1650                    return GB_export_error("ARB_DB CLIENT ERROR receive failed 4236");
1651                }
1652                if (gb2 ) {
1653                    GB_CREATE_EXT(gb2);
1654                    gb2->ext->creation_date = gb2->ext->update_date = clock[0];
1655                }
1656                break;
1657            case GBCM_COMMAND_PUT_UPDATE_DELETE:
1658                if (gb2) gb_delete_entry(&gb2);
1659                break;
1660            case GBCM_COMMAND_PUT_UPDATE_KEYS:
1661                error = gbcmc_read_keys(socket,gbd);
1662                if (error) return error;
1663                break;
1664            case GBCM_COMMAND_PUT_UPDATE_END:
1665                goto endof_gbcmc_begin_transaction;
1666            default:
1667                return GB_export_error("ARB_DB CLIENT ERROR receive failed 6574");
1668        }
1669    }
1670 endof_gbcmc_begin_transaction:
1671    gbcm_read_flush(socket);
1672    return 0;
1673}
1674
1675GB_ERROR gbcmc_init_transaction(GBCONTAINER *gbd)
1676{
1677    long clock[1];
1678    long buffer[4];
1679    GB_ERROR error = 0;
1680    GB_MAIN_TYPE *Main = GBCONTAINER_MAIN(gbd);
1681    int socket = Main->c_link->socket;
1682
1683    if (gbcm_write_two(socket,GBCM_COMMAND_INIT_TRANSACTION,Main->clock) ) {
1684        return GB_export_errorf("Cannot send '%s' to server",GB_KEY((GBDATA*)gbd));
1685    }
1686    gbcm_write_string(socket,Main->this_user->username);
1687    if (gbcm_write_flush(socket)) {
1688        return GB_export_error("ARB_DB CLIENT ERROR send failed 1426");
1689    }
1690
1691    if (gbcm_read_two(socket,GBCM_COMMAND_TRANSACTION_RETURN,0,clock)){
1692        return GB_export_error("ARB_DB CLIENT ERROR receive failed 3456");
1693    };
1694    Main->clock = clock[0];
1695
1696    if (gbcm_read_two(socket,GBCM_COMMAND_TRANSACTION_RETURN,0,buffer)){
1697        return GB_export_error("ARB_DB CLIENT ERROR receive failed 3654");
1698    };
1699    gbd->server_id = buffer[0];
1700
1701    if (gbcm_read_two(socket,GBCM_COMMAND_TRANSACTION_RETURN,0,buffer)){
1702        return GB_export_error("ARB_DB CLIENT ERROR receive failed 3654");
1703    };
1704    Main->this_user->userid = (int)buffer[0];
1705    Main->this_user->userbit = 1<<((int)buffer[0]);
1706
1707    GBS_write_hashi(Main->remote_hash,gbd->server_id,(long)gbd);
1708
1709    if (gbcm_read(socket,(char *)buffer, 2 * sizeof(long)) !=  2 * sizeof(long)) {
1710        return GB_export_error("ARB_DB CLIENT ERROR receive failed 2336");
1711    }
1712    error = gbcmc_read_keys(socket,(GBDATA *)gbd);
1713    if (error) return error;
1714
1715    gbcm_read_flush(socket);
1716    return 0;
1717}
1718
1719GB_ERROR gbcmc_commit_transaction(GBDATA *gbd)
1720{
1721    long dummy[1];
1722    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1723    int socket = Main->c_link->socket;
1724
1725    if (gbcm_write_two(socket,GBCM_COMMAND_COMMIT_TRANSACTION,gbd->server_id) ) {
1726        return GB_export_errorf("Cannot send '%s' to server",GB_KEY(gbd));
1727    }
1728    if (gbcm_write_flush(socket)) {
1729        return GB_export_error("ARB_DB CLIENT ERROR send failed");
1730    }
1731    gbcm_read_two(socket,GBCM_COMMAND_TRANSACTION_RETURN,0,dummy);
1732    gbcm_read_flush(socket);
1733    return 0;
1734}
1735GB_ERROR gbcmc_abort_transaction(GBDATA *gbd)
1736{
1737    long dummy[1];
1738    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1739    int socket = Main->c_link->socket;
1740    if (gbcm_write_two(socket,GBCM_COMMAND_ABORT_TRANSACTION,gbd->server_id) ) {
1741        return GB_export_errorf("Cannot send '%s' to server",GB_KEY(gbd));
1742    }
1743    if (gbcm_write_flush(socket)) {
1744        return GB_export_error("ARB_DB CLIENT ERROR send failed");
1745    }
1746    gbcm_read_two(socket,GBCM_COMMAND_TRANSACTION_RETURN,0,dummy);
1747    gbcm_read_flush(socket);
1748    return 0;
1749}
1750
1751GB_ERROR gbcms_add_to_delete_list(GBDATA *gbd)
1752{
1753    struct Hs_struct *hs;
1754    struct gbcms_delete_list    *dl;
1755    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1756    hs = (struct Hs_struct *)Main->server_data;
1757    if (!hs) return 0;
1758    if (!hs->soci) return 0;
1759    dl = (struct gbcms_delete_list *)gbm_get_mem(sizeof(struct gbcms_delete_list),GBM_CB_INDEX);
1760    dl->creation_date = GB_GET_EXT_CREATION_DATE(gbd);
1761    dl->update_date = GB_GET_EXT_UPDATE_DATE(gbd);
1762    dl->gbd = gbd;
1763    if (!hs->del_first) {
1764        hs->del_first = hs->del_last = dl;
1765    }else{
1766        hs->del_last->next = dl;
1767        hs->del_last = dl;
1768    }
1769    return 0;
1770}
1771
1772/**************************************************************************************
1773                How many clients, returns -1 if not server
1774***************************************************************************************/
1775long GB_read_clients(GBDATA *gbd)
1776{
1777    GB_MAIN_TYPE *Main    = GB_MAIN(gbd);
1778    long          clients = -1;
1779
1780    if (Main->local_mode) { /* i am the server */
1781        struct Hs_struct *hs = (struct Hs_struct *)Main->server_data;
1782        clients = hs ? hs->nsoc : 0;
1783    }
1784
1785    return clients;
1786}
1787
1788GB_BOOL GB_is_server(GBDATA *gbd) {
1789    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1790    return Main->local_mode;
1791}
1792GB_BOOL GB_is_client(GBDATA *gbd) {
1793    return !GB_is_server(gbd);
1794}
1795
1796/**************************************************************************************
1797                Query in the server
1798***************************************************************************************/
1799GB_ERROR
1800gbcmc_unfold_list(int socket, GBDATA * gbd)
1801{
1802    long      readvar[2];
1803    GBCONTAINER         *gb_client;
1804    GB_ERROR error;
1805    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1806    if (!gbcm_read(socket, (char *) readvar, sizeof(long) * 2 )) {
1807        return GB_export_error("receive failed");
1808    }
1809    gb_client = (GBCONTAINER *) readvar[1];
1810    if (gb_client) {
1811        error = gbcmc_unfold_list(socket, gbd);
1812        if (error)
1813            return error;
1814        gb_client = (GBCONTAINER *) GBS_read_hashi(Main->remote_hash, (long) gb_client);
1815        gb_unfold(gb_client, 0, (int)readvar[0]);
1816    }
1817    return 0;
1818}
1819
1820GBDATA *GBCMC_find(GBDATA *gbd, const char *key, GB_TYPES type, const char *str, GB_CASE case_sens, enum gb_search_types gbs) {
1821    /* perform search in DB server (from DB client) */
1822    union {
1823        GBDATA *gbd;
1824        long    l;
1825    } result;   
1826    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1827
1828    int socket;
1829    if (Main->local_mode) {
1830        gb_assert(0); // GBCMC_find may only be used in DB clients
1831        return (GBDATA *)-1;
1832    }
1833
1834    socket = Main->c_link->socket;
1835
1836    if (gbcm_write_two(socket,GBCM_COMMAND_FIND,gbd->server_id)){
1837        GB_export_error("Cannot send data to Server");
1838        GB_print_error();
1839        return 0;
1840    }
1841
1842    gbcm_write_string(socket,key);
1843    gbcm_write_long(socket, type);
1844    switch (type) {
1845        case GB_NONE:
1846            break;
1847        case GB_STRING:
1848            gbcm_write_string(socket,str);
1849            gbcm_write_long(socket, case_sens);
1850            break;
1851        case GB_INT:
1852            gbcm_write_long(socket, *(long*)str);
1853            break;
1854        default :
1855            gb_assert(0);
1856            GB_export_errorf("GBCMC_find: Illegal data type (%i)", type);
1857            GB_print_error();
1858            return 0;
1859    }
1860
1861    gbcm_write_long(socket, gbs);
1862   
1863    if (gbcm_write_flush(socket)) {
1864        GB_export_error("ARB_DB CLIENT ERROR send failed");
1865        GB_print_error();
1866        return 0;
1867    }
1868    gbcm_read_two(socket, GBCM_COMMAND_FIND_ERG, 0, &result.l);
1869    if (result.gbd){
1870        gbcmc_unfold_list(socket,gbd);
1871        result.l = GBS_read_hashi(Main->remote_hash, result.l);
1872    }
1873    gbcm_read_flush(socket);
1874    return result.gbd;
1875}
1876
1877
1878long gbcmc_key_alloc(GBDATA *gbd,const char *key)   {
1879    long gb_result[1];
1880    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1881
1882    int socket;
1883    if (Main->local_mode) return 0;
1884    socket = Main->c_link->socket;
1885
1886    if (gbcm_write_two(socket,GBCM_COMMAND_KEY_ALLOC,gbd->server_id)){
1887        GB_export_error("Cannot send data to Server");
1888        GB_print_error();
1889        return 0;
1890    }
1891
1892    gbcm_write_string(socket,key);
1893
1894    if (gbcm_write_flush(socket)) {
1895        GB_export_error("ARB_DB CLIENT ERROR send failed");
1896        GB_print_error();
1897        return 0;
1898    }
1899    gbcm_read_two(socket,GBCM_COMMAND_KEY_ALLOC_RES,0,gb_result);
1900    gbcm_read_flush(socket);
1901    return gb_result[0];
1902}
1903
1904int GBCMC_system(GBDATA *gbd,const char *ss) {
1905
1906    int socket;
1907    long    gb_result[2];
1908    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1909    if (Main->local_mode){
1910        GB_ERROR error = GB_system(ss);
1911        if (error) GB_export_error(error);
1912        return error != 0;
1913    }
1914    socket = Main->c_link->socket;
1915
1916    if (gbcm_write_two(socket,GBCM_COMMAND_SYSTEM,gbd->server_id)){
1917        GB_export_error("Cannot send data to Server");
1918        GB_print_error();
1919        return -1;
1920    }
1921
1922    gbcm_write_string(socket,ss);
1923    if (gbcm_write_flush(socket)) {
1924        GB_export_error("ARB_DB CLIENT ERROR send failed");
1925        GB_print_error();
1926        return -1;
1927    }
1928    gbcm_read_two(socket,GBCM_COMMAND_SYSTEM_RETURN,0,(long *)gb_result);
1929    gbcm_read_flush(socket);
1930    return 0;
1931}
1932
1933/** send an undo command !!! */
1934GB_ERROR gbcmc_send_undo_commands(GBDATA *gbd, enum gb_undo_commands command){
1935    int socket;
1936    GB_ERROR result;
1937    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1938    if (Main->local_mode)
1939        GB_internal_error("gbcmc_send_undo_commands: cannot call a server in a server");
1940    socket = Main->c_link->socket;
1941
1942    if (gbcm_write_two(socket,GBCM_COMMAND_UNDO,gbd->server_id)){
1943        return GB_export_error("Cannot send data to Server 456");
1944    }
1945    if (gbcm_write_two(socket,GBCM_COMMAND_UNDO_CMD,command)){
1946        return GB_export_error("Cannot send data to Server 96f");
1947    }
1948    if (gbcm_write_flush(socket)) {
1949        return GB_export_error("Cannot send data to Server 536");
1950    }
1951    result = gbcm_read_string(socket);
1952    gbcm_read_flush(socket);
1953    if (result) GB_export_errorf("%s",result);
1954    return result;
1955}
1956
1957char *gbcmc_send_undo_info_commands(GBDATA *gbd, enum gb_undo_commands command){
1958    int socket;
1959    char *result;
1960    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1961    if (Main->local_mode){
1962        GB_internal_error("gbcmc_send_undo_commands: cannot call a server in a server");
1963        return 0;
1964    }
1965    socket = Main->c_link->socket;
1966
1967    if (gbcm_write_two(socket,GBCM_COMMAND_UNDO,gbd->server_id)){
1968        GB_export_error("Cannot send data to Server 456");
1969        return 0;
1970    }
1971    if (gbcm_write_two(socket,GBCM_COMMAND_UNDO_CMD,command)){
1972        GB_export_error("Cannot send data to Server 96f");
1973        return 0;
1974    }
1975    if (gbcm_write_flush(socket)) {
1976        GB_export_error("Cannot send data to Server 536");
1977        return 0;
1978    }
1979    result = gbcm_read_string(socket);
1980    gbcm_read_flush(socket);
1981    return result;
1982}
1983
1984GB_ERROR GB_tell_server_dont_wait(GBDATA *gbd){
1985    int socket;
1986    GB_MAIN_TYPE *Main = GB_MAIN(gbd);
1987
1988    if (Main->local_mode){
1989        return 0;
1990    }
1991    socket = Main->c_link->socket;
1992    if (gbcm_write_two(socket,GBCM_COMMAND_DONT_WAIT,gbd->server_id)){
1993        GB_export_error("Cannot send data to Server 456");
1994        return 0;
1995    }
1996
1997    return 0;
1998}
1999
2000/**************************************************************************************
2001                Login logout functions
2002***************************************************************************************/
2003
2004GB_ERROR gbcm_login(GBCONTAINER *gb_main,const char *user)
2005     /* look for any free user and set this_user */
2006{
2007    int i;
2008    GB_MAIN_TYPE *Main = GBCONTAINER_MAIN(gb_main);
2009
2010    for (i = 0; i<GB_MAX_USERS; i++) {
2011        if (!Main->users[i]) continue;
2012        if (!strcmp(user,Main->users[i]->username) ) {
2013            Main->this_user = Main->users[i];
2014            Main->users[i]->nusers++;
2015            return 0;
2016        }
2017    }
2018    for (i = 0; i<GB_MAX_USERS; i++) {
2019        if (Main->users[i]) continue;
2020        Main->users[i] = (struct gb_user_struct *) GB_calloc(sizeof(struct gb_user_struct),1);
2021        Main->users[i]->username = strdup(user);
2022        Main->users[i]->userid = i;
2023        Main->users[i]->userbit = 1<<i;
2024        Main->users[i]->nusers = 1;
2025        Main->this_user = Main->users[i];
2026        return 0;
2027    }
2028    return GB_export_errorf("Too many users in this database: User '%s' ",user);
2029}
2030
2031long gbcmc_close(struct gbcmc_comm * link)
2032{
2033    if (link->socket) {
2034        if (gbcm_write_two(link->socket, GBCM_COMMAND_CLOSE, 0)) {
2035            GB_export_error("Cannot send data to server");
2036            GB_print_error();
2037            return GBCM_SERVER_FAULT;
2038        }
2039        if (gbcm_write_flush(link->socket)) {
2040            GB_export_error("ARB_DB CLIENT ERROR send failed");
2041            GB_print_error();
2042            return GBCM_SERVER_FAULT;
2043        }
2044        close(link->socket);
2045        link->socket = 0;
2046    }
2047    if (link->unix_name) free(link->unix_name); /* @@@ */
2048    free((char *)link);
2049    return 0;
2050}
2051
2052GB_ERROR gbcm_logout(GBCONTAINER *gb_main,char *user)
2053{
2054    long i;
2055    GB_MAIN_TYPE *Main = GBCONTAINER_MAIN(gb_main);
2056
2057    for (i = 0; i<GB_MAX_USERS; i++) {
2058        if (!Main->users[i]) continue;
2059        if (!strcmp(user,Main->users[i]->username) ) {
2060            Main->users[i]->nusers--;
2061            if (Main->users[i]->nusers<=0) {/* kill user and his projects */
2062                free(Main->users[i]->username);
2063                freeset(Main->users[i], NULL);
2064                fprintf(stdout,"The User %s has logged out\n",user);
2065            }
2066            return 0;
2067        }
2068    }
2069    return GB_export_errorf("User '%s' not logged in",user);
2070}
2071
2072GB_CSTR GB_get_hostname(void){
2073    static char *hn = 0;
2074    if (!hn){
2075        char buffer[4096];
2076        gethostname(buffer,4095);
2077        hn = strdup(buffer);
2078    }
2079    return hn;
2080}
2081
2082GB_ERROR GB_install_pid(int mode) {
2083    /* tell the arb_clean script what programs are running.
2084     * mode == 1 -> install
2085     * mode == 0 -> never install
2086     */
2087
2088    static long lastpid = -1;
2089    GB_ERROR    error   = 0;
2090
2091    if (mode == 0) {
2092        gb_assert(lastpid == -1); // you have to call GB_install_pid(0) before opening any database!
2093        lastpid = -25;            // mark as "never install"
2094    }
2095
2096    if (lastpid != -25) {
2097        long pid = getpid();
2098
2099        if (pid != lastpid) {   // don't install pid multiple times
2100            char *pidfile_name;
2101            {
2102                const char *user    = GB_getenvUSER();
2103                const char *arb_pid = GB_getenv("ARB_PID"); // normally the pid of the 'arb' shell script
2104
2105                gb_assert(user);
2106                if (!arb_pid) arb_pid = "";
2107
2108                pidfile_name = GBS_global_string_copy("arb_pids_%s_%s", user, arb_pid);
2109            }
2110           
2111            char *pid_fullname;
2112            FILE *pidfile = GB_fopen_tempfile(pidfile_name, "at", &pid_fullname);
2113
2114            if (!pidfile) {
2115                error = GBS_global_string("GB_install_pid: %s", GB_await_error());
2116            }
2117            else {
2118                fprintf(pidfile,"%li ", pid);
2119                lastpid = pid; // remember installed pid
2120                fclose(pidfile);
2121            }
2122
2123            // ensure pid file is private, otherwise someone could inject PIDs which will be killed later
2124            gb_assert(GB_is_privatefile(pid_fullname, GB_FALSE));
2125           
2126            free(pid_fullname);
2127            free(pidfile_name);
2128        }
2129    }
2130
2131    return error;
2132}
2133
2134const char *GB_date_string(void) {
2135    struct timeval date;
2136    struct tm *p;
2137
2138    gettimeofday(&date, 0);
2139
2140#if defined(DARWIN)
2141    struct timespec local;
2142    TIMEVAL_TO_TIMESPEC(&date, &local); // not avail in time.h of Linux gcc 2.95.3
2143    p = localtime(&local.tv_sec);
2144#else
2145    p = localtime(&date.tv_sec);
2146#endif // DARWIN
2147
2148    char *readable = asctime(p); // points to a static buffer
2149    char *cr       = strchr(readable, '\n');
2150    gb_assert(cr);
2151    cr[0]          = 0;         // cut of \n
2152
2153    return readable;
2154}
2155
2156
Note: See TracBrowser for help on using the repository browser.