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

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

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