ARB
client.c
Go to the documentation of this file.
1 // ===============================================================
2 /* */
3 // File : client.c
4 // Purpose :
5 /* */
6 // Institute of Microbiology (Technical University Munich)
7 // http://www.arb-home.de/
8 /* */
9 // ===============================================================
10 
11 #include <netdb.h>
12 #include <netinet/tcp.h>
13 #include <sys/stat.h>
14 #include <sys/un.h>
15 
16 #include <unistd.h>
17 #include <cstdarg>
18 
19 #include <arb_cs.h>
20 
21 #include "client_privat.h"
22 #include "client.h"
23 
24 #include "trace.h"
25 
26 #define aisc_assert(cond) arb_assert(cond)
27 
28 // AISC_MKPT_PROMOTE:#include <client_types.h>
29 
30 #define AISC_MAGIC_NUMBER_FILTER 0xffffff00
31 
32 static const char *err_connection_problems = "CONNECTION PROBLEMS";
33 
35 
36 #define CORE() \
37  do { \
38  if (aisc_core_on_error) { \
39  ARB_SIGSEGV(true); \
40  } \
41  } while (0)
42 
44 
46 
47 #define ERRBUF_SIZE 300
48 static char errbuf[ERRBUF_SIZE];
49 
50 #define PRTERR(msg) if (aisc_print_error_to_stderr) fprintf(stderr, "%s: %s\n", msg, link->error);
51 
52 // -----------------------------
53 // bytestring handling
54 
55 
56 static void aisc_c_add_to_bytes_queue(aisc_com *link, char *data, int size) {
57  aisc_bytes_list *bl = (aisc_bytes_list *)calloc(sizeof(*bl), 1);
58 #ifndef NDEBUG
59  memset(bl, 0, sizeof(*bl)); // @@@ clear mem needed to avoid (rui's)
60 #endif
61  bl->data = data;
62  bl->size = size;
63 
64  if (link->aisc_client_bytes_first) {
65  link->aisc_client_bytes_last->next = bl;
66  link->aisc_client_bytes_last = bl;
67  }
68  else {
69  link->aisc_client_bytes_first = bl;
70  link->aisc_client_bytes_last = bl;
71  }
72 }
73 
75  int len;
76  aisc_bytes_list *bl, *bl_next;
77  for (bl = link->aisc_client_bytes_first; bl; bl=bl_next) {
78  bl_next = bl->next;
79  len = arb_socket_write(link->socket, bl->data, bl->size);
80  free(bl);
81  if (len<0)return 1;
82  };
84  return 0;
85 }
86 
87 // --------------------------
88 // message handling
89 
93  char *message;
94 };
95 
96 static int aisc_add_message_queue(aisc_com *link, long size) {
97  client_msg_queue *msg = (client_msg_queue *) calloc(sizeof(client_msg_queue), 1);
98  char *buffer = (char *)calloc(sizeof(char), (size_t)size);
99  long len = arb_socket_read(link->socket, buffer, size);
100 
101  if (len != size) {
103  PRTERR("AISC_ERROR");
104  return 1;
105  }
106  msg->message = strdup(buffer+sizeof(long));
107  msg->message_type = (int)*(long *)buffer;
108  free(buffer);
109 
110  if (!link->message_queue) {
111  link->message_queue = (int *)msg;
112  }
113  else {
114  client_msg_queue *mp;
115  for (mp = (client_msg_queue *)link->message_queue; mp->next; mp=mp->next) ;
116  mp->next = msg;
117  }
118  return 0;
119 }
120 
122  int len;
123  long magic_number;
124  long size;
125 
126  aisc_check_next :
127 
128  link->error = NULp; // @@@ avoid (rui)
129  len = arb_socket_read(link->socket, (char *)(link->aisc_mes_buffer), 2*sizeof(long));
130  if (len != 2*sizeof(long)) {
132  PRTERR("AISC_ERROR");
133  return 1;
134  }
135  if (link->aisc_mes_buffer[0] >= AISC_MESSAGE_BUFFER_LEN) {
137  PRTERR("AISC_ERROR");
138  return 1;
139  }
140  magic_number = link->aisc_mes_buffer[1];
141  if ((unsigned long)(magic_number & AISC_MAGIC_NUMBER_FILTER) != (unsigned long)(link->magic & AISC_MAGIC_NUMBER_FILTER)) {
143  PRTERR("AISC_ERROR");
144  return 1;
145  }
146  size = link->aisc_mes_buffer[0];
147  if (size) {
148  if (magic_number-link->magic == AISC_CCOM_MESSAGE) {
149  if (aisc_add_message_queue(link, size*sizeof(long))) return 1;
150  goto aisc_check_next;
151 
152  }
153  len = arb_socket_read(link->socket, (char *)(link->aisc_mes_buffer), size * sizeof(long));
154  if (len != (long)(size*sizeof(long))) {
156  PRTERR("AISC_ERROR");
157  return 1;
158  }
159  switch (magic_number-link->magic) {
160  case AISC_CCOM_OK:
161  return 0;
162  case AISC_CCOM_ERROR: {
163  const char *errmsg = (const char *)(link->aisc_mes_buffer);
164  int length = strlen(errmsg);
165 
166  if ((length+15) < ERRBUF_SIZE) {
167  strcpy(errbuf, "SERVER_ERROR: ");
168  strcat(errbuf, errmsg);
169  }
170  else {
171  fprintf(stderr, "SERVER_ERROR: %s\n", errmsg);
172  sprintf(errbuf, "SERVER_ERROR: overlong msg dumped to STDERR");
173  }
174  link->error = errbuf;
175  PRTERR("AISC_ERROR");
176  return 1;
177  }
178  default:
179  return 0;
180  }
181  }
182  return 0;
183 }
184 
185 
186 
188  int mes_cnt;
189  mes_cnt = 2;
190  link->aisc_mes_buffer[0] = mes_cnt-2;
191  link->aisc_mes_buffer[1] = AISC_INIT+link->magic;
192  if (arb_socket_write(link->socket, (const char *)link->aisc_mes_buffer, mes_cnt * sizeof(long))) {
194  PRTERR("AISC_CONN_ERROR");
195  return 0;
196  }
197  aisc_check_error(link);
198  return link->aisc_mes_buffer[0];
199 }
200 
201 static void aisc_free_link(aisc_com *link) {
202  free(link);
203 }
204 
205 aisc_com *aisc_open(const char *path, AISC_Object& main_obj, long magic, GB_ERROR *error) {
206  aisc_com *link;
207  const char *err;
208 
209  aisc_assert(error && !*error);
210  aisc_assert(!main_obj.exists()); // already initialized
211 
212  link = (aisc_com *) calloc(sizeof(aisc_com), 1);
213  link->aisc_client_bytes_first = link->aisc_client_bytes_last = NULp;
214  link->magic = magic;
215  {
216  char *unix_name = NULp;
217  err = arb_open_socket(path, true, &link->socket, &unix_name);
218  aisc_assert(link->socket>=0);
219  free(unix_name);
220  }
221  if (err) {
222  if (*err) {
223  link->error = err;
224  PRTERR("AISC");
225  }
226  if (link->socket) {
227  shutdown(link->socket, SHUT_RDWR);
228  close(link->socket);
229  }
230  *error = link->error;
231  free(link);
232  aisc_assert(!(*error && main_obj.exists()));
233  return NULp;
234  }
235 
236  main_obj.init(aisc_init_client(link));
237  if (!main_obj.exists() || link->error) {
238  *error = link->error;
239  main_obj.clear();
240  aisc_free_link(link);
241  aisc_assert(!(*error && main_obj.exists()));
242  return NULp;
243  }
244  aisc_client_link = link;
245  aisc_assert(!*error);
246  return link;
247 }
248 
250  if (link) {
251  if (link->socket) {
252  link->aisc_mes_buffer[0] = 0;
253  link->aisc_mes_buffer[1] = 0;
254  link->aisc_mes_buffer[2] = 0;
255  arb_socket_write(link->socket, (const char *)link->aisc_mes_buffer, 3 * sizeof(long));
256  shutdown(link->socket, SHUT_RDWR);
257  close(link->socket);
258  link->socket = 0;
259  }
260  aisc_free_link(link);
261  }
262  object.clear();
263  return 0;
264 }
265 
266 int aisc_get(aisc_com *link, int o_type, const AISC_Object& object, ...) {
267  // goes to header: __ATTR__SENTINEL
268  long *arg_pntr[MAX_AISC_SET_GET];
269  long arg_types[MAX_AISC_SET_GET];
270  long mes_cnt;
271  long arg_cnt;
272  va_list parg;
273  long type, o_t;
274  long attribute, code;
275  long count;
276  long i, len;
277  long size;
278 
279  AISC_DUMP_SEP();
280 
281  mes_cnt = 2;
282  arg_cnt = 0;
283  count = 4;
284 
285  link->aisc_mes_buffer[mes_cnt++] = object.get();
286  aisc_assert(object.type() == o_type);
287 
288  va_start(parg, object);
289  while ((code=va_arg(parg, long))) {
290  attribute = code & AISC_ATTR_MASK;
291  type = code & AISC_VAR_TYPE_MASK;
292  o_t = code & AISC_OBJ_TYPE_MASK;
293 
294  if ((o_t != (int)o_type)) {
295  sprintf(errbuf, "ARG NR %li DON'T FIT OBJECT", count);
296  link->error = errbuf;
297  PRTERR("AISC_GET_ERROR");
298  CORE();
299  return 1;
300  };
301 
302  if ((attribute > AISC_MAX_ATTR)) {
303  sprintf(errbuf, "ARG %li IS NOT AN ATTRIBUTE_TYPE", count);
304  link->error = errbuf;
305  PRTERR("AISC_GET_ERROR");
306  CORE();
307  return 1;
308  };
309  link->aisc_mes_buffer[mes_cnt++] = code;
310  arg_pntr[arg_cnt] = va_arg(parg, long *);
311  arg_types[arg_cnt++] = type;
312  count += 2;
313  if (arg_cnt>=MAX_AISC_SET_GET) {
314  sprintf(errbuf, "TOO MANY ARGS (>%i)", MAX_AISC_SET_GET);
315  link->error = errbuf;
316  PRTERR("AISC_GET_ERROR");
317  CORE();
318  return 1;
319  }
320  }
321  va_end(parg);
322  if (mes_cnt > 3) {
323  link->aisc_mes_buffer[0] = mes_cnt - 2;
324  link->aisc_mes_buffer[1] = AISC_GET+link->magic;
325  if (arb_socket_write(link->socket, (const char *)(link->aisc_mes_buffer),
326  (size_t)(mes_cnt * sizeof(long)))) {
328  PRTERR("AISC_GET_ERROR");
329  return 1;
330  }
331 
332  if (aisc_check_error(link)) return 1;
333  mes_cnt = 0;
334  for (i=0; i<arg_cnt; i++) {
335  switch (arg_types[i]) {
336  case AISC_TYPE_INT:
337  case AISC_TYPE_COMMON:
338  AISC_DUMP(aisc_get, int, link->aisc_mes_buffer[mes_cnt]);
339  arg_pntr[i][0] = link->aisc_mes_buffer[mes_cnt++];
340  break;
341  case AISC_TYPE_DOUBLE:
342  AISC_DUMP(aisc_get, double, *(double*)(char*)/*avoid aliasing problems*/&(link->aisc_mes_buffer[mes_cnt]));
343  ((int*)arg_pntr[i])[0] = (int)(link->aisc_mes_buffer[mes_cnt++]);
344  ((int*)arg_pntr[i])[1] = (int)(link->aisc_mes_buffer[mes_cnt++]);
345  break;
346  case AISC_TYPE_STRING: {
347  char *str = strdup((char *)(&(link->aisc_mes_buffer[mes_cnt+1])));
348  AISC_DUMP(aisc_get, charPtr, str);
349  arg_pntr[i][0] = (long)str;
350  mes_cnt += link->aisc_mes_buffer[mes_cnt] + 1;
351  break;
352  }
353  case AISC_TYPE_BYTES:
354  size = arg_pntr[i][1] = link->aisc_mes_buffer[mes_cnt++];
355  AISC_DUMP(aisc_get, int, size);
356  if (size) {
357  arg_pntr[i][0] = (long)calloc(sizeof(char), (size_t)size);
358  len = arb_socket_read(link->socket, (char *)(arg_pntr[i][0]), size);
359  if (size!=len) {
361  PRTERR("AISC_GET_ERROR");
362  }
363 #if defined(DUMP_COMMUNICATION)
364  aisc_dump_hex("aisc_get bytestring: ", (char *)(arg_pntr[i][0]), size);
365 #endif // DUMP_COMMUNICATION
366  }
367  else {
368  arg_pntr[i][0] = 0;
369  }
370  break;
371 
372  default:
373  link->error = "UNKNOWN TYPE";
374  PRTERR("AISC_GET_ERROR");
375  CORE();
376  return 1;
377  }
378  }
379 
380  }
381  return 0;
382 }
383 
384 long *aisc_debug_info(aisc_com *link, int o_type, const AISC_Object& object, int attribute) {
385  int mes_cnt;
386  int o_t;
387 
388  mes_cnt = 2;
389  o_t = attribute & AISC_OBJ_TYPE_MASK;
390  if ((o_t != (int)o_type)) {
391  link->error = "ATTRIBUTE DON'T FIT OBJECT";
392  PRTERR("AISC_DEBUG_ERROR");
393  CORE();
394  return NULp;
395  };
396  attribute = attribute&0xffff;
397  if ((attribute > AISC_MAX_ATTR)) {
398  link->error = "CLIENT DEBUG NOT CORRECT TYPE";
399  PRTERR("AISC_DEBUG_ERROR");
400  CORE();
401  return NULp;
402  };
403  aisc_assert(object.type() == o_type);
404  link->aisc_mes_buffer[mes_cnt++] = object.get();
405  link->aisc_mes_buffer[mes_cnt++] = attribute;
406  link->aisc_mes_buffer[0] = mes_cnt - 2;
407  link->aisc_mes_buffer[1] = AISC_DEBUG_INFO+link->magic;
408  if (arb_socket_write(link->socket, (const char *)(link->aisc_mes_buffer), mes_cnt * sizeof(long))) {
410  PRTERR("AISC_GET_ERROR");
411  return NULp;
412  }
413  if (aisc_check_error(link)) return NULp;
414  return &(link->aisc_mes_buffer[0]);
415 }
416 
417 
418 inline char *part_of(const char *str, size_t max_len, size_t str_len) {
419  aisc_assert(strlen(str) == str_len);
420  char *part;
421  if (str_len <= max_len) {
422  part = strdup(str);
423  }
424  else {
425  const int DOTS = 3;
426  int copy = max_len-DOTS;
427 
428  part = (char*)malloc(max_len+1);
429  memcpy(part, str, copy);
430  memset(part+copy, '.', DOTS);
431 
432  part[max_len] = 0;
433  }
434  return part;
435 }
436 
437 static int aisc_collect_sets(aisc_com *link, int mes_cnt, va_list parg, int o_type, int count) {
438  int arg_cnt = 0;
439 
440  AISC_DUMP_SEP();
441 
442  int code;
443  while ((code=va_arg(parg, int))) {
444  int attribute = code & AISC_ATTR_MASK;
445  int type = code & AISC_VAR_TYPE_MASK;
446  int o_t = code & AISC_OBJ_TYPE_MASK;
447 
448  if (code != AISC_INDEX) {
449  if ((o_t != (int)o_type)) {
450  sprintf(errbuf, "ATTRIBUTE ARG NR %i DON'T FIT OBJECT", count);
451  link->error = errbuf;
452  PRTERR("AISC_SET_ERROR");
453  CORE();
454  return 0;
455  }
456  if ((attribute > AISC_MAX_ATTR)) {
457  sprintf(errbuf, "ARG %i IS NOT AN ATTRIBUTE_TYPE", count);
458  link->error = errbuf;
459  PRTERR("AISC_SET_ERROR");
460  CORE();
461  return 0;
462  }
463  }
464  link->aisc_mes_buffer[mes_cnt++] = code;
465  switch (type) {
466  case AISC_TYPE_INT:
467  case AISC_TYPE_COMMON:
468  link->aisc_mes_buffer[mes_cnt++] = va_arg(parg, long);
469  AISC_DUMP(aisc_collect_sets, int, link->aisc_mes_buffer[mes_cnt-1]);
470  break;
471  case AISC_TYPE_DOUBLE: {
472  double_xfer darg;
473 
474  darg.as_double = va_arg(parg, double);
475  AISC_DUMP(aisc_collect_sets, double, darg.as_double);
476 
477  link->aisc_mes_buffer[mes_cnt++] = darg.as_int[0];
478  link->aisc_mes_buffer[mes_cnt++] = darg.as_int[1];
479  break;
480  }
481  case AISC_TYPE_STRING: {
482  const char *str = va_arg(parg, const char *);
483  aisc_assert(str);
484  AISC_DUMP(aisc_collect_sets, charPtr, str);
485  size_t len = strlen(str)+1;
486  if (len > AISC_MAX_STRING_LEN) {
487  char *strpart = part_of(str, AISC_MAX_STRING_LEN-40, len-1);
488  sprintf(errbuf, "ARG %i: STRING \'%s\' TOO LONG", count+2, strpart);
489  free(strpart);
490 
491  link->error = errbuf;
492  PRTERR("AISC_SET_ERROR");
493  CORE();
494 
495  return 0;
496  }
497  size_t ilen = (len)/sizeof(long) + 1;
498  link->aisc_mes_buffer[mes_cnt++] = ilen;
499  link->aisc_mes_buffer[mes_cnt+ilen-1] = 0; // make sure last sent long is completely initialized ('str' may only use part of it)
500  memcpy((char *)(&(link->aisc_mes_buffer[mes_cnt])), str, len);
501  mes_cnt += ilen;
502  break;
503  }
504  case AISC_TYPE_BYTES: {
505  bytestring *bs;
506  bs = va_arg(parg, bytestring *);
507  AISC_DUMP(aisc_collect_sets, int, bs->size);
508  if (bs->data && bs->size) {
509  aisc_c_add_to_bytes_queue(link, bs->data, bs->size);
510 #if defined(DUMP_COMMUNICATION)
511  aisc_dump_hex("aisc_collect_sets bytestring: ", bs->data, bs->size);
512 #endif // DUMP_COMMUNICATION
513  }
514  link->aisc_mes_buffer[mes_cnt++] = bs->size; // size
515  break;
516  }
517  default:
518  link->error = "UNKNOWN TYPE";
519  PRTERR("AISC_SET_ERROR");
520  CORE();
521  return 0;
522  }
523 
524  count += 2;
525  if ((arg_cnt++) >= MAX_AISC_SET_GET) {
526  sprintf(errbuf, "TOO MANY ARGS (%i>%i)", arg_cnt, MAX_AISC_SET_GET);
527  link->error = errbuf;
528  PRTERR("AISC_SET_ERROR");
529  CORE();
530  return 0;
531  }
532  }
533  return mes_cnt;
534 }
535 
536  // @@@ DRY aisc_put vs aisc_nput
537  // @@@ the difference between aisc_put and aisc_nput is: aisc_put may return an error from server
538 
539 int aisc_put(aisc_com *link, int o_type, const AISC_Object& object, ...) { // goes to header: __ATTR__SENTINEL
540  aisc_assert(object.type() == o_type);
541 
542  int mes_cnt = 2;
543  link->aisc_mes_buffer[mes_cnt++] = object.get();
544  link->aisc_mes_buffer[mes_cnt++] = o_type;
545 
546  va_list parg;
547  va_start(parg, object);
548  if (!(mes_cnt = aisc_collect_sets(link, mes_cnt, parg, o_type, 4))) return 1;
549 
550  if (mes_cnt > 3) {
551  link->aisc_mes_buffer[0] = mes_cnt - 2;
552  link->aisc_mes_buffer[1] = AISC_SET+link->magic;
553  if (arb_socket_write(link->socket, (const char *)(link->aisc_mes_buffer), mes_cnt * sizeof(long))) {
555  PRTERR("AISC_SET_ERROR");
556  return 1;
557  }
558  if (aisc_c_send_bytes_queue(link)) return 1;
559  if (aisc_check_error(link)) return 1;
560  }
561  return 0;
562 }
563 
564 int aisc_nput(aisc_com *link, int o_type, const AISC_Object& object, ...) { // goes to header: __ATTR__SENTINEL
565  aisc_assert(object.type() == o_type);
566 
567  int mes_cnt = 2;
568  link->aisc_mes_buffer[mes_cnt++] = object.get();
569  link->aisc_mes_buffer[mes_cnt++] = o_type;
570 
571  va_list parg;
572  va_start(parg, object);
573  if (!(mes_cnt = aisc_collect_sets(link, mes_cnt, parg, o_type, 4))) {
574  return 1;
575  }
576 
577  if (mes_cnt > 3) {
578  link->aisc_mes_buffer[0] = mes_cnt - 2;
579  link->aisc_mes_buffer[1] = AISC_NSET+link->magic;
580 
581  if (arb_socket_write(link->socket, (const char *)(link->aisc_mes_buffer), mes_cnt * sizeof(long))) {
583  PRTERR("AISC_SET_ERROR");
584  return 1;
585  }
586  if (aisc_c_send_bytes_queue(link)) {
587  return 1;
588  }
589  }
590  return 0;
591 }
592 
593 int aisc_create(aisc_com *link, int father_type, const AISC_Object& father,
594  int attribute, int object_type, AISC_Object& object, ...)
595 {
596  // goes to header: __ATTR__SENTINEL
597  // arguments in '...' set elements of CREATED object (not of father)
598  int mes_cnt;
599  va_list parg;
600  mes_cnt = 2;
601  if ((father_type&0xff00ffff)) {
602  link->error = "FATHER_TYPE UNKNOWN";
603  PRTERR("AISC_CREATE_ERROR");
604  CORE();
605  return 1;
606  }
607  if ((object_type&0xff00ffff)) {
608  link->error = "OBJECT_TYPE UNKNOWN";
609  PRTERR("AISC_CREATE_ERROR");
610  CORE();
611  return 1;
612  }
613  aisc_assert(father.type() == father_type);
614  aisc_assert(object.type() == object_type);
615  link->aisc_mes_buffer[mes_cnt++] = father_type;
616  link->aisc_mes_buffer[mes_cnt++] = father.get();
617  link->aisc_mes_buffer[mes_cnt++] = attribute;
618  link->aisc_mes_buffer[mes_cnt++] = object_type;
619  if (father_type != (attribute & AISC_OBJ_TYPE_MASK)) {
620  link->error = "ATTRIBUTE TYPE DON'T FIT OBJECT";
621  PRTERR("AISC_CREATE_ERROR");
622  CORE();
623  return 1;
624  }
625  va_start(parg, object);
626  if (!(mes_cnt = aisc_collect_sets(link, mes_cnt, parg, object_type, 7))) return 1;
627  link->aisc_mes_buffer[0] = mes_cnt - 2;
628  link->aisc_mes_buffer[1] = AISC_CREATE+link->magic;
629  if (arb_socket_write(link->socket, (const char *)(link->aisc_mes_buffer), mes_cnt * sizeof(long))) {
631  PRTERR("AISC_CREATE_ERROR");
632  return 1;
633  }
634  if (aisc_c_send_bytes_queue(link)) return 1;
635  if (aisc_check_error(link)) return 1;
636  object.init(link->aisc_mes_buffer[0]);
637  return 0;
638 }
639 
640 /* --------------------------------------------------------------------------------
641  * Note: it's not possible to define unit tests here - they won't execute
642  * Instead put your tests into ../../SERVERCNTRL/servercntrl.cxx@UNIT_TESTS
643  */
644 
645 
int aisc_core_on_error
Definition: client.c:34
const char * GB_ERROR
Definition: arb_core.h:25
GB_TYPES type
#define PRTERR(msg)
Definition: client.c:50
aisc_com * aisc_client_link
Definition: client.c:43
long get() const
Definition: aisc_global.h:68
int aisc_close(aisc_com *link, AISC_Object &object)
Definition: client.c:249
aisc_bytes_list * next
Definition: client_privat.h:34
long
Definition: AW_awar.cxx:152
#define AISC_MAX_STRING_LEN
Definition: client_privat.h:28
void init(long remotePtr)
Definition: aisc_global.h:72
static int aisc_add_message_queue(aisc_com *link, long size)
Definition: client.c:96
static char errbuf[ERRBUF_SIZE]
Definition: client.c:48
#define MAX_AISC_SET_GET
Definition: client_privat.h:27
GB_ERROR arb_open_socket(const char *name, bool do_connect, int *fd, char **filename_out)
Definition: arb_cs.cxx:124
char * part_of(const char *str, size_t max_len, size_t str_len)
Definition: client.c:418
long * aisc_debug_info(aisc_com *link, int o_type, const AISC_Object &object, int attribute)
Definition: client.c:384
int message_type
Definition: client.c:92
int aisc_nput(aisc_com *link, int o_type, const AISC_Object &object,...)
Definition: client.c:564
long aisc_mes_buffer[AISC_MESSAGE_BUFFER_LEN]
Definition: client_privat.h:45
#define AISC_DUMP(where, type, var)
Definition: trace.h:58
char buffer[MESSAGE_BUFFERSIZE]
Definition: seq_search.cxx:34
#define AISC_ATTR_MASK
Definition: aisc_global.h:39
client_msg_queue * next
Definition: client.c:91
static const char * err_connection_problems
Definition: client.c:32
static int aisc_c_send_bytes_queue(aisc_com *link)
Definition: client.c:74
char * message
Definition: client.c:93
POS_TREE1 * father
Definition: probe_tree.h:39
int aisc_put(aisc_com *link, int o_type, const AISC_Object &object,...)
Definition: client.c:539
#define AISC_TYPE_INT
Definition: aisc_global.h:31
bool exists() const
Definition: aisc_global.h:67
int type() const
Definition: aisc_global.h:69
#define CORE()
Definition: client.c:36
#define AISC_TYPE_DOUBLE
Definition: aisc_global.h:32
aisc_bytes_list * aisc_client_bytes_first
Definition: client_privat.h:46
char * data
Definition: bytestring.h:16
#define AISC_MAGIC_NUMBER_FILTER
Definition: client.c:30
#define ERRBUF_SIZE
Definition: client.c:47
static int aisc_check_error(aisc_com *link)
Definition: client.c:121
static void error(const char *msg)
Definition: mkptypes.cxx:96
int as_int[2]
Definition: aisc_global.h:51
void clear()
Definition: aisc_global.h:71
#define AISC_VAR_TYPE_MASK
Definition: aisc_global.h:37
#define AISC_INDEX
Definition: aisc_global.h:41
static long aisc_init_client(aisc_com *link)
Definition: client.c:187
#define AISC_OBJ_TYPE_MASK
Definition: aisc_global.h:38
va_end(argPtr)
long magic
Definition: client_privat.h:42
double as_double
Definition: aisc_global.h:50
static void copy(double **i, double **j)
Definition: trnsprob.cxx:32
size_t arb_socket_read(int socket, char *ptr, size_t size)
Definition: arb_cs.cxx:61
static int aisc_collect_sets(aisc_com *link, int mes_cnt, va_list parg, int o_type, int count)
Definition: client.c:437
#define AISC_TYPE_BYTES
Definition: aisc_global.h:35
aisc_com * link
aisc_com * aisc_open(const char *path, AISC_Object &main_obj, long magic, GB_ERROR *error)
Definition: client.c:205
#define AISC_TYPE_STRING
Definition: aisc_global.h:33
#define AISC_MESSAGE_BUFFER_LEN
Definition: client_privat.h:29
va_start(argPtr, format)
static void aisc_c_add_to_bytes_queue(aisc_com *link, char *data, int size)
Definition: client.c:56
#define AISC_MAX_ATTR
Definition: client_privat.h:26
#define NULp
Definition: cxxforward.h:116
int aisc_get(aisc_com *link, int o_type, const AISC_Object &object,...)
Definition: client.c:266
const char * error
Definition: client_privat.h:43
ssize_t arb_socket_write(int socket, const char *ptr, size_t size)
Definition: arb_cs.cxx:75
static void aisc_free_link(aisc_com *link)
Definition: client.c:201
static int aisc_print_error_to_stderr
Definition: client.c:45
size_t length
#define AISC_TYPE_COMMON
Definition: aisc_global.h:34
int * message_queue
Definition: client_privat.h:41
int aisc_create(aisc_com *link, int father_type, const AISC_Object &father, int attribute, int object_type, AISC_Object &object,...)
Definition: client.c:593
aisc_bytes_list * aisc_client_bytes_last
Definition: client_privat.h:47
#define AISC_DUMP_SEP()
Definition: trace.h:59
#define aisc_assert(cond)
Definition: client.c:26