ARB
server.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <errno.h>
5 #include <string.h>
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <sys/un.h>
9 #include <netinet/in.h>
10 #include <netinet/tcp.h>
11 #include <arpa/inet.h>
12 #include <sys/stat.h>
13 #include <limits.h>
14 
15 #include "trace.h"
16 
17 #define FD_SET_TYPE
18 
19 #if defined(DEBUG)
20 // #define SERVER_TERMINATE_ON_CONNECTION_CLOSE
21 #endif // DEBUG
22 
23 #include <signal.h>
24 #include <sys/time.h>
25 #include <netdb.h>
26 #include <setjmp.h>
27 
28 #include <aisc_com.h>
29 // AISC_MKPT_PROMOTE:#include <aisc_func_types.h>
30 #include "server.h"
31 
32 #include <SigHandler.h>
33 #include <arb_cs.h>
34 #include <static_assert.h>
35 
36 // AISC_MKPT_PROMOTE:#ifndef _STDIO_H
37 // AISC_MKPT_PROMOTE:#include <stdio.h>
38 // AISC_MKPT_PROMOTE:#endif
39 
40 #define aisc_assert(cond) arb_assert(cond)
41 
42 #define AISC_SERVER_OK 1
43 #define AISC_SERVER_FAULT 0
44 #define MAX_QUEUE_LEN 5
45 
46 #define AISC_MAGIC_NUMBER_FILTER 0xffffff00
47 
48 // -------------------------
49 // some structures
50 
51 #ifdef __cplusplus
52 extern "C" {
53 #endif
54 
55  struct Socinf {
57  int socket;
58  aisc_destroy_callback destroy_callback;
60  int lasttime;
61  };
62 
63 #ifdef __cplusplus
64 }
65 #endif
66 
67 struct pollfd;
68 struct Hs_struct : virtual Noncopyable {
69  int hso;
71  struct pollfd *fds;
72  unsigned long nfds;
73  int nsoc;
74  int timeout;
75  int fork;
76  char *unix_name;
77 
79  : hso(0),
80  soci(NULp),
81  fds(NULp),
82  nfds(0),
83  nsoc(0),
84  timeout(0),
85  fork(0),
86  unix_name(NULp)
87  {}
88  ~Hs_struct() { freenull(unix_name); }
89 };
90 
91 struct aisc_bytes_list {
92  char *data;
93  int size;
95 };
96 
99 
100 
101 extern char *aisc_object_names[];
102 extern char **aisc_attribute_names_list[];
103 
104 extern aisc_talking_func_long *aisc_talking_functions_get[];
105 extern aisc_talking_func_long *aisc_talking_functions_set[];
106 extern aisc_talking_func_longp *aisc_talking_functions_copy[];
107 extern aisc_talking_func_longp *aisc_talking_functions_find[];
108 extern aisc_talking_func_longp *aisc_talking_functions_create[];
109 extern aisc_talking_func_long aisc_talking_functions_delete[];
110 
111 const char *aisc_server_error;
112 
113 const int ERRORBUFSIZE = 256;
114 static char error_buf[ERRORBUFSIZE];
115 
116 static int aisc_server_con;
118 
119 // -----------------------
120 // error handling
121 
122 void aisc_server_errorf(const char *templat, ...) {
123  // goes to header: __ATTR__FORMAT(1)
124  va_list parg;
125 
126  va_start(parg, templat);
127  int printed = vsprintf(error_buf, templat, parg);
128 
129  if (printed >= ERRORBUFSIZE) {
130  fprintf(stderr,
131  "Fatal: buffer overflow in aisc_server_errorf\n"
132  "Error was: ");
133  vfprintf(stderr, templat, parg);
134  fputs("\nTerminating..\n", stderr);
135  fflush(stderr);
136  exit(EXIT_FAILURE);
137  }
138  va_end(parg);
139 
140  aisc_server_error = error_buf;
141 }
142 
143 
144 // -----------------------------
145 // valid memory tester
146 
147 static bool sigsegv_occurred = false;
148 static bool catch_sigsegv = 0;
149 static jmp_buf return_after_segv;
150 
151 static const char *test_address_valid(void *address, long key) {
152  /* tests whether 'address' is a valid readable address
153  * if 'key' != 0 -> check if 'address' contains 'key'
154  *
155  * returns NULp or error string
156  */
157 
158  static char buf[256];
159  char *result = buf;
160 
161  sigsegv_occurred = false;
162  catch_sigsegv = true;
163 
164  // ----------------------------------------
165  // start of critical section
166  // (need volatile for modified local auto variables, see man longjump)
167  volatile long i = 0;
168  volatile int trapped = sigsetjmp(return_after_segv, 1);
169 
170  if (trapped == 0) { // normal execution
171  i = *(long *)address; // here a SIGSEGV may happen. Execution will continue in else-branch
172  }
173  else { // return after SEGV
174  aisc_assert(trapped == 666); // oops - SEGV did not occur in mem access above!
175  aisc_assert(sigsegv_occurred); // oops - wrong handler installed ?
176  }
177  // end of critical section
178  // ----------------------------------------
179 
180  catch_sigsegv = false;
181 
182  if (sigsegv_occurred) {
183  sprintf(buf, "AISC memory manager error: can't access memory at address %p", address);
184  }
185  else {
186  if (key && i != key) {
187  sprintf(buf, "AISC memory manager error: object at address %p has wrong type (found: 0x%lx, expected: 0x%lx)",
188  address, i, key);
189  }
190  else {
191  result = NULp; // ok, address (and key) valid
192  }
193  }
194 
195  return result;
196 }
197 
199 
200 __ATTR__NORETURN static void aisc_server_sigsegv(int sig) {
201  sigsegv_occurred = true;
202  if (catch_sigsegv) {
203  siglongjmp(return_after_segv, 666); // never returns
204  }
205  // unexpected SEGV
206 
207  UNINSTALL_SIGHANDLER(SIGSEGV, aisc_server_sigsegv, old_sigsegv_handler, "aisc_server_sigsegv");
208  old_sigsegv_handler(sig);
209  aisc_assert(0); // oops - old handler returned
210  abort();
211 }
212 
213 
214 // ----------------------------------------------
215 // object+attr_names for error messages
216 
217 
218 const char *aisc_get_object_names(long i) {
219  if ((i<0) || (i>=AISC_MAX_OBJECT) || (!aisc_object_names[i])) {
220  return "<unknown object>";
221  }
222  return aisc_object_names[i];
223 }
224 
225 static const char *aisc_get_object_attribute(long i, long j) {
226  if ((i<0) || (i>=AISC_MAX_OBJECT) || (!aisc_attribute_names_list[i])) {
227  return "<null>";
228  }
229  if ((j<0) || (j>=AISC_MAX_ATTR) || (!aisc_attribute_names_list[i][j])) {
230  return "<unknown attribute>";
231  }
232  return aisc_attribute_names_list[i][j];
233 }
234 
235 Hs_struct *open_aisc_server(const char *path, int timeout, int fork) {
236  Hs_struct *hs = new Hs_struct;
237  if (hs) {
238  hs->timeout = timeout;
239  hs->fork = fork;
240 
241  static int so;
242  const char *err = arb_open_socket(path, false, &so, &hs->unix_name);
243 
244  if (err) {
245  if (*err) printf("Error in open_aisc_server: %s\n", err);
246  shutdown(so, SHUT_RDWR);
247  close(so);
248  delete hs; hs = NULp;
249  }
250  else {
251  // install signal handlers
252  fprintf(stderr, "Installing signal handler from open_aisc_server\n"); fflush(stderr);
253  old_sigsegv_handler = INSTALL_SIGHANDLER(SIGSEGV, aisc_server_sigsegv, "open_aisc_server");
254 
255  aisc_server_bytes_first = NULp;
256  aisc_server_bytes_last = NULp;
257  // simply take first address
258  if (listen(so, MAX_QUEUE_LEN) < 0) {
259  printf("Error in open_aisc_server: could not listen (errno=%i)\n", errno);
260  delete hs; hs = NULp;
261  }
262  else {
263  hs->hso = so;
264  }
265  }
266  }
267  return hs;
268 }
269 
270 static void aisc_s_add_to_bytes_queue(char *data, int size) {
271  aisc_bytes_list *bl;
272  bl = (aisc_bytes_list *)calloc(sizeof(aisc_bytes_list), 1);
273  bl->data = data;
274  bl->size = size;
275 
276  if (aisc_server_bytes_first) {
277  aisc_server_bytes_last->next = bl;
278  aisc_server_bytes_last = bl;
279  }
280  else {
281  aisc_server_bytes_first = bl;
282  aisc_server_bytes_last = bl;
283  }
284 }
285 
286 static int aisc_s_send_bytes_queue(int socket) {
287  aisc_bytes_list *bl, *bl_next;
288  for (bl = aisc_server_bytes_first; bl; bl=bl_next) {
289  bl_next = bl->next;
290  if (arb_socket_write(socket, (char *)bl->data, bl->size)) return 1;
291  free(bl);
292  };
293  aisc_server_bytes_first = aisc_server_bytes_last = NULp;
294  return 0;
295 }
296 
297 static long aisc_talking_get(long *in_buf, int size, long *out_buf, int) { // handles AISC_GET
298  aisc_server_error = NULp;
299 
300  long in_pos = 0;
301  long out_pos = 0;
302  long object = in_buf[in_pos++];
303  long object_type = (in_buf[in_pos] & AISC_OBJ_TYPE_MASK);
304 
305 
306  if (object_type > (AISC_MAX_OBJECT*0x10000)) {
307  aisc_server_error = "UNKNOWN OBJECT";
308  object = 0;
309  }
310  else {
311  aisc_server_error = test_address_valid((void *)object, object_type);
312  }
313  object_type = object_type >> (16);
314 
315  AISC_DUMP_SEP();
316  AISC_DUMP(aisc_talking_get, int, object_type);
317 
318  long attribute = 0;
319  long erg = 0;
320  while (!aisc_server_error && (in_pos < size)) {
321  long code = in_buf[in_pos];
322  long type = (code & AISC_VAR_TYPE_MASK);
323  attribute = (code & AISC_ATTR_MASK);
324 
325  aisc_talking_func_long *functions = aisc_talking_functions_get[object_type];
326 
327  if (!functions) {
328  aisc_server_error = "OBJECT HAS NO ATTRIBUTES";
329  attribute = 0;
330  break;
331  }
332  if (attribute > AISC_MAX_ATTR) {
333  sprintf(error_buf, "ATTRIBUTE %lx OUT of RANGE", attribute);
334  aisc_server_error = error_buf;
335  attribute = 0;
336  break;
337  }
338  aisc_talking_func_long function = functions[attribute];
339  if (!function) {
340  sprintf(error_buf, "DON'T KNOW ATTRIBUTE %li",
341  attribute);
342  aisc_server_error = error_buf;
343  break;
344  }
345 
346  AISC_DUMP(aisc_talking_get, int, attribute);
347  AISC_DUMP(aisc_talking_get, int, type);
348 
349  double_xfer derg;
350  STATIC_ASSERT(sizeof(derg.as_double) <= sizeof(derg.as_int));
351 
352  if (type == AISC_TYPE_DOUBLE) {
353  aisc_talking_func_double dfunction = AISC_CASTSIG(aisc_talking_func_double, function);
354  derg.as_double = dfunction(object);
355  }
356  else {
357  erg = function(object);
358  }
359  if (aisc_server_error) {
360  break;
361  }
362  switch (type) {
363  case AISC_TYPE_INT:
364  case AISC_TYPE_COMMON:
365  AISC_DUMP(aisc_talking_get, int, erg);
366  out_buf[out_pos++] = erg;
367  break;
368 
369  case AISC_TYPE_DOUBLE:
370  AISC_DUMP(aisc_talking_get, double, derg.as_double);
371  out_buf[out_pos++] = derg.as_int[0];
372  out_buf[out_pos++] = derg.as_int[1];
373  break;
374 
375  case AISC_TYPE_STRING: {
376  if (!erg) erg = (long) "(null)";
377  long len = strlen((char *)erg);
378  if (len > AISC_MAX_STRING_LEN) {
379  erg = (long) "(string too long)";
380  len = strlen((char *)erg);
381  }
382 
383  AISC_DUMP(aisc_talking_get, charPtr, (char*)erg);
384 
385  len += 1;
386  len /= sizeof(long);
387  len++;
388  out_buf[out_pos++] = len;
389  strcpy((char *)&out_buf[out_pos], (char *)erg);
390  out_pos += len;
391  break;
392  }
393  case AISC_TYPE_BYTES: {
394  bytestring *bs = (bytestring *)erg;
395 
396  AISC_DUMP(aisc_talking_get, int, bs->size);
397 #if defined(DUMP_COMMUNICATION)
398  aisc_dump_hex("aisc_talking_get bytestring: ", bs->data, bs->size);
399 #endif // DUMP_COMMUNICATION
400 
401  if (bs->data && bs->size) {
403  }
404  out_buf[out_pos++] = bs->size; // size
405  break;
406  }
407  default:
408  aisc_server_error = "UNKNOWN TYPE";
409  break;
410  }
411  in_pos++;
412  }
413  if (aisc_server_error) {
414  sprintf((char *) out_buf, "AISC_GET_SERVER_ERROR %s: OBJECT:%s ATTRIBUTE:%s",
415  aisc_server_error,
416  aisc_get_object_names(object_type),
417  aisc_get_object_attribute(object_type, attribute));
418  return -((strlen((char *)out_buf) + 1) / sizeof(long) + 1);
419  }
420  return out_pos;
421 }
422 
423 static int aisc_server_index = -1;
424 
425 static void aisc_talking_set_index(int */*obj*/, int i) {
426  aisc_server_index = i;
427 }
428 
429 int aisc_talking_get_index(int u, int o) {
430  if (aisc_server_index==-1) {
431  aisc_server_error = "AISC_SERVER_ERROR MISSING AN AISC_INDEX";
432  return -1;
433  }
434  if ((aisc_server_index<u) || (aisc_server_index>=o)) {
435  sprintf(error_buf, "AISC_SET_SERVER_ERROR: INDEX %i IS OUT OF RANGE [%i,%i]",
436  aisc_server_index, u, o);
437  aisc_server_error = error_buf;
438  }
439 
440  AISC_DUMP(aisc_talking_get_index, int, aisc_server_index);
441 
442  return aisc_server_index;
443 }
444 
445 static long aisc_talking_sets(long *in_buf, int size, long *out_buf, long *object, int object_type) {
446  int blen, bsize;
447  long in_pos, out_pos;
448  long code, attribute, type;
449 
450  aisc_talking_func_long function;
451  aisc_talking_func_long *functions;
452  in_pos = out_pos = 0;
453  aisc_server_index = -1;
454  aisc_server_error = NULp;
455  object_type = (object_type & AISC_OBJ_TYPE_MASK);
456 
457  attribute = 0;
458  if (object_type > (AISC_MAX_OBJECT*0x10000)) {
459  object_type = 0;
460  aisc_server_error = "UNKNOWN OBJECT";
461  }
462  else {
463  aisc_server_error = test_address_valid((void *)object, object_type);
464  }
465  object_type = object_type>>(16);
466  functions = aisc_talking_functions_set[object_type];
467  if (!functions) {
468  sprintf(error_buf, "OBJECT %x HAS NO ATTRIBUTES",
469  object_type);
470  aisc_server_error = error_buf;
471  }
472 
473  AISC_DUMP_SEP();
474  AISC_DUMP(aisc_talking_sets, int, object_type);
475 
476  while (!aisc_server_error && (in_pos<size)) {
477  code = in_buf[in_pos++];
478  attribute = code & AISC_ATTR_MASK;
479  type = code & AISC_VAR_TYPE_MASK;
480  if (attribute > AISC_MAX_ATTR) {
481  sprintf(error_buf, "ATTRIBUTE %li DOESN'T EXIST",
482  attribute);
483  aisc_server_error = error_buf;
484  attribute = 0;
485  break;
486  }
487  if (code == AISC_INDEX) {
488  function = AISC_CASTSIG(aisc_talking_func_long, aisc_talking_set_index);
489  }
490  else {
491  function = functions[attribute];
492  }
493  if (!function) {
494  sprintf(error_buf, "ATTRIBUTE %li DOESN'T EXIST",
495  attribute);
496  aisc_server_error = error_buf;
497  break;
498  }
499 
500  AISC_DUMP(aisc_talking_sets, int, attribute);
501  AISC_DUMP(aisc_talking_sets, int, type);
502 
503  switch (type) {
504  case AISC_TYPE_INT:
505  case AISC_TYPE_COMMON:
506 
507  AISC_DUMP(aisc_talking_sets, long, in_buf[in_pos]);
508 
509  function((long)object, in_buf[in_pos++]);
510  break;
511  case AISC_TYPE_DOUBLE: {
512  double_xfer derg;
513  derg.as_int[0] = in_buf[in_pos++];
514  derg.as_int[1] = in_buf[in_pos++];
515 
516  AISC_DUMP(aisc_talking_sets, double, derg.as_double);
517 
518  function((long)object, derg.as_double);
519  break;
520  }
521  case AISC_TYPE_STRING: {
522  char *str = strdup((char *)&(in_buf[in_pos+1]));
523 
524  AISC_DUMP(aisc_talking_sets, charPtr, str);
525 
526  function((long)object, str);
527  in_pos += in_buf[in_pos]+1;
528  break;
529  }
530  case AISC_TYPE_BYTES:
531  bsize = (int)in_buf[in_pos++];
532 
533  AISC_DUMP(aisc_talking_sets, int, bsize);
534 
535  if (bsize) {
536  long *ptr = (long*)calloc(sizeof(char), bsize);
537  blen = arb_socket_read(aisc_server_con, (char *)ptr, bsize);
538  if (bsize!=blen) {
539  aisc_server_error = "CONNECTION PROBLEMS IN BYTESTRING";
540  free(ptr);
541  }
542  else {
543  bytestring bs;
544  bs.data = (char *)ptr;
545  bs.size = bsize;
546 
547 #if defined(DUMP_COMMUNICATION)
548  aisc_dump_hex("aisc_talking_sets bytestring: ", (char*)ptr, bsize);
549 #endif // DUMP_COMMUNICATION
550 
551  function((long)object, &bs);
552  }
553  }
554  else {
555  function((long)object, 0);
556  }
557  break;
558  default:
559  aisc_server_error = "UNKNOWN TYPE";
560  break;
561  }
562  }
563  if (aisc_server_error) {
564  sprintf((char *) out_buf, "AISC_SET_SERVER_ERROR %s: OBJECT:%s ATTRIBUTE:%s",
565  aisc_server_error,
566  aisc_get_object_names(object_type),
567  aisc_get_object_attribute(object_type, attribute));
568  return -((strlen((char *)out_buf) + 1) / sizeof(long) + 1);
569  }
570  return 0;
571 }
572 
573 static long aisc_talking_set(long *in_buf, int size, long *out_buf, int) { // handles AISC_SET
574  aisc_server_error = NULp;
575 
576  int in_pos = 0;
577  long object = in_buf[in_pos++];
578  int object_type = ((int)in_buf[in_pos++]) & AISC_OBJ_TYPE_MASK;
579 
580  return aisc_talking_sets(&(in_buf[in_pos]), size-in_pos, out_buf, (long *)object, object_type);
581 }
582 
583 static long aisc_talking_nset(long *in_buf, int size, long *out_buf, int) { // handles AISC_NSET
584  aisc_server_error = NULp;
585 
586  int in_pos = 0;
587  long object = in_buf[in_pos++];
588  int object_type = (int)(in_buf[in_pos++] & AISC_OBJ_TYPE_MASK);
589 
590  aisc_talking_sets(&(in_buf[in_pos]), size-in_pos, out_buf, (long *)object, object_type);
591  return AISC_NO_ANSWER;
592 }
593 
594 static struct aisc_static_set_mem {
595  long *ibuf, *obuf;
596  int size, type;
597 } md;
598 
599 long aisc_make_sets(long *obj) {
600  if (md.size>0) {
601  return aisc_talking_sets(md.ibuf, md.size, md.obuf, obj, md.type);
602  }
603  else {
604  return 0;
605  }
606 }
607 
608 static long aisc_talking_create(long *in_buf, int size, long *out_buf, int) { // handles AISC_CREATE
609  aisc_server_error = NULp;
610 
611  int in_pos = 0;
612  long father_type = in_buf[in_pos++];
613  long father = in_buf[in_pos++];
614 
615  long *erg = NULp;
616  for (int i=0; i<1; i++) {
617  if ((father_type&0xff00ffff) ||
618  (((unsigned int)father_type& 0xff0000) >= (AISC_MAX_OBJECT*0x10000))) {
619  aisc_server_error = "AISC_CREATE_SERVER_ERROR: FATHER UNKNOWN";
620  break;
621  }
622  aisc_server_error = test_address_valid((void *)father, father_type);
623  if (aisc_server_error) break;
624 
625  father_type = father_type>>16;
626  aisc_talking_func_longp *functions = aisc_talking_functions_create[father_type];
627 
628  long code = in_buf[in_pos++];
629  long attribute = code & AISC_ATTR_MASK;
630  long object_type = in_buf[in_pos++];
631 
632  if (!functions) {
633  sprintf(error_buf, "AISC_CREATE_SERVER_ERROR: FATHER %s DOESN'T HAVE TARGET-ATTRIBUTE %s",
634  aisc_get_object_names(father_type), aisc_get_object_attribute(father_type, attribute));
635  aisc_server_error = error_buf;
636  break;
637  }
638  if (attribute > AISC_MAX_ATTR) {
639  aisc_server_error = "AISC_CREATE_SERVER_ERROR: UNKNOWN ATTRIBUTE";
640  break;
641  }
642  aisc_talking_func_longp function = functions[attribute];
643  if (!function) {
644  sprintf(error_buf, "AISC_CREATE_SERVER_ERROR: FATHER %s FATHER DOESN'T HAVE TARGET-ATTRIBUTE %s",
645  aisc_get_object_names(father_type), aisc_get_object_attribute(father_type, attribute));
646  aisc_server_error = error_buf;
647  break;
648  }
649  md.ibuf = &(in_buf[in_pos]);
650  md.obuf = out_buf;
651  md.size = size - in_pos;
652  md.type = (int)object_type;
653  erg = function(father);
654  }
655  if (aisc_server_error) {
656  sprintf((char *) out_buf, "%s", aisc_server_error);
657  return -((strlen(aisc_server_error) + 1) / sizeof(long) + 1);
658  }
659  else {
660  out_buf[0] = (long)erg;
661  return 1;
662  }
663 }
664 
665 static long aisc_talking_copy(long *in_buf, int size, long *out_buf, int /*max_size*/) { // handles AISC_COPY
666  aisc_server_error = NULp;
667 
668  int in_pos = 0;
669  long object = in_buf[in_pos++];
670  int father_type = (int)in_buf[in_pos++];
671  long father = in_buf[in_pos++];
672 
673  long *erg = NULp;
674  for (int i=0; i<1; i++) {
675  if ((father_type&0xff00ffff) ||
676  (((unsigned int)father_type& 0xff0000) >= (AISC_MAX_OBJECT*0x10000))) {
677  aisc_server_error = "AISC_COPY_SERVER_ERROR: FATHER UNKNOWN";
678  break;
679  }
680  aisc_server_error = test_address_valid((void *)father, father_type);
681  if (aisc_server_error) break;
682 
683  father_type = father_type>>16;
684  aisc_talking_func_longp *functions = aisc_talking_functions_copy[father_type];
685 
686  if (!functions) {
687  aisc_server_error = "AISC_COPY_SERVER_ERROR: FATHER DOESN'T HAVE TARGET-ATTRIBUTES";
688  break;
689  }
690 
691  int code = (int)in_buf[in_pos++];
692  int object_type = (int)in_buf[in_pos++];
693  int attribute = code & AISC_ATTR_MASK;
694 
695  if (attribute > AISC_MAX_ATTR) {
696  aisc_server_error = "AISC_COPY_SERVER_ERROR: UNKNOWN ATTRIBUTE";
697  break;
698  }
699  aisc_talking_func_longp function = functions[attribute];
700  if (!function) {
701  sprintf(error_buf, "AISC_COPY_SERVER_ERROR: FATHER %s DOESN'T HAVE TARGET-ATTRIBUTE %s",
702  aisc_get_object_names(father_type), aisc_get_object_attribute(father_type, attribute));
703  aisc_server_error = error_buf;
704  break;
705  }
706  aisc_server_error = test_address_valid((void *)object, object_type);
707  if (aisc_server_error) break;
708 
709  md.ibuf = &(in_buf[in_pos]);
710  md.obuf = out_buf;
711  md.size = size - in_pos;
712  md.type = object_type;
713  erg = function(father, object);
714  }
715  if (aisc_server_error) {
716  sprintf((char *) out_buf, "%s", aisc_server_error);
717  return -((strlen(aisc_server_error) + 1) / sizeof(long) + 1);
718  }
719  else {
720  out_buf[0] = (long)erg;
721  return 1;
722  }
723 }
724 
725 static long aisc_talking_find(long *in_buf, int /*size*/, long *out_buf, int /*max_size*/) { // handles AISC_FIND
726  aisc_server_error = NULp;
727 
728  int in_pos = 0;
729  long father_type = in_buf[in_pos++];
730  long father = in_buf[in_pos++];
731 
732  long *erg = NULp;
733  for (int i = 0; i < 1; i++) {
734  if ((father_type & 0xff00ffff) ||
735  (((unsigned int) father_type & 0xff0000) >= (AISC_MAX_OBJECT*0x10000))) {
736  aisc_server_error = "AISC_FIND_SERVER_ERROR: FATHER UNKNOWN";
737  break;
738  }
739  aisc_server_error = test_address_valid((void *)father, father_type);
740  if (aisc_server_error)
741  break;
742 
743  father_type = father_type>>16;
744  aisc_talking_func_longp *functions = aisc_talking_functions_find[father_type];
745 
746  long code = in_buf[in_pos++];
747  long attribute = code & AISC_ATTR_MASK;
748 
749  if (!functions) {
750  aisc_server_error = "AISC_FIND_SERVER_ERROR: FATHER DON'T KNOW ATTRIBUTES FOR SEARCH";
751  break;
752  }
753  if (attribute > AISC_MAX_ATTR) {
754  aisc_server_error = "AISC_FIND_SERVER_ERROR: UNKNOWN ATTRIBUTE";
755  break;
756  }
757  aisc_talking_func_longp function = functions[attribute];
758  if (!function) {
759  sprintf(error_buf, "AISC_FIND_SERVER_ERROR: FATHER %s DON'T KNOW ATTRIBUTE %s FOR SEARCH",
760  aisc_get_object_names(father_type), aisc_get_object_attribute(father_type, attribute));
761  aisc_server_error = error_buf;
762  break;
763  }
764  if (in_buf[in_pos++]<=0) {
765  aisc_server_error = " AISC_FIND_SERVER_ERROR: CANNOT FIND EMPTY IDENT";
766  break;
767  }
768  erg = function(father, &(in_buf[in_pos]));
769  }
770  if (aisc_server_error) {
771  sprintf((char *) out_buf, "%s", aisc_server_error);
772  return -((strlen(aisc_server_error) + 1) / sizeof(long) + 1);
773  }
774  else {
775  out_buf[0] = (long) erg;
776  return 1;
777  }
778 }
779 
780 extern int *aisc_main;
781 
782 static long aisc_talking_init(long */*in_buf*/, int /*size*/, long *out_buf, int /*max_size*/) { // handles AISC_INIT
783  aisc_server_error = NULp;
784  out_buf[0] = (long)aisc_main;
785  return 1;
786 }
787 
788 static long aisc_fork_server(long */*in_buf*/, int /*size*/, long */*out_buf*/, int /*max_size*/) { // handles AISC_FORK_SERVER
789  pid_t pid = fork();
790  return pid<0 ? 0 : pid; // return OK(=0) when fork does not work
791 }
792 
793 static long aisc_talking_delete(long *in_buf, int /*size*/, long *out_buf, int /*max_size*/) { // handles AISC_DELETE
794  int in_pos, out_pos;
795  long object_type;
796 
797  aisc_talking_func_long function;
798 
799  int i;
800  long object;
801  in_pos = out_pos = 0;
802  aisc_server_error = NULp;
803  object_type = in_buf[in_pos++];
804  object_type = (object_type & AISC_OBJ_TYPE_MASK);
805  object = in_buf[in_pos++];
806  for (i = 0; i < 1; i++) {
807  if (object_type > (AISC_MAX_OBJECT*0x10000)) {
808  aisc_server_error = "AISC_GET_SERVER_ERROR: UNKNOWN OBJECT";
809  }
810  else {
811  aisc_server_error = test_address_valid((void *)object, object_type);
812  }
813  if (aisc_server_error)
814  break;
815  object_type = object_type >> (16);
816  function = aisc_talking_functions_delete[object_type];
817  if (!function) {
818  sprintf(error_buf, "AISC_SET_SERVER_ERROR: OBJECT %s cannot be deleted",
819  aisc_object_names[object_type]);
820  aisc_server_error = error_buf;
821  break;
822  }
823  else {
824  function(object);
825  }
826  }
827  if (aisc_server_error) {
828  sprintf((char *) out_buf, "%s", aisc_server_error);
829  return -((strlen(aisc_server_error) + 1) / sizeof(long) + 1);
830  }
831  return 0;
832 }
833 
834 static long aisc_talking_debug_info(long *in_buf, int /*size*/, long *out_buf, int /*max_size*/) { // handles AISC_DEBUG_INFO
835  int in_pos, out_pos;
836  long object_type, attribute;
837 
838  aisc_talking_func_long *functionsg;
839  aisc_talking_func_long *functionss;
840  aisc_talking_func_longp *functions;
841 
842  int i;
843  long *object;
844 
845  in_pos = out_pos = 0;
846  aisc_server_error = NULp;
847 
848  for (i=0; i<256; i++) out_buf[i] = 0;
849  for (i = 0; i < 1; i++) {
850  object = (long *)in_buf[in_pos++];
851  attribute = in_buf[in_pos++];
852  aisc_server_error = test_address_valid((void *)object, 0);
853 
854  if (aisc_server_error)
855  break;
856 
857  object_type = *object;
858  if ((object_type > (AISC_MAX_OBJECT*0x10000)) || (object_type&0xff00ffff) || (object_type<0x00010000)) {
859  aisc_server_error = "AISC_DEBUGINFO_SERVER_ERROR: UNKNOWN OBJECT";
860  break;
861  }
862  attribute &= AISC_ATTR_MASK;
863  object_type = object_type>>16;
864 
865  if (!aisc_talking_functions_delete[object_type]) { out_buf[0] = 1; };
866 
867  if (!(functionsg=aisc_talking_functions_get[object_type])) {
868  out_buf[1] = 2;
869  }
870  else {
871  if (!functionsg[attribute]) out_buf[1] = 1;
872  };
873 
874  if (!(functionss=aisc_talking_functions_set[object_type])) {
875  out_buf[2] = 2;
876  }
877  else {
878  if (!functionss[attribute]) out_buf[2] = 1;
879  };
880 
881  if (!(functions=aisc_talking_functions_find[object_type])) {
882  out_buf[3] = 2;
883  }
884  else {
885  if (!functions[attribute]) out_buf[3] = 1;
886  };
887 
888  if (!(functions=aisc_talking_functions_create[object_type])) {
889  out_buf[4] = 2;
890  }
891  else {
892  if (!functions[attribute]) out_buf[4] = 1;
893  };
894 
895  if (!(functions=aisc_talking_functions_copy[object_type])) {
896  out_buf[5] = 2;
897  }
898  else {
899  if (!functions[attribute]) out_buf[5] = 1;
900  };
901 
902  }
903  if (aisc_server_error) {
904  sprintf((char *) out_buf, "%s", aisc_server_error);
905  return -((strlen(aisc_server_error) + 1) / sizeof(long) + 1);
906  }
907  else {
908  return 20;
909  }
910 }
911 
912 int aisc_broadcast(Hs_struct *hs, int message_type, const char *message) {
913  Socinf *si;
914  int size = message ? strlen(message) : 0;
915  int sizeL = (size+1+sizeof(long)-1) / sizeof(long); // number of longs needed to safely store string
916  long *out_buf = (long *)calloc(sizeL+3, sizeof(long));
917 
918  if (!message) {
919  out_buf[3] = 0;
920  }
921  else {
922  char *strStart = (char*)(out_buf+3);
923  int pad = sizeL*sizeof(long)-(size+1);
924 
925  aisc_assert(pad >= 0);
926 
927  memcpy(strStart, message, size+1);
928  if (pad) memset(strStart+size+1, 0, pad); // avoid to send uninitialized bytes
929  }
930 
931  aisc_assert(sizeL >= 1);
932 
933  out_buf[0] = sizeL+1;
934  out_buf[1] = AISC_CCOM_MESSAGE;
935  out_buf[2] = message_type;
936 
937  for (si=hs->soci; si; si=si->next) {
938  arb_socket_write(si->socket, (char *)out_buf, (sizeL + 3) * sizeof(long));
939  }
940  free(out_buf);
941  return 0;
942 }
943 
944 #ifdef __cplusplus
945 extern "C" {
946 #endif
947 
948  typedef long (*aisc_talking_function_type)(long*, int, long*, int);
949 
950 #ifdef __cplusplus
951 }
952 #endif
953 
955  aisc_talking_get, // AISC_GET
956  aisc_talking_set, // AISC_SET
957  aisc_talking_nset, // AISC_NSET
958  aisc_talking_create, // AISC_CREATE
959  aisc_talking_find, // AISC_FIND
960  aisc_talking_copy, // AISC_COPY
961  aisc_talking_delete, // AISC_DELETE
962  aisc_talking_init, // AISC_INIT
963  aisc_talking_debug_info, // AISC_DEBUG_INFO
964  aisc_fork_server // AISC_FORK_SERVER
965 };
966 
967 static int aisc_talking(int con) {
968  static long buf[AISC_MESSAGE_BUFFER_LEN];
969  static long out_buf[AISC_MESSAGE_BUFFER_LEN];
970  unsigned long len;
971  static long size;
972  long magic_number;
973  len = arb_socket_read(con, (char *)buf, 2* sizeof(long));
974  if (len == 2*sizeof(long)) {
975  aisc_server_con = con;
976  if (buf[0] >= AISC_MESSAGE_BUFFER_LEN)
977  return AISC_SERVER_FAULT;
978  magic_number = buf[1];
979  if ((unsigned long)(magic_number & AISC_MAGIC_NUMBER_FILTER) != (unsigned long)(AISC_MAGIC_NUMBER & AISC_MAGIC_NUMBER_FILTER)) {
980  return AISC_SERVER_FAULT;
981  }
982  size = buf[0];
983 
984  {
985  long expect = size*sizeof(long);
986  aisc_assert(expect >= 0);
987  aisc_assert(expect <= INT_MAX);
988 
989  len = arb_socket_read(con, (char *)buf, (int)expect);
990  aisc_assert(len <= LONG_MAX);
991 
992  if ((long)len != expect) {
993  printf(" ERROR in AISC_SERVER: Expected to get %li bytes from client (got %lu)\n", expect, len);
994  return AISC_SERVER_OK;
995  }
996  }
997  magic_number &= ~AISC_MAGIC_NUMBER_FILTER;
998  size = (aisc_talking_functions[magic_number])
999  (buf, (int)size, out_buf + 2, AISC_MESSAGE_BUFFER_LEN - 2);
1000  if (size >= 0) {
1001  out_buf[1] = AISC_CCOM_OK;
1002  }
1003  else {
1004  if (size == (long)AISC_NO_ANSWER) {
1005  return AISC_SERVER_OK;
1006  }
1007  out_buf[1] = AISC_CCOM_ERROR;
1008  size *= -1;
1009  }
1010  out_buf[0] = size;
1011  if (arb_socket_write(con, (char *)out_buf, (int)(size + 2) * sizeof(long))) {
1012  return AISC_SERVER_FAULT;
1013  }
1014  if (aisc_server_bytes_first) {
1015  if (aisc_s_send_bytes_queue(con)) {
1016  return AISC_SERVER_FAULT;
1017  }
1018  }
1019  return AISC_SERVER_OK;
1020  }
1021  else {
1022  return AISC_SERVER_FAULT;
1023  }
1024 }
1025 
1027  int con;
1028  int anz, i;
1029  Socinf *si, *si_last = NULp, *sinext, *sptr;
1030  fd_set set, setex;
1031  struct timeval timeout;
1032 
1033  if (!hs) {
1034  fprintf(stderr, "AISC_SERVER_ERROR socket error (==0)\n");
1035  }
1036 
1037  timeout.tv_sec = hs->timeout / 1000;
1038  timeout.tv_usec = (hs->timeout % 1000) * 1000;
1039 
1040  aisc_server_hs = hs;
1041 
1042  while (hs) {
1043  FD_ZERO(&set);
1044  FD_ZERO(&setex);
1045  FD_SET(hs->hso, &set);
1046  FD_SET(hs->hso, &setex);
1047 
1048  for (si=hs->soci, i=1; si; si=si->next, i++) {
1049  FD_SET(si->socket, &set);
1050  FD_SET(si->socket, &setex);
1051  }
1052  if (hs->timeout >= 0) {
1053  anz = select(FD_SETSIZE, FD_SET_TYPE &set, NULp, FD_SET_TYPE &setex, &timeout);
1054  }
1055  else {
1056  anz = select(FD_SETSIZE, FD_SET_TYPE &set, NULp, FD_SET_TYPE &setex, NULp);
1057  }
1058 
1059  if (anz==-1) {
1060  printf("ERROR: poll in aisc_accept_calls\n");
1061  return NULp;
1062  }
1063  if (!anz) { // timed out
1064  return hs;
1065  }
1066  // an event has occurred
1067  if ((timeout.tv_usec>=0)&&(timeout.tv_usec<100000)) timeout.tv_usec = 100000;
1068 
1069  if (FD_ISSET(hs->hso, &set)) {
1070  con = accept(hs->hso, NULp, NULp);
1071  if (hs->fork) {
1072  long id = fork();
1073  if (!id) {
1074  return hs;
1075  }
1076  }
1077 
1078  if (con>0) {
1079  static int optval;
1080  sptr = (Socinf *)calloc(sizeof(Socinf), 1);
1081  if (!sptr) return NULp;
1082  sptr->next = hs->soci;
1083  sptr->socket = con;
1084  hs->soci=sptr;
1085  hs->nsoc++;
1086  optval = 1;
1087  setsockopt(con, IPPROTO_TCP, TCP_NODELAY, (char *)&optval, 4);
1088  }
1089  }
1090  else {
1091  si_last = NULp;
1092 
1093  for (si=hs->soci; si; si_last=si, si=sinext) {
1094  sinext = si->next;
1095 
1096  if (FD_ISSET(si->socket, &set)) {
1097  if (AISC_SERVER_OK == aisc_talking(si->socket)) continue;
1098  } else if (!FD_ISSET(si->socket, &setex)) continue;
1099 
1100  if (close(si->socket) != 0) {
1101  printf("aisc_accept_calls: ");
1102  printf("couldn't close socket!\n");
1103  }
1104 
1105  hs->nsoc--;
1106  if (si == hs->soci) { // first one
1107  hs->soci = si->next;
1108  }
1109  else {
1110  si_last->next = si->next;
1111  }
1112  if (si->destroy_callback) {
1114  }
1115  free(si);
1116 #ifdef SERVER_TERMINATE_ON_CONNECTION_CLOSE
1117  if (hs->nsoc == 0) { // no clients left
1118  if (hs->fork) exit(EXIT_SUCCESS); // child exits
1119  return hs; // parent exits
1120  }
1121  break;
1122 #else
1123  // normal behavior
1124  if (hs->nsoc == 0 && hs->fork) exit(EXIT_SUCCESS);
1125  break;
1126 #endif
1127  }
1128  }
1129  } // while main loop
1130 
1131  return hs;
1132 }
1133 
1135  Socinf *si;
1136 
1137  for (si=hs->soci; si; si=si->next) {
1138  shutdown(si->socket, SHUT_RDWR);
1139  close(si->socket);
1140  }
1141  shutdown(hs->hso, SHUT_RDWR);
1142  close(hs->hso);
1143  if (hs->unix_name) unlink(hs->unix_name);
1144  delete hs; hs = NULp;
1145 }
1146 
1147 // ---------------------------
1148 // special functions
1149 
1150 
1151 int aisc_add_destroy_callback(aisc_destroy_callback callback, long clientdata) { // call from server function
1152  Socinf *si;
1153  int socket = aisc_server_con;
1154  Hs_struct *hs = aisc_server_hs;
1155  if (!hs)
1156  return socket;
1157  for (si = hs->soci; si; si = si->next) {
1158  if (si->socket == socket) {
1159  if (si->destroy_callback) {
1160  fputs("Error: destroy_callback already bound (did you open two connections in client?)\n", stderr);
1161  fputs("Note: calling bound and installing new destroy_callback\n", stderr);
1163  }
1164 
1165  si->destroy_callback = callback;
1166  si->destroy_clientdata = clientdata;
1167  }
1168  }
1169  return socket;
1170 }
1171 
1172 void aisc_remove_destroy_callback() { // call from server function
1173  Socinf *si;
1174  int socket = aisc_server_con;
1175  Hs_struct *hs = aisc_server_hs;
1176  if (!hs)
1177  return;
1178  for (si = hs->soci; si; si = si->next) {
1179  if (si->socket == socket) {
1180  si->destroy_callback = NULp;
1181  si->destroy_clientdata = 0;
1182  }
1183  }
1184 }
1185 
1186 int aisc_server_save_token(FILE *fd, const char *buffer, int maxsize) {
1187  putc('{',fd);
1188  const char *p = buffer;
1189  while (maxsize-->0) {
1190  int c = *(p++);
1191  if (!c) break;
1192  if (c=='}' || c == '\\') putc('\\',fd);
1193  putc(c,fd);
1194  }
1195  putc('}',fd);
1196  return 0;
1197 }
1198 
1199 int aisc_server_load_token(FILE *fd, char *buffer, int maxsize) {
1200  int in_brackets = 0;
1201  char *p = buffer;
1202  int result = EOF;
1203 
1204  while (maxsize-- > 0) {
1205  int c = getc(fd);
1206  if (c==EOF) break;
1207  if (in_brackets) {
1208  if (c=='\\') {
1209  c = getc(fd);
1210  *(p++) = c;
1211  }
1212  else if (c!='}') {
1213  *(p++) = c;
1214  }
1215  else {
1216  result = 0;
1217  break;
1218  }
1219  }
1220  else if (c=='{') {
1221  if (p!=buffer) {
1222  *(p++) = '{';
1223  *p=0;
1224  return 0;
1225  }
1226  else {
1227  in_brackets = 1;
1228  }
1229  }
1230  else if (c==' ' || c=='\n') {
1231  if (p!=buffer) {
1232  result = 0;
1233  break;
1234  }
1235  }
1236  else if (c=='}') {
1237  *(p++) = '}';
1238  result = 0;
1239  break;
1240  }
1241  else {
1242  *(p++) = c;
1243  }
1244  }
1245 
1246  *p = 0;
1247  return result; // read error maxsize reached
1248 }
#define AISC_MAGIC_NUMBER_FILTER
Definition: server.c:46
string result
GB_TYPES type
int socket
Definition: server.c:57
aisc_talking_func_longp * aisc_talking_functions_copy[]
static int aisc_server_con
Definition: server.c:116
static long aisc_talking_get(long *in_buf, int size, long *out_buf, int)
Definition: server.c:297
aisc_talking_func_long * aisc_talking_functions_set[]
static const char * aisc_get_object_attribute(long i, long j)
Definition: server.c:225
Hs_struct * open_aisc_server(const char *path, int timeout, int fork)
Definition: server.c:235
#define INSTALL_SIGHANDLER(sig, handler, context)
Definition: SigHandler.h:87
static aisc_bytes_list * aisc_server_bytes_last
Definition: server.c:98
void aisc_server_shutdown(Hs_struct *&hs)
Definition: server.c:1134
static long aisc_fork_server(long *, int, long *, int)
Definition: server.c:788
static long aisc_talking_create(long *in_buf, int size, long *out_buf, int)
Definition: server.c:608
aisc_bytes_list * next
Definition: client_privat.h:34
long
Definition: AW_awar.cxx:154
aisc_destroy_callback destroy_callback
Definition: server.c:58
#define AISC_MAX_STRING_LEN
Definition: client_privat.h:28
static long aisc_talking_delete(long *in_buf, int, long *out_buf, int)
Definition: server.c:793
static long aisc_talking_nset(long *in_buf, int size, long *out_buf, int)
Definition: server.c:583
GB_ERROR arb_open_socket(const char *name, bool do_connect, int *fd, char **filename_out)
Definition: arb_cs.cxx:124
long aisc_make_sets(long *obj)
Definition: server.c:599
int aisc_add_destroy_callback(aisc_destroy_callback callback, long clientdata)
Definition: server.c:1151
#define EXIT_SUCCESS
Definition: arb_a2ps.c:154
int aisc_server_load_token(FILE *fd, char *buffer, int maxsize)
Definition: server.c:1199
#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
#define AISC_CASTSIG(sig, cb)
Definition: aisc_global.h:47
static struct aisc_static_set_mem md
POS_TREE1 * father
Definition: probe_tree.h:39
static bool catch_sigsegv
Definition: server.c:148
static long aisc_talking_init(long *, int, long *out_buf, int)
Definition: server.c:782
#define AISC_TYPE_INT
Definition: aisc_global.h:31
static char error_buf[ERRORBUFSIZE]
Definition: server.c:114
static int aisc_talking(int con)
Definition: server.c:967
fflush(stdout)
void aisc_remove_destroy_callback()
Definition: server.c:1172
aisc_talking_func_long * aisc_talking_functions_get[]
static SigHandler old_sigsegv_handler
Definition: server.c:198
static const char * test_address_valid(void *address, long key)
Definition: server.c:151
static Hs_struct * aisc_server_hs
Definition: server.c:117
char * aisc_object_names[]
#define AISC_TYPE_DOUBLE
Definition: aisc_global.h:32
char ** aisc_attribute_names_list[]
aisc_talking_func_longp * aisc_talking_functions_create[]
char * data
Definition: bytestring.h:16
int lasttime
Definition: server.c:60
static __ATTR__NORETURN void aisc_server_sigsegv(int sig)
Definition: server.c:200
void message(char *errortext)
aisc_talking_func_longp * aisc_talking_functions_find[]
int fork
Definition: server.c:75
int as_int[2]
Definition: aisc_global.h:51
static aisc_talking_function_type aisc_talking_functions[]
Definition: server.c:954
#define AISC_VAR_TYPE_MASK
Definition: aisc_global.h:37
#define AISC_INDEX
Definition: aisc_global.h:41
static bool sigsegv_occurred
Definition: server.c:147
static jmp_buf return_after_segv
Definition: server.c:149
static long aisc_talking_copy(long *in_buf, int size, long *out_buf, int)
Definition: server.c:665
int nsoc
Definition: server.c:73
const char * aisc_get_object_names(long i)
Definition: server.c:218
static aisc_bytes_list * aisc_server_bytes_first
Definition: server.c:97
vfprintf(stderr, format, parg)
struct pollfd * fds
Definition: server.c:71
#define FD_SET_TYPE
Definition: server.c:17
#define aisc_assert(cond)
Definition: server.c:40
int aisc_broadcast(Hs_struct *hs, int message_type, const char *message)
Definition: server.c:912
#define AISC_SERVER_OK
Definition: server.c:42
char * unix_name
Definition: server.c:76
static int aisc_server_index
Definition: server.c:423
static long aisc_talking_sets(long *in_buf, int size, long *out_buf, long *object, int object_type)
Definition: server.c:445
#define AISC_OBJ_TYPE_MASK
Definition: aisc_global.h:38
Definition: server.c:55
va_end(argPtr)
#define EXIT_FAILURE
Definition: arb_a2ps.c:157
static void aisc_s_add_to_bytes_queue(char *data, int size)
Definition: server.c:270
int timeout
Definition: server.c:74
int aisc_server_save_token(FILE *fd, const char *buffer, int maxsize)
Definition: server.c:1186
#define AISC_MAGIC_NUMBER
Definition: client_privat.h:51
fputs(TRACE_PREFIX, stderr)
double as_double
Definition: aisc_global.h:50
long(* aisc_talking_function_type)(long *, int, long *, int)
Definition: server.c:948
size_t arb_socket_read(int socket, char *ptr, size_t size)
Definition: arb_cs.cxx:61
const char * aisc_server_error
Definition: server.c:111
#define AISC_TYPE_BYTES
Definition: aisc_global.h:35
#define AISC_SERVER_FAULT
Definition: server.c:43
#define MAX_QUEUE_LEN
Definition: server.c:44
int aisc_talking_get_index(int u, int o)
Definition: server.c:429
unsigned long nfds
Definition: server.c:72
aisc_talking_func_long aisc_talking_functions_delete[]
const int ERRORBUFSIZE
Definition: server.c:113
#define AISC_TYPE_STRING
Definition: aisc_global.h:33
#define AISC_MESSAGE_BUFFER_LEN
Definition: client_privat.h:29
va_start(argPtr, format)
int hso
Definition: server.c:69
static long aisc_talking_find(long *in_buf, int, long *out_buf, int)
Definition: server.c:725
#define AISC_MAX_ATTR
Definition: client_privat.h:26
static long aisc_talking_set(long *in_buf, int size, long *out_buf, int)
Definition: server.c:573
#define NULp
Definition: cxxforward.h:97
~Hs_struct()
Definition: server.c:88
#define __ATTR__NORETURN
Definition: attributes.h:56
#define UNINSTALL_SIGHANDLER(sig, handler, old_handler, context)
Definition: SigHandler.h:88
#define AISC_NO_ANSWER
Definition: aisc_global.h:42
ssize_t arb_socket_write(int socket, const char *ptr, size_t size)
Definition: arb_cs.cxx:75
Hs_struct()
Definition: server.c:78
static int aisc_s_send_bytes_queue(int socket)
Definition: server.c:286
static long aisc_talking_debug_info(long *in_buf, int, long *out_buf, int)
Definition: server.c:834
Socinf * next
Definition: server.c:56
#define AISC_TYPE_COMMON
Definition: aisc_global.h:34
#define STATIC_ASSERT(const_expression)
Definition: static_assert.h:36
Hs_struct * aisc_accept_calls(Hs_struct *hs)
Definition: server.c:1026
int * aisc_main
Definition: names.cxx:64
void aisc_server_errorf(const char *templat,...)
Definition: server.c:122
#define AISC_DUMP_SEP()
Definition: trace.h:59
static void aisc_talking_set_index(int *, int i)
Definition: server.c:425
Socinf * soci
Definition: server.c:70
void(* SigHandler)(int)
Definition: SigHandler.h:23
long destroy_clientdata
Definition: server.c:59