[BACK]Return to sio.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / io

File: [local] / OpenXM_contrib2 / asir2000 / io / sio.c (download)

Revision 1.9.2.1, Wed Nov 8 08:18:14 2000 UTC (23 years, 6 months ago) by maekawa
Branch: maekawa-ipv6
Changes since 1.9: +127 -130 lines

Rewrite to protocol-independent code.

try_accept() have still af_unix.
Both old and new codes have security bugs. should be rewriten.

/*
 * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED 
 * All rights reserved.
 * 
 * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
 * non-exclusive and royalty-free license to use, copy, modify and
 * redistribute, solely for non-commercial and non-profit purposes, the
 * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
 * conditions of this Agreement. For the avoidance of doubt, you acquire
 * only a limited right to use the SOFTWARE hereunder, and FLL or any
 * third party developer retains all rights, including but not limited to
 * copyrights, in and to the SOFTWARE.
 * 
 * (1) FLL does not grant you a license in any way for commercial
 * purposes. You may use the SOFTWARE only for non-commercial and
 * non-profit purposes only, such as academic, research and internal
 * business use.
 * (2) The SOFTWARE is protected by the Copyright Law of Japan and
 * international copyright treaties. If you make copies of the SOFTWARE,
 * with or without modification, as permitted hereunder, you shall affix
 * to all such copies of the SOFTWARE the above copyright notice.
 * (3) An explicit reference to this SOFTWARE and its copyright owner
 * shall be made on your publication or presentation in any form of the
 * results obtained by use of the SOFTWARE.
 * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
 * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
 * for such modification or the source code of the modified part of the
 * SOFTWARE.
 * 
 * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
 * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
 * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
 * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
 * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
 * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
 * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
 * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
 * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
 * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
 * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
 * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
 * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
 * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
 * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
 * $OpenXM: OpenXM_contrib2/asir2000/io/sio.c,v 1.9.2.1 2000/11/08 08:18:14 maekawa Exp $ 
*/
#if INET
#include "ca.h"
#include "setjmp.h"
#include "ox.h"
#if defined(VISUAL)
#include <winsock.h>
#else
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/ioctl.h>
#include <sys/un.h>
#endif
#include<signal.h>

#define SOCKQUEUELENGTH 5
#define ISIZ sizeof(int)

extern int little_endian;

int I_am_server;
struct IOFP iofp[MAXIOFP];

#if !defined(_PA_RISC1_1)
#define RSH "rsh"
#else
#define RSH "remsh"
#endif

void init_socket(void);

int getremotesocket(s)
int s;
{
	return iofp[s].s;
}

void getremotename(s,name)
int s;
char *name;
{
	union {
		struct sockaddr sa;
		char data[SOCK_MAXADDRLEN];
	} dummy;
	struct sockaddr *sa;
	socklen_t len;
	char host[NI_MAXHOST];
	int rs;

	rs = getremotesocket(s);
	len = SOCK_MAXADDRLEN;
	getpeername(rs, (struct sockaddr *)dummy.data, &len);
	sa = &(dummy.sa);
	getnameinfo(sa, sa->sa_len, host, sizeof(host), NULL, 0, 0);
	strcpy(name, host);
}

int generate_port(use_unix,port_str)
int use_unix;
char *port_str;
{
	double get_current_time();
	unsigned long mt_genrand();
	unsigned int port;
	static int count=0;

#if !defined(VISUAL)
	if ( use_unix ) {
		sprintf(port_str,"/tmp/ox%02x.XXXXXX",count);
		count++;
		mktemp(port_str);
	} else 
#endif
	{
		port = ((unsigned int)mt_genrand()+(unsigned int)get_current_time())
			%(65536-1024)+1024;
		sprintf(port_str,"%d",port);
	}
}

int try_bind_listen(use_unix,port_str)
int use_unix;
char *port_str;
{
	struct addrinfo hints, *res, *ai;
	int s, error;
	char *errstr;

	memset(&hints, 0, sizeof(hints));
#if defined(VISUAL)
	hints.ai_family = PF_UNSPEC;
#else
	if (use_unix)
		hints.ai_family = PF_UNIX;
	else
		hints.ai_family = PF_UNSPEC;
#endif /* VISUAL */
	hints.ai_socktype = SOCK_STREAM;

	error = getaddrinfo(NULL, port_str, &hints, &res);
	if (error) {
		warnx("try_bind_listen(): %s", gai_strerror(error));
		return (-1);
	}

	for (ai = res ; ai != NULL ; ai = ai->ai_next) {
		if ((s = socket(ai->ai_family, ai->ai_socktype,
				ai->ai_protocol)) < 0 ) {
			errstr = "in socket";
			continue;
		}

		if (bind(s, ai->ai_addr, ai->ai_addrlen) < 0) {
			errstr = "in bind";
			close(s);
			s = -1;
			continue;
		}

		if (listen(s, SOCKQUEUELENGTH) < 0) {
			errstr = "in listen";
			close(s);
			s = -1;
			continue;
		}

		/* established connection */
		break;
	}
	freeaddrinfo(res);

	if (s < 0)
		perror(errstr);
	return (s);
}

/*
  try to accept a connection request

  Input
    af_unix: s is UNIX domain socket if af_unix is nonzero
    s: socket

  Output
    c: an accepted socket which is newly created
    -1: if failed to accept

  the original socket is always closed.
*/

int try_accept(af_unix,s)
int af_unix,s;
{
	union {
		struct sockaddr sa;
		char data[SOCK_MAXADDRLEN];
	} dummy;
	socklen_t len;
	int c, i;

	len = SOCK_MAXADDRLEN;
	if (getsockname(s, (struct sockaddr *)dummy.data, &len) < 0) {
		close(s);
		return (-1)
	}

	for (i = 0 ; i < 10 ; i++) {
		c = accept(s, &(dummy.sa), &len);
		if (c >= 0) {
			close(s);
			return (c);
		}
	}

	close(s);
	return (-1);
}

int try_connect(use_unix,host,port_str)
int use_unix;
char *host,*port_str;
{
	struct addrinfo hints, *res, *ai;
	int s, error, i;
	char *errstr;

	memset(&hints, 0, sizeof(hints));
#if defined(VISUAL)
	hints.ai_family = PF_UNSPEC;
#else
	if (use_unix)
		hints.ai_family = PF_UNIX;
	else
		hints.ai_family = PF_UNSPEC;
#endif /* VISUAL */
	hints.ai_socktype = SOCK_STREAM;

	error = getaddrinfo(host, port_str, &hints, &res);
	if (error) {
		warnx("try_connect: %s", gai_strerror(error));
		return (-1);
	}
	for (i = 0 ; i < 10 ; i++) {
		for (ai = res ; ai != NULL ; ai = ai->ai_next) {
			if ((s = socket(ai->ai_family, ai->ai_socktype,
					ai->ai_protocol)) < 0 ) {
				errstr = "socket";
				continue;
			}
			if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) {
				errstr = "connect";
				close(s);
				s = -1;
				continue;
			}

			/* established a connection */
			break;
		}

		if (s >= 0) {
			freeaddrinfo(res);
			return (s);
		}

#if defined(VISUAL)
		Sleep(100);
#else
		usleep(100000);
#endif
	}
	freeaddrinfo(res);

	perror(errstr);
	return (-1);
}

#if 0
close_allconnections()
{
	int s;

#if defined(SIGPIPE)
	signal(SIGPIPE,SIG_IGN);
#endif
	for ( s = 0; s < MAXIOFP; s++ )
		close_connection(s);
}

close_connection(s)
int s;
{
	struct IOFP *r;

	r = &iofp[s];
	if ( r->in && r->out ) {
		if ( check_sm_by_mc(s,SM_shutdown) )
			ox_send_cmd(s,SM_shutdown);
		free_iofp(s);
	}
}
#else
close_allconnections()
{
	shutdown_all();
}
#endif

free_iofp(s)
int s;
{
	struct IOFP *r;

	r = &iofp[s];
	r->in = r->out = 0; r->s = 0;
#if !defined(VISUAL)
	if ( r->socket )
		unlink(r->socket);
#endif
}

#define LBUFSIZ BUFSIZ*10

int get_iofp(s1,af_sock,is_server)
int s1;
char *af_sock;
int is_server;
{
	int i;
	unsigned char c,rc;
	extern int mpi_myid;

#if MPI
	iofp[s1].s = s1;
	if ( mpi_myid == s1 ) {
		iofp[s1].in = 0;
		iofp[s1].out = 0;
	} else {
		iofp[s1].in = WSIO_open(s1,"r");
		iofp[s1].out = WSIO_open(s1,"w");
	}
	iofp[s1].conv = 0;
	iofp[s1].socket = 0;

	return s1;
#else
	for ( i = 0; i < MAXIOFP; i++ )
		if ( !iofp[i].in )
			break;
	iofp[i].s = s1;
#if defined(VISUAL)
	iofp[i].in = WSIO_open(s1,"r");
	iofp[i].out = WSIO_open(s1,"w");
#else
	iofp[i].in = fdopen(s1,"r");
	iofp[i].out = fdopen(s1,"w");
	setbuffer(iofp[i].in,(char *)malloc(LBUFSIZ),LBUFSIZ);
	setbuffer(iofp[i].out,(char *)malloc(LBUFSIZ),LBUFSIZ);
#endif
	if ( little_endian )
		c = 1;
	else
		c = 0xff;
	if ( is_server ) {
		/* server : write -> read */
		write_char(iofp[i].out,&c); ox_flush_stream_force(i);
		read_char(iofp[i].in,&rc);
	} else {
		/* client : read -> write */
		read_char(iofp[i].in,&rc);
		/* special care for a failure of spawing a server */
		if ( rc !=0 && rc != 1 && rc != 0xff )
			return -1;	
		write_char(iofp[i].out,&c); ox_flush_stream_force(i);
	}
	iofp[i].conv = c == rc ? 0 : 1;
	if ( af_sock && af_sock[0] ) {
		iofp[i].socket = (char *)malloc(strlen(af_sock)+1);
		strcpy(iofp[i].socket,af_sock);
	} else
		iofp[i].socket = 0;
	return i;
#endif
}

#if defined(VISUAL)
void init_socket()
{
	static int socket_is_initialized;
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD(2,0);

	if ( socket_is_initialized )
		return;
	err = WSAStartup(wVersionRequested,&wsaData);	
	if ( err )
		return;
}
#endif

get_fd(index)
int index;
{
	return iofp[index].s;
}

get_index(fd)
int fd;
{
	int i;

	for ( i = 0; i < MAXIOFP; i++ )
		if ( iofp[i].s == fd )
			return i;
	return -1;
}

#endif /* INET */