[BACK]Return to oxserv.c CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_ntl

Annotation of OpenXM/src/ox_ntl/oxserv.c, Revision 1.1

1.1     ! iwane       1: /* $OpenXM$ */
        !             2:
        !             3: #include <stdio.h>
        !             4: #include <stdlib.h>
        !             5: #include <string.h>
        !             6: #include <errno.h>
        !             7:
        !             8: #include "oxserv.h"
        !             9:
        !            10:
        !            11: #define DPRINTF(x)     printf x; fflush(stdout)
        !            12:
        !            13: #define delete_cmo(m)
        !            14:
        !            15: #define OXSERV_INIT_STACK_SIZE 2048
        !            16: #define OXSERV_EXT_STACK_SIZE  2048
        !            17:
        !            18: #if 0
        !            19: /*===========================================================================*
        !            20:  * for DEBUG
        !            21:  *===========================================================================*/
        !            22: #include <stdarg.h>
        !            23: void
        !            24: dprintf(const char *fmt, ...)
        !            25: {
        !            26:        FILE *fp;
        !            27:        va_list ap;
        !            28:        va_start(ap, fmt);
        !            29:
        !            30:        fp = fopen("error.txt", "a");
        !            31:
        !            32:        vfprintf(fp, fmt, ap);
        !            33:
        !            34:        fflush(fp);
        !            35:        fclose(fp);
        !            36:
        !            37:        va_end(ap);
        !            38: }
        !            39: #endif
        !            40:
        !            41: /*===========================================================================*
        !            42:  * Global Variables.
        !            43:  *===========================================================================*/
        !            44: /* cmo stack */
        !            45: static int G_ox_stack_size = 0;
        !            46: static int G_ox_stack_pointer = 0;
        !            47: static cmo **G_ox_stack = NULL;
        !            48:
        !            49: /* ox */
        !            50: static cmo_mathcap *G_oxserv_mathcap = NULL;
        !            51:
        !            52: /* User Function */
        !            53: static cmo *(*G_userExecuteFunction)(const char *, cmo **, int) = NULL;
        !            54: static cmo *(*G_userExecuteStringParser)(const char *) = NULL;
        !            55:
        !            56: static cmo *(*G_convertCmo)(cmo *) = NULL; /* convert user object ==> cmo */
        !            57:
        !            58: /*===========================================================================*
        !            59:  * CMO STACK FUNCTIONs
        !            60:  *===========================================================================*/
        !            61: /*****************************************************************************
        !            62:  * return the number of cmo in the stack.
        !            63:  * PARAM   : NONE
        !            64:  * RETURN  : the number of cmo in the stack.
        !            65:  *****************************************************************************/
        !            66: #define oxserv_get_stack_pointer()  G_ox_stack_pointer
        !            67:
        !            68:
        !            69: /*****************************************************************************
        !            70:  * initialize stack.
        !            71:  * PARAM   : NONE
        !            72:  * RETURN  : if success return OXSERV_SUCCESS, else OXSERV_FAILURE.
        !            73:  *****************************************************************************/
        !            74: static int
        !            75: oxserv_init_stack(void)
        !            76: {
        !            77:        free(G_ox_stack);
        !            78:
        !            79:        G_ox_stack_pointer = 0;
        !            80:        G_ox_stack_size = OXSERV_INIT_STACK_SIZE;
        !            81:        G_ox_stack = (cmo **)malloc(G_ox_stack_size * sizeof(cmo *));
        !            82:        if (G_ox_stack == NULL) {
        !            83:                DPRINTF(("server: %d: %s\n", errno, strerror(errno)));
        !            84:                return (OXSERV_FAILURE);
        !            85:        }
        !            86:        return (OXSERV_SUCCESS);
        !            87: }
        !            88:
        !            89: /*****************************************************************************
        !            90:  *
        !            91:  * PARAM   : NONE
        !            92:  * RETURN  : if success return OXSERV_SUCCESS, else OXSERV_FAILURE.
        !            93:  *****************************************************************************/
        !            94: static int
        !            95: oxserv_extend_stack(void)
        !            96: {
        !            97:        int size2 = G_ox_stack_size + OXSERV_EXT_STACK_SIZE;
        !            98:        cmo **stack2 = (cmo **)malloc(size2 * sizeof(cmo *));
        !            99:        if (stack2 == NULL) {
        !           100:                DPRINTF(("server: %d: %s\n", errno, strerror(errno)));
        !           101:                return (OXSERV_FAILURE);
        !           102:        }
        !           103:
        !           104:        memcpy(stack2, G_ox_stack, G_ox_stack_size * sizeof(cmo *));
        !           105:        free(G_ox_stack);
        !           106:
        !           107:        G_ox_stack = stack2;
        !           108:        G_ox_stack_size = size2;
        !           109:
        !           110:        return (OXSERV_SUCCESS);
        !           111: }
        !           112:
        !           113: /*****************************************************************************
        !           114:  * push a cmo onto the topof the stack.
        !           115:  * PARAM   : m  : the cmo to be pushed on the stack.
        !           116:  * RETURN  : if success return OXSERV_SUCCESS, else OXSERV_FAILURE.
        !           117:  *****************************************************************************/
        !           118: static int
        !           119: oxserv_push(cmo *m)
        !           120: {
        !           121:        int ret;
        !           122:
        !           123:        if (G_ox_stack_pointer >= G_ox_stack_size) {
        !           124:                ret = oxserv_extend_stack();
        !           125:                if (ret != OXSERV_SUCCESS)
        !           126:                        return (ret);
        !           127:        }
        !           128:
        !           129:        G_ox_stack[G_ox_stack_pointer] = m;
        !           130:        G_ox_stack_pointer++;
        !           131:
        !           132:        return (OXSERV_SUCCESS);
        !           133: }
        !           134:
        !           135: /*****************************************************************************
        !           136:  * remove thd CMO at the top of this stack and
        !           137:  * returns that cmo as the value of this function.
        !           138:  * PARAM   : NONE
        !           139:  * RETURN  : CMO at the top of the stack.
        !           140:  *****************************************************************************/
        !           141: static cmo *
        !           142: oxserv_pop(void)
        !           143: {
        !           144:        cmo *c;
        !           145:        if (G_ox_stack_pointer > 0) {
        !           146:                G_ox_stack_pointer--;
        !           147:                c = G_ox_stack[G_ox_stack_pointer];
        !           148:                G_ox_stack[G_ox_stack_pointer] = NULL;
        !           149:                return (c);
        !           150:        }
        !           151:        return (NULL);
        !           152: }
        !           153:
        !           154: /*****************************************************************************
        !           155:  * return the cmo at the specified position in the stack without removing it from the stack.
        !           156:  * PARAM : NONE
        !           157:  * RETURN: thd cmo at the specified position in the stack.
        !           158:  *****************************************************************************/
        !           159: static cmo *
        !           160: oxserv_get(int i)
        !           161: {
        !           162:        if (i < G_ox_stack_pointer && i >= 0) {
        !           163:                return (G_ox_stack[i]);
        !           164:        }
        !           165:        return (NULL);
        !           166: }
        !           167:
        !           168:
        !           169: /*****************************************************************************
        !           170:  * return the cmo at the top of the stack without removing it from the stack.
        !           171:  * PARAM : NONE
        !           172:  * RETURN: the cmo at the top of the stack.
        !           173:  *****************************************************************************/
        !           174: static cmo *
        !           175: oxserv_peek(void)
        !           176: {
        !           177:        return (oxserv_get(G_ox_stack_pointer - 1));
        !           178: }
        !           179:
        !           180: /*****************************************************************************
        !           181:  *
        !           182:  * defined for SM_pops
        !           183:  *
        !           184:  * PARAM : n : remove count
        !           185:  * RETURN: NONE
        !           186:  *****************************************************************************/
        !           187: static void
        !           188: oxserv_remove(int n)
        !           189: {
        !           190:        int i;
        !           191:        cmo *m;
        !           192:
        !           193:        if (n > G_ox_stack_size)
        !           194:                n = G_ox_stack_size;
        !           195:
        !           196:        for (i = 0; i < n; i++) {
        !           197:                --G_ox_stack_pointer;
        !           198:                m = G_ox_stack[G_ox_stack_pointer];
        !           199:                G_ox_stack[G_ox_stack_pointer] = NULL;
        !           200:                delete_cmo(m);
        !           201:        }
        !           202: }
        !           203:
        !           204:
        !           205: /*===========================================================================*
        !           206:  * OX_SERVER
        !           207:  *===========================================================================*/
        !           208:
        !           209: /*****************************************************************************
        !           210:  * pop n and to discard element from the stack
        !           211:  * PARAM : fd : OXFILE
        !           212:  * RETURN: NONE
        !           213:  *****************************************************************************/
        !           214: static void
        !           215: oxserv_sm_popCMO(OXFILE *fd)
        !           216: {
        !           217:        cmo *m = oxserv_pop();
        !           218:        if (m == NULL) {
        !           219:                m = new_cmo_null();
        !           220:        } else if (G_convertCmo) {
        !           221:                m = G_convertCmo(m);
        !           222:        }
        !           223:
        !           224:        send_ox_cmo(fd, m);
        !           225:
        !           226:        delete_cmo(m);
        !           227: }
        !           228:
        !           229: /*****************************************************************************
        !           230:  * pop an cmo from stack, convert it into a string according to the
        !           231:  * output format of the local system, and send the string.
        !           232:  * PARAM : fd : OXFILE
        !           233:  * RETURN: NONE
        !           234:  *****************************************************************************/
        !           235: static void
        !           236: oxserv_sm_popString(OXFILE *fd)
        !           237: {
        !           238:        char *str;
        !           239:        cmo *m = oxserv_pop();
        !           240:        cmo_string *m_str;
        !           241:
        !           242:        if (m == NULL)
        !           243:                m = new_cmo_null();
        !           244:
        !           245:        str = new_string_set_cmo(m);
        !           246:
        !           247:        m_str = new_cmo_string(str);
        !           248:
        !           249:        send_ox_cmo(fd, (cmo *)m_str);
        !           250:
        !           251:        delete_cmo(m);
        !           252:        delete_cmo(m_str);
        !           253:
        !           254: /* free(str); */
        !           255: }
        !           256:
        !           257: /*****************************************************************************
        !           258:  * pop n and to discard element from the stack
        !           259:  * PARAM : fd : OXFILE
        !           260:  * RETURN: NONE
        !           261:  *****************************************************************************/
        !           262: static void
        !           263: oxserv_sm_pops()
        !           264: {
        !           265:        cmo_int32 *c;
        !           266:
        !           267:        c = (cmo_int32 *)oxserv_pop(); /* suppose */
        !           268:
        !           269:        oxserv_remove(c->i)
        !           270:
        !           271:        delete_cmo(c);
        !           272: }
        !           273:
        !           274: /*****************************************************************************
        !           275:  * for SM_getsp
        !           276:  *
        !           277:  * PARAM : fd : OXFILE
        !           278:  * RETURN: NONE
        !           279:  *****************************************************************************/
        !           280: static void
        !           281: oxserv_sm_getsp()
        !           282: {
        !           283:        cmo_int32 *m = new_cmo_int32(oxserv_get_stack_pointer());
        !           284:        oxserv_push((cmo *)m);
        !           285: }
        !           286:
        !           287: /*****************************************************************************
        !           288:  *
        !           289:  * PARAM : ver    :
        !           290:  *       : vstr   :
        !           291:  *       : sysname:
        !           292:  *       : cmos   :
        !           293:  *       : sms    :
        !           294:  * RETURN: NONE
        !           295:  * SEE   : oxserv_set();
        !           296:  *****************************************************************************/
        !           297: static void
        !           298: oxserv_mathcap_init(int ver, char *vstr, char *sysname, int *cmos, int *sms)
        !           299: {
        !           300:        int i;
        !           301:
        !           302:        int local_sms[] = {
        !           303:                SM_popCMO,
        !           304:                SM_mathcap,
        !           305:                SM_setMathCap,
        !           306:                SM_pops,
        !           307:                SM_getsp,
        !           308:                SM_popString,
        !           309:                SM_pushCMOtag,
        !           310:                0,
        !           311:                SM_executeFunction,
        !           312:                SM_dupErrors,
        !           313:                SM_executeStringByLocalParser,
        !           314:                SM_executeStringByLocalParserInBatchMode,
        !           315:                SM_shutdown,
        !           316:                0,
        !           317:        };
        !           318:
        !           319:        /* depend on ox_toolkit */
        !           320:        int local_cmos[] = {
        !           321:                CMO_ERROR2,
        !           322:                CMO_NULL,
        !           323:                CMO_INT32,
        !           324:                CMO_STRING,
        !           325:                CMO_MATHCAP,
        !           326:                CMO_LIST,
        !           327:                CMO_MONOMIAL32,
        !           328:                CMO_ZZ,
        !           329:                CMO_ZERO,
        !           330:                CMO_RECURSIVE_POLYNOMIAL,
        !           331:                CMO_DISTRIBUTED_POLYNOMIAL,
        !           332:                CMO_POLYNOMIAL_IN_ONE_VARIABLE,
        !           333:                CMO_DMS_GENERIC,
        !           334:                CMO_RING_BY_NAME,
        !           335:                CMO_INDETERMINATE,
        !           336:                CMO_TREE,
        !           337:                CMO_LAMBDA,
        !           338:                0,
        !           339:                CMO_QQ,
        !           340:                CMO_ATTRIBUTE_LIST,
        !           341:                CMO_DMS,
        !           342:                CMO_DMS_OF_N_VARIABLES,
        !           343:                CMO_LIST_R,
        !           344:                CMO_INT32COEFF,
        !           345:                CMO_RATIONAL,
        !           346:                CMO_DATUM,
        !           347:                0,
        !           348:        };
        !           349:
        !           350:        if (sms == NULL) {
        !           351:                sms = local_sms;
        !           352:
        !           353:                for (i = 0; sms[i] != 0; i++)
        !           354:                        ;
        !           355:                if (G_userExecuteFunction != NULL)
        !           356:                        sms[i++] = SM_executeFunction;
        !           357:
        !           358:                if (G_userExecuteStringParser != NULL) {
        !           359:                        sms[i++] = SM_executeStringByLocalParser;
        !           360:                        sms[i++] = SM_executeStringByLocalParserInBatchMode;
        !           361:                }
        !           362:
        !           363:                sms[i] = 0;
        !           364:        }
        !           365:        if (cmos == NULL)
        !           366:                cmos = local_cmos;
        !           367:
        !           368:        mathcap_init(ver, vstr, sysname, cmos, sms);
        !           369:
        !           370:        delete_cmo(G_oxserv_mathcap);
        !           371:
        !           372:        G_oxserv_mathcap = mathcap_get(new_mathcap());
        !           373: }
        !           374:
        !           375: static void
        !           376: oxserv_sm_mathcap()
        !           377: {
        !           378:        if (G_oxserv_mathcap == NULL) {
        !           379:                oxserv_mathcap_init(0, "", "oxserv", NULL, NULL);
        !           380:        }
        !           381:
        !           382:        oxserv_push((cmo *)G_oxserv_mathcap);
        !           383: }
        !           384:
        !           385: static void
        !           386: oxserv_sm_executeStringByLocalParserInBatchMode(void)
        !           387: {
        !           388:        cmo_string *str = (cmo_string *)oxserv_peek();
        !           389:        cmo *c;
        !           390:        c = G_userExecuteStringParser(str->s);
        !           391:        oxserv_push(c);
        !           392: }
        !           393:
        !           394: static void
        !           395: oxserv_sm_executeStringByLocalParser(void)
        !           396: {
        !           397:        cmo_string *str = (cmo_string *)oxserv_pop();
        !           398:        cmo *c;
        !           399:        c = G_userExecuteStringParser(str->s);
        !           400:        oxserv_push(c);
        !           401: }
        !           402:
        !           403:
        !           404:
        !           405: static void
        !           406: oxserv_sm_executeFunction(void)
        !           407: {
        !           408:        int i;
        !           409:        cmo_string *name = (cmo_string *)oxserv_pop();
        !           410:        cmo_int32 *cnt = (cmo_int32 *)oxserv_pop();
        !           411:        cmo **arg = (cmo **)malloc(cnt->i * sizeof(cmo *));
        !           412:        cmo *ret;
        !           413:
        !           414:        for (i = 0; i < cnt->i; i++) {
        !           415:                arg[i] = oxserv_pop();
        !           416:        }
        !           417:
        !           418:        /* user function */
        !           419:        ret = G_userExecuteFunction(name->s, arg, cnt->i);
        !           420:
        !           421:        oxserv_push(ret);
        !           422:
        !           423:        for (i = 0; i < cnt->i; i++) {
        !           424:                delete_cmo(arg[i]);
        !           425:        }
        !           426:
        !           427:        delete_cmo(name);
        !           428:        delete_cmo(cnt);
        !           429:
        !           430:        free(arg);
        !           431: }
        !           432:
        !           433: static void
        !           434: oxserv_sm_pushCMOtag()
        !           435: {
        !           436:        cmo *c = oxserv_peek();
        !           437:        cmo_int32 *tag = new_cmo_int32(c->tag);
        !           438:
        !           439:        oxserv_push((cmo *)tag);
        !           440: }
        !           441:
        !           442:
        !           443: static void
        !           444: oxserv_sm_dupErrors()
        !           445: {
        !           446:        cmo_list *list;
        !           447:        cmo *c;
        !           448:        int i;
        !           449:
        !           450:        list = new_cmo_list();
        !           451:
        !           452:        for (i = 0; i < oxserv_get_stack_pointer(); i++) {
        !           453:                c = oxserv_get(i);
        !           454:                if (c->tag == CMO_ERROR2) {
        !           455:                        list_append(list, c);
        !           456:                }
        !           457:        }
        !           458:
        !           459:        oxserv_push((cmo *)list);
        !           460: }
        !           461:
        !           462:
        !           463: static int
        !           464: oxserv_receive_and_execute_sm_command(OXFILE *fd)
        !           465: {
        !           466:        int code = receive_int32(fd);
        !           467:
        !           468:        DPRINTF(("SM_CODE=%d=0x%x\n", code, code));
        !           469:
        !           470:        switch (code) {
        !           471:        case SM_popCMO:
        !           472:                oxserv_sm_popCMO(fd);
        !           473:                break;
        !           474:        case SM_executeStringByLocalParser:
        !           475:                if (G_userExecuteStringParser)
        !           476:                        oxserv_sm_executeStringByLocalParser();
        !           477:                break;
        !           478:        case SM_executeStringByLocalParserInBatchMode:
        !           479:                if (G_userExecuteStringParser)
        !           480:                        oxserv_sm_executeStringByLocalParserInBatchMode();
        !           481:                break;
        !           482:        case SM_pops:
        !           483:                oxserv_sm_pops();
        !           484:                break;
        !           485:        case SM_popString:
        !           486:                oxserv_sm_popString(fd);
        !           487:                break;
        !           488:        case SM_getsp:
        !           489:                oxserv_sm_getsp();
        !           490:                break;
        !           491:        case SM_mathcap:
        !           492:                oxserv_sm_mathcap();
        !           493:                break;
        !           494:        case SM_setMathCap:
        !           495:                /* dont support */
        !           496:                oxserv_pop();
        !           497:                break;
        !           498:        case SM_executeFunction:
        !           499:                if (G_userExecuteFunction)
        !           500:                        oxserv_sm_executeFunction();
        !           501:                break;
        !           502:        case SM_pushCMOtag:
        !           503:                oxserv_sm_pushCMOtag();
        !           504:                break;
        !           505:        case SM_dupErrors:
        !           506:                oxserv_sm_dupErrors();
        !           507:                break;
        !           508:        default:
        !           509:                break;
        !           510:        }
        !           511:        return (OXSERV_SUCCESS);
        !           512: }
        !           513:
        !           514:
        !           515: /*****************************************************************************
        !           516:  * reveice ox_data
        !           517:  * PARAM : fd : OXFILE
        !           518:  * RETURN: NONE
        !           519:  *****************************************************************************/
        !           520: int
        !           521: oxserv_receive(OXFILE *fd)
        !           522: {
        !           523:        int tag;
        !           524:        cmo *c;
        !           525:        int ret = OXSERV_SUCCESS;
        !           526:
        !           527:        tag = receive_ox_tag(fd);
        !           528:
        !           529:        DPRINTF(("oxserv_TAG=%d=0x%x\n", tag, tag));
        !           530:        switch (tag) {
        !           531:        case OX_DATA:
        !           532:                c = receive_cmo(fd);
        !           533:                DPRINTF(("CMO_TAG=%d=0x%x\n", c->tag, c->tag));
        !           534:                oxserv_push(c);
        !           535:                break;
        !           536:
        !           537:        case OX_COMMAND:
        !           538:                ret = oxserv_receive_and_execute_sm_command(fd);
        !           539:                break;
        !           540:
        !           541:        default:
        !           542:                DPRINTF(("receive unknown ox_tag: %d=0x%x\n", tag, tag));
        !           543:                return (OXSERV_FAILURE);
        !           544:        }
        !           545:
        !           546:        return (ret);
        !           547: }
        !           548:
        !           549:
        !           550: /*****************************************************************************
        !           551:  * initialize oxserver
        !           552:  *
        !           553:  * PARAM : see oxserv_mathcap_init()
        !           554:  * RETURN: NONE
        !           555:  * SEE   : oxserv_mathcap_init()
        !           556:  *       : oxserv_set();
        !           557:  *****************************************************************************/
        !           558: int
        !           559: oxserv_init(OXFILE *oxfp, int ver, char *vstr, char *sysname, int *cmos, int *sms)
        !           560: {
        !           561:        int ret;
        !           562:
        !           563:        ret = oxserv_init_stack();
        !           564:        if (ret != OXSERV_SUCCESS)
        !           565:                return (ret);
        !           566:
        !           567:        oxserv_mathcap_init(ver, vstr, sysname, cmos, sms);
        !           568:
        !           569:        oxf_determine_byteorder_server(oxfp);
        !           570:
        !           571:        return (OXSERV_SUCCESS);
        !           572: }
        !           573:
        !           574:
        !           575: /*****************************************************************************
        !           576:  * set oxserver
        !           577:  * PARAM : mode : mode
        !           578:  *              :
        !           579:  *       : ptr  :
        !           580:  *       : rsv  : reserve space.
        !           581:  * RETURN: NONE
        !           582:  * SEE   :
        !           583:  *****************************************************************************/
        !           584: int
        !           585: oxserv_set(int mode, void *ptr, void *rsv)
        !           586: {
        !           587:        switch (mode) {
        !           588:        case OXSERV_SET_EXECUTE_FUNCTION:
        !           589:                G_userExecuteFunction = (cmo *(*)(const char *, cmo **, int))ptr;
        !           590:                break;
        !           591:        case OXSERV_SET_EXECUTE_STRING_PARSER:
        !           592:                G_userExecuteStringParser = (cmo *(*)(const char *))ptr;
        !           593:                break;
        !           594:        case OXSERV_SET_CONVERT_CMO:
        !           595:                G_convertCmo = (cmo *(*)(cmo *))ptr;
        !           596:                break;
        !           597:        default:
        !           598:                return (OXSERV_FAILURE);
        !           599:        }
        !           600:
        !           601:
        !           602:        return (OXSERV_SUCCESS);
        !           603: }
        !           604:
        !           605:
        !           606: /*****************************************************************************
        !           607:  * destroy
        !           608:  * PARAM : mode : mode
        !           609:  *              :
        !           610:  *       : ptr  :
        !           611:  *       : rsv  : reserve space.
        !           612:  * RETURN: NONE
        !           613:  * SEE   :
        !           614:  *****************************************************************************/
        !           615: void
        !           616: oxserv_dest()
        !           617: {
        !           618:        free(G_ox_stack);
        !           619: }
        !           620:
        !           621:
        !           622: #if 0
        !           623:
        !           624: cmo *
        !           625: oxserv_executeFunction(const char *func, cmo **arg, int argc)
        !           626: {
        !           627:        int i;
        !           628:
        !           629:        printf("%s()\n", func);
        !           630:
        !           631:        for (i = 0; i < argc; i++) {
        !           632:                printf("\t%2d: %s\n", i, new_string_set_cmo(arg[i]));
        !           633:        }
        !           634:
        !           635:        return ((cmo *)new_cmo_int32(0));
        !           636: }
        !           637:
        !           638: int
        !           639: main(int argc, char *argv[])
        !           640: {
        !           641:        int fd = 3;
        !           642:        int i;
        !           643:        int ret;
        !           644:
        !           645:        OXFILE *oxfp = oxf_open(fd);
        !           646:
        !           647:        ox_stderr_init(stderr);
        !           648:
        !           649:        oxserv_init(0, "$Date: 2003/11/02 16:39:16 $", "oxserv", NULL, NULL);
        !           650:
        !           651:        DPRINTF(("main - start\n"));
        !           652:        for (i = 0;; i++) {
        !           653:                DPRINTF(("@"));
        !           654:                ret = oxserv_receive(oxfp);
        !           655:                if (ret != OXSERV_SUCCESS)
        !           656:                        break;
        !           657:        }
        !           658:
        !           659:        oxf_close(fd);
        !           660:        delete_cmo(G_oxserv_mathcap);
        !           661:
        !           662:        return (0);
        !           663: }
        !           664:
        !           665: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>