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

1.1       ohara       1: /* -*- mode: C; coding: euc-japan -*- */
1.8     ! ohara       2: /* $OpenXM: OpenXM/src/ox_toolkit/oxf.c,v 1.7 2000/11/28 22:11:14 ohara Exp $ */
1.1       ohara       3:
                      4: /*
                      5:    This module includes functions for sending/receiveng CMO's.
                      6:    Some commnets is written in Japanese by the EUC-JP coded
                      7:    character set.
                      8: */
                      9:
                     10: #include <stdio.h>
                     11: #include <stdlib.h>
                     12: #include <string.h>
                     13: #include <unistd.h>
                     14: #include <fcntl.h>
                     15: #include <sys/file.h>
                     16: #include <sys/param.h>
                     17: #include <time.h>
                     18:
                     19: #include "mysocket.h"
                     20: #include "ox_toolkit.h"
                     21:
1.6       ohara      22: static mathcap *oxf_mathcap(OXFILE *oxfp);
                     23:
1.4       ohara      24: static int send_int32_lbo(OXFILE *oxfp, int int32);
                     25: static int send_int32_nbo(OXFILE *oxfp, int int32);
                     26: static int receive_int32_lbo(OXFILE *oxfp);
                     27: static int receive_int32_nbo(OXFILE *oxfp);
                     28:
1.2       ohara      29: int oxf_read(void *buffer, size_t size, size_t num, OXFILE *oxfp)
                     30: {
1.5       ohara      31:     int n = read(oxfp->fd, buffer, size*num);
                     32:     if (n <= 0) {
                     33:         oxfp->error = 1;
                     34:     }
1.2       ohara      35:     return n;
                     36: }
                     37:
                     38: int oxf_write(void *buffer, size_t size, size_t num, OXFILE *oxfp)
                     39: {
                     40:     return write(oxfp->fd, buffer, size*num);
                     41: }
                     42:
1.4       ohara      43: /* sending an object of int32 type with Network Byte Order.
                     44:    (not equal to cmo_int32 type)  */
                     45: static int send_int32_nbo(OXFILE *oxfp, int int32)
                     46: {
                     47:     int32 = htonl(int32);
                     48:     return oxf_write(&int32, sizeof(int), 1, oxfp);
                     49: }
                     50:
                     51: /* sending an object of int32 type with Local Byte Order.
                     52:    (not equal to cmo_int32 type)  */
                     53: static int send_int32_lbo(OXFILE *oxfp, int int32)
                     54: {
                     55:     return oxf_write(&int32, sizeof(int), 1, oxfp);
                     56: }
                     57:
                     58: /* receiving an object of int32 type with Network Byte Order.
                     59:    (not equal to cmo_int32 type)  */
                     60: static int receive_int32_nbo(OXFILE *oxfp)
                     61: {
                     62:     int tag;
                     63:     oxf_read(&tag, sizeof(int), 1, oxfp);
                     64:     return ntohl(tag);
                     65: }
                     66:
                     67: /* receiving an object of int32 type with Local Byte Order.
                     68:    (not equal to cmo_int32 type)  */
                     69: static int receive_int32_lbo(OXFILE *oxfp)
                     70: {
                     71:     int tag;
                     72:     oxf_read(&tag, sizeof(int), 1, oxfp);
                     73:     return tag;
                     74: }
                     75:
                     76: /* socket システムコールなどで socket を開いたのち、
                     77:    fdopen(sd, "a+") でバッファリングする(予定)。("w+" ではない)
                     78:    バッファリングの後、バイトオーダを決定し、
                     79:    oxf_setopt() で関数ポインタを設定し直す。*/
                     80:
1.1       ohara      81: OXFILE *oxf_open(int fd)
                     82: {
                     83:     OXFILE *oxfp = (OXFILE *)malloc(sizeof(OXFILE));
                     84:     oxfp->fd = fd;
                     85:     oxfp->send_int32    = send_int32_nbo;
                     86:     oxfp->receive_int32 = receive_int32_nbo;
1.7       ohara      87:     oxfp->serial_number = 0;
1.5       ohara      88:     oxfp->control = NULL;
                     89:     oxfp->error = 0;
                     90:     oxfp->mathcap = NULL;
1.1       ohara      91:     return oxfp;
                     92:     /* oxfp->fp = fdopen(fd, "a+"); */
                     93:     /* return (oxfp->fp != NULL)? oxfp: NULL; */
1.7       ohara      94: }
                     95:
                     96: int oxf_fileno(OXFILE *oxfp)
                     97: {
                     98:     return oxfp->fd;
1.1       ohara      99: }
                    100:
                    101: OXFILE *oxf_control(OXFILE *oxfp)
                    102: {
1.5       ohara     103:     return oxfp->control;
1.1       ohara     104: }
                    105:
                    106: /* The function determines a byte order of integer on the OpenXM
                    107:    connection `oxfp'. */
                    108: /* REMARKS:
                    109:    we request the byte order of macine integer on a local machine by
                    110:    (*(char *)&offer).  The fact depends on OX_BYTE_LITTLE_ENDIAN==1. */
                    111: void oxf_determine_byteorder_client(OXFILE *oxfp)
                    112: {
                    113:     int  offer = OX_BYTE_LITTLE_ENDIAN;
                    114:     char receiv;
                    115:     int  mode;
                    116:
                    117:     oxf_read(&receiv, 1, 1, oxfp);
                    118:     oxf_write(&offer, 1, 1, oxfp);
                    119:     mode = (receiv == *(char *)&offer);
                    120:     oxf_setopt(oxfp, mode);
                    121: }
                    122:
                    123: /* Server 側ではこちらを用いる */
                    124: /* いまの実装は dup されていることが前提になっている */
                    125: void oxf_determine_byteorder_server(OXFILE *oxfp)
                    126: {
                    127:     int  offer = OX_BYTE_LITTLE_ENDIAN;
                    128:     char receiv;
                    129:     int  mode;
                    130:
                    131:     oxf_write(&offer, 1, 1, oxfp);
                    132:     oxf_read(&receiv, 1, 1, oxfp);
                    133:     mode = (receiv == *(char *)&offer);
                    134:     oxf_setopt(oxfp, mode);
                    135: }
                    136:
                    137: void oxf_flush(OXFILE *oxfp)
                    138: {
                    139:     /* fflush(oxfp->fp); */
                    140: }
                    141:
                    142: void oxf_close(OXFILE *oxfp)
                    143: {
                    144:     close(oxfp->fd);
                    145:     /* fclose(oxfp->fp); */
                    146: }
                    147:
                    148: #define OXF_SETOPT_NBO  0
                    149: #define OXF_SETOPT_LBO  1
                    150:
                    151: void oxf_setopt(OXFILE *oxfp, int mode)
                    152: {
                    153:     if (mode == OXF_SETOPT_LBO) {
                    154:         oxfp->send_int32    = send_int32_lbo;
                    155:         oxfp->receive_int32 = receive_int32_lbo;
                    156:     }else if (mode == OXF_SETOPT_NBO) {
                    157:         oxfp->send_int32    = send_int32_nbo;
                    158:         oxfp->receive_int32 = receive_int32_nbo;
                    159:     }
                    160: }
                    161:
1.4       ohara     162: int oxf_listen(short *portp)
                    163: {
                    164:     char localhost[MAXHOSTNAMELEN];
                    165:     if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
1.5       ohara     166:         return mysocketListen(localhost, portp);
                    167:     }
                    168:     return -1;
1.4       ohara     169: }
                    170:
1.1       ohara     171: OXFILE *oxf_connect_active(char *hostname, short port)
                    172: {
                    173:     int fd = mysocketOpen(hostname, port);
                    174:     return oxf_open(fd);
                    175: }
                    176:
                    177: OXFILE *oxf_connect_passive(int listened)
                    178: {
                    179:     int fd = mysocketAccept(listened);
                    180:     return oxf_open(fd);
                    181: }
                    182:
                    183: #define LENGTH_OF_ONETIME_PASSWORD 64
                    184:
                    185: /* a password generator. */
                    186: char *generate_otp()
                    187: {
1.5       ohara     188:     static char crypto[] = "%.,^_+-=/@0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1.1       ohara     189:     static char otp[LENGTH_OF_ONETIME_PASSWORD+1] = {0};
                    190:     int i;
                    191:
                    192:     srandom(time(NULL));
                    193:     for(i=0; i<LENGTH_OF_ONETIME_PASSWORD; i++) {
                    194:         otp[i] = crypto[random() % (sizeof(crypto)-1)];
                    195:     }
                    196:     return otp;
                    197: }
                    198:
                    199: /* proceeding a one time password. */
                    200: /* if the password is right,
                    201:    then the function returns 1, if otherwise, then 0. */
                    202: int oxf_confirm_client(OXFILE *oxfp, char *passwd)
                    203: {
                    204:     int len = strlen(passwd)+1;
                    205:     char *buf = alloca(len);
                    206:
                    207:     oxf_read(buf, 1, len, oxfp);
                    208:     return !strcmp(passwd, buf);
                    209: }
                    210:
                    211: int oxf_confirm_server(OXFILE *oxfp, char *passwd)
                    212: {
                    213:     return oxf_write(passwd, 1, strlen(passwd)+1, oxfp);
                    214: }
                    215:
1.6       ohara     216: __inline__
                    217: static mathcap *oxf_mathcap(OXFILE *oxfp)
1.5       ohara     218: {
                    219:     if (oxfp->mathcap == NULL) {
                    220:         oxfp->mathcap = new_mathcap();
                    221:     }
1.6       ohara     222:        return oxfp->mathcap;
                    223: }
                    224:
                    225: cmo_mathcap *oxf_cmo_mathcap(OXFILE *oxfp)
                    226: {
                    227:        return mathcap_get(oxf_mathcap(oxfp));
                    228: }
                    229:
                    230: void oxf_mathcap_update(OXFILE *oxfp, cmo_mathcap *ob)
                    231: {
                    232:     mathcap_update(oxf_mathcap(oxfp), ob);
1.5       ohara     233: }
                    234:
1.1       ohara     235: /* example: which("xterm", getenv("PATH")); */
                    236: char *which(char *exe, const char *env)
                    237: {
                    238:     char *tok;
                    239:     char *path;
                    240:     char delim[] = ":";
                    241:     char *e = alloca(strlen(env)+1);
                    242:     strcpy(e, env);
                    243:     tok = strtok(e, delim);
                    244:     while (tok != NULL) {
                    245:         path = malloc(strlen(tok)+strlen(exe)+2);
                    246:         sprintf(path, "%s/%s", tok, exe);
                    247:         if (access(path, X_OK&R_OK) == 0) {
                    248:             return path;
                    249:         }
                    250:         free(path);
                    251:         tok = strtok(NULL, delim);
                    252:     }
                    253:     return NULL;
                    254: }
                    255:
                    256: /* Remarks: ssh determines remote host by his name, i.e. by arg[0]. */
                    257: int oxc_start(char *remote_host, short port, char *passwd)
                    258: {
                    259:     char localhost[MAXHOSTNAMELEN];
                    260:     char ports[128];
                    261:     int pid = 0;
1.2       ohara     262:     char *cmd = "oxc";
1.1       ohara     263:
                    264:     if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
                    265:         if ((pid = fork()) == 0) {
                    266:             sprintf(ports, "%d", port);
                    267: #ifdef DEBUG
                    268:             fprintf(stderr, "oxf.c:: oxc_start() does %s(ssh) -f %s -h %s -p %s -c %s\n", remote_host, cmd, localhost, ports, passwd);
                    269: #endif
                    270:             execlp("ssh", remote_host, "-f", cmd,
                    271:                   "-h", localhost, "-p", ports,"-c", passwd, NULL);
                    272:         }
                    273:     }
                    274:     return pid;
1.8     ! ohara     275: }
        !           276:
        !           277: /* Remarks: ssh determines remote host by his name, i.e. by arg[0]. */
        !           278: int oxc_start_with_pipe(char *remote_host, int port, char *passwd)
        !           279: {
        !           280:     char localhost[MAXHOSTNAMELEN];
        !           281:     char ports[128];
        !           282:     int  pid = 0;
        !           283:     char *cmd = "oxc";
        !           284:        int  pipefd[2];
        !           285:
        !           286:     if (gethostname(localhost, MAXHOSTNAMELEN)==0) {
        !           287:                if (pipe(pipefd) < 0) {
        !           288:                        return -1;
        !           289:                }
        !           290:         if ((pid = fork()) == 0) {
        !           291:                        dup2(pipefd[1], 0);
        !           292:                        close(pipefd[0]);
        !           293:                        close(pipefd[1]);
        !           294:             execlp("ssh", remote_host, cmd, NULL);
        !           295:                        exit(1);
        !           296:         }
        !           297:                close(pipefd[1]);
        !           298:                pipe_send_info(pipefd[0], localhost, port, passwd);
        !           299:     }
        !           300:     return pid;
        !           301: }
        !           302:
        !           303: /* pipe_*_info で送る情報の形式の定義 */
        !           304: /* Integer port    : 4byte, ポート番号, Network byte order
        !           305:    String  hostname: ホスト名
        !           306:    String  password: パスワード
        !           307:
        !           308:    String は C のストリングではなくて、cmo_string のような、長さ付きの
        !           309:    ストリングである。ただし、\0 文字を含む。
        !           310:    すなわち、"Hello" は (int32)6 H e l l o \0 に展開される(合計10byte)。
        !           311: */
        !           312:
        !           313: static void pipe_send_string(int fd, char *s)
        !           314: {
        !           315:        int len  = strlen(s)+1;
        !           316:        int lenN = htonl(len);
        !           317:        write(fd, &lenN, sizeof(int));
        !           318:        write(fd, s, len);
        !           319: }
        !           320:
        !           321: static char *pipe_read_string()
        !           322: {
        !           323:        int len;
        !           324:        char *s;
        !           325:        read(0, &len, sizeof(int));
        !           326:        len = ntohl(len);
        !           327:        s = malloc(len);
        !           328:        read(0, s, len);
        !           329:        return s;
        !           330: }
        !           331:
        !           332: void pipe_send_info(int fd, char *hostname, int port, char *password)
        !           333: {
        !           334:        port = htonl(port);
        !           335:        write(fd, &port, sizeof(int));
        !           336:        pipe_send_string(fd, hostname);
        !           337:        pipe_send_string(fd, password);
        !           338: }
        !           339:
        !           340: void pipe_read_info(char **hostname, int *port, char **password)
        !           341: {
        !           342:        if (read(0, port, sizeof(int)) > 0) {
        !           343:                *port = ntohl(*port);
        !           344:                *hostname = pipe_read_string();
        !           345:                *password = pipe_read_string();
        !           346:                return 0;
        !           347:        }
        !           348:        return -1;
1.4       ohara     349: }
                    350:
                    351: /*  Example: oxf_execute_cmd(oxfp, "ox_sm1"); */
                    352: OXFILE *oxf_execute_cmd(OXFILE *oxfp, char *cmd)
                    353: {
1.5       ohara     354:     short port = 0;
                    355:     int listened;
1.4       ohara     356:
1.5       ohara     357:     if ((listened = oxf_listen(&port)) != -1) {
                    358:         send_ox_cmo(oxfp, (cmo *)new_cmo_int32(port));
                    359:         send_ox_cmo(oxfp, (cmo *)new_cmo_string(cmd));
                    360:         send_ox_cmo(oxfp, (cmo *)new_cmo_int32(2));  /* number of arguments */
                    361:         send_ox_cmo(oxfp, (cmo *)new_cmo_string("oxc_open"));
                    362:         send_ox_command(oxfp, SM_executeFunction);
                    363:         return oxf_connect_passive(listened);
                    364:     }
                    365:     return NULL;
1.1       ohara     366: }

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