=================================================================== RCS file: /home/cvs/OpenXM/src/ox_toolkit/oxf.c,v retrieving revision 1.5 retrieving revision 1.12 diff -u -p -r1.5 -r1.12 --- OpenXM/src/ox_toolkit/oxf.c 2000/11/24 05:49:27 1.5 +++ OpenXM/src/ox_toolkit/oxf.c 2002/04/10 08:55:45 1.12 @@ -1,9 +1,9 @@ /* -*- mode: C; coding: euc-japan -*- */ -/* $OpenXM: OpenXM/src/ox_toolkit/oxf.c,v 1.4 2000/10/12 15:53:25 ohara Exp $ */ +/* $OpenXM: OpenXM/src/ox_toolkit/oxf.c,v 1.11 2000/12/16 01:49:32 ohara Exp $ */ /* This module includes functions for sending/receiveng CMO's. - Some commnets is written in Japanese by the EUC-JP coded + Some commnets are written in Japanese by the EUC-JP coded character set. */ @@ -16,9 +16,17 @@ #include #include +#if defined(__sun__) +#include +#include +#include +#endif + #include "mysocket.h" #include "ox_toolkit.h" +static mathcap *oxf_mathcap(OXFILE *oxfp); + static int send_int32_lbo(OXFILE *oxfp, int int32); static int send_int32_nbo(OXFILE *oxfp, int int32); static int receive_int32_lbo(OXFILE *oxfp); @@ -71,17 +79,19 @@ static int receive_int32_lbo(OXFILE *oxfp) return tag; } -/* socket システムコールなどで socket を開いたのち、 - fdopen(sd, "a+") でバッファリングする(予定)。("w+" ではない) - バッファリングの後、バイトオーダを決定し、 - oxf_setopt() で関数ポインタを設定し直す。*/ - +/* (1) getting the fd by socket(2). + (2) preparing a buffer by fdopen(fd, "a+"). (not "w+") + (3) determing the byte order of the OX connection. + (4) setting function pointers by oxf_setopt(). +*/ OXFILE *oxf_open(int fd) { OXFILE *oxfp = (OXFILE *)malloc(sizeof(OXFILE)); + oxfp = (OXFILE *)malloc(sizeof(OXFILE)); oxfp->fd = fd; oxfp->send_int32 = send_int32_nbo; oxfp->receive_int32 = receive_int32_nbo; + oxfp->serial_number = 0; oxfp->control = NULL; oxfp->error = 0; oxfp->mathcap = NULL; @@ -90,6 +100,11 @@ OXFILE *oxf_open(int fd) /* return (oxfp->fp != NULL)? oxfp: NULL; */ } +int oxf_fileno(OXFILE *oxfp) +{ + return oxfp->fd; +} + OXFILE *oxf_control(OXFILE *oxfp) { return oxfp->control; @@ -112,8 +127,7 @@ void oxf_determine_byteorder_client(OXFILE *oxfp) oxf_setopt(oxfp, mode); } -/* Server 側ではこちらを用いる */ -/* いまの実装は dup されていることが前提になっている */ +/* If the program is an OX server, then you must use this function. */ void oxf_determine_byteorder_server(OXFILE *oxfp) { int offer = OX_BYTE_LITTLE_ENDIAN; @@ -163,13 +177,13 @@ int oxf_listen(short *portp) OXFILE *oxf_connect_active(char *hostname, short port) { int fd = mysocketOpen(hostname, port); - return oxf_open(fd); + return (fd < 0)? NULL: oxf_open(fd); } OXFILE *oxf_connect_passive(int listened) { int fd = mysocketAccept(listened); - return oxf_open(fd); + return (fd < 0)? NULL: oxf_open(fd); } #define LENGTH_OF_ONETIME_PASSWORD 64 @@ -205,14 +219,25 @@ int oxf_confirm_server(OXFILE *oxfp, char *passwd) return oxf_write(passwd, 1, strlen(passwd)+1, oxfp); } -void oxf_mathcap_update(OXFILE *oxfp, cmo_mathcap *ob) +__inline__ +static mathcap *oxf_mathcap(OXFILE *oxfp) { if (oxfp->mathcap == NULL) { oxfp->mathcap = new_mathcap(); } - mathcap_update(oxfp->mathcap, ob); + return oxfp->mathcap; } +cmo_mathcap *oxf_cmo_mathcap(OXFILE *oxfp) +{ + return mathcap_get(oxf_mathcap(oxfp)); +} + +void oxf_mathcap_update(OXFILE *oxfp, cmo_mathcap *ob) +{ + mathcap_update(oxf_mathcap(oxfp), ob); +} + /* example: which("xterm", getenv("PATH")); */ char *which(char *exe, const char *env) { @@ -255,6 +280,71 @@ int oxc_start(char *remote_host, short port, char *pas return pid; } +/* Remarks: ssh determines remote host by his name, i.e. by arg[0]. */ +int oxc_start_with_pipe(char *remote_host, int port, char *passwd) +{ + char localhost[MAXHOSTNAMELEN]; + char ports[128]; + int pid = 0; + char *cmd = "oxc"; + int pipefd[2]; + + if (gethostname(localhost, MAXHOSTNAMELEN)==0) { + if (pipe(pipefd) < 0) { + return -1; + } + if ((pid = fork()) == 0) { + dup2(pipefd[1], 0); + close(pipefd[0]); + close(pipefd[1]); + execlp("ssh", remote_host, cmd, NULL); + exit(1); + } + close(pipefd[1]); + pipe_send_info(pipefd[0], localhost, port, passwd); + } + return pid; +} + +static void pipe_send_string(int fd, char *s) +{ + int len = strlen(s); + int lenN = htonl(len); + write(fd, &lenN, sizeof(int)); + write(fd, s, len+1); +} + +static char *pipe_read_string() +{ + int len; + char *s; + read(0, &len, sizeof(int)); + len = ntohl(len)+1; + s = malloc(len); + read(0, s, len); + return s; +} + +/* The data format used by pipe_send_info() is defined in OX-RFC-101. */ +void pipe_send_info(int fd, char *hostname, int port, char *password) +{ + port = htonl(port); + write(fd, &port, sizeof(int)); + pipe_send_string(fd, hostname); + pipe_send_string(fd, password); +} + +void pipe_read_info(char **hostname, int *port, char **password) +{ + if (read(0, port, sizeof(int)) > 0) { + *port = ntohl(*port); + *hostname = pipe_read_string(); + *password = pipe_read_string(); + return 0; + } + return -1; +} + /* Example: oxf_execute_cmd(oxfp, "ox_sm1"); */ OXFILE *oxf_execute_cmd(OXFILE *oxfp, char *cmd) { @@ -262,11 +352,9 @@ OXFILE *oxf_execute_cmd(OXFILE *oxfp, char *cmd) int listened; if ((listened = oxf_listen(&port)) != -1) { - send_ox_cmo(oxfp, (cmo *)new_cmo_int32(port)); - send_ox_cmo(oxfp, (cmo *)new_cmo_string(cmd)); - send_ox_cmo(oxfp, (cmo *)new_cmo_int32(2)); /* number of arguments */ - send_ox_cmo(oxfp, (cmo *)new_cmo_string("oxc_open")); - send_ox_command(oxfp, SM_executeFunction); + cmo_list *args = list_appendl(NULL, list_append(new_cmo_list(), new_cmo_int32(port)), new_cmo_string(cmd), NULL); + send_ox_cmo(oxfp, (cmo *)args); + send_ox_command(oxfp, SM_control_spawn_server); return oxf_connect_passive(listened); } return NULL;