Esempio n. 1
0
void mupip_cvtgbl(void)
{
	unsigned short	fn_len, len;
	char		fn[256];
	unsigned char	buff[7];
	uint4		begin, end;
	int		i, format;
	uint4	        cli_status;
	gtm_int64_t	begin_i8, end_i8;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	/* If an online rollback occurs when we are loading up the database with new globals and takes us back to a prior logical
	 * state, then we should not continue with the load. The reason being that the application might rely on certain globals to
	 * be present before loading others and that property could be voilated if online rollback takes the database back to a
	 * completely different logical state. Set the variable issue_DBROLLEDBACK_anyways that forces the restart logic to issue
	 * an rts_error the first time it detects an online rollback (that takes the database to a prior logical state).
	 */
	TREF(issue_DBROLLEDBACK_anyways) = TRUE;
	is_replicator = TRUE;
	skip_dbtriggers = TRUE;
	fn_len = SIZEOF(fn);
	if (cli_present("STDIN"))
	{
		/* User wants to load from standard input */
		assert(SIZEOF(fn) > sys_input.len);
		memcpy(fn, sys_input.addr, sys_input.len);
		fn_len = sys_input.len;
		assert(-1 != fcntl(fileno(stdin), F_GETFD));
		/* Check if both file name and -STDIN specified. */
		if (cli_get_str("FILE", fn, &fn_len))
			mupip_exit(ERR_MUPCLIERR);
	} else if (!cli_get_str("FILE", fn, &fn_len))  /* User wants to read from a file. */
		mupip_exit(ERR_MUPCLIERR); /* Neither -STDIN nor file name specified. */
	if (mupip_error_occurred)
		exit(-1);
	file_input_init(fn, fn_len);
	mu_outofband_setup();
	if ((cli_status = cli_present("BEGIN")) == CLI_PRESENT)
	{
	        if (!cli_get_int64("BEGIN", &begin_i8))
			mupip_exit(ERR_MUPCLIERR);
		if (1 > begin_i8)
			mupip_exit(ERR_LOADBGSZ);
		else if (MAXUINT4 < begin_i8)
			mupip_exit(ERR_LOADBGSZ2);
		begin = (uint4) begin_i8;
	} else
	{
		begin = 1;
		begin_i8 = 1;
	}
	if ((cli_status = cli_present("END")) == CLI_PRESENT)
	{
	        if (!cli_get_int64("END", &end_i8))
			mupip_exit(ERR_MUPCLIERR);
		if (1 > end_i8)
			mupip_exit(ERR_LOADEDSZ);
		else if (MAXUINT4 < end_i8)
			mupip_exit(ERR_LOADEDSZ2);
		if (end_i8 < begin_i8)
			mupip_exit(ERR_LOADEDBG);
		end = (uint4) end_i8;
	} else
		end = MAXUINT4;
	if ((cli_status = cli_present("FILL_FACTOR")) == CLI_PRESENT)
	{
		assert(SIZEOF(gv_fillfactor) == SIZEOF(int4));
	        if (!cli_get_int("FILL_FACTOR", (int4 *)&gv_fillfactor))
			gv_fillfactor = MAX_FILLFACTOR;
		if (gv_fillfactor < MIN_FILLFACTOR)
			gv_fillfactor = MIN_FILLFACTOR;
		else if (gv_fillfactor > MAX_FILLFACTOR)
			gv_fillfactor = MAX_FILLFACTOR;
	} else
		gv_fillfactor = MAX_FILLFACTOR;

	if (cli_present("FORMAT") == CLI_PRESENT)
	{
	        len = SIZEOF("FORMAT");
		if (!cli_get_str("FORMAT", (char *)buff, &len))
			go_load(begin, end);
		else
		{
		        lower_to_upper(buff, buff, len);
			if (!memcmp(buff, "ZWR", len))
				go_load(begin, end);
			else if (!memcmp(buff, "BINARY", len))
				bin_load(begin, end);
			else if (!memcmp(buff, "GO", len))
				go_load(begin, end);
			else if (!memcmp(buff, "GOQ", len))
				goq_load();
			else
			{
			        util_out_print("Illegal format for load",TRUE);
				mupip_exit(ERR_MUPCLIERR);
			}
		}
	} else
		go_load(begin, end);

	if (mupip_error_occurred)
	{
	        util_out_print("Error occurred during loading",TRUE);
		exit(-1);
	}
	else
		mupip_exit(SS_NORMAL);
}
Esempio n. 2
0
int4* find_line_addr (rhdtyp *routine, mstr *label, int4 offset, mident **lent_name)
{
 	lab_tabent	*base, *top, *ptr;
	rhdtyp		*real_routine;
	mident_fixed	target_label;
	mident		lname;
	lnr_tabent	*line_table, *first_line;
	int		stat, n;
	error_def(ERR_LABELONLY);

	if (!routine)
		return NULL;
	real_routine = CURRENT_RHEAD_ADR(routine);
	first_line = LNRTAB_ADR(real_routine);

	if (!label->len  ||  !*label->addr)
	{ /* No label specified. Return the first line */
		base = LABTAB_ADR(real_routine);
		assert(0 == base->lab_name.len);
		if (lent_name)
			*lent_name = &base->lab_name;
		line_table = first_line;
	}
	else
	{
		lname.len = (label->len <= MAX_MIDENT_LEN) ? label->len : MAX_MIDENT_LEN;
		if (cmd_qlf.qlf & CQ_LOWER_LABELS)
			lname.addr = label->addr;
		else
		{
			lower_to_upper((uchar_ptr_t)&target_label.c[0], (uchar_ptr_t)label->addr, lname.len);
			lname.addr = &target_label.c[0];
		}

		ptr = base = LABTAB_ADR(real_routine);
		top = base + real_routine->labtab_len;
		for (  ;  ;  )
		{
			n = (int)(top - base) / 2;
			ptr = base + n;
			MIDENT_CMP(&lname, &ptr->lab_name, stat);
			if (0 == stat)
			{
				if (lent_name)
					*lent_name = &ptr->lab_name;
				line_table = LABENT_LNR_ENTRY(real_routine, ptr);
				break;
			}
			else if (stat > 0)
				base = ptr;
			else
				top = ptr;

			if (n < 1)
				return NULL;
		}
	}

	line_table += offset;
	if (line_table < first_line  ||  line_table >= first_line + real_routine->lnrtab_len)
		return NULL;

	return line_table;
}
Esempio n. 3
0
void	op_fnzparse (mval *file, mval *field, mval *def1, mval *def2, mval *type, mval *ret)
{
	char 		field_type;
	uint4 		status;
	char 		field_buf[DIR_LEN], type_buf[SYN_LEN], result[MAX_FBUFF + 1];
	parse_blk	pblk;

	error_def(ERR_ZPARSETYPE);
	error_def(ERR_ZPARSFLDBAD);
	error_def(ERR_INVSTRLEN);

	MV_FORCE_STR(field);
	MV_FORCE_STR(def1);
	MV_FORCE_STR(def2);
	MV_FORCE_STR(file);
	MV_FORCE_STR(type);

	if (def1->str.len > MAX_FBUFF)
		rts_error(VARLSTCNT(4) ERR_INVSTRLEN, 2, def1->str.len, MAX_FBUFF);
	if (def2->str.len > MAX_FBUFF)
		rts_error(VARLSTCNT(4) ERR_INVSTRLEN, 2, def2->str.len, MAX_FBUFF);

	if (field->str.len == 0)
	{
		field_type = ZP_FULL;
	}
	else
	{
		field_type = 0;
		if (field->str.len <= DIR_LEN)
		{
			lower_to_upper((uchar_ptr_t)&field_buf[0], (uchar_ptr_t)field->str.addr, field->str.len);
			switch( field_buf[0] )
			{
			case 'D':
				if (field->str.len <= DEV_LEN  &&  memcmp(&field_buf[0], "DEVICE", field->str.len) == 0)
					field_type = ZP_DEVICE;
				else if (field->str.len <= DIR_LEN  &&  memcmp(&field_buf[0], "DIRECTORY", field->str.len) == 0)
					field_type = ZP_DIRECTORY;
				break;

			case 'N':
				if (field->str.len <= ZP_LEN)
				{
					if (memcmp(&field_buf[0], "NAME", field->str.len) == 0)
						field_type = ZP_NAME;
					else if (memcmp(&field_buf[0], "NODE", field->str.len) == 0)
						field_type = ZP_NODE;
				}
				break;

			case 'T':
				if (field->str.len <= ZP_LEN  &&  memcmp(&field_buf[0], "TYPE", field->str.len) == 0)
					field_type = ZP_TYPE;
				break;

			case 'V':
				if (field->str.len <= VER_LEN  &&  memcmp(&field_buf[0], "VERSION", field->str.len) == 0)
					field_type = ZP_VERSION;
				break;

			default:
				break;

			}
		}
		if (field_type == 0)
			rts_error(VARLSTCNT(4) ERR_ZPARSFLDBAD, 2, field->str.len, field->str.addr);
	}

	memset(&pblk, 0, sizeof(pblk));

	if (type->str.len != 0)
	{
		if (type->str.len <= SYN_LEN)
			lower_to_upper((uchar_ptr_t)&type_buf[0], (uchar_ptr_t)type->str.addr, type->str.len);

		if (type->str.len <= SYN_LEN  &&  memcmp(&type_buf[0], "SYNTAX_ONLY", type->str.len) == 0)
			pblk.fop |= F_SYNTAXO;
		else if (type->str.len <= NCON_LEN  &&  memcmp(&type_buf[0], "NO_CONCEAL", type->str.len) == 0)
		{
			/* no meaning on unix */
		}
		else
			rts_error(VARLSTCNT(4) ERR_ZPARSETYPE, 2, type->str.len, type->str.addr);
	}

	pblk.buffer = result;
	pblk.buff_size = MAX_FBUFF;
	pblk.def1_size = def1->str.len;
	pblk.def1_buf = def1->str.addr;
	pblk.def2_size = def2->str.len;
	pblk.def2_buf = def2->str.addr;

	if ((parse_file(&file->str, &pblk) & 1) == 0)
	{
		ret->mvtype = MV_STR;
		ret->str.len = 0;
		return;
	}

	ret->mvtype = MV_STR;
	switch( field_type )
	{
	case ZP_DIRECTORY:
		ret->str.addr = pblk.l_dir;
		ret->str.len = pblk.b_dir;
		break;

	case ZP_NAME:
		ret->str.addr = pblk.l_name;
		ret->str.len = pblk.b_name;
		break;

	case ZP_TYPE:
		ret->str.addr = pblk.l_ext;
		ret->str.len = pblk.b_ext;
		break;

	default:
		ret->str.addr = pblk.buffer;
		ret->str.len = pblk.b_esl;
		break;

	}
	s2pool(&ret->str);
	return;
}
Esempio n. 4
0
void op_fngetjpi(mint jpid, mval *kwd, mval *ret)
{
	error_def	(ERR_BADJPIPARAM);
	struct tms	proc_times;
	int4		info ;
	int		keywd_indx;
	char		upcase[MAX_KEY_LEN];

	assert (stringpool.free >= stringpool.base);
	assert (stringpool.top >= stringpool.free);
	if (stringpool.top - stringpool.free < MAX_STR)
		stp_gcol(MAX_STR);

	MV_FORCE_STR(kwd);
	if (kwd->str.len == 0)
		rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, 4, "Null");

	if (MAX_KEY < kwd->str.len)
		rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, kwd->str.len, kwd->str.addr);

	lower_to_upper((uchar_ptr_t)upcase, (uchar_ptr_t)kwd->str.addr, (int)kwd->str.len);

	keywd_indx = kw_cputim ;
	/* future enhancement:
	 * 	(i) since keywords are sorted, we can exit the while loop if 0 < memcmp.
	 * 	(ii) also, the current comparison relies on kwd->str.len which means a C would imply CPUTIM instead of CSTIME
	 * 		or CUTIME this ambiguity should probably be removed by asking for an exact match of the full keyword
	 */
	while ((0 != memcmp(upcase, key[keywd_indx], kwd->str.len)) && keywd_indx < MAX_KEY)
		keywd_indx++;

	if( keywd_indx == MAX_KEY )
        {
                 rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, kwd->str.len, kwd->str.addr);
        }

	if ((kw_isprocalive != keywd_indx) && ((unsigned int)-1 == times(&proc_times)))
	{
		rts_error(VARLSTCNT(1) errno);	/* need a more specific GTM error message in addition to errno */
		return;
	}
	switch (keywd_indx)
	{
		case kw_cputim:
			info = proc_times.tms_utime + proc_times.tms_stime + proc_times.tms_cutime + proc_times.tms_cstime;
			break;
		case kw_cstime:
			info = proc_times.tms_cstime;
			break;
		case kw_cutime:
			info = proc_times.tms_cutime;
			break;
		case kw_isprocalive:
			info = (0 != jpid) ? is_proc_alive(jpid, 0) : 1;
			break;
		case kw_stime:
			info = proc_times.tms_stime;
			break;
		case kw_utime:
			info = proc_times.tms_utime;
			break;
		case kw_end:
		default:
			rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, kwd->str.len, kwd->str.addr);
			return;
	}
	if (kw_isprocalive != keywd_indx)
		info = (int4)((info * 100) / sysconf(_SC_CLK_TCK));	/* Convert to standard 100 ticks per second */
	i2mval(ret, info);
}
socket_struct *iosocket_create(char *sockaddr, uint4 bfsize, int file_des, boolean_t listen_specified)
{
	socket_struct		*socketptr;
	socket_struct		*prev_socketptr;
	socket_struct		*socklist_head;
	boolean_t		passive = FALSE;
	unsigned short		port;
	int			ii, save_errno, tmplen, errlen, sockaddrlen;
	char 			temp_addr[SA_MAXLITLEN], protocolstr[6], *adptr;
	const char		*errptr;
	struct addrinfo		*ai_ptr;
	struct addrinfo		hints, *addr_info_ptr = NULL;
#ifndef VMS
	struct sockaddr_un	*sa_un_ptr, sa_un_trans;
	mval			localpath;
	mstr			transpath;
	int			trans_status;
#endif
	enum socket_protocol	protocol;
	int			af;
	int			sd;
	int			errcode;
	char			host_buffer[NI_MAXHOST];
	char			port_buffer[NI_MAXSERV];
	int			port_buffer_len;
	int			colon_cnt, protooffset;
	char			*last_2colon = NULL;
	int			addrlen;
	GTM_SOCKLEN_TYPE	tmp_addrlen;

	if (0 > file_des)
	{	/* no socket descriptor yet */
		memset(&hints, 0, SIZEOF(hints));

		protooffset = colon_cnt = 0;
		sockaddrlen = STRLEN(sockaddr);
		for (ii = sockaddrlen - 1; 0 <= ii; ii--)
		{
			if (SEPARATOR == sockaddr[ii])
			{
				colon_cnt++;
				if (1 == colon_cnt)
					protooffset = ii + 1;
				else
				{
					last_2colon = &sockaddr[ii];
					break;
				}
			}
		}
		if (0 == colon_cnt)
		{
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVPORTSPEC);
			return NULL;
		}
		tmplen = sockaddrlen - protooffset;
		if (SIZEOF(protocolstr) <= tmplen)
		{	/* last piece just too big to be valid */
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_PROTNOTSUP, 2, tmplen , &sockaddr[protooffset]);
			return NULL;
		}
		lower_to_upper((uchar_ptr_t)protocolstr, (uchar_ptr_t)&sockaddr[protooffset], tmplen);
		if (((SIZEOF("TCP") - 1) == tmplen) && (0 == MEMCMP_LIT(protocolstr, "TCP")))
			protocol = socket_tcpip;
#		ifndef VMS
		else if (((SIZEOF("LOCAL") - 1) == tmplen) && (0 == MEMCMP_LIT(protocolstr, "LOCAL")))
			protocol = socket_local;
#		endif
		else
		{
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_PROTNOTSUP, 2, tmplen , &sockaddr[protooffset]);
			return NULL;
		}
		if (socket_tcpip == protocol)
		{
			if (1 == colon_cnt)
			{	/* for listening socket or broadcasting socket */
				if (!listen_specified || (SSCANF(sockaddr, PORT_PROTO_FORMAT, &port, protocolstr) < 2))
				{
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVPORTSPEC);
					return NULL;
				}
				passive = TRUE;
				/* We always first try using IPv6 address, if supported */
				af = ((GTM_IPV6_SUPPORTED && !ipv4_only) ? AF_INET6 : AF_INET);
				if (-1 == (sd = socket(af, SOCK_STREAM, IPPROTO_TCP)))
				{
					/* Try creating IPv4 socket */
					af = AF_INET;
					if (-1 == (sd = socket(af, SOCK_STREAM, IPPROTO_TCP)))
					{
						save_errno = errno;
						errptr = (char *)STRERROR(save_errno);
						errlen = STRLEN(errptr);
						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, save_errno,
							errlen, errptr);
						return NULL;
					}
				}
				SERVER_HINTS(hints, af);
				port_buffer_len = 0;
				I2A(port_buffer, port_buffer_len, port);
				port_buffer[port_buffer_len]='\0';
				if (0 != (errcode = getaddrinfo(NULL, port_buffer, &hints, &addr_info_ptr)))
				{
					close(sd);
					RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode);
					return NULL;
				}
				SOCKET_ALLOC(socketptr);
				socketptr->local.port = port;
				socketptr->temp_sd = sd;
				socketptr->sd = FD_INVALID;
				ai_ptr = &(socketptr->local.ai);
				memcpy(ai_ptr, addr_info_ptr, SIZEOF(struct addrinfo));
				SOCKET_AI_TO_LOCAL_ADDR(socketptr, addr_info_ptr);
				ai_ptr->ai_addr = SOCKET_LOCAL_ADDR(socketptr);
				ai_ptr->ai_addrlen = addr_info_ptr->ai_addrlen;
				ai_ptr->ai_next = NULL;
				freeaddrinfo(addr_info_ptr);
			} else
			{	/* connection socket */
				assert(2 == colon_cnt);
				if (listen_specified || (SSCANF(last_2colon + 1, PORT_PROTO_FORMAT, &port, protocolstr) < 2))
				{
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVADDRSPEC);
					return NULL;
				}
				/* for connection socket */
				SPRINTF(port_buffer, "%hu", port);
				addrlen = last_2colon - sockaddr;
				if ('[' == sockaddr[0])
				{
					if (NULL == memchr(sockaddr, ']', addrlen))
					{
						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVADDRSPEC);
						return NULL;
					}
					addrlen -= 2;
					memcpy(temp_addr, &sockaddr[1], addrlen);
				} else
					memcpy(temp_addr, sockaddr, addrlen);
				temp_addr[addrlen] = 0;
				CLIENT_HINTS(hints);
				if (0 != (errcode = getaddrinfo(temp_addr, port_buffer, &hints, &addr_info_ptr)))
				{
					RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode);
					return NULL;
				}
				/*  we will test all address families in iosocket_connect() */
				SOCKET_ALLOC(socketptr);
				socketptr->remote.ai_head = addr_info_ptr;
				socketptr->remote.port = port;
				socketptr->sd = socketptr->temp_sd = FD_INVALID; /* don't mess with 0 */
			}
#		ifndef VMS
		} else if (socket_local == protocol)
		{	/* should we get_full_path first */
			/* check protooffset < sizeof sun_path */
			/* protooffset is after colon */
			SOCKET_ALLOC(socketptr);
			socketptr->protocol = socket_local;
			sa_un_ptr = malloc(SIZEOF(struct sockaddr_un));
			sa_un_ptr->sun_family = AF_UNIX;
			MV_INIT_STRING(&localpath, protooffset - 1, sockaddr);
			trans_status = TRANS_LOG_NAME(&localpath.str, &transpath, sa_un_trans.sun_path,
				(int)SIZEOF(sa_un_trans.sun_path), dont_sendmsg_on_log2long);
			if (SS_LOG2LONG == trans_status)
			{	/* if LOG2LONG, returned len not valid so report untranslated length */
				SOCKET_FREE(socketptr);
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_ADDRTOOLONG, 4, localpath.str.len, localpath.str.addr,
					localpath.str.len, SIZEOF(sa_un_trans.sun_path));
				return NULL;
			}
			memcpy(sa_un_ptr->sun_path, transpath.addr, transpath.len);
			sa_un_ptr->sun_path[transpath.len] = '\0';
			if (listen_specified)
			{
				passive = TRUE;
				socketptr->local.sa = (struct sockaddr *)sa_un_ptr;
				socketptr->local.ai.ai_family = AF_UNIX;
				socketptr->local.ai.ai_socktype = SOCK_STREAM;
				socketptr->local.ai.ai_addrlen = (size_t)((struct sockaddr_un *)0)->sun_path + protooffset;
				if (-1 == (sd = socket(AF_UNIX, SOCK_STREAM, 0)))
				{
					save_errno = errno;
					SOCKET_FREE(socketptr);
					errptr = (char *)STRERROR(save_errno);
					errlen = STRLEN(errptr);
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, save_errno, errlen, errptr);
					return NULL;
				}
				socketptr->temp_sd = sd;
				socketptr->sd = FD_INVALID;
			} else
			{
				socketptr->remote.sa = (struct sockaddr *)sa_un_ptr;
				/* setup remote fields */
				socketptr->remote.ai.ai_family = AF_UNIX;
				socketptr->remote.ai.ai_socktype = SOCK_STREAM;
				socketptr->remote.ai.ai_addrlen = (size_t)((struct sockaddr_un *)0)->sun_path + protooffset;
				socketptr->sd = socketptr->temp_sd = FD_INVALID; /* don't mess with 0 */
			}
#		endif
		} else
Esempio n. 6
0
bool mubgetfil(backup_reg_list *list, char *name, unsigned short len)
{
	struct stat	stat_buf;
	int		stat_res;
	char		temp;
	char 		tcp[5];

	if (0 == len)
		return FALSE;
	if (list != mu_repl_inst_reg_list)
	{	/* Do the following checks only if this region does NOT correspond to the replication instance region. */
		if ('|' == *name)
		{
			len -= 1;
			list->backup_to = backup_to_exec;
			list->backup_file.len = len;
			list->backup_file.addr = (char *)malloc(len + 1);
			memcpy(list->backup_file.addr, name + 1, len);
			return TRUE;
		}
		if (len > 5)
		{
			lower_to_upper((uchar_ptr_t)tcp, (uchar_ptr_t)name, 5);
			if (0 == memcmp(tcp, "TCP:/", 5))
			{
				list->backup_to = backup_to_tcp;
				len -= 5;
				name += 5;
				while ('/' == *name)
				{
					len--;
					name++;
				}
				list->backup_file.len = len;
				list->backup_file.addr = (char *)malloc(len + 1);
				memcpy(list->backup_file.addr, name, len);
				*(list->backup_file.addr + len) = 0;
				return TRUE;
			}
		}
	}
	temp = name[len];
	name[len] = 0;
	STAT_FILE(name, &stat_buf, stat_res);
	if (-1 == stat_res)
	{
		if (errno != ENOENT)
		{
			util_out_print("Error accessing backup output file or directory: !AD", TRUE, len, name);
			mupip_exit(errno);
		} else
		{	/* new file */
			list->backup_file.len = len;
			list->backup_file.addr = (char *)malloc(len + 1);
			memcpy(list->backup_file.addr, name, len);
			*(list->backup_file.addr + len) = 0;
		}
	} else if (S_ISDIR(stat_buf.st_mode))
	{
		if (!is_directory)
		{
			is_directory = TRUE;
			directory.len = len;
			directory.addr = (char *)malloc(len + 1);
			memcpy(directory.addr, name, len);
			*(directory.addr + len) = 0;
		}
		mubexpfilnam(name, len, list);
	} else
	{	/* the file already exists */
		util_out_print("File !AD already exists.", TRUE, len, name);
		error_mupip = TRUE;
		return FALSE;
	}
	name[len] = temp;
	return TRUE;
}
Esempio n. 7
0
void op_fnztrnlnm(mval *name,mval *table,int4 ind,mval *mode,mval *case_blind,mval *item,mval *ret)
{
	struct dsc$descriptor	lname, ltable;
	uint4		attribute, status, retlen, mask, full_mask;
	char			acmode;
	short int		*item_code, pass, index;
	bool			full;
	char			buff[256], result[MAX_RESULT_SIZE];
	char			i, slot, last_slot;
	char			def_table[] = "LNM$DCL_LOGICAL";

	struct
	{
		item_list_3	item[3];
		int4		terminator;
	} item_list;
	error_def(ERR_BADTRNPARAM);

	if(!name->str.len || MAX_LOGNAM_LENGTH < name->str.len || MAX_LOGNAM_LENGTH < table->str.len)
		rts_error(VARLSTCNT(1) SS$_IVLOGNAM);
	memset(&item_list,0,SIZEOF(item_list));
	item_list.item[0].item_code = 0;
	item_list.item[0].buffer_address = result;
	item_list.item[0].buffer_length = MAX_RESULT_SIZE;
	item_list.item[0].return_length_address = &retlen;
	item_code = &item_list.item[0].item_code;

	lname.dsc$w_length = name->str.len;
	lname.dsc$a_pointer = name->str.addr;
	lname.dsc$b_dtype = DSC$K_DTYPE_T;
	lname.dsc$b_class = DSC$K_CLASS_S;

	if (table->str.len)
	{	ltable.dsc$w_length = table->str.len;
		ltable.dsc$a_pointer = table->str.addr;
	}else
	{	ltable.dsc$a_pointer = def_table;
		ltable.dsc$w_length = strlen(def_table);
	}
	ltable.dsc$b_dtype = DSC$K_DTYPE_T;
	ltable.dsc$b_class = DSC$K_CLASS_S;

	if(ind)
	{	item_list.item[0].item_code = LNM$_INDEX;
		item_list.item[0].buffer_address = &ind;
		item_list.item[1].item_code = 0;
		item_list.item[1].buffer_address = result;
		item_list.item[1].buffer_length = MAX_RESULT_SIZE;
		item_list.item[1].return_length_address = &retlen;
		item_code = &item_list.item[1].item_code;
	}

	attribute = LNM$M_CASE_BLIND;
	if (case_blind->str.len)
	{
		if (case_blind->str.len > 14)
			rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2,
				MIN(SHRT_MAX, case_blind->str.len), case_blind->str.addr);
		lower_to_upper(buff,case_blind->str.addr,case_blind->str.len);
		if (case_blind->str.len == 14 && !memcmp(buff,"CASE_SENSITIVE",14))
			attribute = 0;
		else if (case_blind->str.len != 10 || memcmp(buff,"CASE_BLIND",10))
			rts_error(VARLSTCNT(4) ERR_BADTRNPARAM,2,case_blind->str.len,case_blind->str.addr);
	}

	acmode = NOVALUE;
	if (mode->str.len)
	{
		if (mode->str.len > 14)
			rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2,
				MIN(SHRT_MAX, mode->str.len), mode->str.addr);
		lower_to_upper(buff,mode->str.addr,mode->str.len);
		switch (buff[0])
		{
		case 'U':
			if ( mode->str.len = 4 && !memcmp(buff, "USER", 4))
				acmode = PSL$C_USER;
		case 'S':
			if ( mode->str.len = 10 && !memcmp(buff, "SUPERVISOR", 10))
				acmode = PSL$C_SUPER;
		case 'K':
			if ( mode->str.len = 6 && !memcmp(buff, "KERNEL", 6))
				acmode = PSL$C_KERNEL;
		case 'E':
			if ( mode->str.len = 9 && !memcmp(buff, "EXECUTIVE", 9))
				acmode = PSL$C_EXEC;
		}
		if (acmode == NOVALUE)
			rts_error(VARLSTCNT(4) ERR_BADTRNPARAM,2,mode->str.len,mode->str.addr);
	}

	full = FALSE;
	*item_code = NOVALUE;
	if (item->str.len)
	{	if (item->str.len > 12)
			rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2,
				MIN(SHRT_MAX, item->str.len), item->str.addr);
		lower_to_upper(buff,item->str.addr,item->str.len);
		if ((i = buff[0] - 'A') < MIN_INDEX || i > MAX_INDEX)
		{	rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2, item->str.len, item->str.addr);
		}
		if ( trnlnm_index[i].len)
		{	slot = trnlnm_index[i].index;
			last_slot = trnlnm_index[i].len;
			for (; slot < last_slot; slot++)
			{	if (item->str.len == trnlnm_table[slot].len &&
					!memcmp(trnlnm_table[slot].name, buff, item->str.len))
				{	if (trnlnm_table[slot].item_code == FULL_VALUE)
					{	if (ind)
							index = 2;
						else
							index = 1;
						*item_code = LNM$_STRING;
						item_list.item[index].buffer_address = &full_mask;
						item_list.item[index].buffer_length = SIZEOF(full_mask);
						item_list.item[index].item_code = LNM$_ATTRIBUTES;
						item_code = &item_list.item[index].item_code;
						full = TRUE;
					}else
					{	*item_code = trnlnm_table[slot].item_code;
					}
					break;
				}
			}
		}
		if (*item_code == NOVALUE)
		{	rts_error(VARLSTCNT(4) ERR_BADTRNPARAM,2,item->str.len,item->str.addr);
		}
	}else
	{	*item_code = LNM$_STRING;
	}
	for ( pass = 0 ; ; pass++ )
	{	retlen = 0;
		status = sys$trnlnm(&attribute, &ltable, &lname, acmode == NOVALUE ? 0 : &acmode, &item_list);
		if (status & 1)
		{	if (*item_code == LNM$_STRING || *item_code == LNM$_TABLE)
			{	ret->mvtype = MV_STR;
				ENSURE_STP_FREE_SPACE(retlen);
				ret->str.addr = stringpool.free;
				ret->str.len = retlen;
				memcpy(ret->str.addr, result, retlen);
				stringpool.free += retlen;
				return;
			}else if (*item_code == LNM$_LENGTH || *item_code == LNM$_MAX_INDEX)
			{
				MV_FORCE_MVAL(ret,*(int4 *)result) ;
				n2s(ret);
				return;
			}else if (*item_code == LNM$_ACMODE)
			{	ret->mvtype = MV_STR;
				switch(*result)
				{	case PSL$C_USER:
						ENSURE_STP_FREE_SPACE(4);
						ret->str.addr = stringpool.free;
						ret->str.len = 4;
						memcpy(ret->str.addr, "USER", 4);
						stringpool.free += 4;
						return;
					case PSL$C_SUPER:
						ENSURE_STP_FREE_SPACE(5);
						ret->str.addr = stringpool.free;
						ret->str.len = 5;
						memcpy(ret->str.addr, "SUPER", 5);
						stringpool.free += 5;
						return;
					case PSL$C_EXEC:
						ENSURE_STP_FREE_SPACE(9);
						ret->str.addr = stringpool.free;
						ret->str.len = 9;
						memcpy(ret->str.addr, "EXECUTIVE", 9);
						stringpool.free += 9;
						return;
					case PSL$C_KERNEL:
						ENSURE_STP_FREE_SPACE(6);
						ret->str.addr = stringpool.free;
						ret->str.len = 6;
						memcpy(ret->str.addr, "KERNEL", 6);
						stringpool.free += 6;
						return;
					default:
						GTMASSERT;
				}
			}else
			{	assert(*item_code == LNM$_ATTRIBUTES);
				if (full)
				{	if (!retlen)	/* If the logical name exists, but has no entry for the specified index, */
					{		/* then the return status will be normal as the TERMINAL attribute will  */
							/* be filled in, but there will be no equivalence name, thus retlen == 0 */
						ret->mvtype = MV_STR;
						if (!pass)
						{	ret->str.len = 0;
							return;
						}
						ENSURE_STP_FREE_SPACE(lname.dsc$w_length);
						ret->str.addr = stringpool.free;
						ret->str.len = lname.dsc$w_length;
						memcpy(ret->str.addr, lname.dsc$a_pointer, lname.dsc$w_length);
						stringpool.free += lname.dsc$w_length;
						return;
					}
					if(full_mask & LNM$M_TERMINAL)
					{	ret->mvtype = MV_STR;
						ENSURE_STP_FREE_SPACE(retlen);
						ret->str.addr = stringpool.free;
						ret->str.len = retlen;
						memcpy(ret->str.addr, result, retlen);
						stringpool.free += retlen;
						return;
					}
					memcpy(buff,result,retlen);
					lname.dsc$w_length = retlen;
					lname.dsc$a_pointer = buff;
				}else
				{	mask = attr_tab[slot];
					if (mask == NOVALUE)
						GTMASSERT;
					MV_FORCE_MVAL(ret,( *((int4*)result) & mask ? 1 : 0 )) ;
					n2s(ret);
					return;
				}
			}
		}else if (status == SS$_NOLOGNAM)
		{	ret->mvtype = MV_STR;
			if (full && pass > 0)
			{
				ENSURE_STP_FREE_SPACE(lname.dsc$w_length);
				ret->str.addr = stringpool.free;
				ret->str.len = lname.dsc$w_length;
				memcpy(ret->str.addr, lname.dsc$a_pointer, lname.dsc$w_length);
				stringpool.free += lname.dsc$w_length;
			}else
			{	ret->str.len = 0;
			}
			return;
		}else
		{	rts_error(VARLSTCNT(1) status);
		}
	}
	MV_FORCE_MVAL(ret, 0) ;
	return;
}
Esempio n. 8
0
void op_fngetdvi(mval *device, mval *keyword, mval *ret)
{
	itmlist_struct	item_list;
	short 		out_len, iosb[4];
	uint4 	status;
	char 		index, slot, last_slot;
	int4 		item_code, out_value;
	unsigned char 	buff[MAX_KEY_LENGTH], *upper_case;
	bool		want_secondary;
	$DESCRIPTOR(device_name,"");
	error_def(ERR_DVIKEYBAD);
	error_def(ERR_INVSTRLEN);

	MV_FORCE_STR(device);
	MV_FORCE_STR(keyword);

	if (MAX_DEV_LENGTH < device->str.len)
		rts_error(VARLSTCNT(1) SS$_IVLOGNAM);
	if (keyword->str.len > MAX_KEY_LENGTH)
		rts_error(VARLSTCNT(4) ERR_INVSTRLEN, 2, keyword->str.len, MAX_KEY_LENGTH);
	if (!keyword->str.len)
	{	rts_error(VARLSTCNT(6) ERR_DVIKEYBAD, 4, device->str.len, device->str.addr, 4, "NULL");
	}

	lower_to_upper(&buff[0], keyword->str.addr, keyword->str.len);
	upper_case = buff;
	if ( device->str.len == 0 || (device->str.len == 1 && *device->str.addr == '0'))
	{	device_name.dsc$a_pointer = "SYS$INPUT";
		device_name.dsc$w_length = SIZEOF("SYS$INPUT")-1;
	}
	else
	{	device_name.dsc$a_pointer = device->str.addr;
		device_name.dsc$w_length = device->str.len;
	}
	item_list.bufflen = VAL_LENGTH;
	item_list.itmcode = SPL_CODE;
	item_list.buffaddr = &out_value;
	item_list.retlen = &out_len;
	item_list.end = NULL;
	status = sys$getdvi( efn_immed_wait, 0, &device_name, &item_list, &iosb[0], 0, 0, 0 );
	if (status != SS$_NORMAL && status != SS$_NONLOCAL)
	{	rts_error(VARLSTCNT(1)  status ) ;
	}
	sys$synch(efn_immed_wait, &iosb[0]);
	if (iosb[0] != SS$_NORMAL && iosb[0] != SS$_NONLOCAL)
	{	rts_error(VARLSTCNT(1)  iosb[0] );
	}
	if (out_value != NULL)
	{	want_secondary = TRUE;
	}
	else
	{	want_secondary = FALSE;
	}

	if ((index = *upper_case - 'A') < MIN_INDEX || index > MAX_INDEX)
	{	rts_error(VARLSTCNT(6) ERR_DVIKEYBAD, 4, device->str.len, device->str.addr, keyword->str.len, keyword->str.addr);
	}
	item_code = 0;
	if ( dvi_index[ index ].len)
	{
		slot = dvi_index[ index ].index;
		last_slot = dvi_index[ index ].len;
		for ( ; slot < last_slot ; slot++ )
		{	if (keyword->str.len == dvi_table[ slot ].len &&
				!memcmp(dvi_table[ slot ].name, upper_case, keyword->str.len))
			{	item_code = dvi_table[ slot ].item_code;
				break;
			}
		}
	}
	if (!item_code)
	{	rts_error(VARLSTCNT(6) ERR_DVIKEYBAD, 4, device->str.len, device->str.addr, keyword->str.len, keyword->str.addr);
	}

	switch( item_code )
	{
	/* **** the following item codes require a string be returned **** */
	case DVI$_ALLDEVNAM:
	case DVI$_DEVLOCKNAM:
	case DVI$_DEVNAM:
	case DVI$_FULLDEVNAM:
	case DVI$_LOGVOLNAM:
	case DVI$_NEXTDEVNAM:
	case DVI$_ROOTDEVNAM:
	case DVI$_TT_ACCPORNAM:
	case DVI$_TT_PHYDEVNAM:
	case DVI$_VOLNAM:
		if (want_secondary)
		{
			if (!((item_code == DVI$_DEVNAM) && (keyword->str.len == 9)))
			{	item_code |= DVI$C_SECONDARY;
			}
		}
		assert(stringpool.free >= stringpool.base);
		assert(stringpool.top >= stringpool.free);
		ENSURE_STP_FREE_SPACE(MAX_DVI_STRLEN);
		item_list.bufflen = MAX_DVI_STRLEN;
		item_list.itmcode = item_code;
		item_list.buffaddr = stringpool.free;
		item_list.retlen = &out_len;
		item_list.end = NULL;
		status = sys$getdvi( efn_immed_wait, 0, &device_name, &item_list, &iosb[0], 0, 0, 0 );
		if (status != SS$_NORMAL && status != SS$_NONLOCAL)
		{		rts_error(VARLSTCNT(1)  status );
		}
		sys$synch(efn_immed_wait, &iosb[0]);
		if (iosb[0] != SS$_NORMAL && iosb[0] != SS$_NONLOCAL)
		{		rts_error(VARLSTCNT(1)  iosb[0] ) ;
		}
		ret->str.addr = stringpool.free;
		ret->str.len = out_len;
		ret->mvtype = MV_STR;
		stringpool.free += out_len;
		assert(stringpool.free >= stringpool.base);
		assert(stringpool.top >= stringpool.free);
		return;

	default:
		if (want_secondary)
			item_code |= DVI$C_SECONDARY;
		item_list.itmcode = item_code;
		item_list.bufflen = VAL_LENGTH;
		item_list.buffaddr = &out_value;
		item_list.retlen = &out_len;
		item_list.end = NULL;
		status = sys$getdvi( efn_immed_wait, 0, &device_name, &item_list, &iosb[0], 0, 0, 0 );
		if (status != SS$_NORMAL && status != SS$_NONLOCAL)
			rts_error(VARLSTCNT(1)  status );
		sys$synch(efn_immed_wait, &iosb[0]);
		if (iosb[0] != SS$_NORMAL && iosb[0] != SS$_NONLOCAL)
			rts_error(VARLSTCNT(1)  iosb[0] );
		if (want_secondary)
			item_code = item_code - 1;
		switch(item_code)
		{	case DVI$_LOCKID:
			case DVI$_ACPPID:
			case DVI$_OWNUIC:
			if (out_value)
			{	assert(stringpool.free >= stringpool.base);
				assert(stringpool.top >= stringpool.free);
				ENSURE_STP_FREE_SPACE(HEX_LEN);
				i2hex(out_value, stringpool.free, HEX_LEN);
				ret->str.addr = stringpool.free;
				ret->str.len = HEX_LEN;
				stringpool.free += HEX_LEN;
				assert(stringpool.free >= stringpool.base);
				assert(stringpool.top >= stringpool.free);
			}
			else
			{	ret->str.addr = "";
				ret->str.len = 0;
			}
			ret->mvtype = MV_STR;
			break;
		case DVI$_ACPTYPE:
			switch(out_value)
			{
			case 0: ret->str.addr = "ILLEGAL";
				ret->str.len = 7;
				break;
			case 1: ret->str.addr = "F11V1";
				ret->str.len = 5;
				break;
			case 2: ret->str.addr = "F11V2";
				ret->str.len = 5;
				break;
			case 3: ret->str.addr = "MTA";
				ret->str.len = 3;
				break;
			case 4: ret->str.addr = "NET";
				ret->str.len = 3;
				break;
			case 5: ret->str.addr = "REM";
				ret->str.len = 3;
			}
			ret->mvtype = MV_STR;
			break;
		default:
			i2mval(ret,out_value) ;
		}
		return;
	}
}
Esempio n. 9
0
bool io_open_try(io_log_name *naml, io_log_name *tl, mval *pp, int4 timeout, mval *mspace)
{
	char		buf1[MAX_TRANS_NAME_LEN];	/* buffer to hold translated name */
	char		dev_type[MAX_DEV_TYPE_LEN];
        int             n;
	mstr		tn;				/* translated name */
	uint4		stat;				/* status */
	int		p_offset;
	unsigned char	ch;
	ABS_TIME	cur_time, end_time;
	bool		out_of_time = FALSE;

	if (0 == naml->iod)
	{
		if (0 == tl->iod)
		{
			tl->iod = (io_desc *)malloc(SIZEOF(io_desc));
			memset((char*)tl->iod, 0, SIZEOF(io_desc));
			tl->iod->pair.in  = tl->iod;
			tl->iod->pair.out = tl->iod;
			tl->iod->trans_name = tl;
			p_offset = 0;
			while (iop_eol != *(pp->str.addr + p_offset))
			{
				if ((iop_tmpmbx == (ch = *(pp->str.addr + p_offset++))) || (iop_prmmbx == ch))
					tl->iod->type = mb;
				else  if (iop_nl == ch)
					tl->iod->type = nl;
				p_offset += ((IOP_VAR_SIZE == io_params_size[ch]) ?
					(unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[ch]);
			}
			if (!tl->iod->type && mspace && mspace->str.len)
			{
				lower_to_upper(dev_type, mspace->str.addr, mspace->str.len);
				if (((SIZEOF("SOCKET") - 1) == mspace->str.len)
					&& (0 == memcmp(dev_type, LIT_AND_LEN("SOCKET"))))
					tl->iod->type = gtmsocket;
				else
					tl->iod->type = us;
			}
			if (!tl->iod->type)
			{
				tn.len = tl->len;
				tn.addr = &tl->dollar_io;
				tl->iod->type = io_type(&tn);
			}
		}
		naml->iod = tl->iod;
	}
	tl->iod->disp_ptr = &io_dev_dispatch[tl->iod->type];
	assert(0 != naml->iod);
	active_device = naml->iod;
	if (dev_never_opened == naml->iod->state)
	{
		naml->iod->wrap = DEFAULT_IOD_WRAP;
		naml->iod->width = DEFAULT_IOD_WIDTH;
		naml->iod->length = DEFAULT_IOD_LENGTH;
		naml->iod->write_filter = write_filter;
	}
	if (dev_open != naml->iod->state)
	{
		naml->iod->dollar.x = 0;
		naml->iod->dollar.y = 0;
		naml->iod->dollar.za = 0;
		naml->iod->dollar.zb[0] = 0;
		naml->iod->dollar.zeof = FALSE;
	}
	if (0 == timeout)
		stat = (naml->iod->disp_ptr->open)(naml, pp, -1, mspace, timeout);	/* ZY: add a parameter timeout */
	else  if (NO_M_TIMEOUT == timeout)
	{
		while (FALSE == (stat = (naml->iod->disp_ptr->open)(naml, pp, -1, mspace, timeout)))	/* ZY: add timeout */
		{
			hiber_start(1000);	/* 1 second */
			if (outofband)
				outofband_action(FALSE);
		}
	} else
	{
		sys_get_curr_time(&cur_time);
		add_int_to_abs_time(&cur_time, timeout * 1000, &end_time);
		while (FALSE == (stat = (naml->iod->disp_ptr->open)(naml, pp, -1, mspace, timeout))	/* ZY: add timeout */
			&& (!out_of_time))
		{
			hiber_start(1000);	/* 1 second */
			if (outofband)
				outofband_action(FALSE);
			sys_get_curr_time(&cur_time);
			if (abs_time_comp(&end_time, &cur_time) <= 0)
				out_of_time = TRUE;
		}
	}
	if (TRUE == stat)
	{
		naml->iod->state = dev_open;
		if (27 == naml->iod->trans_name->dollar_io[0])
		{
			tn.addr = &naml->iod->trans_name->dollar_io[4];
			n = naml->iod->trans_name->len - 4;
			if (n < 0)
				n = 0;
			tn.len = n;
			naml->iod->trans_name = get_log_name(&tn, INSERT);
			naml->iod->trans_name->iod = naml->iod;
		}
	}
	else
	{
		if (dev_open == naml->iod->state && (gtmsocket != naml->iod->type))
			naml->iod->state = dev_closed;
		else if ((gtmsocket == naml->iod->type) && naml->iod->newly_created)
		{
			assert(naml->iod->state != dev_open);
			iosocket_destroy(naml->iod);
		}
	}
	active_device = 0;
	if ((NO_M_TIMEOUT != timeout) && IS_MCODE_RUNNING)
		return (stat);
	return FALSE;
}
Esempio n. 10
0
short	iosocket_open(io_log_name *dev, mval *pp, int file_des, mval *mspace, int4 timepar)
{
	char			addr[SA_MAXLITLEN], *errptr, sockaddr[SA_MAXLITLEN],
		                temp_addr[SA_MAXLITLEN], dev_type[MAX_DEV_TYPE_LEN];
	unsigned char		ch, *c, *next, *top;
	int			handle_len, moreread_timeout, len;
	unsigned short		port;
	int4			errlen, msec_timeout, real_errno, p_offset = 0, zff_len, delimiter_len;
	int			d_socket_struct_len;
	ABS_TIME		cur_time, end_time;
	io_desc			*ioptr;
	struct sockaddr_in	peer;		/* socket address + port */
	fd_set			tcp_fd;
	uint4			bfsize = DEFAULT_SOCKET_BUFFER_SIZE, ibfsize;
        d_socket_struct         *dsocketptr;
	socket_struct		*socketptr;
	mv_stent		*mv_zintdev;
	boolean_t		zint_conn_restart = FALSE;
	socket_interrupt	*sockintr;
	mstr			chset_mstr;
	boolean_t		attach_specified = FALSE,
		                listen_specified = FALSE,
		                connect_specified = FALSE,
	                	ioerror_specified = FALSE,
		                delay_specified = FALSE,
		                nodelay_specified = FALSE,
		                ibfsize_specified = FALSE,
		                moreread_specified = FALSE,
		                is_principal = FALSE,	/* called from inetd */
		                ichset_specified,
		                ochset_specified;
	unsigned char 		delimiter_buffer[MAX_N_DELIMITER * (MAX_DELIM_LEN + 1)], zff_buffer[MAX_ZFF_LEN];
	char			ioerror, ip[3], tcp[4],
 		                sock_handle[MAX_HANDLE_LEN], delimiter[MAX_DELIM_LEN + 1];

	error_def(ERR_DELIMSIZNA);
	error_def(ERR_ADDRTOOLONG);
	error_def(ERR_SOCKETEXIST);
	error_def(ERR_ABNCOMPTINC);
	error_def(ERR_DEVPARINAP);
	error_def(ERR_DEVPARMNEG);
	error_def(ERR_ILLESOCKBFSIZE);
	error_def(ERR_ZFF2MANY);
	error_def(ERR_DELIMWIDTH);
	error_def(ERR_SOCKMAX);
	error_def(ERR_ZINTRECURSEIO);
	error_def(ERR_MRTMAXEXCEEDED);

	ioptr = dev->iod;
	assert((params) *(pp->str.addr + p_offset) < (unsigned char)n_iops);
	assert(ioptr != 0);
	assert(ioptr->state >= 0 && ioptr->state < n_io_dev_states);
	assert(ioptr->type == gtmsocket);
	if ((ioptr->state == dev_closed) && mspace && mspace->str.len && mspace->str.addr)
	{
		lower_to_upper((uchar_ptr_t)dev_type, (uchar_ptr_t)mspace->str.addr, mspace->str.len);
		if (STR_LIT_LEN("SOCKET") != mspace->str.len || 0 != memcmp(dev_type, "SOCKET", STR_LIT_LEN("SOCKET")))
		{
			if (ioptr->dev_sp)
				free(ioptr->dev_sp);
			ioptr->state = dev_never_opened;
		}
	}
	d_socket_struct_len = SIZEOF(d_socket_struct) + (SIZEOF(socket_struct) * (gtm_max_sockets - 1));
	if (ioptr->state == dev_never_opened)
	{
		dsocketptr = ioptr->dev_sp = (void *)malloc(d_socket_struct_len);
		memset(dsocketptr, 0, d_socket_struct_len);
		dsocketptr->iod = ioptr;
	} else
		dsocketptr = (d_socket_struct *)ioptr->dev_sp;

	if (ioptr->state == dev_never_opened)
	{
		ioptr->state	= dev_closed;
		ioptr->width	= TCPDEF_WIDTH;
		ioptr->length	= TCPDEF_LENGTH;
		ioptr->wrap	= TRUE;
		if (-1 == iotcp_fillroutine())
			assert(FALSE);
		if (!io_std_device.in)
			/* called from io_init */
			is_principal = TRUE;
	}
        if (dsocketptr->mupintr)
	{	/* check if connect was interrupted */
		sockintr = &dsocketptr->sock_save_state;
		if (sockwhich_invalid == sockintr->who_saved)
			GTMASSERT;	/* Interrupt should never have an invalid save state */
		if (dollar_zininterrupt)
		{
			dsocketptr->mupintr = FALSE;
			sockintr->who_saved = sockwhich_invalid;
			rts_error(VARLSTCNT(1) ERR_ZINTRECURSEIO);
		}
		if (sockwhich_connect != sockintr->who_saved)
			GTMASSERT;	/* ZINTRECURSEIO should have caught */
		mv_zintdev = io_find_mvstent(dsocketptr->iod, FALSE);
		if (mv_zintdev && mv_zintdev->mv_st_cont.mvs_zintdev.buffer_valid)
		{	/* mupintr will be reset and mvstent popped in iosocket_connect */
			connect_specified = TRUE;
			ibfsize_specified = sockintr->ibfsize_specified;
			assert(newdsocket);
			assert(newdsocket == sockintr->newdsocket);
			memcpy(newdsocket, (d_socket_struct *)mv_zintdev->mv_st_cont.mvs_zintdev.curr_sp_buffer.addr,
					d_socket_struct_len);
			socketptr = newdsocket->socket[newdsocket->current_socket];
			assert(socketptr == (socket_struct *)mv_zintdev->mv_st_cont.mvs_zintdev.socketptr);
			zint_conn_restart = TRUE;	/* skip what we already did, state == dev_closed */
		}
	} else
	{
		ioptr->dollar.zeof = FALSE;
		if (NULL == newdsocket)
			newdsocket = (d_socket_struct *)malloc(d_socket_struct_len);
		memcpy(newdsocket, dsocketptr, d_socket_struct_len);
		memcpy(newdsocket->dollar_device, "0", SIZEOF("0"));
		zff_len = -1; /* indicates neither ZFF nor ZNOFF specified */
		delimiter_len = -1; /* indicates neither DELIM nor NODELIM specified */
		ichset_specified = ochset_specified = FALSE;
		while (iop_eol != (ch = *(pp->str.addr + p_offset++)))
		{
			switch(ch)
			{
				case iop_delimiter:
					delimiter_len = (int4)(unsigned char)*(pp->str.addr + p_offset);
					if (((MAX_DELIM_LEN + 1) * MAX_N_DELIMITER) >= delimiter_len)
						memcpy(delimiter_buffer, (pp->str.addr + p_offset + 1), delimiter_len);
					else
						rts_error(VARLSTCNT(1) ERR_DELIMSIZNA);
					break;
				case iop_ipchset:
					UNICODE_ONLY(
						if (gtm_utf8_mode)
					        {	/* Only change ipchset if in UTF8 mode */
							chset_mstr.addr = (char *)(pp->str.addr + p_offset + 1);
							chset_mstr.len = *(pp->str.addr + p_offset);
							SET_ENCODING(ioptr->ichset, &chset_mstr);
							ichset_specified = TRUE;
						}
					);
					break;
				case iop_opchset:
					UNICODE_ONLY(
						if (gtm_utf8_mode)
		 				{       /* Only change ipchset if in UTF8 mode */
							chset_mstr.addr = (char *)(pp->str.addr + p_offset + 1);
							chset_mstr.len = *(pp->str.addr + p_offset);
							SET_ENCODING(ioptr->ochset, &chset_mstr);
							ochset_specified = TRUE;
						}
					);
					break;
                        	case iop_chset:
					UNICODE_ONLY(
						if (gtm_utf8_mode)
						{       /* Only change ipchset/opchset if in UTF8 mode */
							chset_mstr.addr = (char *)(pp->str.addr + p_offset + 1);
							chset_mstr.len = *(pp->str.addr + p_offset);
							SET_ENCODING(ioptr->ichset, &chset_mstr);
							ioptr->ochset = ioptr->ichset;
							ichset_specified = ochset_specified = TRUE;
                                        	}
					);
					break;
			/* Note the following 4 cases (iop_m/utf16/utf16be/utf16le) have no corresponding device parameter
			   but are included here because they can be easily used in internal processing.
			*/
				case iop_m:
					UNICODE_ONLY(
						ioptr->ichset = ioptr->ochset = CHSET_M;
						ichset_specified = ochset_specified = TRUE;
					);
Esempio n. 11
0
void mu_extract(void)
{
	int 				stat_res, truncate_res;
	int				reg_max_rec, reg_max_key, reg_max_blk, reg_std_null_coll;
	int				iter, format, local_errno, int_nlen;
	boolean_t			freeze = FALSE, logqualifier, success;
	char				format_buffer[FORMAT_STR_MAX_SIZE],  ch_set_name[MAX_CHSET_NAME], cli_buff[MAX_LINE],
					label_buff[LABEL_STR_MAX_SIZE], gbl_name_buff[MAX_MIDENT_LEN + 2]; /* 2 for null and '^' */
	glist				gl_head, *gl_ptr;
	gd_region			*reg, *region_top;
	mu_extr_stats			global_total, grand_total;
	uint4				item_code, devbufsiz, maxfield;
	unsigned short			label_len, n_len, ch_set_len, buflen;
	unsigned char			*outbuf, *outptr, *chptr, *leadptr;
	struct stat                     statbuf;
	mval				val, curr_gbl_name, op_val, op_pars;
	mstr				chset_mstr;
	gtm_chset_t 			saved_out_set;
	static unsigned char		ochset_set = FALSE;
	static readonly unsigned char	open_params_list[] =
	{
		(unsigned char)iop_noreadonly,
		(unsigned char)iop_nowrap,
		(unsigned char)iop_stream,
		(unsigned char)iop_eol
	};
	static readonly unsigned char no_param = (unsigned char)iop_eol;
	coll_hdr	extr_collhdr;

	error_def(ERR_NOSELECT);
	error_def(ERR_GTMASSERT);
	error_def(ERR_EXTRACTCTRLY);
	error_def(ERR_EXTRACTFILERR);
	error_def(ERR_MUPCLIERR);
	error_def(ERR_MUNOACTION);
	error_def(ERR_MUNOFINISH);
	error_def(ERR_RECORDSTAT);
	error_def(ERR_NULLCOLLDIFF);

        /* Initialize all local character arrays to zero before using */

        memset(cli_buff, 0, sizeof(cli_buff));
        memset(outfilename, 0, sizeof(outfilename));
        memset(label_buff, 0, sizeof(label_buff));
        memset(format_buffer, 0, sizeof(format_buffer));
	active_device = io_curr_device.out;

	mu_outofband_setup();

	if (CLI_PRESENT == cli_present("OCHSET"))
	{
		ch_set_len = sizeof(ch_set_name);
		if (cli_get_str("OCHSET", ch_set_name, &ch_set_len))
		{
			if (0 == ch_set_len)
				mupip_exit(ERR_MUNOACTION);	/* need to change to OPCHSET error when added */
			ch_set_name[ch_set_len] = '\0';
#ifdef KEEP_zOS_EBCDIC
			if ( (iconv_t)0 != active_device->output_conv_cd)
				ICONV_CLOSE_CD(active_device->output_conv_cd);
			if (DEFAULT_CODE_SET != active_device->out_code_set)
				ICONV_OPEN_CD(active_device->output_conv_cd, INSIDE_CH_SET, ch_set_name);
#else
			chset_mstr.addr = ch_set_name;
			chset_mstr.len = ch_set_len;
			SET_ENCODING(active_device->ochset, &chset_mstr);
			get_chset_desc(&chset_names[active_device->ochset]);
#endif
			ochset_set = TRUE;
		}
	}
	logqualifier = (CLI_NEGATED != cli_present("LOG"));
	if (CLI_PRESENT == cli_present("FREEZE"))
		freeze = TRUE;

	n_len = sizeof(format_buffer);
	if (FALSE == cli_get_str("FORMAT", format_buffer, &n_len))
	{
		n_len = sizeof("ZWR") - 1;
		memcpy(format_buffer, "ZWR", n_len);
	}
	int_nlen = n_len;
	lower_to_upper((uchar_ptr_t)format_buffer, (uchar_ptr_t)format_buffer, int_nlen);
	if (0 == memcmp(format_buffer, "ZWR", n_len))
	        format = MU_FMT_ZWR;
	else if (0 == memcmp(format_buffer, "GO", n_len))
	{
		if (gtm_utf8_mode)
		{
			util_out_print("Extract error: GO format is not supported in UTF-8 mode. Use ZWR format.", TRUE);
			mupip_exit(ERR_MUPCLIERR);
		}
	        format = MU_FMT_GO;
	} else if (0 == memcmp(format_buffer, "BINARY", n_len))
		format = MU_FMT_BINARY;
	else
	{
		util_out_print("Extract error: bad format type", TRUE);
		mupip_exit(ERR_MUPCLIERR);
	}
	n_len = sizeof(cli_buff);
	if (FALSE == cli_get_str((char *)select_text, cli_buff, &n_len))
	{
		n_len = 1;
		cli_buff[0] = '*';
	}
	/* gv_select will select globals */
        gv_select(cli_buff, n_len, freeze, (char *)select_text, &gl_head, &reg_max_rec, &reg_max_key, &reg_max_blk);
 	if (!gl_head.next)
        {
                rts_error(VARLSTCNT(1) ERR_NOSELECT);
                mupip_exit(ERR_NOSELECT);
        }
	/* For binary format, check whether all regions have same null collation order */
	if (MU_FMT_BINARY == format)
	{
		for (reg = gd_header->regions, region_top = gd_header->regions + gd_header->n_regions, reg_std_null_coll = -1;
			reg < region_top ; reg++)
		{
			if (reg->open)
			{
				if (reg_std_null_coll != reg->std_null_coll)
				{
					if (reg_std_null_coll == -1)
						reg_std_null_coll = reg->std_null_coll;
					else
					{
						rts_error(VARLSTCNT(1) ERR_NULLCOLLDIFF);
						mupip_exit(ERR_NULLCOLLDIFF);
					}
				}
			}
		}
		assert(-1 != reg_std_null_coll);
	}
	grand_total.recknt = grand_total.reclen = grand_total.keylen = grand_total.datalen = 0;
	global_total.recknt = global_total.reclen = global_total.keylen = global_total.datalen = 0;

	n_len = sizeof(outfilename);
	if (FALSE == cli_get_str("FILE", outfilename, &n_len))
	{
		rts_error(VARLSTCNT(1) ERR_MUPCLIERR);
		mupip_exit(ERR_MUPCLIERR);
	}
	if (-1 == Stat((char *)outfilename, &statbuf))
        {
		if (ENOENT != errno)
		{
			local_errno = errno;
			perror("Error opening output file");
			mupip_exit(local_errno);
		}
	}
	else
	{
		util_out_print("Error opening output file: !AD -- File exists", TRUE, n_len, outfilename);
		mupip_exit(ERR_MUNOACTION);
	}
	op_pars.mvtype = MV_STR;
	op_pars.str.len = sizeof(open_params_list);
	op_pars.str.addr = (char *)open_params_list;
	op_val.mvtype = MV_STR;
	op_val.str.len = filename_len = n_len;
	op_val.str.addr = (char *)outfilename;
	(*op_open_ptr)(&op_val, &op_pars, 0, 0);
	ESTABLISH(mu_extract_handler);
	op_use(&op_val, &op_pars);
	if (MU_FMT_BINARY == format)
	{
		/* binary header label format:
		 *	fixed length text, fixed length date & time,
		 *	fixed length max blk size, fixed length max rec size, fixed length max key size, fixed length std_null_coll
		 *	32-byte padded user-supplied string
		 */
		outbuf = (unsigned char *)malloc(sizeof(BIN_HEADER_LABEL) + sizeof(BIN_HEADER_DATEFMT) - 1 +
				4 * BIN_HEADER_NUMSZ + BIN_HEADER_LABELSZ);
		outptr = outbuf;

		MEMCPY_LIT(outptr, BIN_HEADER_LABEL);
		outptr += STR_LIT_LEN(BIN_HEADER_LABEL);

		stringpool.free = stringpool.base;
		op_horolog(&val);
		stringpool.free = stringpool.base;
		op_fnzdate(&val, (mval *)&mu_bin_datefmt, &null_str, &null_str, &val);
		memcpy(outptr, val.str.addr, val.str.len);
		outptr += val.str.len;

		WRITE_NUMERIC(reg_max_blk);
		WRITE_NUMERIC(reg_max_rec);
		WRITE_NUMERIC(reg_max_key);
		WRITE_NUMERIC(reg_std_null_coll);

		if (gtm_utf8_mode)
		{
			MEMCPY_LIT(outptr, UTF8_NAME);
			label_len = STR_LIT_LEN(UTF8_NAME);
			outptr[label_len++] = ' ';
		} else
			label_len = 0;
		buflen = sizeof(label_buff);
		if (FALSE == cli_get_str("LABEL", label_buff, &buflen))
		{
			MEMCPY_LIT(&outptr[label_len], EXTR_DEFAULT_LABEL);
			buflen = STR_LIT_LEN(EXTR_DEFAULT_LABEL);
		} else
			memcpy(&outptr[label_len], label_buff, buflen);
		label_len += buflen;
		if (label_len > BIN_HEADER_LABELSZ)
		{ /* Label size exceeds the space, so truncate the label and back off to
		     the valid beginning (i.e. to the leading byte) of the last character
		     that can entirely fit in the space */
			label_len = BIN_HEADER_LABELSZ;
			chptr = &outptr[BIN_HEADER_LABELSZ];
			UTF8_LEADING_BYTE(chptr, outptr, leadptr);
			assert(chptr - leadptr < 4);
			if (leadptr < chptr)
				label_len -= (chptr - leadptr);
		}
		outptr += label_len;
		for (iter = label_len;  iter < BIN_HEADER_LABELSZ;  iter++)
			*outptr++ = ' ';

		label_len = outptr - outbuf;
		if (!ochset_set)
		{
#ifdef KEEP_zOS_EBCDIC
			/* extract ascii header for binary by default */
			/* Do we need to restore it somewhere? */
			saved_out_set = (io_curr_device.out)->out_code_set;
			(io_curr_device.out)->out_code_set = DEFAULT_CODE_SET;
#else
			saved_out_set = (io_curr_device.out)->ochset;
			(io_curr_device.out)->ochset = CHSET_M;
#endif
		}
		op_val.str.addr = (char *)(&label_len);
		op_val.str.len = sizeof(label_len);
		op_write(&op_val);
		op_val.str.addr = (char *)outbuf;
		op_val.str.len = label_len;
		op_write(&op_val);
	} else
	{
		assert((MU_FMT_GO == format) || (MU_FMT_ZWR == format));
		label_len = sizeof(label_buff);
		if (FALSE == cli_get_str("LABEL", label_buff, &label_len))
		{
			MEMCPY_LIT(label_buff, EXTR_DEFAULT_LABEL);
			label_len = STR_LIT_LEN(EXTR_DEFAULT_LABEL);
		}
		if (gtm_utf8_mode)
		{
			label_buff[label_len++] = ' ';
			MEMCPY_LIT(&label_buff[label_len], UTF8_NAME);
			label_len += STR_LIT_LEN(UTF8_NAME);
		}
		label_buff[label_len++] = '\n';
		op_val.mvtype = MV_STR;
		op_val.str.len = label_len;
		op_val.str.addr = label_buff;
		op_write(&op_val);
		stringpool.free = stringpool.base;
		op_horolog(&val);
		stringpool.free = stringpool.base;
		op_fnzdate(&val, &datefmt, &null_str, &null_str, &val);
		op_val = val;
		op_val.mvtype = MV_STR;
		op_write(&op_val);
		if (MU_FMT_ZWR == format)
		{
			op_val.str.addr = " ZWR";
			op_val.str.len = sizeof(" ZWR") - 1;
			op_write(&op_val);
		}
		op_wteol(1);
	}
	REVERT;

	ESTABLISH(mu_extract_handler1);
	success = TRUE;
	for (gl_ptr = gl_head.next; gl_ptr; gl_ptr = gl_ptr->next)
	{
		if (mu_ctrly_occurred)
			break;
		if (mu_ctrlc_occurred)
		{
			gbl_name_buff[0]='^';
			memcpy(&gbl_name_buff[1], gl_ptr->name.str.addr, gl_ptr->name.str.len);
			gtm_putmsg(VARLSTCNT(8) ERR_RECORDSTAT, 6, gl_ptr->name.str.len + 1, gbl_name_buff,
				global_total.recknt, global_total.keylen, global_total.datalen, global_total.reclen);
			mu_ctrlc_occurred = FALSE;
		}
		gv_bind_name(gd_header, &gl_ptr->name.str);
		if (MU_FMT_BINARY == format)
		{
			label_len = sizeof(extr_collhdr);
			op_val.mvtype = MV_STR;
			op_val.str.addr = (char *)(&label_len);
			op_val.str.len = sizeof(label_len);
			op_write(&op_val);
			extr_collhdr.act = gv_target->act;
			extr_collhdr.nct = gv_target->nct;
			extr_collhdr.ver = gv_target->ver;
			op_val.str.addr = (char *)(&extr_collhdr);
			op_val.str.len = sizeof(extr_collhdr);
			op_write(&op_val);
		}
		/* Note: Do not change the order of the expression below.
		 * Otherwise if success is FALSE, mu_extr_gblout() will not be called at all.
		 * We want mu_extr_gblout() to be called irrespective of the value of success */
		success = mu_extr_gblout(&gl_ptr->name, &global_total, format) && success;
		if (logqualifier)
		{
			gbl_name_buff[0]='^';
			memcpy(&gbl_name_buff[1], gl_ptr->name.str.addr, gl_ptr->name.str.len);
			gtm_putmsg(VARLSTCNT(8) ERR_RECORDSTAT, 6, gl_ptr->name.str.len + 1, gbl_name_buff,
				global_total.recknt, global_total.keylen, global_total.datalen, global_total.reclen);
			mu_ctrlc_occurred = FALSE;
		}
		grand_total.recknt += global_total.recknt;
		if (grand_total.reclen < global_total.reclen)
			grand_total.reclen = global_total.reclen;
		if (grand_total.keylen < global_total.keylen)
			grand_total.keylen = global_total.keylen;
		if (grand_total.datalen < global_total.datalen)
			grand_total.datalen = global_total.datalen;

	}
	op_val.mvtype = op_pars.mvtype = MV_STR;
	op_val.str.addr = (char *)outfilename;;
	op_val.str.len = filename_len;
	op_pars.str.len = sizeof(no_param);
	op_pars.str.addr = (char *)&no_param;
	op_close(&op_val, &op_pars);
	REVERT;
	if (mu_ctrly_occurred)
	{
		gtm_putmsg(VARLSTCNT(1) ERR_EXTRACTCTRLY);
		mupip_exit(ERR_MUNOFINISH);
	}
	gtm_putmsg(VARLSTCNT(8) ERR_RECORDSTAT, 6, LEN_AND_LIT(gt_lit),
		grand_total.recknt, grand_total.keylen, grand_total.datalen, grand_total.reclen);
	if (MU_FMT_BINARY == format)
	{
		/*      truncate the last newline charactor flushed by op_close */
		STAT_FILE((char *)outfilename, &statbuf, stat_res);
		if (-1 == stat_res)
			rts_error(VARLSTCNT(1) errno);
		TRUNCATE_FILE((const char *)outfilename, statbuf.st_size - 1, truncate_res);
		if (-1 == truncate_res)
			rts_error(VARLSTCNT(1) errno);
	}
	mupip_exit(success ? SS_NORMAL : ERR_MUNOFINISH);
}
Esempio n. 12
0
void mupip_cvtgbl(void)
{
	char		fn[MAX_FN_LEN + 1], *line1_ptr, *line3_ptr;
	gtm_int64_t	begin_i8, end_i8;
	int		dos, i, file_format, line1_len, line3_len, utf8;
	uint4	        begin, cli_status, end, max_rec_size;
	unsigned char	buff[MAX_ONERROR_VALUE_LEN];
	unsigned short	fn_len, len;

	DCL_THREADGBL_ACCESS;
	SETUP_THREADGBL_ACCESS;
	assert(MAX_ONERROR_VALUE_LEN > MAX_FORMAT_VALUE_LEN);	/* so the buff[] definition above is good for FORMAT and ONERROR */
	/* If an online rollback occurs when we are loading up the database with new globals and takes us back to a prior logical
	 * state, then we should not continue with the load. The reason being that the application might rely on certain globals to
	 * be present before loading others and that property could be violated if online rollback takes the database back to a
	 * completely different logical state. Set the variable issue_DBROLLEDBACK_anyways that forces the restart logic to issue
	 * an rts_error the first time it detects an online rollback (that takes the database to a prior logical state).
	 */
	TREF(issue_DBROLLEDBACK_anyways) = TRUE;
	is_replicator = TRUE;
	skip_dbtriggers = TRUE;
	fn_len = SIZEOF(fn);
	if (cli_present("STDIN"))
	{
		/* User wants to load from standard input */
		assert(SIZEOF(fn) > sys_input.len);
		memcpy(fn, sys_input.addr, sys_input.len);
		fn_len = sys_input.len;
		assert(-1 != fcntl(fileno(stdin), F_GETFD));
		/* Check if both file name and -STDIN specified. */
		if (cli_get_str("FILE", fn, &fn_len))
			mupip_exit(ERR_MUPCLIERR);
	} else if (!cli_get_str("FILE", fn, &fn_len))  /* User wants to read from a file. */
		mupip_exit(ERR_MUPCLIERR); /* Neither -STDIN nor file name specified. */
	file_input_init(fn, fn_len, IOP_EOL);
	if (mupip_error_occurred)
		EXIT(-1);
	mu_outofband_setup();
	if ((cli_status = cli_present("BEGIN")) == CLI_PRESENT)
	{
	        if (!cli_get_int64("BEGIN", &begin_i8))
			mupip_exit(ERR_MUPCLIERR);
		if (1 > begin_i8)
			mupip_exit(ERR_LOADBGSZ);
		else if (MAXUINT4 < begin_i8)
			mupip_exit(ERR_LOADBGSZ2);
		begin = (uint4) begin_i8;
	} else
	{
		begin = 1;
		begin_i8 = 1;
	}
	if ((cli_status = cli_present("END")) == CLI_PRESENT)
	{
	        if (!cli_get_int64("END", &end_i8))
			mupip_exit(ERR_MUPCLIERR);
		if (1 > end_i8)
			mupip_exit(ERR_LOADEDSZ);
		else if (MAXUINT4 < end_i8)
			mupip_exit(ERR_LOADEDSZ2);
		if (end_i8 < begin_i8)
			mupip_exit(ERR_LOADEDBG);
		end = (uint4) end_i8;
	} else
		end = MAXUINT4;
	if ((cli_status = cli_present("FILL_FACTOR")) == CLI_PRESENT)
	{
		assert(SIZEOF(gv_fillfactor) == SIZEOF(int4));
	        if (!cli_get_int("FILL_FACTOR", (int4 *)&gv_fillfactor))
			gv_fillfactor = MAX_FILLFACTOR;
		if (gv_fillfactor < MIN_FILLFACTOR)
			gv_fillfactor = MIN_FILLFACTOR;
		else if (gv_fillfactor > MAX_FILLFACTOR)
			gv_fillfactor = MAX_FILLFACTOR;
	} else
		gv_fillfactor = MAX_FILLFACTOR;
	if (cli_present("ONERROR") == CLI_PRESENT)
	{
		len = SIZEOF(buff);
		if (!cli_get_str("ONERROR", (char *)buff, &len))
		{
			assert(FALSE);
			onerror = ONERROR_PROCEED;
		} else
		{
			lower_to_upper(buff, buff, len);
			if (!memcmp(buff, "STOP", len))
				onerror = ONERROR_STOP;
			else if (!memcmp(buff, "PROCEED", len))
				onerror = ONERROR_PROCEED;
			else if (!memcmp(buff, "INTERACTIVE", len))
			{
				if (isatty(0)) /*if stdin is a terminal*/
					onerror = ONERROR_INTERACTIVE;
				else
					onerror = ONERROR_STOP;
			} else
			{
				util_out_print("Illegal ONERROR parameter for load",TRUE);
				mupip_exit(ERR_MUPCLIERR);
			}
		}
	} else
		onerror = ONERROR_PROCEED; /* Default: Proceed on error */
	file_format = get_load_format(&line1_ptr, &line3_ptr, &line1_len, &line3_len, &max_rec_size, &utf8, &dos); /* from header */
	if (MU_FMT_GOQ == file_format)
		mupip_exit(ERR_LDBINFMT);
	if (BADZCHSET == utf8)
		mupip_exit(ERR_MUNOFINISH);
	if (cli_present("FORMAT") == CLI_PRESENT)
	{	/* If the command speficies a format see if it matches the label */
		len = SIZEOF(buff);
		if (!cli_get_str("FORMAT", (char *)buff, &len))
			go_load(begin, end, (unsigned char *)line1_ptr, line3_ptr, line3_len, max_rec_size, file_format, utf8, dos);
		else
		{
		        lower_to_upper(buff, buff, len);
			if (!memcmp(buff, "ZWR", len))
			{	/* If the label did not determine a format let them specify ZWR and they can sort out the result */
				if ((MU_FMT_ZWR == file_format) || (MU_FMT_UNRECOG == file_format))
					go_load(begin, end, (unsigned char *)line1_ptr, line3_ptr, line3_len, max_rec_size,
						MU_FMT_ZWR, utf8, dos);
				else
					mupip_exit(ERR_LDBINFMT);
			} else if (!memcmp(buff, "BINARY", len))
			{
				if (MU_FMT_BINARY == file_format)
					bin_load(begin, end, line1_ptr, line1_len);
				else
					mupip_exit(ERR_LDBINFMT);
			} else if (!memcmp(buff, "GO", len))
			{	/* If the label did not determine a format let them specify GO and they can sort out the result */
				if ((MU_FMT_GO == file_format) || (MU_FMT_UNRECOG == file_format))
					go_load(begin, end, (unsigned char *)line1_ptr, line3_ptr, line3_len, max_rec_size,
						MU_FMT_GO, utf8, dos);
				else
					mupip_exit(ERR_LDBINFMT);
			} else if (!memcmp(buff, "GOQ", len))
			{	/* get_load_format doesn't recognize GOQ labels' */
				if (MU_FMT_UNRECOG == file_format)
					goq_load();
				else
					mupip_exit(ERR_LDBINFMT);
			} else
			{
					util_out_print("Illegal file format for load",TRUE);
					mupip_exit(ERR_MUPCLIERR);
			}
		}
	} else
	{
		if (MU_FMT_BINARY == file_format)
			bin_load(begin, end, line1_ptr, line1_len);
		else if ((MU_FMT_ZWR == file_format) || (MU_FMT_GO == file_format))
			go_load(begin, end, (unsigned char *)line1_ptr, line3_ptr, line3_len, max_rec_size, file_format, utf8, dos);
		else
		{
			assert(MU_FMT_UNRECOG == file_format);
			mupip_exit(ERR_LDBINFMT);
		}
	}
	mupip_exit(mupip_error_occurred ? ERR_MUNOFINISH : SS_NORMAL);
}
Esempio n. 13
0
void mupip_backup(void)
{
	bool		journal;
	char		*tempdirname, *tempfilename, *ptr;
	uint4		level, blk, status, ret;
	unsigned short	s_len, length, ntries;
	int4		size, gds_ratio, buff_size, i, crit_counter;
	uint4		ustatus;
	size_t		backup_buf_size;
	trans_num	tn;
	backup_buff_ptr_t	bptr;
	static boolean_t	once = TRUE;
	backup_reg_list	*rptr, *clnup_ptr;
	boolean_t	inc_since_inc , inc_since_rec, result, newjnlfiles, gotit,
			newjnlfiles_specified, keep_prev_link, bkdbjnl_disable_specified, bkdbjnl_off_specified;
	unsigned char	since_buff[50];
	jnl_create_info jnl_info;
	file_control	*fc;
	char            tempdir_trans_buffer[MAX_TRANS_NAME_LEN],
			tempnam_prefix[MAX_FN_LEN], tempdir_full_buffer[MAX_FN_LEN + 1], jnl_file_name[JNL_NAME_SIZE];
	char		*jnl_str_ptr, rep_str[256], jnl_str[256], entry[256],
			full_jnl_fn[JNL_NAME_SIZE], prev_jnl_fn[JNL_NAME_SIZE];
	int		ccnt, index, comparison, num, jnl_fstat;
	mstr            tempdir_log, tempdir_trans, *file, tempdir_full, filestr;
	uint4		jnl_status, temp_file_name_len, tempdir_trans_len, trans_log_name_status;

#if defined(VMS)
	struct FAB	temp_fab;
	struct NAM	temp_nam;
	struct XABPRO	temp_xabpro;
	short		iosb[4];
	char		def_jnl_fn[MAX_FN_LEN];
	GDS_INFO	*gds_info;
	char		exp_file_name[MAX_FN_LEN];
	uint4		exp_file_name_len;
#elif defined(UNIX)
	struct stat     stat_buf;
	int		fstat_res;
	int		sync_io_status;
	boolean_t	sync_io, sync_io_specified;
#else
# error UNSUPPORTED PLATFORM
#endif
	boolean_t	jnl_options[jnl_end_of_list] = {FALSE, FALSE, FALSE}, save_no_prev_link;


	error_def(ERR_BACKUPCTRL);
	error_def(ERR_MUPCLIERR);
	error_def(ERR_FREEZECTRL);
	error_def(ERR_DBRDONLY);
	error_def(ERR_DBFILERR);
	error_def(ERR_MUNOACTION);
	error_def(ERR_MUNOFINISH);
	error_def(ERR_BACKUP2MANYKILL);
        error_def(ERR_MUSELFBKUP);
        error_def(ERR_JNLNOCREATE);
        error_def(ERR_JNLCREATE);
	error_def(ERR_PREVJNLLINKCUT);
	error_def(ERR_JNLSTATE);
	error_def(ERR_FILEEXISTS);
	error_def(ERR_JNLDISABLE);
	error_def(ERR_FILEPARSE);
	error_def(ERR_JNLFNF);
	error_def(ERR_NOTRNDMACC);

	/* ==================================== STEP 1. Initialization ======================================= */

	ret = SS_NORMAL;
	jnl_str_ptr = &jnl_str[0];
	halt_ptr = grlist = NULL;
	in_backup = TRUE;
	inc_since_inc = inc_since_rec = file_backed_up = error_mupip = FALSE;
	debug_mupip = (CLI_PRESENT == cli_present("DBG"));

	mu_outofband_setup();
	jnl_status = 0;
	if (once)
	{
		gvinit();
		once = FALSE;
	}

	/* ============================ STEP 2. Parse and construct grlist ================================== */

	if (incremental = (CLI_PRESENT == cli_present("INCREMENTAL") || CLI_PRESENT == cli_present("BYTESTREAM")))
	{
		int4 temp_tn;

		if (0 == cli_get_hex("TRANSACTION", &temp_tn))
		{
			temp_tn = 0;
			s_len = sizeof(since_buff);
			if (cli_get_str("SINCE", (char *)since_buff, &s_len))
			{
				lower_to_upper(since_buff, since_buff, s_len);
				if ((0 == memcmp(since_buff, "INCREMENTAL", s_len))
					|| (0 == memcmp(since_buff, "BYTESTREAM", s_len)))
					inc_since_inc = TRUE;
				else if (0 == memcmp(since_buff, "RECORD", s_len))
					inc_since_rec = TRUE;
			}
		} else if (temp_tn < 1)
		{
			util_out_print("The minimum allowable transaction number is one.", TRUE);
			mupip_exit(ERR_MUNOACTION);
		}
		tn = (trans_num)temp_tn;
	}
	online = (TRUE != cli_negated("ONLINE"));
	record = (CLI_PRESENT == cli_present("RECORD"));
	newjnlfiles_specified = FALSE;
	newjnlfiles = TRUE;	/* by default */
	keep_prev_link = TRUE;
	if (CLI_PRESENT == cli_present("NEWJNLFILES"))
	{
		newjnlfiles_specified = newjnlfiles = TRUE;
		if (CLI_NEGATED == cli_present("NEWJNLFILES.PREVLINK"))
			keep_prev_link = FALSE;
		UNIX_ONLY(
			sync_io_status = cli_present("NEWJNLFILES.SYNC_IO");
			sync_io_specified = TRUE;
			if (CLI_PRESENT == sync_io_status)
				sync_io = TRUE;
			else if (CLI_NEGATED == sync_io_status)
				sync_io = FALSE;
			else
				sync_io_specified = FALSE;
		)
	} else if (CLI_NEGATED == cli_present("NEWJNLFILES"))
Esempio n. 14
0
void str_to_upper(char* str)  {
  for(char* pc=str;*pc!=0;++pc) 
  {
    *pc = lower_to_upper(*pc);
  }
}
Esempio n. 15
0
void	iosocket_tls(mval *optionmval, int4 timeoutarg, mval *tlsid, mval *password, mval *extraarg)
{	/* note extraarg is not currently used */
	int4			length, flags, timeout, msec_timeout, status, status2, len, errlen, devlen, tls_errno, save_errno;
	io_desc			*iod;
	d_socket_struct 	*dsocketptr;
	socket_struct		*socketptr;
	char			optionstr[MAX_TLSOPTION], idstr[MAX_TLSID_LEN], passwordstr[GTM_PASSPHRASE_MAX_ASCII + 1];
	const char		*errp;
	tls_option		option;
	gtm_tls_socket_t	*tlssocket;
	ABS_TIME		cur_time, end_time;
#	ifdef USE_POLL
	struct pollfd		fds;
#	else
	fd_set			fds, *readfds, *writefds;
	struct timeval		timeout_spec, *timeout_ptr;
#	endif

	iod = io_curr_device.out;
	assert(gtmsocket == iod->type);
	dsocketptr = (d_socket_struct *)iod->dev_sp;
	if (0 >= dsocketptr->n_socket)
	{
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOSOCKETINDEV);
		return;
	}
	if (dsocketptr->n_socket <= dsocketptr->current_socket)
	{
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CURRSOCKOFR, 2, dsocketptr->current_socket, dsocketptr->n_socket);
		return;
	}
	if (dsocketptr->mupintr)
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZINTRECURSEIO);
	socketptr = dsocketptr->socket[dsocketptr->current_socket];
	ENSURE_DATA_SOCKET(socketptr);
	if (socket_tcpip != socketptr->protocol)
	{
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSPARAM, 4, RTS_ERROR_MVAL(optionmval),
			LEN_AND_LIT("but socket is not TCP"));
		return;
	}
	if (socket_connected != socketptr->state)
	{
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSPARAM, 4, LEN_AND_LIT("/TLS"),
			LEN_AND_LIT("but socket not connected"));
		return;
	}
	if (NULL != tlsid)
	{
		length = tlsid->str.len;
		if (MAX_TLSID_LEN < (length + 1))	/* for null */
		{
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSPARAM, 4, LEN_AND_LIT("TLSID"), LEN_AND_LIT("too long"));
			return;
		}
		STRNCPY_STR(idstr, tlsid->str.addr, length);
		idstr[length] = '\0';
	} else
		idstr[0] = '\0';
	if (NULL != password)
	{
		length = password->str.len;
		if (GTM_PASSPHRASE_MAX_ASCII < length)
		{
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSPARAM, 4, LEN_AND_LIT("passphrase"),
				LEN_AND_LIT("too long"));
			return;
		}
		STRNCPY_STR(passwordstr, password->str.addr, length);
		passwordstr[length] = '\0';
	} else
		passwordstr[0] = '\0';
	length = MIN(MAX_TLSOPTION, optionmval->str.len);
	lower_to_upper((uchar_ptr_t)optionstr, (uchar_ptr_t)optionmval->str.addr, length);
	if (0 == memcmp(optionstr, "CLIENT", length))
		option = tlsopt_client;
	else if (0 == memcmp(optionstr, "SERVER", length))
		option = tlsopt_server;
	else if (0 == memcmp(optionstr, "RENEGOTIATE", length))
		option = tlsopt_renegotiate;
	else
		option = tlsopt_invalid;
	memcpy(iod->dollar.device, "0", SIZEOF("0"));
	if (NO_M_TIMEOUT != timeoutarg)
	{
		msec_timeout = timeout2msec(timeoutarg);
		sys_get_curr_time(&cur_time);
		add_int_to_abs_time(&cur_time, msec_timeout, &end_time);
	} else
		msec_timeout = -1;
	if ((tlsopt_client == option) || (tlsopt_server == option))
	{	/* most of the setup is common */
		if (socketptr->tlsenabled)
		{
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSPARAM, 4, LEN_AND_STR(optionstr),
				LEN_AND_LIT("but TLS already enabled"));
			return;
		}
		assertpro((0 >= socketptr->buffered_length) && (0 >= socketptr->obuffer_length));
		if (NULL == tls_ctx)
		{	/* first use of TLS */
			if (-1 == gtm_tls_loadlibrary())
			{
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSDLLNOOPEN, 0, ERR_TEXT, 2, LEN_AND_STR(dl_err));
				return;
			}
			if (NULL == (tls_ctx = (gtm_tls_init(GTM_TLS_API_VERSION, GTMTLS_OP_INTERACTIVE_MODE))))
			{
				errp = gtm_tls_get_error();
				len = SIZEOF(ONE_COMMA) - 1;
				memcpy(iod->dollar.device, ONE_COMMA, len);
				errlen = STRLEN(errp);
				devlen = MIN((SIZEOF(iod->dollar.device) - len - 1), errlen);
				memcpy(&iod->dollar.device[len], errp, devlen + 1);
				if (devlen < errlen)
					iod->dollar.device[SIZEOF(iod->dollar.device) - 1] = '\0';
				if (socketptr->ioerror)
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSINIT, 0, ERR_TEXT, 2, errlen, errp);
				if (NO_M_TIMEOUT != timeoutarg)
					dollar_truth = FALSE;
				return;
			}
		}
		socketptr->tlsenabled = TRUE;
		flags = GTMTLS_OP_SOCKET_DEV | ((tlsopt_client == option) ? GTMTLS_OP_CLIENT_MODE : 0);
		socketptr->tlssocket = gtm_tls_socket(tls_ctx, NULL, socketptr->sd, idstr, flags);
		if (NULL == socketptr->tlssocket)
		{
			socketptr->tlsenabled = FALSE;
			errp = gtm_tls_get_error();
			len = SIZEOF(ONE_COMMA) - 1;
			memcpy(iod->dollar.device, ONE_COMMA, len);
			errlen = STRLEN(errp);
			devlen = MIN((SIZEOF(iod->dollar.device) - len - 1), errlen);
			memcpy(&iod->dollar.device[len], errp, devlen + 1);
			if (devlen < errlen)
				iod->dollar.device[SIZEOF(iod->dollar.device) - 1] = '\0';
			if (socketptr->ioerror)
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSCONVSOCK, 0, ERR_TEXT, 2, errlen, errp);
			if (NO_M_TIMEOUT != timeoutarg)
				dollar_truth = FALSE;
			return;
		}
		status = 0;
#		ifndef	USE_POLL
		if (NO_M_TIMEOUT == timeoutarg)
			timeout_ptr = NULL;
		else
		{
			timeout_spec.tv_sec = msec_timeout / 1000;
			timeout_spec.tv_usec = (msec_timeout % 1000) * 1000;	/* remainder in millsecs to microsecs */
			timeout_ptr = &timeout_spec;
		}
#		endif
		do
		{
			status2 = 0;
			if (0 != status)
			{
#				ifdef USE_POLL
				fds.fd = socketptr->sd;
				fds.events = (GTMTLS_WANT_READ == status) ? POLLIN : POLLOUT;
#				else
				readfds = writefds = NULL;
				assertpro(FD_SETSIZE > socketptr->sd);
				FD_ZERO(&fds);
				FD_SET(socketptr->sd, &fds);
				writefds = (GTMTLS_WANT_WRITE == status) ? &fds : NULL;
				readfds = (GTMTLS_WANT_READ == status) ? &fds : NULL;
#				endif
				POLL_ONLY(if (-1 == (status2 = poll(&fds, 1, msec_timeout))))
				SELECT_ONLY(if (-1 == (status2 = select(socketptr->sd + 1, readfds, writefds, NULL, timeout_ptr))))
				{
					save_errno = errno;
					if (EAGAIN == save_errno)
					{
						rel_quant();	/* allow resources to become available */
						status2 = 0;	/* treat as timeout */
					} else if (EINTR == save_errno)
						status2 = 0;
				}
			} else
				status2 = 1;	/* do accept/connect first time */
			if (0 < status2)
			{
				if (tlsopt_server == option)
					status = gtm_tls_accept((gtm_tls_socket_t *)socketptr->tlssocket);
				else
					status = gtm_tls_connect((gtm_tls_socket_t *)socketptr->tlssocket);
			}
			if ((0 > status2) || ((status != 0) && ((GTMTLS_WANT_READ != status) && (GTMTLS_WANT_WRITE != status))))
			{
				if (0 != status)
				{
					tls_errno = gtm_tls_errno();
					if (0 > tls_errno)
						errp = gtm_tls_get_error();
					else
						errp = STRERROR(tls_errno);
				} else
					errp = STRERROR(save_errno);
				socketptr->tlsenabled = FALSE;
				len = SIZEOF(ONE_COMMA) - 1;
				memcpy(iod->dollar.device, ONE_COMMA, len);
				errlen = STRLEN(errp);
				devlen = MIN((SIZEOF(iod->dollar.device) - len - 1), errlen);
				memcpy(&iod->dollar.device[len], errp, devlen + 1);
				if (devlen < errlen)
					iod->dollar.device[SIZEOF(iod->dollar.device) - 1] = '\0';
				if (socketptr->ioerror)
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSHANDSHAKE, 0,
						ERR_TEXT, 2, errlen, errp);
				return;
			}
			if ((0 != status) && (0 <= status2))	/* not accepted/connected and not error */
			{	/* check for timeout if not error or want read or write */
				if ((0 != timeoutarg) && (NO_M_TIMEOUT != timeoutarg))
				{
					sys_get_curr_time(&cur_time);
					cur_time = sub_abs_time(&end_time, &cur_time);
					if (0 >= cur_time.at_sec)
					{	/* no more time */
						gtm_tls_session_close((gtm_tls_socket_t **)&socketptr->tlssocket);
						socketptr->tlsenabled = FALSE;
						dollar_truth = FALSE;
						return;
					} else
					{	/* adjust msec_timeout for poll/select */
#					ifdef	USE_POLL
						msec_timeout = (cur_time.at_sec * 1000) + (cur_time.at_usec / 1000);
#					else
						timeout_spec.tv_sec = cur_time.at_sec;
						timeout_spec.tv_usec = (gtm_tv_usec_t)cur_time.at_usec;
#					endif
					}
				} else if (0 == timeoutarg)
				{	/* only one chance */
					gtm_tls_session_close((gtm_tls_socket_t **)&socketptr->tlssocket);
					socketptr->tlsenabled = FALSE;
					dollar_truth = FALSE;
					return;
				}
				continue;
			}
		} while ((GTMTLS_WANT_READ == status) || (GTMTLS_WANT_WRITE == status));
		/* turn on output buffering */
		if (0 == socketptr->obuffer_size)
			socketptr->obuffer_size = socketptr->buffer_size;
		socketptr->obuffer_length = socketptr->obuffer_offset = 0;
		socketptr->obuffer_wait_time = DEFAULT_WRITE_WAIT;
		socketptr->obuffer_flush_time = DEFAULT_WRITE_WAIT * 2;	/* until add device parameter */
		socketptr->obuffer = malloc(socketptr->obuffer_size);
	} else if (tlsopt_renegotiate == option)
Esempio n. 16
0
int f_text(oprtype *a, opctype op)
{
	int	implicit_offset = 0;
	triple	*r, *label;

	error_def(ERR_TEXTARG);
	error_def(ERR_RTNNAME);

	r = maketriple(op);
	switch (window_token)
	{
		case TK_CIRCUMFLEX:
			implicit_offset = 1;
			/* CAUTION - fall-through */
		case TK_PLUS:
			r->operand[0] = put_str(zero_mstr.addr, 0);	/* Null label - top of routine */
			break;
		case TK_INTLIT:
			int_label();
			/* CAUTION - fall through */
		case TK_IDENT:
			if (!(cmd_qlf.qlf & CQ_LOWER_LABELS))
				lower_to_upper((uchar_ptr_t)window_ident.addr, (uchar_ptr_t)window_ident.addr, window_ident.len);
			r->operand[0] = put_str(window_ident.addr, window_ident.len);
			advancewindow();
			break;
		case TK_ATSIGN:
			if (!indirection(&(r->operand[0])))
				return FALSE;
			r->opcode = OC_INDTEXT;
			break;
		default:
			stx_error(ERR_TEXTARG);
			return FALSE;
	}
	assert(TK_PLUS == window_token || TK_CIRCUMFLEX == window_token || TK_RPAREN == window_token || TK_EOL == window_token);
	if (OC_INDTEXT != r->opcode || TK_PLUS == window_token || TK_CIRCUMFLEX == window_token)
	{	/* Need another parm chained in to deal with offset and routine name except for the case where an
		 * indirect specifies the entire argument.
		 */
		label = newtriple(OC_PARAMETER);
		r->operand[1] = put_tref(label);
	}
	if (TK_PLUS != window_token)
	{
		if (OC_INDTEXT != r->opcode || TK_CIRCUMFLEX == window_token)
			/* Set default offset (0 or 1 as computed above) when offset not specified */
			label->operand[0] = put_ilit(implicit_offset);
		else
		{	/* Fill in indirect text for case where indirect specifies entire operand */
			r->opcode = OC_INDFUN;
			r->operand[1] = put_ilit((mint)indir_fntext);
		}
	} else
	{	/* Process offset */
		advancewindow();
		if (!intexpr(&(label->operand[0])))
			return FALSE;
	}
	if (TK_CIRCUMFLEX != window_token)
	{	/* No routine specified - default to current routine */
		if (OC_INDFUN != r->opcode)
		{
			if (!run_time)
				label->operand[1] = put_str(routine_name.addr, routine_name.len);
			else
				label->operand[1] = put_tref(newtriple(OC_CURRTN));
		}
	} else
	{	/* Routine has been specified - pull it */
		advancewindow();
		switch(window_token)
		{
			case TK_IDENT:
#				ifdef GTM_TRIGGER
				if (TK_HASH == director_token)
					/* Coagulate tokens as necessary (and available) to allow '#' in the routine name */
					advwindw_hash_in_mname_allowed();
#				endif
				label->operand[1] = put_str(window_ident.addr, window_ident.len);
				advancewindow();
				break;
			case TK_ATSIGN:
				if (!indirection(&label->operand[1]))
					return FALSE;
				r->opcode = OC_INDTEXT;
				break;
			default:
				stx_error(ERR_RTNNAME);
				return FALSE;
		}
	}
	ins_triple(r);
	*a = put_tref(r);
	return TRUE;
}
Esempio n. 17
0
int f_text(oprtype *a, opctype op)
{
	char	*c;
	int	implicit_offset = 0, len;
	triple	*label, *r;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	r = maketriple(op);
	switch (TREF(window_token))
	{
	case TK_CIRCUMFLEX:
		implicit_offset = 1;
		/* CAUTION - fall-through */
	case TK_PLUS:
		r->operand[0] = put_str(zero_mstr.addr, 0);	/* Null label - top of routine */
		break;
	case TK_INTLIT:
		int_label();
		/* CAUTION - fall through */
	case TK_IDENT:
		if (!(cmd_qlf.qlf & CQ_LOWER_LABELS))
			lower_to_upper((uchar_ptr_t)(TREF(window_ident)).addr, (uchar_ptr_t)(TREF(window_ident)).addr,
				(TREF(window_ident)).len);
		r->operand[0] = put_str((TREF(window_ident)).addr, (TREF(window_ident)).len);
		advancewindow();
		break;
	case TK_ATSIGN:
		if (!indirection(&(r->operand[0])))
			return FALSE;
		r->opcode = OC_INDTEXT;
		break;
	default:
		stx_error(ERR_TEXTARG);
		return FALSE;
	}
	/* The assert below can be useful when working on $TEXT parsing issues but causes problems in debug builds with
	 * bad syntax asserts. Hence it is normally commented out. Uncomment to re-enable for $TEXT parsing issues.
	 */
	/* assert((TK_PLUS == TREF(window_token)) || (TK_CIRCUMFLEX == TREF(window_token)) || (TK_RPAREN == TREF(window_token))
	 *	|| (TK_EOL == TREF(window_token)));
	 */
	if ((OC_INDTEXT != r->opcode) || (TK_PLUS == TREF(window_token)) || (TK_CIRCUMFLEX == TREF(window_token)))
	{	/* Need another parm chained in to deal with offset and routine name except for the case where an
		 * indirect specifies the entire argument.
		 */
		label = newtriple(OC_PARAMETER);
		r->operand[1] = put_tref(label);
	}
	if (TK_PLUS != TREF(window_token))
	{
		if ((OC_INDTEXT != r->opcode) || (TK_CIRCUMFLEX == TREF(window_token)))
			/* Set default offset (0 or 1 as computed above) when offset not specified */
			label->operand[0] = put_ilit(implicit_offset);
		else
		{	/* Fill in indirect text for case where indirect specifies entire operand */
			r->opcode = OC_INDFUN;
			r->operand[1] = put_ilit((mint)indir_fntext);
		}
	} else
	{	/* Process offset */
		advancewindow();
		if (EXPR_FAIL == expr(&(label->operand[0]), MUMPS_INT))
			return FALSE;
	}
	if (TK_CIRCUMFLEX != TREF(window_token))
	{	/* No routine specified - default to current routine */
		if (OC_INDFUN != r->opcode)
			label->operand[1] = PUT_CURRENT_RTN; /* tell op_fntext to pick up current routine version */
	} else
	{	/* Routine has been specified - pull it */
		advancewindow();
		switch (TREF(window_token))
		{
		case TK_IDENT:
#			ifdef GTM_TRIGGER
			if (TK_HASH == TREF(director_token))
				/* Coagulate tokens as necessary (and available) to allow '#' in the routine name */
				advwindw_hash_in_mname_allowed();
#			endif
			if (TK_DOLLAR == TREF(director_token))		/* the item has a $ in it */
			{	/*  violate information hiding to special case illegal names GT.M can return from $STACK() et al */
				c = TREF(lexical_ptr) - STR_LIT_LEN("GTM$");
				advancewindow();			/* parse to $ */
				if (0 == memcmp(c, "GTM$", STR_LIT_LEN("GTM$")))
				{	/* parse past GTM$DMOD or GTM$CI to prevent RPARENMISSING error */
					advancewindow();		/* parse to end of ident */
					len = TREF(lexical_ptr) - c - (TK_EOL == TREF(director_token) ? 0 : 1);
					for (implicit_offset = 0; ARRAYSIZE(suppressed_values) > implicit_offset; implicit_offset++)
					{	 /* reuse of implicit_offset */
						if ((STRLEN(suppressed_values[implicit_offset]) == len)
								&& (0 == memcmp(c, suppressed_values[implicit_offset], len)))
						{
							label->operand[1] = put_str(suppressed_values[implicit_offset], len);
							break;
						}
					}
					if (ARRAYSIZE(suppressed_values) == implicit_offset)
						(TREF(last_source_column))--;	/* if no match (error) adjust for extra parse */
				} else
					implicit_offset = ARRAYSIZE(suppressed_values);
				if (ARRAYSIZE(suppressed_values) == implicit_offset)
				{	/* give the error that would arise had we just ignored the $ */
					stx_error(ERR_RPARENMISSING);
					return FALSE;
				}
			} else
				label->operand[1] = put_str((TREF(window_ident)).addr, (TREF(window_ident)).len);
			advancewindow();
			break;
		case TK_ATSIGN:
			if (!indirection(&label->operand[1]))
				return FALSE;
			r->opcode = OC_INDTEXT;
			break;
		default:
			stx_error(ERR_RTNNAME);
			return FALSE;
		}
	}
	ins_triple(r);
	*a = put_tref(r);
	return TRUE;
}