Пример #1
0
void gtcm_cn_disc(omi_conn *cptr, omi_conn_ll *cll)
{
	time_t	end;
	int	i, nxact, nerrs;
	int	rc;

	/*  Cumulative statistics */
	end = time((time_t *)0);
	cll->st_cn.start      += end - cptr->stats.start;
	cll->st_cn.bytes_recv += cptr->stats.bytes_recv;
	cll->st_cn.bytes_send += cptr->stats.bytes_send;
	for (i = 0, nxact = 0; i < OMI_OP_MAX; i++)
	{
		cll->st_cn.xact[i] += cptr->stats.xact[i];
		nxact              += cptr->stats.xact[i];
	}
	for (i = 0, nerrs = 0; i < OMI_ER_MAX; i++)
	{
		cll->st_cn.errs[i] += cptr->stats.errs[i];
		nerrs              += cptr->stats.errs[i];
	}
	cll->stats.disc++;
	if (cptr->state != OMI_ST_DISC)
		cll->stats.clos++;
	OMI_DBG_STMP;
	OMI_DBG((omi_debug, "%s: connection %d to %s closed\n",
	SRVR_NAME, cptr->stats.id, gtcm_hname(&cptr->stats.sin)));
	OMI_DBG((omi_debug, "%s:\t%ld seconds connect time\n", SRVR_NAME, end - cptr->stats.start));
	OMI_DBG((omi_debug, "%s:\t%d transactions\n", SRVR_NAME, nxact));
	OMI_DBG((omi_debug, "%s:\t%d errors\n", SRVR_NAME, nerrs));
	OMI_DBG((omi_debug, "%s:\t%d bytes recv'd\n", SRVR_NAME, cptr->stats.bytes_recv));
	OMI_DBG((omi_debug, "%s:\t%d bytes sent\n", SRVR_NAME, cptr->stats.bytes_send));
#ifdef BSD_TCP
	/*  Close out the network connection */
	CLOSEFILE_RESET(cptr->fd, rc);	/* resets "cptr->fd" to FD_INVALID */
#endif /* defined(BSD_TCP) */
	if (FD_INVALID != cptr->pklog)
		CLOSEFILE_RESET(cptr->pklog, rc);	/* resets "cptr->pklog" to FD_INVALID */
#ifdef GTCM_RC
	if (cptr->of)
		rc_oflow_fin(cptr->of);
#endif /* defined(GTCM_RC) */
	/*  Release locks held on this connection */
	omi_prc_unla(cptr, cptr->buff, cptr->buff, cptr->buff);
	/*  Release the buffer and connection structure */
	free(cptr->buff);
	free(cptr);
	return;
}
Пример #2
0
/* On OSF/1 (Digital Unix), pointers are 64 bits wide; the only exception to this is C programs for which one may
 * specify compiler and link editor options in order to use (and allocate) 32-bit pointers.  However, since C is
 * the only exception and, in particular because the operating system does not support such an exception, the argv
 * array passed to the main program is an array of 64-bit pointers.  Thus the C program needs to declare argv[]
 * as an array of 64-bit pointers and needs to do the same for any pointer it sets to an element of argv[].
 */
void gtcm_init(int argc, char_ptr_t argv[])
{
	char			*ptr;
	struct sigaction 	ignore, act;
	void			get_page_size();
	int		  	pid;
	char			msg[256];
	int			save_errno, maxfds;

	/*  Disassociate from the rest of the universe */
	get_page_size();
	gtm_wcswidth_fnptr = gtm_wcswidth;
#	ifndef GTCM_DEBUG_NOBACKGROUND
	FORK(pid);
	if (0 > pid)
	{
		save_errno = errno;
		SPRINTF(msg, "Unable to detach %s from controlling tty", SRVR_NAME);
		gtcm_rep_err(msg, save_errno);
		EXIT(-1);
	}
	else if (0 < pid)
		EXIT(0);
	(void) setpgrp();
#	endif
	/* Initialize logging */
	omi_pid = getpid();
	/*  Initialize signals */
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	ignore = act;
	ignore.sa_handler = SIG_IGN;
	act.sa_handler = (void (*)()) gtcm_term;
	(void) sigaction(SIGTERM, &act, 0);
	act.sa_handler = (void (*)()) gtcm_dmpstat;
	(void) sigaction(SIGUSR1, &act, 0);

	(void) sigaction(SIGUSR2, &ignore, 0);
	(void) sigaction(SIGALRM, &ignore, 0);
	(void) sigaction(SIGPIPE, &ignore, 0);
	(void) sigaction(SIGINT, &ignore, 0);
#	ifdef GTCM_RC
	act.sa_handler = gtcm_fail;
	act.sa_flags = SA_RESETHAND;
	/* restore signal handler to default action upon receipt
	   of signal */
	(void) sigaction(SIGSEGV, &act, 0);
	(void) sigaction(SIGBUS, &act, 0);
	(void) sigaction(SIGILL, &act, 0);
	(void) sigaction(SIGTRAP, &act, 0);
	(void) sigaction(SIGABRT, &act, 0);
#	ifndef __linux__
	(void) sigaction(SIGEMT, &act, 0);
	(void) sigaction(SIGSYS, &act, 0);
#	endif
#	endif
	/*  Initialize the process flags */
	if (0 != gtcm_prsopt(argc, argv))
		EXIT(-1);
	/* Write down pid into log file */
	 OMI_DBG((omi_debug, "GTCM_SERVER pid : %d\n", omi_pid));
	/* Initialize history mechanism */
	if (history)
	{
		init_hist();
		act.sa_handler = (void (*)())dump_rc_hist;
		act.sa_flags = 0;
		(void) sigaction(SIGUSR2, &act, 0);
	}
	/*  Initialize the DBMS */
	licensed = TRUE;
	getjobnum();
	getzdir();
	if ((maxfds = getmaxfds()) < 0)
	{
		gtcm_rep_err("Unable to get system resource limits", errno);
		EXIT(errno);
	}
	assert(SIZEOF(gtcm_ast_avail) == 2);	/* check that short is size 2 bytes as following code relies on that */
	gtcm_ast_avail = (maxfds > MAXINT2) ? MAXINT2 : maxfds;
	stp_init(STP_INITSIZE);
	rts_stringpool = stringpool;
	curr_pattern = pattern_list = &mumps_pattern;
	pattern_typemask = mumps_pattern.typemask;
	INVOKE_INIT_SECSHR_ADDRS;
	initialize_pattern_table();
	/* Preallocate some timer blocks. */
	prealloc_gt_timers();
	gt_timers_add_safe_hndlrs();
	/* Moved to omi_gvextnam, omi_lkextnam */
	/*    gvinit(); */
	return;
}
int omi_prc_conn(omi_conn *cptr, char *xend, char *buff, char *bend)
{
    omi_si	si, eightbit, chartran, ss_len, ext_cnt;
    omi_li	li_min, li_max, ext;
    uns_short	li_val;
    int		len, i;
    char	*bptr, *eptr;
    char	*ag_name, *ag_pass, *s;

    bptr = buff;

/*  Version numbers */
    OMI_SI_READ(&si, cptr->xptr);
    if (si.value != OMI_PROTO_MAJOR)
	return -OMI_ER_SE_VRSNOTSUPP;
    OMI_SI_WRIT(OMI_PROTO_MAJOR, bptr);
/*  XXX minor version numbers */
    OMI_SI_READ(&si, cptr->xptr);
    OMI_SI_WRIT(OMI_PROTO_MINOR, bptr);

/*  Minimum and maximum parameters */

/*  Data */
    OMI_LI_READ(&li_min, cptr->xptr);
    if (OMI_MAX_DATA < li_min.value)
    {
	cptr->state = OMI_ST_CLOS;
	return -OMI_ER_SE_LENMIN;
    }
    OMI_LI_READ(&li_max, cptr->xptr);
    li_val = MIN(li_max.value, OMI_MAX_DATA);
    OMI_LI_WRIT(li_val, bptr);

/*  Subscript */
    OMI_LI_READ(&li_min, cptr->xptr);
    if (OMI_MAX_SUBSCR < li_min.value)
    {
	cptr->state = OMI_ST_CLOS;
	return -OMI_ER_SE_LENMIN;
    }
    OMI_LI_READ(&li_max, cptr->xptr);
    li_val = MIN(li_max.value, OMI_MAX_SUBSCR);
    OMI_LI_WRIT(li_val, bptr);

/*  Reference */
    OMI_LI_READ(&li_min, cptr->xptr);
    if (OMI_MAX_REF < li_min.value)
    {
	cptr->state = OMI_ST_CLOS;
	return -OMI_ER_SE_LENMIN;
    }
    OMI_LI_READ(&li_max, cptr->xptr);
    li_val = MIN(li_max.value, OMI_MAX_REF);
    OMI_LI_WRIT(li_val, bptr);

/*  Message */
    OMI_LI_READ(&li_min, cptr->xptr);
    if (cptr->bsiz < li_min.value)
    {
	cptr->state = OMI_ST_CLOS;
	return -OMI_ER_SE_LENMIN;
    }
    OMI_LI_READ(&li_max, cptr->xptr);
    li_val = MIN(li_max.value, cptr->bsiz);
    OMI_LI_WRIT(li_val, bptr);

/*  Oustanding */
    OMI_LI_READ(&li_min, cptr->xptr);
    if (1 < li_min.value)
    {
	cptr->state = OMI_ST_CLOS;
	return -OMI_ER_SE_LENMIN;
    }
    OMI_LI_READ(&li_max, cptr->xptr);
    li_val = MIN(li_max.value, 1);
    OMI_LI_WRIT(li_val, bptr);

/*  Other parameters */
    OMI_SI_READ(&eightbit, cptr->xptr);
    OMI_SI_WRIT(eightbit.value, bptr);
    OMI_SI_READ(&chartran, cptr->xptr);
    OMI_SI_WRIT(chartran.value, bptr);

/*  Bounds checking */
    if (cptr->xptr > xend || bptr >= bend)
	return -OMI_ER_PR_INVMSGFMT;

/*  Implementation ID (in) */
    OMI_SI_READ(&ss_len,   cptr->xptr);
    cptr->xptr += ss_len.value;

/*  Agent name (in) */
    OMI_SI_READ(&ss_len, cptr->xptr);
    if ((ag_name = (char *) malloc(ss_len.value + 1)) == NULL)
    {
	    OMI_DBG((omi_debug, "%s:  memory allocation error (insufficient resources) while\n", SRVR_NAME));
	    OMI_DBG((omi_debug, "processing connect request from connection %d, %s.\n",
	    		cptr->stats.id, gtcm_hname(&cptr->stats.ai)));
	    return -OMI_ER_DB_UNRECOVER;
    }
    assert(ss_len.value < MAX_USER_NAME && ss_len.value > 0);
    memcpy(ag_name, cptr->xptr, ss_len.value);
    ag_name[ss_len.value] = '\0';
    strcpy(cptr->ag_name, ag_name);
    cptr->xptr += ss_len.value;

/*  Agent password (in) */
    OMI_SI_READ(&ss_len, cptr->xptr);
    if ((ag_pass = (char *) malloc(ss_len.value + 1)) == NULL)
    {
	    OMI_DBG((omi_debug, "%s:  memory allocation error (insufficient resources) while\n", SRVR_NAME));
	    OMI_DBG((omi_debug, "processing connect request from connection %d, %s.\n",
	    		cptr->stats.id, gtcm_hname(&cptr->stats.ai)));
	    return -OMI_ER_DB_UNRECOVER;
    }

    memcpy(ag_pass, cptr->xptr, ss_len.value);
    ag_pass[ss_len.value] = '\0';
    cptr->xptr += ss_len.value;

/* No support for authentication on SCO, Linux, Cygwin, or z/OS at the moment...*/
#if !(defined(SCO) || defined(__linux__) || defined(__CYGWIN__) || defined(__MVS__))
    if (authenticate)  /* verify password and user name */
    {
#ifdef SHADOWPW
	    struct spwd *spass, *getspnam();
	    struct stat buf;
#endif
	    struct passwd *pass;
	    char *pw, *syspw;

	    /* lowercase agent name */
	    for(s = ag_name; *s; s++)
		    if (ISUPPER_ASCII(*s))
			    *s = TOLOWER(*s);

#ifdef SHADOWPW
	    if (!Stat("/etc/shadow", &buf))
	    {
		if ((spass = getspnam(ag_name)) == NULL)
		{
		    if (errno)
		    {
			OMI_DBG((omi_debug, "%s:  error opening /etc/shadow for input\n",
				 SRVR_NAME, ag_name));
			PERROR("/etc/shadow");
			return -OMI_ER_DB_USERNOAUTH;
		    }
		    OMI_DBG((omi_debug, "%s:  user %s not found in /etc/shadow\n",
			     SRVR_NAME, ag_name));
		    return -OMI_ER_DB_USERNOAUTH;
		}
		syspw = spass->sp_pwdp;
	    } else if ((pass = getpwnam(ag_name)) == NULL)
	    {
		    OMI_DBG((omi_debug, "%s:  user %s not found in /etc/passwd\n",
			     SRVR_NAME, ag_name));
		    return -OMI_ER_DB_USERNOAUTH;
	    } else
		syspw = pass->pw_passwd;



#else    /* ndef SHADOWPW */
	    if ((pass = getpwnam(ag_name)) == NULL)
	    {
		    OMI_DBG((omi_debug, "%s:  user %s not found in /etc/passwd\n",
			     SRVR_NAME, ag_name));
		    return -OMI_ER_DB_USERNOAUTH;
	    } else
		syspw = pass->pw_passwd;

#endif   /* SHADOWPW */

	    pw = (char *) crypt(ag_pass, syspw);

	    if (strcmp(pw, syspw) != 0)
	    {
		    OMI_DBG((omi_debug, "%s:  login attempt for user %s failed.\n",
			     SRVR_NAME, ag_name));
		    return -OMI_ER_DB_USERNOAUTH;
	    }
    }
#endif  /* SCO or linux or cygwin or z/OS */


/*  Server name (in) */
    OMI_SI_READ(&ss_len,   cptr->xptr);
    cptr->xptr += ss_len.value;

/*  Implementation ID (out) */
    len = SIZEOF(GTM_RELEASE_NAME) - 1;
    OMI_SI_WRIT(len, bptr);
    (void) memcpy(bptr, GTM_RELEASE_NAME, len);
    bptr += len;
/*  Server name (out) */
    OMI_SI_WRIT(0, bptr);
/*  Server password (out) */
    OMI_SI_WRIT(0, bptr);

/*  Bounds checking */
    if (cptr->xptr > xend || bptr >= bend)
	return -OMI_ER_PR_INVMSGFMT;

/*  Extensions (in) -- count through them */
    OMI_SI_READ(&ext_cnt, cptr->xptr);
    for (i = 0; i < ext_cnt.value; i++)
    {
	OMI_LI_READ(&ext, cptr->xptr);
	cptr->exts |= (1 << (ext.value - 1));
    }

/*  Mask off extensions we don't support */
    cptr->exts &= OMI_EXTENSIONS;

/*  Negotiate extension combinations */
    if (cptr->exts & OMI_XTF_RC && cptr->exts & OMI_XTF_BUNCH)
	cptr->exts &= ~OMI_XTF_BUNCH;
#ifdef GTCM_RC
    if (cptr->exts & OMI_XTF_RC)
	cptr->of = rc_oflow_alc();
#endif /* defined(GTCM_RC) */

/*  Extensions (out) */
    eptr  = bptr;
    bptr += OMI_SI_SIZ;
    i     = 0;
    if (cptr->exts & OMI_XTF_BUNCH)
    {
	OMI_LI_WRIT(OMI_XTN_BUNCH, bptr);
	i++;
    }
    if (cptr->exts & OMI_XTF_GGR)
    {
	OMI_LI_WRIT(OMI_XTN_GGR, bptr);
	i++;
    }
    if (cptr->exts & OMI_XTF_NEWOP)
    {
	OMI_LI_WRIT(OMI_XTN_NEWOP, bptr);
	i++;
    }
    if (cptr->exts & OMI_XTF_RC)
    {
	OMI_LI_WRIT(OMI_XTN_RC, bptr);
	i++;
    }
/*  Number of extensions */
    OMI_SI_WRIT(i, eptr);

/*  Bounds checking */
    if (cptr->xptr > xend || bptr >= bend)
	return -OMI_ER_PR_INVMSGFMT;

/*  Change the state of the connection */
    cptr->state = OMI_ST_CONN;

    return (int)(bptr - buff);

}
Пример #4
0
void gtcm_pktdmp(char *ptr, int length, char *msg)
{

	char *end;
	char *chr;
	int buf[5];
	int len;
	int j;
	int offset = 0;
	static int fileID = 0;
	char tbuf[16];
	char fileName[256];
	time_t ctim;
	struct tm *ltime;
	FILE *fp;
	char *gtm_dist;

	ctim = time(0);
	GTM_LOCALTIME(ltime, &ctim);
	SPRINTF(tbuf, "%02d%02d%02d%02d",ltime->tm_mon + 1,ltime->tm_mday,
		ltime->tm_hour,ltime->tm_min);

	if (gtm_dist=getenv("gtm_dist"))
	{
	    	char subdir[256];
		struct stat buf;

		/* check for the subdirectory $gtm_dist/log/<omi_service>
		 * If the subdirectory exists, place the log file there.
		 * Otherwise...place the file in $gtm_dist/log.
		 */
		SPRINTF(subdir,"%s/log/%s", gtm_dist, omi_service);
		if (stat(subdir,&buf) == 0
		    && S_ISDIR(buf.st_mode))
		{
		    SPRINTF(fileName,"%s/%s_%s.%d", subdir, omi_service,
			tbuf, fileID++);
		}
		else
		{
		    SPRINTF(fileName,"%s/log/%s_%s.%d", gtm_dist, omi_service,
			    tbuf, fileID++);
		}
	}
	else
		SPRINTF(fileName,"/usr/tmp/%s_%s.%d", omi_service,
			tbuf, fileID++);

#ifdef __MVS__
	if (-1 == gtm_zos_create_tagged_file(fileName, TAG_EBCDIC))
	{
		FPRINTF(stderr,"Could not create and tag new packet dump file (%s).\n", fileName);
		perror(fileName);
	}
#endif
	fp = fopen(fileName, "w");
	if (fp == NULL)
	{
		FPRINTF(stderr,"Could not open packet dump file (%s).\n", fileName);
		perror(fileName);
		return;
	}

	OMI_DBG((omi_debug, "%s\n", msg));
	OMI_DBG((omi_debug, "Log dumped to %s.\n", fileName));

	FPRINTF(fp,"%s\n", msg);

	buf[4] = '\0';

	end = ptr + length;
	chr = (char *)buf;
	    while (ptr < end) {
		fputc('\t', fp);
		if ((len = (int)(end - ptr)) > 16)
		    len = 16;
		memcpy(chr, ptr, len);
		ptr += len;
		offset += len;
		for (j = len; j < 16; j++)
		    chr[j] = '\0';
		for (j = 0; j < 4; j++)
		    FPRINTF(fp,"%08x ", buf[j]);
		for (j = 0; j < 16; j++)
		    if (j >= len)
			chr[j] = ' ';
		    else if (chr[j] < 32 || chr[j] > 126)
			chr[j] = '.';
		FPRINTF(fp,"%16s %x\n", chr, offset);
	    }
	FFLUSH(fp);
	fclose(fp);
}
Пример #5
0
int gtcm_bgn_net(omi_conn_ll *cll)
{
	extern int4	omi_nxact, omi_nerrs, omi_brecv, omi_bsent;
	omi_fd		fd;
	int		i;
	int 		save_errno;
	int		rc;
#ifdef NET_TCP
	struct servent		*se;
	unsigned short		port;
	char			port_buffer[NI_MAXSERV];
#endif /* defined(NET_TCP) */
#ifdef BSD_TCP
	struct addrinfo		*ai_ptr, hints;
	const  boolean_t	reuseaddr = TRUE;
	int			errcode;
#else /* defined(BSD_TCP) */
#ifdef SYSV_TCP
	struct t_bind		*bind;
#endif /* defined(SYSV_TCP) */
#endif /* !defined(BSD_TCP) */

	/*  The linked list of connections */
	cll->head = cll->tail = (omi_conn *)0;
	/*  The statistics */
	cll->stats.conn = cll->stats.clos = cll->stats.disc = 0;
	cll->st_cn.bytes_recv = 0;
	cll->st_cn.bytes_send = 0;
	cll->st_cn.start      = 0;
	for (i = 0; i < OMI_OP_MAX; i++)
		cll->st_cn.xact[i] = 0;
	for (i = 0; i < OMI_ER_MAX; i++)
		cll->st_cn.errs[i] = 0;
	omi_nxact = omi_nerrs = omi_brecv = omi_bsent = 0;
	/*  Fall back on a compile time constant */
	if (!omi_service)
		omi_service = SRVC_NAME;
#ifdef NET_TCP
	/* NET_TCP is defined only when BSD_TCP is defined or SYSV_TCP is defined, but SYSV_TCP is never defined (a bug?)
	 * so we move the code of obtaining port information from service down to #ifdef BSD_TCP
	 */
#ifdef SYSV_TCP
	GTMASSERT;
#endif
#endif /* defined(NET_TCP) */
#ifdef BSD_TCP
	/*  Create a socket always tries IPv6 first */
	SERVER_HINTS(hints, ((GTM_IPV6_SUPPORTED && !ipv4_only) ? AF_INET6 : AF_INET));
	if ((fd = socket(hints.ai_family, SOCK_STREAM, 0)) < 0)
	{
		if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
		{
			save_errno = errno;
			return save_errno;
		}
		hints.ai_family = AF_INET;
	}
	/*  Bind an address to the socket */
	if (0 != (errcode = getaddrinfo(NULL, omi_service, &hints, &ai_ptr)))
	{
		RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode);
		return errcode;
	}
	if (ISDIGIT_ASCII(*omi_service))
		port = atoi(omi_service);
	else
	{
		if (0 != (errcode = getnameinfo(ai_ptr->ai_addr, ai_ptr->ai_addrlen, NULL, 0, port_buffer,
						 NI_MAXSERV, NI_NUMERICSERV)))
		{
			assert(FALSE);
			RTS_ERROR_ADDRINFO(NULL, ERR_GETNAMEINFO, errcode);
			return errcode;
		}
		port = atoi(port_buffer);
	}
	/*  Reuse a specified address */
	if (port && setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&reuseaddr, SIZEOF(reuseaddr)) < 0)
	{
		save_errno = errno;
		CLOSEFILE_RESET(fd, rc);	/* resets "fd" to FD_INVALID */
		return save_errno;
	}
	if (bind(fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen) < 0)
	{
		save_errno = errno;
		CLOSEFILE_RESET(fd, rc);	/* resets "fd" to FD_INVALID */
		return save_errno;
	}
	/*  Initialize the listen queue */
	if (listen(fd, 5) < 0)
	{
		save_errno = errno;
		CLOSEFILE_RESET(fd, rc);	/* resets "fd" to FD_INVALID */
		return save_errno;
	}
	/* set up raw socket for use with pinging option */
	if (ping_keepalive)
		psock = init_ping();
	/*  Store the file descriptor away for use later */
	cll->nve = fd;
	OMI_DBG_STMP;
	OMI_DBG((omi_debug, "%s: socket registered at port %d\n", SRVR_NAME, (int)port));
#ifdef GTCM_RC
	OMI_DBG((omi_debug, "RC server ID %d, Process ID %d\n", rc_server_id, omi_pid));
#endif
	if (authenticate)
		OMI_DBG((omi_debug, "Password verification on OMI connections enabled.\n"));
	if (!one_conn_per_inaddr)
		OMI_DBG((omi_debug, "Multiple connections from the same internet address allowed.\n"));
	if (psock > 0)
		OMI_DBG((omi_debug, "Keepalive option (-ping) enabled.\n"));
	return 0;
#else /* defined(BSD_TCP) */
#ifdef SYSV_TCP
	GTMASSERT;
	if ((fd = t_open(SYSV_TCP, O_RDWR, NULL)) < 0)
	{
		save_errno = errno;
		return save_errno;
	}
	if (!(bind = (struct t_bind *)t_alloc(fd, T_BIND, T_ALL)))
	{
		save_errno = errno;
		(void) t_close(fd);
		return save_errno;
	}
	bind->qlen      = 5;
	bind->addr.len  = 0;
	bind->addr.buf  = 0;
	if (t_bind(fd, bind, bind) < 0)
	{
		save_errno = errno;
		(void) t_free(bind, T_BIND);
		(void) t_close(fd);
		return save_errno;
	}
	/*  Store the file descriptor away for use later */
	cll->nve = fd;
	OMI_DBG_STMP;
	OMI_DBG((omi_debug, "%s: socket registered at port %d\n", SRVR_NAME, (int)port));
#ifdef GTCM_RC
	OMI_DBG((omi_debug, "RC server ID %d\n", rc_server_id));
#endif
	return 0;
#else /* defined(SYSV_TCP) */
	cll->nve = FD_INVALID;
	return -1;
#endif /* !defined(SYSV_TCP) */
#endif /* !defined(BSD_TCP) */
}
Пример #6
0
int gtcm_cn_acpt(omi_conn_ll *cll, int now)		/* now --> current time in seconds */
{
	int		i;
	omi_conn	*cptr;
	omi_fd		fd;
	int		rc;
	char 		*tmp_time;

#ifdef BSD_TCP
	GTM_SOCKLEN_TYPE	sln;
	struct sockaddr_storage	sas;
	int			optsize;
	const boolean_t		keepalive = TRUE;

	/*  Accept the connection from the network layer */
	sln = SIZEOF(sas);
	if ((fd = accept(cll->nve, (struct sockaddr *)&sas, (GTM_SOCKLEN_TYPE *)&sln)) < 0)
		return -1;
#endif				/* defined(BSD_TCP) */

	/*  Build the client data structure */
	if (!(cptr = (omi_conn *)malloc(SIZEOF(omi_conn))) || !(cptr->buff = (char *)malloc(OMI_BUFSIZ)))
	{
		if (cptr)
			free(cptr);
		CLOSEFILE_RESET(fd, rc);	/* resets "fd" to FD_INVALID */
		return -1;
	}
	/*  Initialize the connection structure */
	cptr->next  = (omi_conn *)0;
	cptr->fd    = fd;
	cptr->ping_cnt = 0;
	cptr->timeout = now + conn_timeout;
	cptr->bsiz  = OMI_BUFSIZ;
	cptr->bptr  = cptr->buff;
	cptr->xptr  = (char *)0;
	cptr->blen  = 0;
	cptr->exts  = 0;
	cptr->state = OMI_ST_DISC;
	cptr->ga    = (ga_struct *)0; /* struct gd_addr_struct */
	cptr->of = (oof_struct *) malloc(SIZEOF(struct rc_oflow));
	memset(cptr->of, 0, SIZEOF(struct rc_oflow));
	cptr->pklog = FD_INVALID;
	/*  Initialize the statistics */
	memcpy(&cptr->stats.sas, &sas, sln);
	cptr->stats.ai.ai_addr = (struct sockaddr *)&cptr->stats.sas;
	cptr->stats.ai.ai_addrlen = sln;
	cptr->stats.bytes_recv = 0;
	cptr->stats.bytes_send = 0;
	cptr->stats.start      = time((time_t *)0);
	for (i = 0; i < OMI_OP_MAX; i++)
		cptr->stats.xact[i] = 0;
	for (i = 0; i < OMI_ER_MAX; i++)
		cptr->stats.errs[i] = 0;

	/* if we only allowing one connection per internet address, close any existing ones with the same addr. */
	if (one_conn_per_inaddr)
	{
		omi_conn	*this, *prev;

		for (prev = NULL, this = cll->head; this; prev = this, this = this->next)
		{
			if (0 == memcmp((sockaddr_ptr)(&this->stats.sas), (sockaddr_ptr)&sas, sln))
			{
				if (cll->tail == this)
				    cll->tail = cptr;
				if (prev)
				    prev->next = cptr;
				else
				    cll->head = cptr;
				cptr->next = this->next;
				OMI_DBG_STMP;
				OMI_DBG((omi_debug, "%s: dropping old connection to %s\n",
					SRVR_NAME, gtcm_hname(&cptr->stats.ai)));
				gtcm_cn_disc(this, cll);
				break;
			}
		}
		/* not found - add to the end of the list */
		if (!this)
		{
			if (cll->tail)
			{
				cll->tail->next = cptr;
				cll->tail       = cptr;
			} else
				cll->head = cll->tail = cptr;
		}
	} else
	{
		/*  Insert the client into the list of connections */
		if (cll->tail)
		{
			cll->tail->next = cptr;
			cll->tail       = cptr;
		} else
			cll->head = cll->tail = cptr;
	}
	cptr->stats.id = ++cll->stats.conn;

	DEBUG_ONLY(
		if (omi_pklog)
		{
			int		errno_save;
			char		pklog[1024];

			(void)SPRINTF(pklog, "%s.%04d", omi_pklog, cptr->stats.id);
			if (INV_FD_P((cptr->pklog = OPEN3(pklog, O_WRONLY|O_CREAT|O_APPEND|O_TRUNC, 0644))))
			{
				errno_save = errno;
				OMI_DBG_STMP;
				OMI_DBG((omi_debug, "%s: unable to open packet log \"%s\"\n\t%s\n",
					SRVR_NAME, pklog, STRERROR(errno_save)));
			}
		}
	)
Пример #7
0
short rc_fnd_file(rc_xdsid *xdsid)
{
	gv_namehead	*g;
	short		dsid, node;
	gd_binding	*map;
	char		buff[1024], *cp, *cp1;
	mstr		fpath1, fpath2;
	mval		v;
	int		i, keysize;
	int             len, node2;

	GET_SHORT(dsid, &xdsid->dsid.value);
	GET_SHORT(node, &xdsid->node.value);
	if (!dsid_list)
	{
		/*	open special database, set up entry */
		dsid_list = (rc_dsid_list *)malloc(SIZEOF(rc_dsid_list));
		dsid_list->dsid = RC_NSPACE_DSID;
		dsid_list->next = NULL;
		fpath1.addr = RC_NSPACE_PATH;
		fpath1.len = SIZEOF(RC_NSPACE_PATH);
		if (SS_NORMAL != TRANS_LOG_NAME(&fpath1, &fpath2, buff, SIZEOF(buff), do_sendmsg_on_log2long))
		{
			char msg[256];
			SPRINTF(msg, "Invalid DB filename, \"%s\"", fpath1.addr);
			gtcm_rep_err(msg, errno);
			return RC_BADFILESPEC;
		}
		if (fpath2.len > MAX_FN_LEN)
			return RC_BADFILESPEC;
		dsid_list->fname = (char *)malloc(fpath2.len + 1);
		memcpy(dsid_list->fname, fpath2.addr, fpath2.len);
		*((char*)(dsid_list->fname + fpath2.len)) = 0;
		gv_cur_region = (gd_region *)malloc(SIZEOF(gd_region));
		memset(gv_cur_region, 0, SIZEOF(gd_region));
		gv_cur_region->dyn.addr = (gd_segment *)malloc(SIZEOF(gd_segment));
		memset(gv_cur_region->dyn.addr, 0, SIZEOF(gd_segment));
		memcpy(gv_cur_region->dyn.addr->fname, fpath2.addr, fpath2.len);
		gv_cur_region->dyn.addr->fname_len = fpath2.len;
		gv_cur_region->dyn.addr->acc_meth = dba_bg;
		ESTABLISH_RET(rc_fnd_file_ch1, RC_SUCCESS);
		gvcst_init(gv_cur_region);
		REVERT;
		change_reg();
		/* check to see if this DB has the reserved bytes field set
		 * correctly.  Global pages must always have some extra unused
		 * space left in them (RC_RESERVED bytes) so that the page
		 * will fit into the client buffer when unpacked by the
		 * client.
		 */
		if (cs_data->reserved_bytes < RC_RESERVED)
		{
			OMI_DBG((omi_debug,
			"Unable to access database file:  \"%s\"\nReserved_bytes field in the file header is too small for GT.CM\n",
			fpath2.addr));
			free(dsid_list->fname);
			dsid_list->fname = NULL;
			free(dsid_list);
			dsid_list = NULL;
			free(gv_cur_region->dyn.addr);
			gv_cur_region->dyn.addr = NULL;
			free(gv_cur_region);
			gv_cur_region = NULL;
			return RC_FILEACCESS;
		}
		gv_keysize = DBKEYSIZE(gv_cur_region->max_key_size);
		GVKEY_INIT(gv_currkey, gv_keysize);
		GVKEY_INIT(gv_altkey, gv_keysize);
		cs_addrs->dir_tree = (gv_namehead *)malloc(SIZEOF(gv_namehead) + 2 * SIZEOF(gv_key) + 3 * (gv_keysize - 1));
		g = cs_addrs->dir_tree;
		g->first_rec = (gv_key*)(g->clue.base + gv_keysize);
		g->last_rec = (gv_key*)(g->first_rec->base + gv_keysize);
		g->clue.top = g->last_rec->top = g->first_rec->top = gv_keysize;
		g->clue.prev = g->clue.end = 0;
		g->root = DIR_ROOT;
		dsid_list->gda = (gd_addr*)malloc(SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding));
		dsid_list->gda->n_maps = 3;
		dsid_list->gda->n_regions = 1;
		dsid_list->gda->n_segments = 1;
		dsid_list->gda->maps = (gd_binding*)((char*)dsid_list->gda + SIZEOF(gd_addr));
		dsid_list->gda->max_rec_size = gv_cur_region->max_rec_size;
		map = dsid_list->gda->maps;
		map ++;
		memset(map->name, 0, SIZEOF(map->name));
		map->name[0] = '%';
		map->reg.addr = gv_cur_region;
		map++;
		map->reg.addr = gv_cur_region;
		memset(map->name, -1, SIZEOF(map->name));
		dsid_list->gda->tab_ptr = (hash_table_mname *)malloc(SIZEOF(hash_table_mname));
		init_hashtab_mname(dsid_list->gda->tab_ptr, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE);
		change_reg();
		if (rc_overflow->top < cs_addrs->hdr->blk_size)
		{
			if (rc_overflow->buff)
				free(rc_overflow->buff);
			rc_overflow->top = cs_addrs->hdr->blk_size;
			rc_overflow->buff = (char*)malloc(rc_overflow->top);
			if (rc_overflow_size < rc_overflow->top)
				rc_overflow_size = rc_overflow->top;
		}
	}
	for (fdi_ptr = dsid_list; fdi_ptr && (fdi_ptr->dsid != dsid); fdi_ptr = fdi_ptr->next)
		;
	if (!fdi_ptr)
	{	/*	need to open new database, add to list, set fdi_ptr */
		gd_header = dsid_list->gda;
		gv_currkey->end = 0;
		v.mvtype = MV_STR;
		v.str.len = RC_NSPACE_GLOB_LEN-1;
		v.str.addr = RC_NSPACE_GLOB;
		GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &v.str);
		if (!gv_target->root)	/* No namespace global */
			return RC_UNDEFNAMSPC;
		v.mvtype = MV_STR;
		v.str.len = SIZEOF(RC_NSPACE_DSI_SUB)-1;
		v.str.addr = RC_NSPACE_DSI_SUB;
		mval2subsc(&v,gv_currkey);
		node2 = node;
		MV_FORCE_MVAL(&v,node2);
		mval2subsc(&v,gv_currkey);
		i = dsid / 256;
		MV_FORCE_MVAL(&v,i);
		mval2subsc(&v,gv_currkey);
		if (gvcst_get(&v))
			return RC_UNDEFNAMSPC;
		for (cp = v.str.addr, i = 1; i < RC_FILESPEC_PIECE; i++)
			for (; *cp++ != RC_FILESPEC_DELIM; )
				;
		for (cp1 = cp; *cp1++ != RC_FILESPEC_DELIM; )
			;
		cp1--;
		len = (int)(cp1 - cp);
		if (len > MAX_FN_LEN)
			return RC_BADFILESPEC;
		fdi_ptr = (rc_dsid_list *)malloc(SIZEOF(rc_dsid_list));
		fdi_ptr->fname = (char *)malloc(len+1);
		fdi_ptr->dsid = dsid;
		memcpy(fdi_ptr->fname, cp, len);
		*(fdi_ptr->fname + (len)) = 0;
		gv_cur_region = (gd_region *)malloc(SIZEOF(gd_region));
		memset(gv_cur_region, 0, SIZEOF(gd_region));
		gv_cur_region->dyn.addr = (gd_segment *)malloc(SIZEOF(gd_segment));
		memset(gv_cur_region->dyn.addr, 0, SIZEOF(gd_segment));
		memcpy(gv_cur_region->dyn.addr->fname, cp, len);
		gv_cur_region->dyn.addr->fname_len = len;
		gv_cur_region->dyn.addr->acc_meth = dba_bg;
		ESTABLISH_RET(rc_fnd_file_ch2, RC_SUCCESS);
		gvcst_init(gv_cur_region);
		REVERT;
		change_reg();
		/* check to see if this DB has the reserved bytes field set
		 * correctly.  Global pages must always have some extra unused
		 * space left in them (RC_RESERVED bytes) so that the page
		 * will fit into the client buffer when unpacked by the
		 * client.
		 */
		if (cs_data->reserved_bytes < RC_RESERVED)
		{
			OMI_DBG((omi_debug,
			"Unable to access database file:  \"%s\"\nReserved_bytes field in the file header is too small for GT.CM\n",
			fdi_ptr->fname));
			free(dsid_list->fname);
			dsid_list->fname = NULL;
			free(dsid_list);
			dsid_list = NULL;
			free(gv_cur_region->dyn.addr);
			gv_cur_region->dyn.addr = NULL;
			free(gv_cur_region);
			gv_cur_region = NULL;
			return RC_FILEACCESS;
		}
		assert(!cs_addrs->hold_onto_crit);	/* this ensures we can safely do unconditional grab_crit and rel_crit */
		grab_crit(gv_cur_region);
		cs_data->rc_srv_cnt++;
		if (!cs_data->dsid)
		{
			cs_data->dsid = dsid;
			cs_data->rc_node = node;
		} else if (cs_data->dsid != dsid || cs_data->rc_node != node)
		{
			cs_data->rc_srv_cnt--;
			rel_crit(gv_cur_region);
			OMI_DBG((omi_debug, "Dataset ID/RC node mismatch"));
			OMI_DBG((omi_debug, "DB file:  \"%s\"\n", dsid_list->fname));
			OMI_DBG((omi_debug, "Stored DSID:  %d\tRC Node:  %d\n", cs_data->dsid, cs_data->rc_node));
			OMI_DBG((omi_debug, "RC Rq DSID:  %d\tRC Node:  %d\n", dsid,node));
			free(fdi_ptr->fname);
			fdi_ptr->fname = NULL;
			free(fdi_ptr);
			fdi_ptr = NULL;
			free(gv_cur_region->dyn.addr);
			gv_cur_region->dyn.addr = NULL;
			free(gv_cur_region);
			gv_cur_region = NULL;
			return RC_FILEACCESS;
		}
		rel_crit(gv_cur_region);
		keysize = DBKEYSIZE(gv_cur_region->max_key_size);
		GVKEYSIZE_INCREASE_IF_NEEDED(keysize);
		cs_addrs->dir_tree = (gv_namehead *)malloc(SIZEOF(gv_namehead) + 2 * SIZEOF(gv_key) + 3 * (keysize - 1));
		g = cs_addrs->dir_tree;
		g->first_rec = (gv_key*)(g->clue.base + keysize);
		g->last_rec = (gv_key*)(g->first_rec->base + keysize);
		g->clue.top = g->last_rec->top = g->first_rec->top = keysize;
		g->clue.prev = g->clue.end = 0;
		g->root = DIR_ROOT;
		fdi_ptr->gda = (gd_addr*)malloc(SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding));
		fdi_ptr->gda->n_maps = 3;
		fdi_ptr->gda->n_regions = 1;
		fdi_ptr->gda->n_segments = 1;
		fdi_ptr->gda->maps = (gd_binding*)((char*)fdi_ptr->gda + SIZEOF(gd_addr));
		fdi_ptr->gda->max_rec_size = gv_cur_region->max_rec_size;
		map = fdi_ptr->gda->maps;
		map ++;
		memset(map->name, 0, SIZEOF(map->name));
		map->name[0] = '%';
		map->reg.addr = gv_cur_region;
		map++;
		map->reg.addr = gv_cur_region;
		memset(map->name, -1, SIZEOF(map->name));
		fdi_ptr->gda->tab_ptr = (hash_table_mname *)malloc(SIZEOF(hash_table_mname));
		init_hashtab_mname(fdi_ptr->gda->tab_ptr, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE);
		fdi_ptr->next = dsid_list->next;
		dsid_list->next = fdi_ptr;
	}
	gv_cur_region = fdi_ptr->gda->maps[1].reg.addr;
	change_reg();
	if (rc_overflow->top < cs_addrs->hdr->blk_size)
	{
		if (rc_overflow->buff)
			free(rc_overflow->buff);
		rc_overflow->top = cs_addrs->hdr->blk_size;
		rc_overflow->buff = (char*)malloc(rc_overflow->top);
		if (rc_overflow_size < rc_overflow->top)
			rc_overflow_size = rc_overflow->top;
	}
	if (!rc_overflow -> top)
	{
		rc_overflow -> top = rc_overflow_size;
		rc_overflow->buff = (char *)malloc(rc_overflow->top);
	}
	gd_header = fdi_ptr->gda;
	return RC_SUCCESS;
}