[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.23

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

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