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

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

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