7 #include <sys/socket.h>
9 #include <netinet/in.h>
10 #include <netinet/tcp.h>
11 #include <arpa/inet.h>
40 #define aisc_assert(cond) arb_assert(cond)
42 #define AISC_SERVER_OK 1
43 #define AISC_SERVER_FAULT 0
44 #define MAX_QUEUE_LEN 5
46 #define AISC_MAGIC_NUMBER_FILTER 0xffffff00
127 int printed = vsprintf(error_buf, templat, parg);
129 if (printed >= ERRORBUFSIZE) {
131 "Fatal: buffer overflow in aisc_server_errorf\n"
134 fputs(
"\nTerminating..\n", stderr);
158 static char buf[256];
171 i = *(
long *)address;
183 sprintf(buf,
"AISC memory manager error: can't access memory at address %p", address);
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)",
219 if ((i<0) || (i>=AISC_MAX_OBJECT) || (!aisc_object_names[i])) {
220 return "<unknown object>";
222 return aisc_object_names[i];
226 if ((i<0) || (i>=AISC_MAX_OBJECT) || (!aisc_attribute_names_list[i])) {
229 if ((j<0) || (j>=
AISC_MAX_ATTR) || (!aisc_attribute_names_list[i][j])) {
230 return "<unknown attribute>";
232 return aisc_attribute_names_list[i][j];
245 if (*err) printf(
"Error in open_aisc_server: %s\n", err);
246 shutdown(so, SHUT_RDWR);
248 delete hs; hs =
NULp;
252 fprintf(stderr,
"Installing signal handler from open_aisc_server\n");
fflush(stderr);
255 aisc_server_bytes_first =
NULp;
256 aisc_server_bytes_last =
NULp;
259 printf(
"Error in open_aisc_server: could not listen (errno=%i)\n", errno);
260 delete hs; hs =
NULp;
276 if (aisc_server_bytes_first) {
277 aisc_server_bytes_last->
next = bl;
278 aisc_server_bytes_last = bl;
281 aisc_server_bytes_first = bl;
282 aisc_server_bytes_last = bl;
288 for (bl = aisc_server_bytes_first; bl; bl=bl_next) {
293 aisc_server_bytes_first = aisc_server_bytes_last =
NULp;
298 aisc_server_error =
NULp;
302 long object = in_buf[in_pos++];
306 if (object_type > (AISC_MAX_OBJECT*0x10000)) {
307 aisc_server_error =
"UNKNOWN OBJECT";
313 object_type = object_type >> (16);
320 while (!aisc_server_error && (in_pos < size)) {
321 long code = in_buf[in_pos];
328 aisc_server_error =
"OBJECT HAS NO ATTRIBUTES";
333 sprintf(error_buf,
"ATTRIBUTE %lx OUT of RANGE", attribute);
338 aisc_talking_func_long
function = functions[attribute];
340 sprintf(error_buf,
"DON'T KNOW ATTRIBUTE %li",
353 aisc_talking_func_double dfunction =
AISC_CASTSIG(aisc_talking_func_double,
function);
357 erg =
function(object);
359 if (aisc_server_error) {
366 out_buf[out_pos++] = erg;
371 out_buf[out_pos++] = derg.
as_int[0];
372 out_buf[out_pos++] = derg.
as_int[1];
376 if (!erg) erg = (
long)
"(null)";
377 long len = strlen((
char *)erg);
379 erg = (
long)
"(string too long)";
380 len = strlen((
char *)erg);
388 out_buf[out_pos++] = len;
389 strcpy((
char *)&out_buf[out_pos], (
char *)erg);
397 #if defined(DUMP_COMMUNICATION)
398 aisc_dump_hex(
"aisc_talking_get bytestring: ", bs->
data, bs->
size);
399 #endif // DUMP_COMMUNICATION
404 out_buf[out_pos++] = bs->
size;
408 aisc_server_error =
"UNKNOWN TYPE";
413 if (aisc_server_error) {
414 sprintf((
char *) out_buf,
"AISC_GET_SERVER_ERROR %s: OBJECT:%s ATTRIBUTE:%s",
418 return -((strlen((
char *)out_buf) + 1) /
sizeof(
long) + 1);
426 aisc_server_index = i;
430 if (aisc_server_index==-1) {
431 aisc_server_error =
"AISC_SERVER_ERROR MISSING AN AISC_INDEX";
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);
445 static long aisc_talking_sets(
long *in_buf,
int size,
long *out_buf,
long *
object,
int object_type) {
447 long in_pos, out_pos;
448 long code, attribute,
type;
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;
458 if (object_type > (AISC_MAX_OBJECT*0x10000)) {
460 aisc_server_error =
"UNKNOWN OBJECT";
465 object_type = object_type>>(16);
468 sprintf(error_buf,
"OBJECT %x HAS NO ATTRIBUTES",
476 while (!aisc_server_error && (in_pos<size)) {
477 code = in_buf[in_pos++];
481 sprintf(error_buf,
"ATTRIBUTE %li DOESN'T EXIST",
491 function = functions[attribute];
494 sprintf(error_buf,
"ATTRIBUTE %li DOESN'T EXIST",
509 function((
long)
object, in_buf[in_pos++]);
513 derg.
as_int[0] = in_buf[in_pos++];
514 derg.
as_int[1] = in_buf[in_pos++];
522 char *
str = strdup((
char *)&(in_buf[in_pos+1]));
526 function((
long)
object, str);
527 in_pos += in_buf[in_pos]+1;
531 bsize = (
int)in_buf[in_pos++];
536 long *ptr = (
long*)calloc(
sizeof(
char), bsize);
539 aisc_server_error =
"CONNECTION PROBLEMS IN BYTESTRING";
544 bs.
data = (
char *)ptr;
547 #if defined(DUMP_COMMUNICATION)
548 aisc_dump_hex(
"aisc_talking_sets bytestring: ", (
char*)ptr, bsize);
549 #endif // DUMP_COMMUNICATION
551 function((
long)
object, &bs);
555 function((
long)
object, 0);
559 aisc_server_error =
"UNKNOWN TYPE";
563 if (aisc_server_error) {
564 sprintf((
char *) out_buf,
"AISC_SET_SERVER_ERROR %s: OBJECT:%s ATTRIBUTE:%s",
568 return -((strlen((
char *)out_buf) + 1) /
sizeof(
long) + 1);
574 aisc_server_error =
NULp;
577 long object = in_buf[in_pos++];
580 return aisc_talking_sets(&(in_buf[in_pos]), size-in_pos, out_buf, (
long *)
object, object_type);
584 aisc_server_error =
NULp;
587 long object = in_buf[in_pos++];
590 aisc_talking_sets(&(in_buf[in_pos]), size-in_pos, out_buf, (
long *)
object, object_type);
609 aisc_server_error =
NULp;
612 long father_type = in_buf[in_pos++];
613 long father = in_buf[in_pos++];
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";
623 if (aisc_server_error)
break;
625 father_type = father_type>>16;
628 long code = in_buf[in_pos++];
630 long object_type = in_buf[in_pos++];
633 sprintf(error_buf,
"AISC_CREATE_SERVER_ERROR: FATHER %s DOESN'T HAVE TARGET-ATTRIBUTE %s",
639 aisc_server_error =
"AISC_CREATE_SERVER_ERROR: UNKNOWN ATTRIBUTE";
642 aisc_talking_func_longp
function = functions[attribute];
644 sprintf(error_buf,
"AISC_CREATE_SERVER_ERROR: FATHER %s FATHER DOESN'T HAVE TARGET-ATTRIBUTE %s",
649 md.
ibuf = &(in_buf[in_pos]);
652 md.
type = (int)object_type;
655 if (aisc_server_error) {
656 sprintf((
char *) out_buf,
"%s", aisc_server_error);
657 return -((strlen(aisc_server_error) + 1) /
sizeof(
long) + 1);
660 out_buf[0] = (
long)erg;
666 aisc_server_error =
NULp;
669 long object = in_buf[in_pos++];
670 int father_type = (
int)in_buf[in_pos++];
671 long father = in_buf[in_pos++];
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";
681 if (aisc_server_error)
break;
683 father_type = father_type>>16;
687 aisc_server_error =
"AISC_COPY_SERVER_ERROR: FATHER DOESN'T HAVE TARGET-ATTRIBUTES";
691 int code = (
int)in_buf[in_pos++];
692 int object_type = (
int)in_buf[in_pos++];
696 aisc_server_error =
"AISC_COPY_SERVER_ERROR: UNKNOWN ATTRIBUTE";
699 aisc_talking_func_longp
function = functions[attribute];
701 sprintf(error_buf,
"AISC_COPY_SERVER_ERROR: FATHER %s DOESN'T HAVE TARGET-ATTRIBUTE %s",
707 if (aisc_server_error)
break;
709 md.
ibuf = &(in_buf[in_pos]);
713 erg =
function(
father, object);
715 if (aisc_server_error) {
716 sprintf((
char *) out_buf,
"%s", aisc_server_error);
717 return -((strlen(aisc_server_error) + 1) /
sizeof(
long) + 1);
720 out_buf[0] = (
long)erg;
726 aisc_server_error =
NULp;
729 long father_type = in_buf[in_pos++];
730 long father = in_buf[in_pos++];
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";
740 if (aisc_server_error)
743 father_type = father_type>>16;
746 long code = in_buf[in_pos++];
750 aisc_server_error =
"AISC_FIND_SERVER_ERROR: FATHER DON'T KNOW ATTRIBUTES FOR SEARCH";
754 aisc_server_error =
"AISC_FIND_SERVER_ERROR: UNKNOWN ATTRIBUTE";
757 aisc_talking_func_longp
function = functions[attribute];
759 sprintf(error_buf,
"AISC_FIND_SERVER_ERROR: FATHER %s DON'T KNOW ATTRIBUTE %s FOR SEARCH",
764 if (in_buf[in_pos++]<=0) {
765 aisc_server_error =
" AISC_FIND_SERVER_ERROR: CANNOT FIND EMPTY IDENT";
768 erg =
function(
father, &(in_buf[in_pos]));
770 if (aisc_server_error) {
771 sprintf((
char *) out_buf,
"%s", aisc_server_error);
772 return -((strlen(aisc_server_error) + 1) /
sizeof(
long) + 1);
775 out_buf[0] = (
long) erg;
783 aisc_server_error =
NULp;
784 out_buf[0] = (
long)aisc_main;
790 return pid<0 ? 0 : pid;
797 aisc_talking_func_long
function;
801 in_pos = out_pos = 0;
802 aisc_server_error =
NULp;
803 object_type = in_buf[in_pos++];
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";
813 if (aisc_server_error)
815 object_type = object_type >> (16);
818 sprintf(error_buf,
"AISC_SET_SERVER_ERROR: OBJECT %s cannot be deleted",
819 aisc_object_names[object_type]);
827 if (aisc_server_error) {
828 sprintf((
char *) out_buf,
"%s", aisc_server_error);
829 return -((strlen(aisc_server_error) + 1) /
sizeof(
long) + 1);
836 long object_type, attribute;
838 aisc_talking_func_long *functionsg;
839 aisc_talking_func_long *functionss;
840 aisc_talking_func_longp *functions;
845 in_pos = out_pos = 0;
846 aisc_server_error =
NULp;
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++];
854 if (aisc_server_error)
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";
863 object_type = object_type>>16;
871 if (!functionsg[attribute]) out_buf[1] = 1;
878 if (!functionss[attribute]) out_buf[2] = 1;
885 if (!functions[attribute]) out_buf[3] = 1;
892 if (!functions[attribute]) out_buf[4] = 1;
899 if (!functions[attribute]) out_buf[5] = 1;
903 if (aisc_server_error) {
904 sprintf((
char *) out_buf,
"%s", aisc_server_error);
905 return -((strlen(aisc_server_error) + 1) /
sizeof(
long) + 1);
914 int size = message ? strlen(message) : 0;
915 int sizeL = (size+1+
sizeof(
long)-1) /
sizeof(
long);
916 long *out_buf = (
long *)calloc(sizeL+3,
sizeof(
long));
922 char *strStart = (
char*)(out_buf+3);
923 int pad = sizeL*
sizeof(
long)-(size+1);
927 memcpy(strStart, message, size+1);
928 if (pad) memset(strStart+size+1, 0, pad);
933 out_buf[0] = sizeL+1;
935 out_buf[2] = message_type;
937 for (si=hs->
soci; si; si=si->
next) {
974 if (len == 2*
sizeof(
long)) {
975 aisc_server_con = con;
978 magic_number = buf[1];
985 long expect = size*
sizeof(
long);
992 if ((
long)len != expect) {
993 printf(
" ERROR in AISC_SERVER: Expected to get %li bytes from client (got %lu)\n", expect, len);
997 magic_number &= ~AISC_MAGIC_NUMBER_FILTER;
1011 if (
arb_socket_write(con, (
char *)out_buf, (
int)(size + 2) *
sizeof(
long))) {
1014 if (aisc_server_bytes_first) {
1031 struct timeval timeout;
1034 fprintf(stderr,
"AISC_SERVER_ERROR socket error (==0)\n");
1037 timeout.tv_sec = hs->
timeout / 1000;
1038 timeout.tv_usec = (hs->
timeout % 1000) * 1000;
1040 aisc_server_hs = hs;
1045 FD_SET(hs->
hso, &set);
1046 FD_SET(hs->
hso, &setex);
1048 for (si=hs->
soci, i=1; si; si=si->
next, i++) {
1049 FD_SET(si->
socket, &set);
1050 FD_SET(si->
socket, &setex);
1060 printf(
"ERROR: poll in aisc_accept_calls\n");
1067 if ((timeout.tv_usec>=0)&&(timeout.tv_usec<100000)) timeout.tv_usec = 100000;
1069 if (FD_ISSET(hs->
hso, &set)) {
1081 if (!sptr)
return NULp;
1082 sptr->next = hs->
soci;
1087 setsockopt(con, IPPROTO_TCP, TCP_NODELAY, (
char *)&optval, 4);
1093 for (si=hs->
soci; si; si_last=si, si=sinext) {
1096 if (FD_ISSET(si->
socket, &set)) {
1098 }
else if (!FD_ISSET(si->
socket, &setex))
continue;
1100 if (close(si->
socket) != 0) {
1101 printf(
"aisc_accept_calls: ");
1102 printf(
"couldn't close socket!\n");
1106 if (si == hs->
soci) {
1116 #ifdef SERVER_TERMINATE_ON_CONNECTION_CLOSE
1117 if (hs->
nsoc == 0) {
1137 for (si=hs->
soci; si; si=si->
next) {
1138 shutdown(si->
socket, SHUT_RDWR);
1141 shutdown(hs->
hso, SHUT_RDWR);
1144 delete hs; hs =
NULp;
1157 for (si = hs->
soci; si; si = si->
next) {
1158 if (si->
socket == socket) {
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);
1178 for (si = hs->
soci; si; si = si->
next) {
1179 if (si->
socket == socket) {
1189 while (maxsize-->0) {
1192 if (c==
'}' || c ==
'\\') putc(
'\\',fd);
1200 int in_brackets = 0;
1204 while (maxsize-- > 0) {
1230 else if (c==
' ' || c==
'\n') {
#define AISC_MAGIC_NUMBER_FILTER
aisc_talking_func_longp * aisc_talking_functions_copy[]
static int aisc_server_con
static long aisc_talking_get(long *in_buf, int size, long *out_buf, int)
aisc_talking_func_long * aisc_talking_functions_set[]
static const char * aisc_get_object_attribute(long i, long j)
Hs_struct * open_aisc_server(const char *path, int timeout, int fork)
#define INSTALL_SIGHANDLER(sig, handler, context)
static aisc_bytes_list * aisc_server_bytes_last
void aisc_server_shutdown(Hs_struct *&hs)
static long aisc_fork_server(long *, int, long *, int)
static long aisc_talking_create(long *in_buf, int size, long *out_buf, int)
aisc_destroy_callback destroy_callback
#define AISC_MAX_STRING_LEN
static long aisc_talking_delete(long *in_buf, int, long *out_buf, int)
static long aisc_talking_nset(long *in_buf, int size, long *out_buf, int)
GB_ERROR arb_open_socket(const char *name, bool do_connect, int *fd, char **filename_out)
long aisc_make_sets(long *obj)
int aisc_add_destroy_callback(aisc_destroy_callback callback, long clientdata)
int aisc_server_load_token(FILE *fd, char *buffer, int maxsize)
#define AISC_DUMP(where, type, var)
char buffer[MESSAGE_BUFFERSIZE]
#define AISC_CASTSIG(sig, cb)
static struct aisc_static_set_mem md
static bool catch_sigsegv
static long aisc_talking_init(long *, int, long *out_buf, int)
static char error_buf[ERRORBUFSIZE]
static int aisc_talking(int con)
void aisc_remove_destroy_callback()
aisc_talking_func_long * aisc_talking_functions_get[]
static SigHandler old_sigsegv_handler
static const char * test_address_valid(void *address, long key)
static Hs_struct * aisc_server_hs
char * aisc_object_names[]
char ** aisc_attribute_names_list[]
aisc_talking_func_longp * aisc_talking_functions_create[]
static __ATTR__NORETURN void aisc_server_sigsegv(int sig)
void message(char *errortext)
aisc_talking_func_longp * aisc_talking_functions_find[]
static aisc_talking_function_type aisc_talking_functions[]
#define AISC_VAR_TYPE_MASK
static bool sigsegv_occurred
static jmp_buf return_after_segv
static long aisc_talking_copy(long *in_buf, int size, long *out_buf, int)
const char * aisc_get_object_names(long i)
static aisc_bytes_list * aisc_server_bytes_first
vfprintf(stderr, format, parg)
#define aisc_assert(cond)
int aisc_broadcast(Hs_struct *hs, int message_type, const char *message)
static int aisc_server_index
static long aisc_talking_sets(long *in_buf, int size, long *out_buf, long *object, int object_type)
#define AISC_OBJ_TYPE_MASK
static void aisc_s_add_to_bytes_queue(char *data, int size)
int aisc_server_save_token(FILE *fd, const char *buffer, int maxsize)
#define AISC_MAGIC_NUMBER
fputs(TRACE_PREFIX, stderr)
long(* aisc_talking_function_type)(long *, int, long *, int)
size_t arb_socket_read(int socket, char *ptr, size_t size)
const char * aisc_server_error
#define AISC_SERVER_FAULT
int aisc_talking_get_index(int u, int o)
aisc_talking_func_long aisc_talking_functions_delete[]
#define AISC_MESSAGE_BUFFER_LEN
static long aisc_talking_find(long *in_buf, int, long *out_buf, int)
static long aisc_talking_set(long *in_buf, int size, long *out_buf, int)
#define UNINSTALL_SIGHANDLER(sig, handler, old_handler, context)
ssize_t arb_socket_write(int socket, const char *ptr, size_t size)
static int aisc_s_send_bytes_queue(int socket)
static long aisc_talking_debug_info(long *in_buf, int, long *out_buf, int)
#define STATIC_ASSERT(const_expression)
Hs_struct * aisc_accept_calls(Hs_struct *hs)
void aisc_server_errorf(const char *templat,...)
static void aisc_talking_set_index(int *, int i)