source: tags/initial/ARBDB/adcomm.c

Last change on this file was 2, checked in by oldcode, 23 years ago

Initial revision

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