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

Annotation of OpenXM/src/ox_toolkit/oxf.c, Revision 1.25

1.1       ohara       1: /* -*- mode: C; coding: euc-japan -*- */
1.25    ! ohara       2: /* $OpenXM: OpenXM/src/ox_toolkit/oxf.c,v 1.24 2016/06/30 01:14:00 ohara Exp $ */
1.1       ohara       3:
                      4: /*
                      5:    This module includes functions for sending/receiveng CMO's.
                      6: */
                      7:
1.24      ohara       8: #if defined(_MSC_VER)
                      9: #define _CRT_RAND_S
                     10: #endif
                     11:
1.1       ohara      12: #include <stdio.h>
                     13: #include <stdlib.h>
                     14: #include <string.h>
                     15: #include <fcntl.h>
                     16: #include <time.h>
1.19      ohara      17: #include <limits.h>
1.12      ohara      18:
1.25    ! ohara      19: #if defined(__sun__) || defined(__FreeBSD__)
1.12      ohara      20: #include <netdb.h>
                     21: #include <sys/types.h>
                     22: #include <netinet/in.h>
1.25    ! ohara      23: #elif defined(__linux__)
        !            24: #include <arpa/inet.h>
1.12      ohara      25: #endif
1.1       ohara      26:
1.19      ohara      27: #if defined(__sun__)
                     28: #include <synch.h>
                     29: #else
                     30: #include <inttypes.h>
                     31: #endif
                     32:
1.23      ohara      33: #if defined(_MSC_VER)
                     34: #include <io.h>
1.24      ohara      35: #include <winsock2.h>
1.23      ohara      36: #define X_OK 0x01
                     37: #define R_OK 0x04
                     38: #define MAXHOSTNAMELEN 256
1.24      ohara      39: #define srandom(s)  (srand((s)))
                     40: static int random()
                     41: {
                     42:     int r;
                     43:     rand_s(&r);
                     44:     return r;
                     45: }
1.25    ! ohara      46: #define READ(fd,buf,n)   (recv((fd),(buf),(n),0))
        !            47: #define WRITE(fd,buf,n)  (send((fd),(buf),(n),0))
1.23      ohara      48: #else
                     49: #include <unistd.h>
                     50: #include <sys/file.h>
                     51: #include <sys/param.h>
1.25    ! ohara      52: #define READ(fd,buf,n)   (read((fd),(buf),(n)))
        !            53: #define WRITE(fd,buf,n)  (write((fd),(buf),(n)))
1.23      ohara      54: #endif
                     55:
1.1       ohara      56: #include "mysocket.h"
                     57: #include "ox_toolkit.h"
                     58:
1.6       ohara      59: static mathcap *oxf_mathcap(OXFILE *oxfp);
                     60:
1.4       ohara      61: static int send_int32_lbo(OXFILE *oxfp, int int32);
                     62: static int send_int32_nbo(OXFILE *oxfp, int int32);
                     63: static int receive_int32_lbo(OXFILE *oxfp);
                     64: static int receive_int32_nbo(OXFILE *oxfp);
                     65:
1.19      ohara      66: static int send_int64_nbo_le(OXFILE *oxfp, double int64);
                     67: static int send_int64_lbo(OXFILE *oxfp, double int64);
1.20      ohara      68: static double receive_int64_nbo_le(OXFILE *oxfp);
                     69: static double receive_int64_lbo(OXFILE *oxfp);
1.19      ohara      70:
1.18      ohara      71: static void pipe_send_info(int fd, char *hostname, int port, char *password);
                     72:
1.19      ohara      73: /* translating double of little endian byte order to one of big endian. */
                     74: double htonll_le(double n)
                     75: {
                     76:     int i;
                     77:     double r;
                     78:        char *sp = (char *)&n, *dp = (char *)&r + sizeof(double)-1;
                     79:     for(i=0; i<sizeof(double); i++) {
                     80:                *dp-- = *sp++;
                     81:     }
                     82:     return r;
                     83: }
                     84:
1.16      ohara      85: /* enable write buffering */
                     86: int oxf_setbuffer(OXFILE *oxfp, char *buf, int size)
                     87: {
                     88:     if (buf == NULL && size > 0) {
1.17      ohara      89:         buf = MALLOC(size);
1.16      ohara      90:     }
                     91:     if (oxfp->wbuf != NULL) {
                     92:         oxf_flush(oxfp);
                     93:     }
                     94:     oxfp->wbuf = buf;
                     95:     oxfp->wbuf_size  = size;
                     96:     oxfp->wbuf_count = 0;
1.18      ohara      97:     return 0;
1.16      ohara      98: }
                     99:
1.25    ! ohara     100: void OX_FD_ZERO(OXFILE_set *s)
        !           101: {
        !           102:     memset(s,0,sizeof(OXFILE_set));
        !           103: }
        !           104:
        !           105: void OX_FD_SET(OXFILE *oxfp,OXFILE_set *s)
        !           106: {
        !           107:     if (oxfp != NULL && oxfp->fd >=0 && oxfp->fd < OX_FD_SETSIZE && !FD_ISSET(oxfp->fd,&(s->fdset))) {
        !           108:         FD_SET(oxfp->fd,&(s->fdset));
        !           109:         s->p[oxfp->fd] = oxfp;
        !           110:         s->count++;
        !           111:     }
        !           112: }
        !           113:
        !           114: void OX_FD_CLR(OXFILE *oxfp,OXFILE_set *s)
        !           115: {
        !           116:     if (oxfp != NULL && oxfp->fd >=0 && oxfp->fd < OX_FD_SETSIZE && FD_ISSET(oxfp->fd,&(s->fdset))) {
        !           117:         FD_CLR(oxfp->fd,&(s->fdset));
        !           118:         s->p[oxfp->fd] = NULL;
        !           119:         s->count--;
        !           120:     }
        !           121: }
        !           122:
        !           123: int OX_FD_ISSET(OXFILE *oxfp,OXFILE_set *s)
        !           124: {
        !           125:     if (oxfp != NULL && oxfp->fd >=0 && oxfp->fd < OX_FD_SETSIZE) {
        !           126:         return FD_ISSET(oxfp->fd,&(s->fdset));
        !           127:     }
        !           128:     return 0;
        !           129: }
        !           130:
        !           131: /* The argument `s' is a set of file descripters for reading */
        !           132: OXFILE *oxf_select(OXFILE_set *s, struct timeval *tv)
        !           133: {
        !           134:     int r;
        !           135:     r = select(OX_FD_SETSIZE,&(s->fdset),NULL,NULL,tv);
        !           136:     return (r<0)? NULL: s->p[r];
        !           137: }
        !           138:
1.2       ohara     139: int oxf_read(void *buffer, size_t size, size_t num, OXFILE *oxfp)
                    140: {
1.25    ! ohara     141:     int n = READ(oxfp->fd, buffer, size*num);
1.5       ohara     142:     if (n <= 0) {
1.22      noro      143: #if 0
1.5       ohara     144:         oxfp->error = 1;
1.22      noro      145: #else
                    146:         exit(0);
                    147: #endif
1.5       ohara     148:     }
1.2       ohara     149:     return n;
                    150: }
                    151:
                    152: int oxf_write(void *buffer, size_t size, size_t num, OXFILE *oxfp)
                    153: {
1.16      ohara     154:     size_t sz = size*num;
                    155:     if (oxfp->wbuf == NULL) { /* no buffering */
1.25    ! ohara     156:         return WRITE(oxfp->fd, buffer, sz);
1.16      ohara     157:     }
                    158:     if ((oxfp->wbuf_count + sz) >= oxfp->wbuf_size) {
                    159:         oxf_flush(oxfp);
1.25    ! ohara     160:         return WRITE(oxfp->fd, buffer, sz);
1.16      ohara     161:     }
                    162:     memcpy(oxfp->wbuf + oxfp->wbuf_count, buffer, sz);
                    163:     oxfp->wbuf_count += sz;
                    164:     return sz;
1.2       ohara     165: }
                    166:
1.19      ohara     167: /* sending an object of int64 type with Network Byte Order. */
                    168: static int send_int64_nbo_le(OXFILE *oxfp, double int64)
                    169: {
                    170:     int64 = htonll_le(int64);
                    171:     return oxf_write(&int64, sizeof(double), 1, oxfp);
                    172: }
                    173:
                    174: /* sending an object of int64 type with Local Byte Order. */
                    175: static int send_int64_lbo(OXFILE *oxfp, double int64)
                    176: {
                    177:     return oxf_write(&int64, sizeof(double), 1, oxfp);
                    178: }
                    179:
                    180: /* receiving an object of int64 type with Network Byte Order. */
1.20      ohara     181: static double receive_int64_nbo_le(OXFILE *oxfp)
1.19      ohara     182: {
1.21      noro      183:     double tag;
1.19      ohara     184:     oxf_read(&tag, sizeof(double), 1, oxfp);
                    185:     return htonll_le(tag);
                    186: }
                    187:
                    188: /* receiving an object of int64 type with Local Byte Order. */
1.20      ohara     189: static double receive_int64_lbo(OXFILE *oxfp)
1.19      ohara     190: {
1.21      noro      191:     double tag;
1.19      ohara     192:     oxf_read(&tag, sizeof(double), 1, oxfp);
                    193:     return tag;
                    194: }
                    195:
1.4       ohara     196: /* sending an object of int32 type with Network Byte Order.
                    197:    (not equal to cmo_int32 type)  */
                    198: static int send_int32_nbo(OXFILE *oxfp, int int32)
                    199: {
                    200:     int32 = htonl(int32);
                    201:     return oxf_write(&int32, sizeof(int), 1, oxfp);
                    202: }
                    203:
                    204: /* sending an object of int32 type with Local Byte Order.
                    205:    (not equal to cmo_int32 type)  */
                    206: static int send_int32_lbo(OXFILE *oxfp, int int32)
                    207: {
                    208:     return oxf_write(&int32, sizeof(int), 1, oxfp);
                    209: }
                    210:
                    211: /* receiving an object of int32 type with Network Byte Order.
                    212:    (not equal to cmo_int32 type)  */
                    213: static int receive_int32_nbo(OXFILE *oxfp)
                    214: {
                    215:     int tag;
                    216:     oxf_read(&tag, sizeof(int), 1, oxfp);
                    217:     return ntohl(tag);
                    218: }
                    219:
                    220: /* receiving an object of int32 type with Local Byte Order.
                    221:    (not equal to cmo_int32 type)  */
                    222: static int receive_int32_lbo(OXFILE *oxfp)
                    223: {
                    224:     int tag;
                    225:     oxf_read(&tag, sizeof(int), 1, oxfp);
                    226:     return tag;
                    227: }
                    228:
1.9       ohara     229: /* (1) getting the fd by socket(2).
                    230:    (2) preparing a buffer by fdopen(fd, "a+"). (not "w+")
                    231:    (3) determing the byte order of the OX connection.
                    232:    (4) setting function pointers by oxf_setopt().
                    233: */
1.1       ohara     234: OXFILE *oxf_open(int fd)
                    235: {
1.17      ohara     236:     OXFILE *oxfp = (OXFILE *)MALLOC(sizeof(OXFILE));
                    237:     oxfp = (OXFILE *)MALLOC(sizeof(OXFILE));
1.1       ohara     238:     oxfp->fd = fd;
                    239:     oxfp->send_int32    = send_int32_nbo;
                    240:     oxfp->receive_int32 = receive_int32_nbo;
1.7       ohara     241:     oxfp->serial_number = 0;
1.5       ohara     242:     oxfp->control = NULL;
                    243:     oxfp->error = 0;
                    244:     oxfp->mathcap = NULL;
1.16      ohara     245:     oxfp->wbuf = NULL;
                    246:     oxfp->wbuf_size = 0;
                    247:     oxfp->wbuf_count = 0;
1.19      ohara     248:     oxfp->send_double    = send_int64_lbo;
                    249:     oxfp->receive_double = receive_int64_lbo;
1.1       ohara     250:     return oxfp;
                    251:     /* oxfp->fp = fdopen(fd, "a+"); */
                    252:     /* return (oxfp->fp != NULL)? oxfp: NULL; */
1.7       ohara     253: }
                    254:
                    255: int oxf_fileno(OXFILE *oxfp)
                    256: {
                    257:     return oxfp->fd;
1.1       ohara     258: }
                    259:
                    260: OXFILE *oxf_control(OXFILE *oxfp)
                    261: {
1.5       ohara     262:     return oxfp->control;
1.1       ohara     263: }
                    264:
                    265: /* The function determines a byte order of integer on the OpenXM
                    266:    connection `oxfp'. */
                    267: /* REMARKS:
                    268:    we request the byte order of macine integer on a local machine by
                    269:    (*(char *)&offer).  The fact depends on OX_BYTE_LITTLE_ENDIAN==1. */
                    270: void oxf_determine_byteorder_client(OXFILE *oxfp)
                    271: {
                    272:     int  offer = OX_BYTE_LITTLE_ENDIAN;
                    273:     char receiv;
                    274:     int  mode;
                    275:
                    276:     oxf_read(&receiv, 1, 1, oxfp);
                    277:     oxf_write(&offer, 1, 1, oxfp);
                    278:     mode = (receiv == *(char *)&offer);
                    279:     oxf_setopt(oxfp, mode);
                    280: }
                    281:
1.9       ohara     282: /* If the program is an OX server, then you must use this function. */
1.1       ohara     283: void oxf_determine_byteorder_server(OXFILE *oxfp)
                    284: {
                    285:     int  offer = OX_BYTE_LITTLE_ENDIAN;
                    286:     char receiv;
                    287:     int  mode;
                    288:
                    289:     oxf_write(&offer, 1, 1, oxfp);
                    290:     oxf_read(&receiv, 1, 1, oxfp);
                    291:     mode = (receiv == *(char *)&offer);
                    292:     oxf_setopt(oxfp, mode);
                    293: }
                    294:
                    295: void oxf_flush(OXFILE *oxfp)
                    296: {
1.16      ohara     297:     if (oxfp->wbuf != NULL) {
1.25    ! ohara     298:         WRITE(oxfp->fd, oxfp->wbuf, oxfp->wbuf_count);
1.16      ohara     299:         oxfp->wbuf_count = 0;
                    300:     }
1.1       ohara     301: }
                    302:
                    303: void oxf_close(OXFILE *oxfp)
                    304: {
1.16      ohara     305:     oxf_flush(oxfp);
1.1       ohara     306:     close(oxfp->fd);
                    307: }
                    308:
                    309: #define OXF_SETOPT_NBO  0
                    310: #define OXF_SETOPT_LBO  1
                    311:
                    312: void oxf_setopt(OXFILE *oxfp, int mode)
                    313: {
1.19      ohara     314:     int m = 1;
                    315:     if (mode == OXF_SETOPT_NBO && *(char *)&m) {
                    316:                /* Little endian architecture. */
                    317:                oxfp->send_int32     = send_int32_nbo;
                    318:                oxfp->receive_int32  = receive_int32_nbo;
                    319:                oxfp->send_double    = send_int64_nbo_le;
                    320:                oxfp->receive_double = receive_int64_nbo_le;
                    321:        }else {
                    322:                oxfp->send_int32     = send_int32_lbo;
                    323:                oxfp->receive_int32  = receive_int32_lbo;
                    324:                oxfp->send_double    = send_int64_lbo;
                    325:                oxfp->receive_double = receive_int64_lbo;
1.1       ohara     326:     }
                    327: }
                    328:
1.18      ohara     329: int oxf_listen(int *portp)
1.4       ohara     330: {
                    331:     char localhost[MAXHOSTNAMELEN];
                    332:     if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
1.5       ohara     333:         return mysocketListen(localhost, portp);
                    334:     }
                    335:     return -1;
1.4       ohara     336: }
                    337:
1.1       ohara     338: OXFILE *oxf_connect_active(char *hostname, short port)
                    339: {
                    340:     int fd = mysocketOpen(hostname, port);
1.11      ohara     341:     return (fd < 0)? NULL: oxf_open(fd);
1.1       ohara     342: }
                    343:
                    344: OXFILE *oxf_connect_passive(int listened)
                    345: {
                    346:     int fd = mysocketAccept(listened);
1.11      ohara     347:     return (fd < 0)? NULL: oxf_open(fd);
1.1       ohara     348: }
                    349:
                    350: #define LENGTH_OF_ONETIME_PASSWORD 64
                    351:
                    352: /* a password generator. */
                    353: char *generate_otp()
                    354: {
1.5       ohara     355:     static char crypto[] = "%.,^_+-=/@0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1.1       ohara     356:     static char otp[LENGTH_OF_ONETIME_PASSWORD+1] = {0};
                    357:     int i;
                    358:
                    359:     srandom(time(NULL));
                    360:     for(i=0; i<LENGTH_OF_ONETIME_PASSWORD; i++) {
                    361:         otp[i] = crypto[random() % (sizeof(crypto)-1)];
                    362:     }
                    363:     return otp;
                    364: }
                    365:
                    366: /* proceeding a one time password. */
                    367: /* if the password is right,
                    368:    then the function returns 1, if otherwise, then 0. */
                    369: int oxf_confirm_client(OXFILE *oxfp, char *passwd)
                    370: {
                    371:     int len = strlen(passwd)+1;
1.17      ohara     372:     char *buf = ALLOCA(len);
1.1       ohara     373:
                    374:     oxf_read(buf, 1, len, oxfp);
                    375:     return !strcmp(passwd, buf);
                    376: }
                    377:
                    378: int oxf_confirm_server(OXFILE *oxfp, char *passwd)
                    379: {
                    380:     return oxf_write(passwd, 1, strlen(passwd)+1, oxfp);
                    381: }
                    382:
1.6       ohara     383: __inline__
                    384: static mathcap *oxf_mathcap(OXFILE *oxfp)
1.5       ohara     385: {
                    386:     if (oxfp->mathcap == NULL) {
                    387:         oxfp->mathcap = new_mathcap();
                    388:     }
1.6       ohara     389:        return oxfp->mathcap;
                    390: }
                    391:
                    392: cmo_mathcap *oxf_cmo_mathcap(OXFILE *oxfp)
                    393: {
                    394:        return mathcap_get(oxf_mathcap(oxfp));
                    395: }
                    396:
                    397: void oxf_mathcap_update(OXFILE *oxfp, cmo_mathcap *ob)
                    398: {
                    399:     mathcap_update(oxf_mathcap(oxfp), ob);
1.5       ohara     400: }
                    401:
1.1       ohara     402: /* example: which("xterm", getenv("PATH")); */
                    403: char *which(char *exe, const char *env)
                    404: {
                    405:     char *tok;
                    406:     char *path;
                    407:     char delim[] = ":";
1.17      ohara     408:     char *e = ALLOCA(strlen(env)+1);
1.1       ohara     409:     strcpy(e, env);
                    410:     tok = strtok(e, delim);
                    411:     while (tok != NULL) {
1.17      ohara     412:         path = MALLOC(strlen(tok)+strlen(exe)+2);
1.1       ohara     413:         sprintf(path, "%s/%s", tok, exe);
                    414:         if (access(path, X_OK&R_OK) == 0) {
                    415:             return path;
                    416:         }
1.17      ohara     417:         FREE(path);
1.1       ohara     418:         tok = strtok(NULL, delim);
                    419:     }
                    420:     return NULL;
                    421: }
                    422:
1.24      ohara     423: #if !defined(_MSC_VER)
1.1       ohara     424: /* Remarks: ssh determines remote host by his name, i.e. by arg[0]. */
1.18      ohara     425: int oxc_start(char *remote_host, int port, char *passwd)
1.1       ohara     426: {
                    427:     char localhost[MAXHOSTNAMELEN];
                    428:     char ports[128];
                    429:     int pid = 0;
1.2       ohara     430:     char *cmd = "oxc";
1.1       ohara     431:
                    432:     if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
                    433:         if ((pid = fork()) == 0) {
                    434:             sprintf(ports, "%d", port);
1.14      ohara     435:             ox_printf("oxf.c:: oxc_start() does %s(ssh) -f %s -h %s -p %s -c %s\n", remote_host, cmd, localhost, ports, passwd);
1.1       ohara     436:             execlp("ssh", remote_host, "-f", cmd,
                    437:                   "-h", localhost, "-p", ports,"-c", passwd, NULL);
                    438:         }
                    439:     }
                    440:     return pid;
1.8       ohara     441: }
                    442:
                    443: /* Remarks: ssh determines remote host by his name, i.e. by arg[0]. */
                    444: int oxc_start_with_pipe(char *remote_host, int port, char *passwd)
                    445: {
                    446:     char localhost[MAXHOSTNAMELEN];
                    447:     int  pid = 0;
                    448:     char *cmd = "oxc";
                    449:        int  pipefd[2];
                    450:
                    451:     if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
                    452:                if (pipe(pipefd) < 0) {
                    453:                        return -1;
                    454:                }
                    455:         if ((pid = fork()) == 0) {
                    456:                        dup2(pipefd[1], 0);
                    457:                        close(pipefd[0]);
                    458:                        close(pipefd[1]);
                    459:             execlp("ssh", remote_host, cmd, NULL);
                    460:                        exit(1);
                    461:         }
                    462:                close(pipefd[1]);
                    463:                pipe_send_info(pipefd[0], localhost, port, passwd);
                    464:     }
                    465:     return pid;
                    466: }
1.24      ohara     467: #endif
1.8       ohara     468:
                    469: static void pipe_send_string(int fd, char *s)
                    470: {
1.9       ohara     471:        int len  = strlen(s);
1.8       ohara     472:        int lenN = htonl(len);
                    473:        write(fd, &lenN, sizeof(int));
1.9       ohara     474:        write(fd, s, len+1);
1.8       ohara     475: }
                    476:
                    477: static char *pipe_read_string()
                    478: {
                    479:        int len;
                    480:        char *s;
                    481:        read(0, &len, sizeof(int));
1.9       ohara     482:        len = ntohl(len)+1;
1.17      ohara     483:        s = MALLOC(len);
1.8       ohara     484:        read(0, s, len);
                    485:        return s;
                    486: }
                    487:
1.9       ohara     488: /* The data format used by pipe_send_info() is defined in OX-RFC-101. */
1.8       ohara     489: void pipe_send_info(int fd, char *hostname, int port, char *password)
                    490: {
                    491:        port = htonl(port);
                    492:        write(fd, &port, sizeof(int));
                    493:        pipe_send_string(fd, hostname);
                    494:        pipe_send_string(fd, password);
                    495: }
                    496:
1.18      ohara     497: int pipe_read_info(char **hostname, int *port, char **password)
1.8       ohara     498: {
                    499:        if (read(0, port, sizeof(int)) > 0) {
                    500:                *port = ntohl(*port);
                    501:                *hostname = pipe_read_string();
                    502:                *password = pipe_read_string();
                    503:                return 0;
                    504:        }
                    505:        return -1;
1.4       ohara     506: }
                    507:
                    508: /*  Example: oxf_execute_cmd(oxfp, "ox_sm1"); */
                    509: OXFILE *oxf_execute_cmd(OXFILE *oxfp, char *cmd)
                    510: {
1.18      ohara     511:     int port = 0;
1.5       ohara     512:     int listened;
1.4       ohara     513:
1.5       ohara     514:     if ((listened = oxf_listen(&port)) != -1) {
1.18      ohara     515:                cmo_list *args =  list_appendl(NULL, list_append(new_cmo_list(), (cmo *)new_cmo_int32(port)), new_cmo_string(cmd), NULL);
1.10      ohara     516:                send_ox_cmo(oxfp, (cmo *)args);
                    517:         send_ox_command(oxfp, SM_control_spawn_server);
1.5       ohara     518:         return oxf_connect_passive(listened);
                    519:     }
                    520:     return NULL;
1.1       ohara     521: }

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