Annotation of OpenXM/src/ox_ntl/oxserv.c, Revision 1.9
1.9 ! iwane 1: /* $OpenXM: OpenXM/src/ox_ntl/oxserv.c,v 1.8 2008/09/19 10:55:40 iwane Exp $ */
1.1 iwane 2:
3: #include <stdio.h>
4: #include <stdlib.h>
5: #include <string.h>
6: #include <errno.h>
1.2 iwane 7: #include <signal.h>
1.3 iwane 8: #include <setjmp.h>
1.1 iwane 9:
10: #include "oxserv.h"
1.2 iwane 11: #include "oxstack.h"
1.1 iwane 12:
1.3 iwane 13: #include "gc/gc.h"
1.1 iwane 14:
1.7 iwane 15: #define DPRINTF(x) printf x; (void)fflush(stdout)
1.1 iwane 16:
1.3 iwane 17: #define FP stdout
1.7 iwane 18: #define EPRINTF(x) fprintf x; (void)fflush(FP)
1.3 iwane 19:
1.1 iwane 20:
1.8 iwane 21:
1.1 iwane 22: /*===========================================================================*
1.2 iwane 23: * MACRO
1.1 iwane 24: *===========================================================================*/
1.8 iwane 25: #define oxserv_get_cmo_tag(m) ((G_getCmoTag == NULL) ? (m)->tag : G_getCmoTag(m))
26:
1.1 iwane 27:
1.8 iwane 28: #define oxserv_delete_cmo(C) \
29: do { \
30: if (C != NULL) { \
31: if ((C)->c) { FREE((C)->c); } \
32: oxserv_delete_cmo_usr(((C)->p)); \
1.9 ! iwane 33: oxserv_free(C, 0); \
1.8 iwane 34: C = NULL; \
35: } \
36: } while (0)
1.1 iwane 37:
1.8 iwane 38: #define oxserv_delete_cmo_usr(c) \
1.2 iwane 39: do { \
1.3 iwane 40: if (c != NULL) { \
41: if (G_DeleteCmo != NULL) \
1.5 iwane 42: G_DeleteCmo((cmo *)c); \
1.3 iwane 43: else \
1.2 iwane 44: c = NULL; \
1.3 iwane 45: } \
1.2 iwane 46: } while (0)
47:
1.1 iwane 48:
49: /*===========================================================================*
1.2 iwane 50: * Global Variables.
1.1 iwane 51: *===========================================================================*/
1.2 iwane 52: /* ox */
53: static OXFILE *G_oxfilep = NULL;
54: static cmo_mathcap *G_oxserv_mathcap = NULL;
1.1 iwane 55:
1.3 iwane 56: /* signal */
1.4 iwane 57: int G_oxserv_sigusr1flag = 0;
58: int G_oxserv_sigusr1cnt = 0;
1.3 iwane 59: static jmp_buf G_jmpbuf;
60:
1.2 iwane 61: /* User Function */
1.8 iwane 62: static void (*G_userExecuteFunction)(const char *, oxstack_node **, int) = NULL;
1.2 iwane 63: static void (*G_userExecuteStringParser)(const char *) = NULL;
1.1 iwane 64:
1.8 iwane 65: static cmo *(*G_convertCmo)(void *) = NULL; /* convert user object ==> cmo */
66: static char *(*G_convertStr)(void *) = NULL; /* convert user object ==> string */
1.1 iwane 67:
1.2 iwane 68: static void (*G_DeleteCmo)(cmo *) = NULL;
1.1 iwane 69:
1.2 iwane 70: static int (*G_getCmoTag)(cmo *) = NULL;
1.1 iwane 71:
1.3 iwane 72:
73: /*===========================================================================*
74: * CMO_ERROR2
75: *===========================================================================*/
76: #define new_cmo_error2_string(msg) new_cmo_error2((cmo *)new_cmo_string(msg))
77:
78:
79: static void
80: oxserv_push_errormes(char *msg)
81: {
82: EPRINTF((FP, "%s\n", msg));
1.8 iwane 83: oxstack_push_cmo((cmo *)new_cmo_error2_string(msg));
1.3 iwane 84: }
85:
86: /*===========================================================================*
87: * synchronized malloc
88: *===========================================================================*/
89: void *
90: oxserv_malloc(size_t size)
91: {
92: void *ptr;
93:
94: BLOCK_INPUT();
95: ptr = GC_malloc(size);
96: UNBLOCK_INPUT();
97:
98: return (ptr);
99: }
100:
101: void
102: oxserv_free(void *ptr, size_t size)
103: {
104: /* nothing */
105: }
106:
107: void *
108: oxserv_realloc(void *org, size_t old, size_t size)
109: {
110: void *ptr;
111:
112: BLOCK_INPUT();
113: ptr = GC_realloc(org, size);
114: UNBLOCK_INPUT();
115:
116: return (ptr);
117: }
118:
119:
120:
1.1 iwane 121: /*===========================================================================*
122: * OX_SERVER
123: *===========================================================================*/
124:
125: /*****************************************************************************
1.2 iwane 126: * -- SM_popCMO --
127: * pop an object from the stack, convert it into a serialized from according
128: * to the standard CMO encoding scheme, and send it to the stream
129: *
1.1 iwane 130: * PARAM : fd : OXFILE
131: * RETURN: NONE
132: *****************************************************************************/
133: static void
134: oxserv_sm_popCMO(OXFILE *fd)
135: {
1.8 iwane 136: cmo *m;
137: oxstack_node *p;
138: int flag = 0;
139: p = oxstack_pop();
140: if (p == NULL) {
1.3 iwane 141: EPRINTF((FP, "stack underflow in popCMO\n"));
1.1 iwane 142: m = new_cmo_null();
1.8 iwane 143: /* asir $B$NF0$-$K=>$&(B */
144: } else {
145: if (p->c != NULL) {
146: m = p->c;
147: } else if (p->p != NULL) {
148: if (G_convertCmo) {
149: m = G_convertCmo(p->p);
150: } else {
151: m = NULL;
152: }
153: if (m == NULL) {
154: m = (cmo *)new_cmo_error2((cmo *)new_cmo_string("convert failed"));
155: flag = 1;
156:
157: }
158: } else {
159: EPRINTF((FP, "converter not defined\n"));
160: m = (cmo *)new_cmo_error2((cmo *)new_cmo_string("converter not defined"));
161: flag = 1;
162: }
163:
164: if (flag) {
165: /*
166: * $B$;$C$+$/7k2L$,$"$k$N$K>C$7$F$7$^$&$N$O(B
167: * $B$b$C$?$$$J$$$N$G;D$9$3$H$K$9$k(B.
168: */
169: oxstack_push(p);
170: } else {
171: oxserv_delete_cmo(p);
1.4 iwane 172: }
1.1 iwane 173: }
174:
1.8 iwane 175:
1.1 iwane 176: send_ox_cmo(fd, m);
177:
1.8 iwane 178: FREE(m);
1.1 iwane 179: }
180:
181: /*****************************************************************************
1.2 iwane 182: * -- SM_popString --
1.1 iwane 183: * pop an cmo from stack, convert it into a string according to the
184: * output format of the local system, and send the string.
1.2 iwane 185: *
1.1 iwane 186: * PARAM : fd : OXFILE
187: * RETURN: NONE
188: *****************************************************************************/
189: static void
190: oxserv_sm_popString(OXFILE *fd)
191: {
192: char *str;
1.8 iwane 193: oxstack_node *p;
194: cmo *m;
1.1 iwane 195: cmo_string *m_str;
196:
1.8 iwane 197: p = oxstack_pop();
198: if (p == NULL) {
199: /* @@TODO
200: * http://www.math.kobe-u.ac.jp/OpenXM/1.2.1/html/OpenXM-ja/OpenXM/node12.html
201: * $B%9%?%C%/$,6u$N>l9g$K$O(B (char *)NULL $B$rJV$9(B.
202: * CMO $B$NMQ8l$G=q$+$l$F$$$J$$$+$i2?$rJV$9$Y$-$+$o$+$i$J$$(B.
203: */
1.1 iwane 204: m = new_cmo_null();
1.8 iwane 205: str = new_string_set_cmo(m);
206: } else {
207: if (p->c) {
208: m = NULL;
209: str = new_string_set_cmo(p->c);
210: } else if (p->p) {
211: if (G_convertStr) {
212: str = G_convertStr(p->p);
213: m = NULL;
214: } else {
215: if (G_convertCmo) {
216: m = G_convertCmo(p->p);
217: } else {
218: /* @@TODO
219: * $BJQ49$G$-$J$$>l9g$O(B... CMO_ERROR2 $B$rLa$9$Y$-$G$"$k(B?
220: * $B$=$N$H$-$N(B stack $B$N>uBV$O$I$&$9$Y$-!)(B
221: */
222: m = NULL;
223: }
224: str = new_string_set_cmo(m);
225: }
226: } else {
227: m = new_cmo_null();
228: str = new_string_set_cmo(m);
229: }
230:
231: oxserv_delete_cmo(p);
1.3 iwane 232: }
1.1 iwane 233:
234: m_str = new_cmo_string(str);
235:
236: send_ox_cmo(fd, (cmo *)m_str);
237:
1.8 iwane 238: FREE(m);
239: FREE(m_str);
1.1 iwane 240:
1.2 iwane 241: /* free(str); */
1.1 iwane 242: }
243:
244: /*****************************************************************************
1.2 iwane 245: * -- SM_pops --
1.1 iwane 246: * pop n and to discard element from the stack
1.2 iwane 247: *
248: * PARAM : NONE
1.1 iwane 249: * RETURN: NONE
250: *****************************************************************************/
251: static void
252: oxserv_sm_pops()
253: {
1.8 iwane 254: oxstack_node *p, *m;
1.1 iwane 255: cmo_int32 *c;
1.2 iwane 256: int n;
257: int i;
258:
1.8 iwane 259: p = oxstack_pop();
260: if (p == NULL) {
261: EPRINTF((FP, "stack underflow in pops\n"));
262: return ;
263: }
264:
265: c = (cmo_int32 *)p->c; /* suppose */
1.3 iwane 266: if (c == NULL) {
267: EPRINTF((FP, "stack underflow in pops\n"));
268: return ;
269: }
1.1 iwane 270:
1.2 iwane 271: n = oxstack_get_stack_pointer();
272: if (c->i < n)
273: n = c->i;
1.1 iwane 274:
1.2 iwane 275: for (i = 0; i < n; i++) {
276: m = oxstack_pop();
277: oxserv_delete_cmo(m);
278: }
279:
1.8 iwane 280: oxserv_delete_cmo(p);
1.1 iwane 281:
282: }
283:
284: /*****************************************************************************
1.2 iwane 285: * -- SM_getsp --
286: * push the current stack pointer onto the stack.
1.1 iwane 287: *
288: * PARAM : fd : OXFILE
289: * RETURN: NONE
290: *****************************************************************************/
291: static void
292: oxserv_sm_getsp()
293: {
1.2 iwane 294: cmo_int32 *m = new_cmo_int32(oxstack_get_stack_pointer());
1.8 iwane 295: oxstack_push_cmo((cmo *)m);
1.1 iwane 296: }
297:
298: /*****************************************************************************
299: *
300: * PARAM : ver :
301: * : vstr :
302: * : sysname:
303: * : cmos :
304: * : sms :
305: * RETURN: NONE
306: * SEE : oxserv_set();
307: *****************************************************************************/
308: static void
309: oxserv_mathcap_init(int ver, char *vstr, char *sysname, int *cmos, int *sms)
310: {
311: int i;
312:
313: int local_sms[] = {
314: SM_popCMO,
315: SM_mathcap,
316: SM_setMathCap,
317: SM_pops,
318: SM_getsp,
319: SM_popString,
320: SM_pushCMOtag,
321: 0,
322: SM_executeFunction,
323: SM_dupErrors,
324: SM_executeStringByLocalParser,
325: SM_executeStringByLocalParserInBatchMode,
326: SM_shutdown,
327: 0,
328: };
329:
330: /* depend on ox_toolkit */
331: int local_cmos[] = {
332: CMO_ERROR2,
333: CMO_NULL,
334: CMO_INT32,
335: CMO_STRING,
336: CMO_MATHCAP,
337: CMO_LIST,
338: CMO_MONOMIAL32,
339: CMO_ZZ,
340: CMO_ZERO,
341: CMO_RECURSIVE_POLYNOMIAL,
342: CMO_DISTRIBUTED_POLYNOMIAL,
343: CMO_POLYNOMIAL_IN_ONE_VARIABLE,
344: CMO_DMS_GENERIC,
345: CMO_RING_BY_NAME,
346: CMO_INDETERMINATE,
347: CMO_TREE,
348: CMO_LAMBDA,
349: 0,
350: CMO_QQ,
351: CMO_ATTRIBUTE_LIST,
352: CMO_DMS,
353: CMO_DMS_OF_N_VARIABLES,
354: CMO_LIST_R,
355: CMO_INT32COEFF,
356: CMO_RATIONAL,
357: CMO_DATUM,
358: 0,
359: };
360:
361: if (sms == NULL) {
362: sms = local_sms;
363:
364: for (i = 0; sms[i] != 0; i++)
365: ;
366: if (G_userExecuteFunction != NULL)
367: sms[i++] = SM_executeFunction;
368:
369: if (G_userExecuteStringParser != NULL) {
370: sms[i++] = SM_executeStringByLocalParser;
371: sms[i++] = SM_executeStringByLocalParserInBatchMode;
372: }
373:
374: sms[i] = 0;
375: }
376: if (cmos == NULL)
377: cmos = local_cmos;
378:
379: mathcap_init(ver, vstr, sysname, cmos, sms);
380:
1.8 iwane 381: if (G_oxserv_mathcap) {
382: FREE(G_oxserv_mathcap);
383: }
1.1 iwane 384:
385: G_oxserv_mathcap = mathcap_get(new_mathcap());
386: }
387:
1.2 iwane 388: /*****************************************************************************
389: * -- SM_mathcap --
390: * push the mathcap of the server.
391: *
392: * PARAM : NONE
393: * RETURN: NONE
394: *****************************************************************************/
1.1 iwane 395: static void
396: oxserv_sm_mathcap()
397: {
398: if (G_oxserv_mathcap == NULL) {
399: oxserv_mathcap_init(0, "", "oxserv", NULL, NULL);
400: }
401:
1.8 iwane 402: oxstack_push_cmo((cmo *)G_oxserv_mathcap);
1.1 iwane 403: }
404:
1.2 iwane 405: /*****************************************************************************
406: * -- SM_executeStringByLocalParserInBatchMode --
407: * peek a character string s, parse it by the local parser of the stack machine,
408: * and interpret by the local interpreter.
409: *
410: * PARAM : NONE
411: * RETURN: NONE
412: *****************************************************************************/
1.1 iwane 413: static void
414: oxserv_sm_executeStringByLocalParserInBatchMode(void)
415: {
1.8 iwane 416: oxstack_node *p;
417: cmo_string *str;
418:
419: p = oxstack_peek();
420: if (p == NULL) {
421: oxserv_push_errormes("stack underflow in executeStringByLocalParserInBatchMode");
422: return ;
423: }
424:
425: str = (cmo_string *)p->c;
1.3 iwane 426: if (str == NULL) {
427: oxserv_push_errormes("stack underflow in executeStringByLocalParserInBatchMode");
428: return ;
429: }
1.2 iwane 430: G_userExecuteStringParser(str->s);
1.1 iwane 431: }
432:
1.2 iwane 433: /*****************************************************************************
434: * -- SM_executeStringByLocalParser --
435: * pop a character string s, parse it by the local parser of the stack machine,
436: * and interpret by the local interpreter.
437: *
438: * PARAM : NONE
439: * RETURN: NONE
440: *****************************************************************************/
1.1 iwane 441: static void
442: oxserv_sm_executeStringByLocalParser(void)
443: {
1.8 iwane 444: oxstack_node *p;
445: cmo_string *str;
446:
447: p = oxstack_pop();
448: if (p == NULL) {
449: oxserv_push_errormes("stack underflow in executeStringByLocalParserInBatchMode");
450: return ;
451: }
452:
453: str = (cmo_string *)p->c;
1.3 iwane 454: if (str == NULL) {
455: oxserv_push_errormes("stack underflow in executeStringByLocalParser");
456: return ;
457: }
1.2 iwane 458: G_userExecuteStringParser(str->s);
1.8 iwane 459: oxserv_delete_cmo(p);
1.1 iwane 460: }
461:
462:
463:
1.2 iwane 464: /*****************************************************************************
465: * -- SM_executeFunction --
466: * pop s as a function name, pop n as the number of arguments and to execute a
467: * local function s with n arguments poped from the stack.
468: *
1.4 iwane 469: * suppose G_userExecuteFunction not equal NULL
470: *
1.2 iwane 471: * PARAM : NONE
472: * RETURN: NONE
473: *****************************************************************************/
1.1 iwane 474: static void
475: oxserv_sm_executeFunction(void)
476: {
477: int i;
1.8 iwane 478: oxstack_node *p1, *p2;
479: cmo_string *name;
480: cmo_int32 *cnt;
481: int total;
482: oxstack_node **arg;
483:
484: if (G_userExecuteFunction == NULL) {
485: oxserv_push_errormes("G_userExecuteFunction not defined");
486: return ;
487: }
488:
489: p1 = oxstack_pop();
490: p2 = oxstack_pop();
491:
492: name = (cmo_string *)p1->c;
493: cnt = (cmo_int32 *)p2->c;
494:
1.3 iwane 495:
496:
497: if (name == NULL || cnt == NULL) {
1.8 iwane 498: oxserv_push_errormes("stack underflow in executeFunction[name,cnt]");
499: return ;
500: }
501: if (name->tag != CMO_STRING) {
502: oxstack_push(p2);
503: oxstack_push(p1);
504: oxserv_push_errormes("invalid parameter #1 not cmo_string");
505: return ;
506: }
507:
508: if (cnt->tag != CMO_INT32) {
509: oxstack_push(p2);
510: oxstack_push(p1);
511: printf("command name=%s\n", name->s);
512: oxserv_push_errormes("invalid parameter #2 not cmo_int32");
1.3 iwane 513: return ;
514: }
1.1 iwane 515:
1.8 iwane 516: total = cnt->i;
517:
1.9 ! iwane 518: arg = (oxstack_node **)oxserv_malloc(total * sizeof(oxstack_node *));
1.8 iwane 519: for (i = 0; i < total; i++) {
1.2 iwane 520: arg[i] = oxstack_pop();
1.3 iwane 521: if (arg[i] == NULL) {
522: oxserv_push_errormes("stack underflow in executeFunction");
1.4 iwane 523:
1.9 ! iwane 524: for (i--; i >= 0; i--) {
1.4 iwane 525: oxserv_delete_cmo(arg[i]);
1.9 ! iwane 526: }
! 527: oxserv_free(arg, 0);
1.3 iwane 528: return ;
529: }
1.1 iwane 530: }
531:
532: /* user function */
1.8 iwane 533: G_userExecuteFunction(name->s, arg, total);
1.1 iwane 534:
535:
1.8 iwane 536: for (i = 0; i < total; i++) {
1.2 iwane 537: oxserv_delete_cmo(arg[i]);
1.1 iwane 538: }
539:
1.8 iwane 540: oxserv_delete_cmo(p1);
541: oxserv_delete_cmo(p2);
1.9 ! iwane 542: oxserv_free(arg, 0);
1.1 iwane 543: }
544:
1.2 iwane 545: /*****************************************************************************
546: * -- SM_pushCMOtag --
547: * push the CMO tag of the top object on the stack.
548: *
1.8 iwane 549: *
550: *
1.2 iwane 551: * PARAM : NONE
552: * RETURN: NONE
553: *****************************************************************************/
1.1 iwane 554: static void
555: oxserv_sm_pushCMOtag()
556: {
1.8 iwane 557: oxstack_node *p = oxstack_peek();
558: cmo *c = p->c;
559: cmo_int32 *tag;
560:
561: if (c == NULL) {
562: if (p->p != NULL && G_convertCmo) {
563: c = p->c = G_convertCmo(p->p);
564: }
565: }
566:
567: if (c == NULL) {
568: tag = new_cmo_int32(oxserv_get_cmo_tag(c));
569: } else {
570: tag = (cmo_int32 *)new_cmo_error2_string("convert from MathObj to CMO failed");
571: }
572: oxstack_push_cmo((cmo *)tag);
1.1 iwane 573: }
574:
575:
1.3 iwane 576: /*****************************************************************************
577: * -- SM_dupErrors --
578: *
579: * PARAM : NONE
580: * RETURN: NONE
581: *****************************************************************************/
1.1 iwane 582: static void
583: oxserv_sm_dupErrors()
584: {
1.8 iwane 585: oxstack_node *p;
1.1 iwane 586: cmo_list *list;
587: int i;
588:
589: list = new_cmo_list();
590:
1.2 iwane 591: for (i = 0; i < oxstack_get_stack_pointer(); i++) {
1.8 iwane 592: p = oxstack_get(i);
593: if (p->c && p->c->tag == CMO_ERROR2) {
594: list_append(list, p->c);
1.1 iwane 595: }
596: }
597:
1.8 iwane 598: oxstack_push_cmo((cmo *)list);
1.1 iwane 599: }
600:
1.3 iwane 601:
602:
603:
604: /*****************************************************************************
605: * -- SM_control_reset_connection -- signal handler for SIGUSR1 --
606: *
607: * PARAM : NONE
1.4 iwane 608: *
609: * : if (sig == 0) called UNBLOCK_INPUT()
1.3 iwane 610: * RETURN: NONE
611: *****************************************************************************/
1.4 iwane 612: void
1.2 iwane 613: oxserv_sm_control_reset_connection(int sig)
614: {
615: int tag;
616: OXFILE *fd = G_oxfilep;
617:
1.4 iwane 618: if (G_oxserv_sigusr1cnt > 0) {
619: G_oxserv_sigusr1flag = 1;
620: return ;
621: }
622:
623:
1.3 iwane 624: DPRINTF(("reset -- start ==> "));
1.4 iwane 625: G_oxserv_sigusr1flag = 0;
626:
1.2 iwane 627: send_ox_tag(fd, OX_SYNC_BALL);
628:
629: oxstack_init_stack();
630:
631: for (;;) {
632: tag = receive_ox_tag(fd);
1.3 iwane 633: DPRINTF(("[OX:%d=0x%x]", tag, tag));
1.2 iwane 634: if (tag == OX_SYNC_BALL)
635: break;
636: if (tag == OX_DATA)
637: receive_cmo(fd);
1.3 iwane 638: else
639: receive_int32(fd);
1.2 iwane 640: }
1.3 iwane 641: DPRINTF((" <== end.\n"));
642:
1.4 iwane 643:
1.3 iwane 644: longjmp(G_jmpbuf, sig);
1.2 iwane 645: }
1.1 iwane 646:
1.3 iwane 647: /*****************************************************************************
648: * execute sm command
649: *
650: * PARAM : NONE
651: * RETURN: NONE
652: *****************************************************************************/
1.1 iwane 653: static int
1.3 iwane 654: oxserv_execute_sm_command(OXFILE *fd, int code)
1.1 iwane 655: {
1.3 iwane 656:
657: DPRINTF(("[SM:%d=0x%x]", code, code));
1.1 iwane 658:
659: switch (code) {
1.3 iwane 660: case SM_popCMO: /* 262 */
1.1 iwane 661: oxserv_sm_popCMO(fd);
662: break;
1.3 iwane 663: case SM_executeStringByLocalParser: /* 268 */
1.1 iwane 664: if (G_userExecuteStringParser)
665: oxserv_sm_executeStringByLocalParser();
666: break;
1.3 iwane 667: case SM_executeStringByLocalParserInBatchMode: /* 274 */
1.1 iwane 668: if (G_userExecuteStringParser)
669: oxserv_sm_executeStringByLocalParserInBatchMode();
670: break;
1.3 iwane 671: case SM_pops: /* 265 */
1.1 iwane 672: oxserv_sm_pops();
673: break;
1.3 iwane 674: case SM_popString: /* 263 */
1.1 iwane 675: oxserv_sm_popString(fd);
676: break;
1.3 iwane 677: case SM_getsp: /* 275 */
1.1 iwane 678: oxserv_sm_getsp();
679: break;
1.3 iwane 680: case SM_mathcap: /* 264 */
1.1 iwane 681: oxserv_sm_mathcap();
682: break;
1.3 iwane 683: case SM_setMathCap: /* 273 */
1.1 iwane 684: /* dont support */
1.2 iwane 685: oxstack_pop();
1.1 iwane 686: break;
1.3 iwane 687: case SM_executeFunction: /* 269 */
1.9 ! iwane 688: oxserv_sm_executeFunction();
1.1 iwane 689: break;
1.3 iwane 690: case SM_pushCMOtag: /* 277 */
1.1 iwane 691: oxserv_sm_pushCMOtag();
692: break;
1.3 iwane 693: case SM_dupErrors: /* 276 */
1.1 iwane 694: oxserv_sm_dupErrors();
695: break;
1.3 iwane 696: case SM_popSerializedLocalObject:
697: case SM_setName:
698: case SM_evalName:
699: case SM_beginBlock:
700: case SM_endBlock:
701: case SM_shutdown:
702: case SM_executeFunctionAndPopCMO:
703: case SM_executeFunctionAndPopSerializedLocalObject:
1.2 iwane 704: case SM_control_reset_connection:
705: case SM_control_reset_connection_server:
1.1 iwane 706: default:
707: break;
708: }
709: return (OXSERV_SUCCESS);
710: }
711:
712:
1.2 iwane 713:
1.1 iwane 714: /*****************************************************************************
715: * reveice ox_data
1.2 iwane 716: *
1.1 iwane 717: * PARAM : fd : OXFILE
718: * RETURN: NONE
719: *****************************************************************************/
1.3 iwane 720: static int
721: oxserv_ox_receive(OXFILE *fd)
1.1 iwane 722: {
723: int tag;
724: cmo *c;
725: int ret = OXSERV_SUCCESS;
1.3 iwane 726: int code;
1.1 iwane 727:
728: tag = receive_ox_tag(fd);
1.8 iwane 729: printf("get ox=[%d=0x%x]\n", tag, tag); fflush(stdout);
1.1 iwane 730:
731: switch (tag) {
732: case OX_DATA:
1.4 iwane 733: BLOCK_INPUT();
1.1 iwane 734: c = receive_cmo(fd);
1.4 iwane 735: UNBLOCK_INPUT();
1.3 iwane 736: DPRINTF(("[CMO:%d=0x%x]", c->tag, c->tag));
1.8 iwane 737: oxstack_push_cmo(c);
1.1 iwane 738: break;
739:
740: case OX_COMMAND:
1.3 iwane 741: code = receive_int32(fd);
742: ret = oxserv_execute_sm_command(fd, code);
1.1 iwane 743: break;
744:
745: default:
746: DPRINTF(("receive unknown ox_tag: %d=0x%x\n", tag, tag));
747: return (OXSERV_FAILURE);
748: }
749:
750: return (ret);
751: }
752:
1.3 iwane 753: int
754: oxserv_receive(OXFILE *fd)
755: {
756: int i = 0;
757: int ret;
758:
1.8 iwane 759:
760: /*-----------------------------------------*
761: * initialize
762: *-----------------------------------------*/
763:
1.3 iwane 764: ret = setjmp(G_jmpbuf);
765: if (ret == 0) {
766: DPRINTF(("setjmp first time -- %d\n", ret));
767: } else {
768: DPRINTF(("setjmp return from longjmp() -- %d -- \n", ret));
769: }
770:
1.8 iwane 771: /*-----------------------------------------*
772: * main loop
773: *-----------------------------------------*/
1.3 iwane 774: for (;; i++) {
775: ret = oxserv_ox_receive(fd);
776: if (ret != OXSERV_SUCCESS)
777: break;
778: }
1.8 iwane 779:
1.3 iwane 780: return (ret);
781: }
782:
1.1 iwane 783:
784: /*****************************************************************************
785: * initialize oxserver
786: *
787: * PARAM : see oxserv_mathcap_init()
1.2 iwane 788: * RETURN: success : OXSERV_SUCCESS
789: * : failure : OXSERV_FAILURE
1.1 iwane 790: * SEE : oxserv_mathcap_init()
791: * : oxserv_set();
792: *****************************************************************************/
793: int
794: oxserv_init(OXFILE *oxfp, int ver, char *vstr, char *sysname, int *cmos, int *sms)
795: {
796: int ret;
797:
1.3 iwane 798: DPRINTF(("init start\n"));
799:
1.2 iwane 800: ret = oxstack_init_stack();
1.1 iwane 801: if (ret != OXSERV_SUCCESS)
802: return (ret);
803:
1.2 iwane 804: G_oxfilep = oxfp;
805:
1.1 iwane 806: oxserv_mathcap_init(ver, vstr, sysname, cmos, sms);
807:
1.2 iwane 808: signal(SIGUSR1, oxserv_sm_control_reset_connection);
809:
1.3 iwane 810: /* initialize GMP memory functions. */
811: mp_set_memory_functions(oxserv_malloc, oxserv_realloc, oxserv_free);
812:
813: /* session start */
1.1 iwane 814: oxf_determine_byteorder_server(oxfp);
815:
816: return (OXSERV_SUCCESS);
817: }
818:
819:
820: /*****************************************************************************
1.3 iwane 821: * set oxserver behavior
1.2 iwane 822: *
1.1 iwane 823: * PARAM : mode : mode
824: * :
825: * : ptr :
826: * : rsv : reserve space.
1.2 iwane 827: * RETURN: success : OXSERV_SUCCESS
828: * : failure : OXSERV_FAILURE
1.1 iwane 829: * SEE :
830: *****************************************************************************/
831: int
832: oxserv_set(int mode, void *ptr, void *rsv)
833: {
834: switch (mode) {
835: case OXSERV_SET_EXECUTE_FUNCTION:
1.8 iwane 836: G_userExecuteFunction = (void (*)(const char *, oxstack_node **, int))ptr;
1.1 iwane 837: break;
838: case OXSERV_SET_EXECUTE_STRING_PARSER:
1.2 iwane 839: G_userExecuteStringParser = (void (*)(const char *))ptr;
1.1 iwane 840: break;
841: case OXSERV_SET_CONVERT_CMO:
1.8 iwane 842: G_convertCmo = (cmo *(*)(void *))ptr;
843: break;
844: case OXSERV_SET_CONVERT_STR:
845: G_convertStr = (char *(*)(void *))ptr;
1.1 iwane 846: break;
1.2 iwane 847: case OXSERV_SET_DELETE_CMO:
848: G_DeleteCmo = (void (*)(cmo *))ptr;
849: break;
850: case OXSERV_SET_GET_CMOTAG:
851: G_getCmoTag = (int (*)(cmo *))ptr;
852: break;
1.1 iwane 853: default:
854: return (OXSERV_FAILURE);
855: }
856:
857:
858: return (OXSERV_SUCCESS);
859: }
860:
861:
862: /*****************************************************************************
863: * destroy
1.2 iwane 864: *
865: * PARAM : NONE
1.1 iwane 866: * RETURN: NONE
867: *****************************************************************************/
868: void
869: oxserv_dest()
870: {
1.8 iwane 871: FREE(G_oxserv_mathcap);
1.2 iwane 872: oxstack_dest();
1.1 iwane 873: }
874:
875:
1.2 iwane 876: #if __OXSERV_DEBUG
877: /*===========================================================================*
878: * DEBUG
879: *===========================================================================*/
880:
1.1 iwane 881:
1.4 iwane 882: void
1.1 iwane 883: oxserv_executeFunction(const char *func, cmo **arg, int argc)
884: {
885: int i;
886:
887: printf("%s()\n", func);
888:
889: for (i = 0; i < argc; i++) {
890: printf("\t%2d: %s\n", i, new_string_set_cmo(arg[i]));
891: }
892:
1.4 iwane 893: return ;
1.1 iwane 894: }
895:
1.2 iwane 896: /*****************************************************************************
897: * main
898: *
899: * PARAM : NONE
900: * RETURN: NONE
901: *****************************************************************************/
1.8 iwane 902: static FILE *dfp = NULL;
1.1 iwane 903: int
904: main(int argc, char *argv[])
905: {
1.8 iwane 906: int fd = 10;
1.1 iwane 907:
1.8 iwane 908: dfp = fopen("/tmp/oxserv,log", "w");
1.1 iwane 909: OXFILE *oxfp = oxf_open(fd);
910:
1.8 iwane 911: fprintf(dfp, "stderr.init start\n"); fflush(dfp);
912: ox_stderr_init(dfp);
1.1 iwane 913:
1.8 iwane 914: fprintf(dfp, "set start\n"); fflush(dfp);
1.9 ! iwane 915: oxserv_set(OXSERV_SET_EXECUTE_FUNCTION, oxserv_executeFunction, NULL);
1.4 iwane 916:
1.9 ! iwane 917: fprintf(dfp, "init start\n"); fflush(dfp);
1.2 iwane 918: oxserv_init(oxfp, 0, "$Date: 2003/11/02 16:39:16 $", "oxserv", NULL, NULL);
1.1 iwane 919:
1.8 iwane 920: fprintf(dfp, "recv start\n"); fflush(dfp);
1.9 ! iwane 921: oxserv_receive(oxfp);
1.1 iwane 922:
1.4 iwane 923: oxserv_dest();
1.2 iwane 924: oxf_close(oxfp);
1.1 iwane 925:
926: return (0);
927: }
928:
929: #endif
1.2 iwane 930:
931:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>