Exemple #1
0
boolean_t mur_report_error(jnl_ctl_list *jctl, enum mur_error code)
{
	error_def(ERR_BOVTMGTEOVTM);
	error_def(ERR_DUPTOKEN);
	error_def(ERR_JNLBADRECFMT);
	error_def(ERR_PREVJNLNOEOF);
	error_def(ERR_UNKNOWNRECTYPE);

	switch (code)
	{
	default:
		assert(FALSE);
		break;

	case MUR_DUPTOKEN:
		assert(FALSE);
 		gtm_putmsg(VARLSTCNT(7) ERR_DUPTOKEN, 5, &((struct_jrec_tcom *)jctl->reg_ctl->mur_desc->jnlrec)->token_seq.token,
 				jctl->jnl_fn_len, jctl->jnl_fn, DB_LEN_STR(jctl->reg_ctl->gd));
		break;

	case MUR_PREVJNLNOEOF:
		gtm_putmsg(VARLSTCNT(4) ERR_PREVJNLNOEOF, 2, jctl->jnl_fn_len, jctl->jnl_fn);
		break;

	case MUR_JNLBADRECFMT:
		gtm_putmsg(VARLSTCNT(5) ERR_JNLBADRECFMT, 3, jctl->jnl_fn_len, jctl->jnl_fn, jctl->rec_offset);
		break;

	case MUR_BOVTMGTEOVTM:
		gtm_putmsg(VARLSTCNT(6) ERR_BOVTMGTEOVTM, 4, jctl->jnl_fn_len, jctl->jnl_fn,
							&jctl->jfh->bov_timestamp, &jctl->jfh->eov_timestamp);
		break;
	}
	return MUR_WITHIN_ERROR_LIMIT(murgbl.err_cnt, mur_options.error_limit); /* side-effect : increments murgbl.err_cnt */
}
Exemple #2
0
boolean_t mur_report_error(enum mur_error code)
{
	error_def(ERR_UNKNOWNRECTYPE);
	error_def(ERR_DUPTOKEN);
	error_def(ERR_PREVJNLNOEOF);
	error_def(ERR_JNLBADRECFMT);

	switch (code)
	{
	default:
		assert(FALSE);
		break;

	case MUR_DUPTOKEN:
		assert(FALSE);
 		gtm_putmsg(VARLSTCNT(7) ERR_DUPTOKEN, 5, &((struct_jrec_tcom *)mur_rab.jnlrec)->token_seq.token,
 				mur_jctl->jnl_fn_len, mur_jctl->jnl_fn, DB_LEN_STR(mur_ctl[mur_regno].gd));
		break;

	case MUR_PREVJNLNOEOF:
		gtm_putmsg(VARLSTCNT(4) ERR_PREVJNLNOEOF, 2, mur_jctl->jnl_fn_len, mur_jctl->jnl_fn);
		break;

	case MUR_JNLBADRECFMT:
		gtm_putmsg(VARLSTCNT(5) ERR_JNLBADRECFMT, 3, mur_jctl->jnl_fn_len, mur_jctl->jnl_fn, mur_jctl->rec_offset);
		break;
	case MUR_BOVTMGTEOVTM:
		break;

	}
	return MUR_WITHIN_ERROR_LIMIT(murgbl.err_cnt, mur_options.error_limit); /* side-effect : increments murgbl.err_cnt */
}
Exemple #3
0
int mu_rndwn_sem_all(void)
{
	int 			save_errno, exit_status = SS_NORMAL, semid;
	char			entry[MAX_ENTRY_LEN];
	FILE			*pf;
	char			fname[MAX_FN_LEN + 1], *fgets_res;
	boolean_t 		rem_sem;
	shm_parms		*parm_buff;

	if (NULL == (pf = POPEN(IPCS_SEM_CMD_STR ,"r")))
        {
		save_errno = errno;
		gtm_putmsg(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("POPEN()"), CALLFROM, save_errno);
                return ERR_MUNOTALLSEC;
        }
	while (NULL != (FGETS(entry, SIZEOF(entry), pf, fgets_res)) && entry[0] != '\n')
	{
		if (-1 != (semid = parse_sem_id(entry)))
		{
			if (is_orphaned_gtm_semaphore(semid))
			{
				if (-1 != semctl(semid, 0, IPC_RMID))
				{
					gtm_putmsg(VARLSTCNT(3) ERR_SEMREMOVED, 1, semid);
					send_msg(VARLSTCNT(3) ERR_SEMREMOVED, 1, semid);
				}
			}
		}
	}
	pclose(pf);
	return exit_status;
}
void cre_jnl_file_intrpt_rename(int fn_len, sm_uc_ptr_t fn)
{
	mstr 		filestr;
	int		status1, status2, ext_new_jnl_fn_len;
	uint4		status, ustatus;
	unsigned char	ext_new_jnl_fn[MAX_FN_LEN];
	error_def(ERR_FILEPARSE);
	error_def(ERR_RENAMEFAIL);
	error_def(ERR_FILEDELFAIL);
	error_def(ERR_FILEDEL);
	error_def(ERR_FILERENAME);

	filestr.addr = (char *)fn;
	filestr.len = fn_len;
	prepare_unique_name((char *)fn, fn_len, "", EXT_NEW, (char *)ext_new_jnl_fn, &ext_new_jnl_fn_len, &ustatus);
	assert(SS_NORMAL == ustatus);
	status1 = gtm_file_stat(&filestr, NULL, NULL, FALSE, &ustatus);
	if (FILE_STAT_ERROR == status1)
	{
		if (run_time)
			send_msg(VARLSTCNT(5) ERR_FILEPARSE, 2, filestr.len, filestr.addr, ustatus);
		else
			gtm_putmsg(VARLSTCNT(5) ERR_FILEPARSE, 2, filestr.len, filestr.addr, ustatus);
		return;
	}
	filestr.addr = (char *)ext_new_jnl_fn;
	filestr.len = ext_new_jnl_fn_len;
	status2 = gtm_file_stat(&filestr, NULL, NULL, FALSE, &ustatus);
	if (FILE_STAT_ERROR == status2)
	{
		if (run_time)
			send_msg(VARLSTCNT(5) ERR_FILEPARSE, 2, filestr.len, filestr.addr, ustatus);
		else
			gtm_putmsg(VARLSTCNT(5) ERR_FILEPARSE, 2, filestr.len, filestr.addr, ustatus);
		return;
	}
	if (FILE_NOT_FOUND == status1)
	{
		if (FILE_PRESENT == status2)
		{
			status = gtm_rename(filestr.addr, filestr.len, (char *)fn, fn_len, &ustatus);
			if (SYSCALL_ERROR(status))
			{
				if (run_time)
				{
					VMS_ONLY(send_msg(VARLSTCNT(8) ERR_RENAMEFAIL, 4, filestr.len, filestr.addr,
						fn_len, fn, status, ustatus);)
					UNIX_ONLY(send_msg(VARLSTCNT(7) ERR_RENAMEFAIL, 4, filestr.len, filestr.addr,
						fn_len, fn, status);)
				} else
				{
					VMS_ONLY(gtm_putmsg(VARLSTCNT(8) ERR_RENAMEFAIL, 4, filestr.len, filestr.addr,
						fn_len, fn, status, ustatus);)
					UNIX_ONLY(gtm_putmsg(VARLSTCNT(7) ERR_RENAMEFAIL, 4, filestr.len, filestr.addr,
						fn_len, fn, status);)
				}
/*
 * Description:
 * 	Grab ftok semaphore on replication instance file
 *	Release all replication semaphores for the instance (both jnlpool and recvpool)
 * 	Release ftok semaphore
 * Parameters:
 * Return Value: TRUE, if succsessful
 *	         FALSE, if fails.
 */
boolean_t mu_replpool_remove_sem(boolean_t immediate)
{
	char            *instname;
	gd_region	*replreg;
	unix_db_info	*udi;
	unsigned int	full_len;
	int		save_errno;

	error_def(ERR_REPLFTOKSEM);
	error_def(ERR_REPLACCSEM);

	/*
	 * JNL POOL SEMAPHORES
	 */
	replreg = jnlpool.jnlpool_dummy_reg;
	assert(replreg);
	instname = (char *)replreg->dyn.addr->fname;
	full_len = replreg->dyn.addr->fname_len;
	if (0 == full_len)
		return TRUE;
	if (!ftok_sem_get(replreg, TRUE, REPLPOOL_ID, immediate))
		rts_error(VARLSTCNT(4) ERR_REPLFTOKSEM, 2, full_len, instname);
	if (0 != remove_sem_set(SOURCE))
	{
		save_errno = REPL_SEM_ERRNO;
		if (!ftok_sem_release(replreg, TRUE, TRUE))
			gtm_putmsg(VARLSTCNT(4) ERR_REPLFTOKSEM, 2, full_len, instname);
		udi = FILE_INFO(replreg);
		rts_error(VARLSTCNT(6) ERR_REPLACCSEM, 3, udi->semid, full_len, instname, save_errno);
	}
	repl_inst_jnlpool_reset();
	/*
	 * RECV POOL SEMAPHORES
	 */
	replreg = recvpool.recvpool_dummy_reg;
	assert(replreg);
	if (0 != remove_sem_set(RECV))
	{
		save_errno = REPL_SEM_ERRNO;
		if (!ftok_sem_release(replreg, TRUE, TRUE))
			gtm_putmsg(VARLSTCNT(4) ERR_REPLFTOKSEM, 2, full_len, instname);
		udi = FILE_INFO(replreg);
		rts_error(VARLSTCNT(6) ERR_REPLACCSEM, 3, udi->semid, full_len, instname, save_errno);
	}
	repl_inst_recvpool_reset();
	if (!ftok_sem_release(replreg, TRUE, immediate))
		rts_error(VARLSTCNT(4) ERR_REPLFTOKSEM, 2, full_len, instname);
	return TRUE;
}
Exemple #6
0
static void tcp_write(char *temp, char *buf, int nbytes)
{
	int 	socket, nwritten, iostatus, send_retry;

	socket = *(int *)(temp);

	nwritten = 0;
	send_retry = MAX_TCP_SEND_RETRY;

	do
	{
		if (-1 != (iostatus = tcp_routines.aa_send(socket, buf + nwritten, nbytes - nwritten, 0)))
		{
			nwritten += iostatus;
			if (nwritten == nbytes)
				break;
		} else if (EINTR != errno)
			break;
	} while (0 < send_retry--);

	if ((nwritten != nbytes) && (-1 == iostatus))
	{
		gtm_putmsg(VARLSTCNT(1) errno);
		tcp_routines.aa_close(socket);
		backup_write_errno = errno;
	}

	return;
}
/* input parameter "command_name" is a string that is either "MUPIP REORG UPGRADE/DOWNGRADE" or "MUPIP SET VERSION" */
int4	desired_db_format_set(gd_region *reg, enum db_ver new_db_format, char *command_name)
{
	boolean_t		was_crit;
	char			*db_fmt_str;
	char			*wcblocked_ptr;
	int4			status;
	uint4			jnl_status;
	inctn_opcode_t		save_inctn_opcode;
	sgmnt_addrs		*csa;
	sgmnt_data_ptr_t	csd;
	trans_num		curr_tn;
	jnl_private_control	*jpc;
	jnl_buffer_ptr_t	jbp;

	assert(reg->open);
	csa = &FILE_INFO(reg)->s_addrs;
	csd = csa->hdr;
	GTMCRYPT_ONLY(
		/* We don't allow databases to be encrypted if the version is V4 */
		if (csd->is_encrypted && (GDSV4 == new_db_format))
		{
			gtm_putmsg(VARLSTCNT(4) ERR_CRYPTNOV4, 2, DB_LEN_STR(reg));
			return ERR_CRYPTNOV4;
		}
	)
Exemple #8
0
STATICFNDEF void mu_rndwn_all_helper(shm_parms *parm_buff, char *fname, int *exit_status, int *tmp_exit_status)
{
	replpool_identifier	replpool_id;
	boolean_t 		ret_status, jnlpool_sem_created;
	unsigned char		ipcs_buff[MAX_IPCS_ID_BUF], *ipcs_ptr;

	ESTABLISH(mu_rndwn_all_helper_ch);
	if (validate_db_shm_entry(parm_buff, fname, tmp_exit_status))
	{
		if (SS_NORMAL == *tmp_exit_status)
		{	/* shm still exists */
			mu_gv_cur_reg_init();
			gv_cur_region->dyn.addr->fname_len = strlen(fname);
			STRNCPY_STR(gv_cur_region->dyn.addr->fname, fname, gv_cur_region->dyn.addr->fname_len);
			if (mu_rndwn_file(gv_cur_region, FALSE))
				gtm_putmsg(VARLSTCNT(4) ERR_MUFILRNDWNSUC, 2, DB_LEN_STR(gv_cur_region));
			else
				*exit_status = ERR_MUNOTALLSEC;
			mu_gv_cur_reg_free();
		} else
		{	/* shm has been cleaned up by "validate_db_shm_entry" so no need of any more cleanup here */
			assert(ERR_SHMREMOVED == *tmp_exit_status);
			*tmp_exit_status = SS_NORMAL;	/* reset tmp_exit_status for below logic to treat this as normal */
		}
	} else if ((SS_NORMAL == *tmp_exit_status)
		&& validate_replpool_shm_entry(parm_buff, (replpool_id_ptr_t)&replpool_id, tmp_exit_status))
	{
		if (SS_NORMAL == *tmp_exit_status)
		{
			assert(JNLPOOL_SEGMENT == replpool_id.pool_type || RECVPOOL_SEGMENT == replpool_id.pool_type);
			ret_status = mu_rndwn_repl_instance(&replpool_id, TRUE, FALSE, &jnlpool_sem_created);
			ipcs_ptr = i2asc((uchar_ptr_t)ipcs_buff, parm_buff->shmid);
			*ipcs_ptr = '\0';
			gtm_putmsg(VARLSTCNT(6) (JNLPOOL_SEGMENT == replpool_id.pool_type) ?
				(ret_status ? ERR_MUJPOOLRNDWNSUC : ERR_MUJPOOLRNDWNFL) :
				(ret_status ? ERR_MURPOOLRNDWNSUC : ERR_MURPOOLRNDWNFL),
				4, LEN_AND_STR(ipcs_buff), LEN_AND_STR(replpool_id.instfilename));
			if (!ret_status)
				*exit_status = ERR_MUNOTALLSEC;
		} else
		{	/* shm has been cleaned up by "validate_replpool_shm_entry" so no need of any more cleanup here */
			assert(ERR_SHMREMOVED == *tmp_exit_status);
			*tmp_exit_status = SS_NORMAL;	/* reset tmp_exit_status for below logic to treat this as normal */
		}
	}
	REVERT;
}
uint4 mupip_set_journal_newstate(set_jnl_options *jnl_options, jnl_create_info *jnl_info, mu_set_rlist *rptr)
{
	enum jnl_state_codes	jnl_curr_state;
	enum repl_state_codes	repl_curr_state;
	boolean_t 		current_image;
	enum db_acc_method	acc_meth;

	error_def(ERR_REPLNOBEFORE);
	error_def(ERR_REPLJNLCNFLCT);
	error_def(ERR_JNLDISABLE);
	error_def(ERR_MMBEFOREJNL);
	error_def(ERR_MMNOBFORRPL);

	jnl_curr_state = (enum jnl_state_codes)rptr->sd->jnl_state;
	repl_curr_state = (enum repl_state_codes)rptr->sd->repl_state;
	acc_meth = rptr->sd->acc_meth;
	current_image = rptr->sd->jnl_before_image;
	if (CLI_ABSENT == jnl_options->cli_journal)
		rptr->jnl_new_state = jnl_curr_state;
	else if ((CLI_NEGATED == jnl_options->cli_journal) || (CLI_NEGATED == jnl_options->cli_enable))
		rptr->jnl_new_state = jnl_notallowed; /* DISABLE specified */
	else if ((jnl_notallowed != jnl_curr_state) || (CLI_PRESENT == jnl_options->cli_enable))
	{	/* journaling is already ENABLED or ENABLE is explicitly specified */
		if (CLI_NEGATED == jnl_options->cli_on)	/* OFF specified */
			rptr->jnl_new_state = jnl_closed;
		else if (repl_curr_state == repl_was_open && CLI_PRESENT != jnl_options->cli_replic_on)
		{ /* Journaling was turned OFF by jnl_file_lost(). Do not allow turning journaling ON without also
		     turning replication ON */
			gtm_putmsg(VARLSTCNT(10) ERR_REPLJNLCNFLCT, 8, LEN_AND_STR(jnl_state_lit[jnl_open]),
					DB_LEN_STR(gv_cur_region), LEN_AND_STR(repl_state_lit[repl_closed]),
					LEN_AND_STR(jnl_state_lit[jnl_open]));
			return EXIT_WRN;
		}
		else /* ON explicitly specified or present by default */
			rptr->jnl_new_state = jnl_open;
	} else	/* jnl_notallowed == jnl_curr_state && CLI_ABSENT == jnl_options->cli_enable */
	{
		if (CLI_PRESENT != jnl_options->cli_replic_on)
		{
			gtm_putmsg(VARLSTCNT(4) ERR_JNLDISABLE, 2, DB_LEN_STR(gv_cur_region));
			return EXIT_WRN;
		} else
			rptr->jnl_new_state = jnl_open;	/* turn journaling on for REPLICATION=ON */
	}
	VMS_ONLY(rptr->before_images = (jnl_options->image_type_specified ?  jnl_info->before_images : current_image);)
Exemple #10
0
boolean_t mur_fopen_sp(jnl_ctl_list *jctl)
{
	struct stat		stat_buf;
	int			status, perms;

	error_def(ERR_JNLFILEOPNERR);
	error_def(ERR_SYSCALL);

	perms = O_RDONLY;
	jctl->read_only = TRUE;
	/* Both for recover and rollback open in read/write mode. We do not need to write in journal file
	 * for mupip journal extract/show/verify or recover -forward.  So open it as read-only
	 */
	if (mur_options.update && !mur_options.forward)
	{
		perms = O_RDWR;
		jctl->read_only = FALSE;
	}
	jctl->channel = OPEN((char *)jctl->jnl_fn, perms);
	if (-1 != jctl->channel)
	{
		FSTAT_FILE(jctl->channel, &stat_buf, status);
		if (-1 != status)
		{
			jctl->os_filesize = (off_jnl_t)stat_buf.st_size;
			return TRUE;
		}
		jctl->status = errno;
		CLOSEFILE(jctl->channel, status);
	} else
		jctl->status = errno;
	if (ENOENT == jctl->status)	/* File Not Found is a common error, so no need for SYSCALL */
		gtm_putmsg(VARLSTCNT(5) ERR_JNLFILEOPNERR, 2, jctl->jnl_fn_len, jctl->jnl_fn, jctl->status);
	else
		gtm_putmsg(VARLSTCNT(12) ERR_JNLFILEOPNERR, 2, jctl->jnl_fn_len, jctl->jnl_fn, ERR_SYSCALL, 5,
			LEN_AND_STR((-1 == jctl->channel) ? "open" : "fstat"), CALLFROM, jctl->status);
	jctl->channel = NOJNL;
	return FALSE;
}
Exemple #11
0
static bool lke_process(int argc)
{
    bool		flag = FALSE;
    int		res;
    static int	save_stderr = SYS_STDERR;

    ESTABLISH_RET(util_ch, TRUE);
    if (util_interrupt)
        rts_error(VARLSTCNT(1) ERR_CTRLC);
    if (SYS_STDERR != save_stderr)  /* necesary in case of rts_error */
        close_fileio(&save_stderr);
    assert(SYS_STDERR == save_stderr);

    func = 0;
    util_interrupt = 0;
    if (argc < 2)
        display_prompt();
    if ( EOF == (res = parse_cmd()))
    {
        if (util_interrupt)
        {
            rts_error(VARLSTCNT(1) ERR_CTRLC);
            REVERT;
            return TRUE;
        }
        else
        {
            REVERT;
            return FALSE;
        }
    } else if (res)
    {
        if (1 < argc)
        {
            REVERT;
            rts_error(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
        } else
            gtm_putmsg(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
    }
    if (func)
    {
        flag = open_fileio(&save_stderr); /* save_stderr = SYS_STDERR if -output option not present */
        func();
        if (flag)
            close_fileio(&save_stderr);
        assert(SYS_STDERR == save_stderr);
    }
    REVERT;
    return(1 >= argc);
}
Exemple #12
0
void turn_tracing_on(mval *gvn)
{
	struct tms	*curr;
	trace_entry	tmp_trc_tbl_entry;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	if (is_tracing_on)
	{
		gtm_putmsg(VARLSTCNT(1) ERR_TRACINGON);
		return;
	}
	if (0 == gvn->str.len || '^' != gvn->str.addr[0])
		rts_error(VARLSTCNT(4) ERR_NOTGBL, 2, gvn->str.len, gvn->str.addr);
	if (!TREF(mprof_ptr))
	{
		TREF(mprof_ptr) = (mprof_wrapper *)malloc(SIZEOF(mprof_wrapper));
		memset(TREF(mprof_ptr), 0, SIZEOF(mprof_wrapper));
	}
	parse_gvn(gvn);
	(TREF(mprof_ptr))->gbl_to_fill = *gvn;
	(TREF(mprof_ptr))->gbl_to_fill.str.addr = (char *)malloc(gvn->str.len); /* len was already set up */
	memcpy((TREF(mprof_ptr))->gbl_to_fill.str.addr, gvn->str.addr, gvn->str.len);
	if (!(TREF(mprof_ptr))->pcavailbase)
	{
		(TREF(mprof_ptr))->pcavailbase = (char **)malloc(PROFCALLOC_DSBLKSIZE);
		*(TREF(mprof_ptr))->pcavailbase = 0;
	}
	(TREF(mprof_ptr))->pcavailptr = (TREF(mprof_ptr))->pcavailbase;
	(TREF(mprof_ptr))->pcavail = PROFCALLOC_DSBLKSIZE - SIZEOF(char *);
	memset((TREF(mprof_ptr))->pcavailptr + 1, 0, (TREF(mprof_ptr))->pcavail);
	curr = &((TREF(mprof_ptr))->tprev);
	TIMES(curr);
	mprof_stack_init();
	TREF(prof_fp) = mprof_stack_push();
	get_entryref_information(FALSE, NULL);
	tmp_trc_tbl_entry.rout_name = NULL;
	tmp_trc_tbl_entry.label_name = NULL;
	(TREF(mprof_ptr))->curr_tblnd = (TREF(mprof_ptr))->head_tblnd = NULL;
	(TREF(prof_fp))->start.tms_stime = (*curr).tms_stime;
	(TREF(prof_fp))->start.tms_utime = (*curr).tms_utime;
	(TREF(prof_fp))->carryover.tms_stime = 0;
	(TREF(prof_fp))->carryover.tms_utime = 0;
	(TREF(prof_fp))->dummy_stack_count = 0;
	(TREF(prof_fp))->rout_name = (TREF(prof_fp))->label_name = NULL;
	POPULATE_PROFILING_TABLE();
	is_tracing_on = TRUE;
	return;
}
/* --------------------------------------------------------------------------------
	This function  renames a file, if exists. Otherwise do nothing.
  --------------------------------------------------------------------------------- */
int rename_file_if_exists(char *org_fn, int org_fn_len, char *rename_fn, int *rename_fn_len, uint4 *ustatus)
{
	mstr 		orgfile;
	int		status;
	error_def(ERR_FILERENAME);
	error_def(ERR_RENAMEFAIL);

	memcpy(rename_fn, org_fn, org_fn_len + 1); /* Ensure it to be NULL terminated */
	*rename_fn_len = org_fn_len;
	orgfile.addr = org_fn;
	orgfile.len = org_fn_len;
	if (FILE_NOT_FOUND == (status = gtm_file_stat(&orgfile, NULL, NULL, FALSE, ustatus)))
		return RENAME_NOT_REQD;
	else if (FILE_STAT_ERROR == status)
		return RENAME_FAILED;
	/* File is present in the system */
	assert(0 <  MAX_FN_LEN - org_fn_len - 1);
	if (SS_NORMAL != (status = prepare_unique_name(org_fn, org_fn_len, "", "", rename_fn, rename_fn_len, ustatus)))
		return RENAME_FAILED;
	assert(0 == rename_fn[*rename_fn_len]);
	if (SS_NORMAL != (status= gtm_rename(org_fn, org_fn_len, rename_fn, *rename_fn_len, ustatus)))
	{
		if (run_time)
			send_msg(VARLSTCNT(9) ERR_RENAMEFAIL, 4, org_fn_len, org_fn, *rename_fn_len, rename_fn,
				status, 0, *ustatus);
		else
			gtm_putmsg(VARLSTCNT1(8) ERR_RENAMEFAIL, 4, org_fn_len, org_fn, *rename_fn_len, rename_fn,
				status, PUT_SYS_ERRNO(*ustatus));
		return RENAME_FAILED;
	}
	if (run_time)
		send_msg(VARLSTCNT (6) ERR_FILERENAME, 4, org_fn_len, org_fn, *rename_fn_len, rename_fn);
	else
		gtm_putmsg(VARLSTCNT (6) ERR_FILERENAME, 4, org_fn_len, org_fn, *rename_fn_len, rename_fn);
	return RENAME_SUCCESS;
}
Exemple #14
0
/* the logic here can be reused in iotcp_readfl.c and iosocket_readfl.c */
static void tcp_read(BFILE *bf, char *buf, int nbytes)
{
	int     	needed, status;
	char		*curr;
	fd_set          fs;
	ABS_TIME	save_nap, nap;

	needed = nbytes;
	curr = buf;

	nap.at_sec = 1;
	nap.at_usec = 0;

	while (1)
	{
		FD_ZERO(&fs);
		FD_SET(bf->fd, &fs);
		assert(0 != FD_ISSET(bf->fd, &fs));
		/* Note: the check for EINTR from the select below should remain, as aa_select is a
		 * function, and not all callers of aa_select behave the same when EINTR is returned.
		 */
                save_nap = nap;
		status = tcp_routines.aa_select(bf->fd + 1, (void *)(&fs), (void *)0, (void *)0, &nap);
                nap = save_nap;

		if (status > 0)
		{
			status = tcp_routines.aa_recv(bf->fd, curr, needed, 0);
			if ((0 == status) || (needed == status))        /* lost connection or all set */
			{
				break;
			} else if (status > 0)
			{
				needed -= status;
				curr += status;
			}
		}
		if ((status < 0) && (errno != EINTR))
		{
			gtm_putmsg(VARLSTCNT(1) errno);
			close(bf->fd);
			restore_read_errno = errno;
			break;
		}
	}
	return;
}
Exemple #15
0
int main (int argc, char **argv)
{
	int		res;
	DCL_THREADGBL_ACCESS;

	GTM_THREADGBL_INIT;
	set_blocksig();
	gtm_imagetype_init(MUPIP_IMAGE);
	invocation_mode = MUMPS_UTILTRIGR;
	gtm_wcswidth_fnptr = gtm_wcswidth;
	gtm_env_init();	/* read in all environment variables */
	err_init(util_base_ch);
	UNICODE_ONLY(gtm_strToTitle_ptr = &gtm_strToTitle);
	GTM_ICU_INIT_IF_NEEDED;	/* Note: should be invoked after err_init (since it may error out) and before CLI parsing */
	sig_init(generic_signal_handler, NULL, suspsigs_handler, continue_handler);	/* Note: no ^C handler is defined (yet) */
	atexit(mupip_exit_handler);
	licensed = TRUE;
	in_backup = FALSE;
	op_open_ptr = mu_op_open;
	mu_get_term_characterstics();
	cli_lex_setup(argc,argv);
	if (argc < 2)			/* Interactive mode */
		display_prompt();
	/*      this call should be after cli_lex_setup() due to S390 A/E conversion    */
	gtm_chk_dist(argv[0]);
	INIT_GBL_ROOT(); /* Needed for GVT initialization */
	init_gtm();
	while (TRUE)
	{	func = 0;
		if ((res = parse_cmd()) == EOF)
			break;
		else if (res)
		{
			if (1 < argc)
				rts_error(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
			else
				gtm_putmsg(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
		}
		if (func)
			func();
		if (argc > 1)		/* Non-interactive mode, exit after command */
			break;
		display_prompt();
	}
	mupip_exit(SS_NORMAL);
}
void gtmsource_seqno_init(void)
{
	/* Find the start_jnl_seqno */

	gd_region		*reg, *region_top;
	seq_num			local_read_jsn, local_jsn;
	sgmnt_addrs		*csa;
	sgmnt_data_ptr_t	csd;
	sm_uc_ptr_t		gld_fn;

	/* Unix and VMS have different field names for now, but will both be soon changed to instname instead of gtmgbldir */
	gld_fn = (sm_uc_ptr_t)jnlpool.jnlpool_ctl->jnlpool_id.gtmgbldir;
	QWASSIGN(jnlpool.jnlpool_ctl->start_jnl_seqno, seq_num_zero);
	QWASSIGN(local_read_jsn, seq_num_zero);
	QWASSIGN(local_jsn, seq_num_zero);
	region_top = gd_header->regions + gd_header->n_regions;
	for (reg = gd_header->regions; reg < region_top; reg++)
	{
		assert(reg->open);
		csa = &FILE_INFO(reg)->s_addrs;
		csd = csa->hdr;
		if (REPL_ALLOWED(csd))
		{
			if (QWLT(local_read_jsn, csd->resync_seqno))
				QWASSIGN(local_read_jsn, csd->resync_seqno);
			if (QWLT(local_jsn, csd->reg_seqno))
				QWASSIGN(local_jsn, csd->reg_seqno);
			/* Copy gtmgbldir into the database shared memory.
			 * Used later to avoid updates from a different gtmgbldir to this database.
			 */
			assert(SIZEOF(csa->nl->replinstfilename) == SIZEOF(jnlpool.jnlpool_ctl->jnlpool_id.gtmgbldir));
			memcpy(csa->nl->replinstfilename, gld_fn, SIZEOF(csa->nl->replinstfilename));
		}
	}
	if (QWEQ(local_jsn, seq_num_zero))
	{
		/* No replicated region, or databases created with older version of GTM */
		gtm_putmsg(VARLSTCNT(5) ERR_NOREPLCTDREG, 3, LEN_AND_LIT("global directory"), gld_fn);
		/* Error, has to shutdown all regions 'cos mupip needs exclusive access to turn replication on */
		gtmsource_autoshutdown();
	}
	QWASSIGN(jnlpool.jnlpool_ctl->start_jnl_seqno, local_jsn);
	QWASSIGN(jnlpool.jnlpool_ctl->jnl_seqno, local_jsn);
	QWASSIGN(jnlpool.gtmsource_local->read_jnl_seqno, local_read_jsn);
}
Exemple #17
0
/* Enables tracing and ensures that all critical structures are initialized */
void turn_tracing_on(mval *gvn, boolean_t from_env, boolean_t save_gbl)
{
	ext_tms		curr;
	trace_entry	tmp_trc_tbl_entry;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	mdb_ch_set = !from_env;
	/* if tracing is on explicitly, or if it is implicit with saving */
	if (save_gbl || !from_env)
	{
		if (is_tracing_on)
		{
			gtm_putmsg(VARLSTCNT(1) ERR_TRACINGON);
			return;
		}
		if ((0 == gvn->str.len) || ('^' != gvn->str.addr[0]))
			MPROF_RTS_ERROR((VARLSTCNT(4) ERR_NOTGBL, 2, gvn->str.len, gvn->str.addr));
	}
	/* the following should only be a one-time operation */
	if (!TREF(mprof_ptr))
	{
		TREF(mprof_ptr) = (mprof_wrapper *)malloc(SIZEOF(mprof_wrapper));
		memset(TREF(mprof_ptr), 0, SIZEOF(mprof_wrapper));
	}
	/* only need to have the gvn if we are going to save the data */
	if (save_gbl && (0 < gvn->str.len))
	{
		parse_gvn(gvn);
		(TREF(mprof_ptr))->gbl_to_fill = *gvn;
		(TREF(mprof_ptr))->gbl_to_fill.str.addr = (char *)malloc(gvn->str.len); /* len was already set up */
		memcpy((TREF(mprof_ptr))->gbl_to_fill.str.addr, gvn->str.addr, gvn->str.len);
	}
	/* preallocate some space */
	if (!(TREF(mprof_ptr))->pcavailbase)
	{
		(TREF(mprof_ptr))->pcavailbase = (char **)malloc(PROFCALLOC_DSBLKSIZE);
		*(TREF(mprof_ptr))->pcavailbase = 0;
	}
	(TREF(mprof_ptr))->pcavailptr = (TREF(mprof_ptr))->pcavailbase;
	(TREF(mprof_ptr))->pcavail = PROFCALLOC_DSBLKSIZE - OFFSET_LEN;
	memset((TREF(mprof_ptr))->pcavailptr + 1, 0, (TREF(mprof_ptr))->pcavail);
	curr = (TREF(mprof_ptr))->tprev;
	TIMES(&curr);
	UNIX_ONLY(child_times_usec();)
Exemple #18
0
uint4	set_jnl_file_close(set_jnl_file_close_opcode_t set_jnl_file_close_opcode)
{
	uint4 		jnl_status = 0;

	cs_addrs = &FILE_INFO(gv_cur_region)->s_addrs;
	jnl_status = jnl_ensure_open();
	if (0 == jnl_status)
	{
		if (0 == cs_addrs->jnl->pini_addr)
			jnl_put_jrt_pini(cs_addrs);
		wcs_flu(WCSFLU_FLUSH_HDR | WCSFLU_WRITE_EPOCH);
		jnl_put_jrt_pfin(cs_addrs);
		jnl_file_close(gv_cur_region, TRUE, TRUE);
	} else
		gtm_putmsg(VARLSTCNT(6) jnl_status, 4, JNL_LEN_STR(cs_addrs->hdr),
			DB_LEN_STR(gv_cur_region));
	return jnl_status;
}
Exemple #19
0
static void file_close(char *temp)
{
	uint4		status;
	struct RAB	*rab;
	void 		gtm_putmsg();

	rab = (struct RAB *)(temp);
	if (error_mupip)
		rab->rab$l_fab->fab$l_fop |= FAB$M_DLT;
	status = sys$close(rab->rab$l_fab);
	if (status != RMS$_NORMAL)
	{
		backup_close_errno = status;
		gtm_putmsg(status);
		util_out_print("FATAL ERROR: System Service failure.",TRUE);
	}

	return;
}
Exemple #20
0
int mu_rndwn_all(void)
{
	int 			save_errno, fname_len, exit_status = SS_NORMAL, shmid, tmp_exit_status;
	char			entry[MAX_ENTRY_LEN];
	FILE			*pf;
	char			*fname, *fgets_res;
	shm_parms		*parm_buff;

	if (NULL == (pf = POPEN(IPCS_CMD_STR ,"r")))
        {
		save_errno = errno;
		gtm_putmsg(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("POPEN()"), CALLFROM, save_errno);
                return ERR_MUNOTALLSEC;
        }
	fname = (char *)malloc(MAX_FN_LEN + 1);
	while (NULL != (FGETS(entry, SIZEOF(entry), pf, fgets_res)) && entry[0] != '\n')
	{
		tmp_exit_status = SS_NORMAL;
		parm_buff = get_shm_parm(entry);
		if (NULL == parm_buff)
		{
			exit_status = ERR_MUNOTALLSEC;
			continue;
		}
		mu_rndwn_all_helper(parm_buff, fname, &exit_status, &tmp_exit_status);
		if ((SS_NORMAL == exit_status) && (SS_NORMAL != tmp_exit_status))
			exit_status = tmp_exit_status;
		if (mu_rndwn_all_helper_error)
		{	/* Encountered a runtime error while processing this ipc. Make sure we return with
			 * MUNOTALLSEC and reset this static variable before starting processing on next ipc.
			 */
			mu_rndwn_all_helper_error = FALSE;
			if (SS_NORMAL == exit_status)
				exit_status = ERR_MUNOTALLSEC;
		}
		if (NULL != parm_buff)
			free(parm_buff);
	}
	pclose(pf);
	free(fname);
	return exit_status;
}
Exemple #21
0
static void file_write(char *temp, char *buf, int nbytes)
{
	uint4		status;
	struct RAB	*rab;
	void		gtm_putmsg();

	assert(nbytes > 4);
	rab = (struct RAB *)(temp);
	rab->rab$w_rsz = nbytes;
	rab->rab$l_rbf = buf;
	if (RMS$_NORMAL != (status = sys$put(rab)))
	{
		backup_write_errno = status;
		gtm_putmsg(status, 0, rab->rab$l_stv);
		(rab->rab$l_fab)->fab$l_fop |= FAB$M_DLT;
		sys$close(rab->rab$l_fab);
	}

	return;
}
Exemple #22
0
void mupip_exit(int4 stat)
{
	int4	tmp_severity;
	if (stat != SS_NORMAL)
	{
		if (error_condition != stat)		/* If message not already put out.. */
		{
			gtm_putmsg(VARLSTCNT(1) stat);
			tmp_severity =  SEVMASK(stat);
		} else
			tmp_severity = severity;
		/* Make sure give an rc when we exit */
		if (SUCCESS != tmp_severity && INFO != tmp_severity)
			stat = (((stat & UNIX_EXIT_STATUS_MASK) != 0) ? stat : -1);
		else
			stat = 0;
	}
	mupip_exit_status_displayed = TRUE;
	exit(stat);
}
Exemple #23
0
static void exec_read(BFILE *bf, char *buf, int nbytes)
{
	int	needed, got;
	int4	status;
	char	*curr;
	pid_t	waitpid_res;

	assert(nbytes > 0);
	needed = nbytes;
	curr = buf;
#ifdef DEBUG_ONLINE
	PRINTF("file descriptor is %d and bytes needed is %d\n", bf->fd, needed);
#endif
	while(0 != (got = read(bf->fd, curr, needed)))
	{
		if (got == needed)
			break;
		else if (got > 0)
		{
			needed -= got;
			curr += got;
		}
		/* the check for EINTR below is valid and should not be converted to an EINTR
		 * wrapper macro, for an immediate retry is not attempted. Instead, wcs_sleep
		 * is called.
		 */
		else if ((EINTR != errno) && (EAGAIN != errno))
		{
			gtm_putmsg(VARLSTCNT(1) errno);
			if ((pipe_child > 0) && (FALSE != is_proc_alive(pipe_child, 0)))
				WAITPID(pipe_child, (int *)&status, 0, waitpid_res);
			close(bf->fd);
			restore_read_errno = errno;
			break;
		}
		wcs_sleep(100);
	}
	return;
}
Exemple #24
0
static bool	dse_process(int argc)
{
	int	res;

	ESTABLISH_RET(util_ch, TRUE);
	func = 0;
	util_interrupt = 0;
	if (EOF == (res = parse_cmd()))
	{
		if (util_interrupt)
		{
			rts_error(VARLSTCNT(1) ERR_CTRLC);
			REVERT;
			return TRUE;
		} else
		{
			REVERT;
			return FALSE;
		}
	} else if (res)
	{
		if (1 < argc)
		{
			/* Here we need to REVERT since otherwise we stay in dse in a loop
			 * The design of dse needs to be changed to act like VMS (which is:
			 * if there is an error in the dse command (dse dumpoa), go to command
			 * prompt, but UNIX exits
			 */
			REVERT;
			rts_error(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
		} else
			gtm_putmsg(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str));
	}
	if (func)
		func();
	REVERT;
	return(1 >= argc);
}
Exemple #25
0
void bin_load(uint4 begin, uint4 end)
{
	unsigned char	*ptr, *cp1, *cp2, *btop, *gvkey_char_ptr, *tmp_ptr, *tmp_key_ptr, *c, *ctop;
	unsigned char	hdr_lvl, src_buff[MAX_KEY_SZ + 1], dest_buff[MAX_ZWR_KEY_SZ],
			cmpc_str[MAX_KEY_SZ + 1], dup_key_str[MAX_KEY_SZ + 1];
	unsigned char	*end_buff;
	unsigned short	rec_len, next_cmpc;
	int		len;
	int		current, last, length, max_blk_siz, max_key, status;
	uint4		iter, max_data_len, max_subsc_len, key_count;
	ssize_t	        rec_count, global_key_count, subsc_len,extr_std_null_coll;
	boolean_t	need_xlation, new_gvn, utf8_extract;
	rec_hdr		*rp, *next_rp;
	mval		v, tmp_mval;
	mstr		mstr_src, mstr_dest;
	collseq		*extr_collseq, *db_collseq, *save_gv_target_collseq;
	coll_hdr	extr_collhdr, db_collhdr;
	gv_key 		*tmp_gvkey = NULL;	/* null-initialize at start, will be malloced later */
	char		std_null_coll[BIN_HEADER_NUMSZ + 1];
#	ifdef GTM_CRYPT
	gtmcrypt_key_t			*encr_key_handles;
	char				*inbuf;
	int4				index;
	int				req_dec_blk_size, init_status, crypt_status;
	muext_hash_hdr_ptr_t		hash_array = NULL;
#	endif
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	assert(4 == SIZEOF(coll_hdr));
	gvinit();
	v.mvtype = MV_STR;
	len = file_input_bin_get((char **)&ptr);
	hdr_lvl = EXTR_HEADER_LEVEL(ptr);
	if (!(((('4' == hdr_lvl) || ('5' == hdr_lvl)) && (BIN_HEADER_SZ == len)) || (('4' > hdr_lvl) && (V3_BIN_HEADER_SZ == len))))
	{
		rts_error(VARLSTCNT(1) ERR_LDBINFMT);
		mupip_exit(ERR_LDBINFMT);
	}
	/* expecting the level in a single character */
	assert(' ' == *(ptr + SIZEOF(BIN_HEADER_LABEL) - 3));
	if (0 != memcmp(ptr, BIN_HEADER_LABEL, SIZEOF(BIN_HEADER_LABEL) - 2) || ('2' > hdr_lvl) || *(BIN_HEADER_VERSION) < hdr_lvl)
	{	/* ignore the level check */
		rts_error(VARLSTCNT(1) ERR_LDBINFMT);
		mupip_exit(ERR_LDBINFMT);
	}
	/* check if extract was generated in UTF-8 mode */
	utf8_extract = (0 == MEMCMP_LIT(&ptr[len - BIN_HEADER_LABELSZ], UTF8_NAME)) ? TRUE : FALSE;
	if ((utf8_extract && !gtm_utf8_mode) || (!utf8_extract && gtm_utf8_mode))
	{ /* extract CHSET doesn't match $ZCHSET */
		if (utf8_extract)
			rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("UTF-8"));
		else
			rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("M"));
		mupip_exit(ERR_LDBINFMT);
	}
	if ('4' >= hdr_lvl)
	{	/* Binary extracts in V50000-to-V52000 (label=4) and pre-V50000 (label=3) could have a '\0' byte (NULL byte)
		 * in the middle of the string. Replace it with ' ' (space) like it would be in V52000 binary extracts and above.
		 */
		for (c = ptr, ctop = c + len; c < ctop; c++)
		{
			if ('\0' == *c)
				*c = ' ';
		}
	}
	util_out_print("Label = !AD\n", TRUE, len, ptr);
	new_gvn = FALSE;
	if (hdr_lvl > '3')
	{
		memcpy(std_null_coll, ptr + BIN_HEADER_NULLCOLLOFFSET, BIN_HEADER_NUMSZ);
		std_null_coll[BIN_HEADER_NUMSZ] = '\0';
		extr_std_null_coll = STRTOUL(std_null_coll, NULL, 10);
		if (0 != extr_std_null_coll && 1!= extr_std_null_coll)
		{
			rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupted null collation field  in header"),
				ERR_LDBINFMT);
			mupip_exit(ERR_LDBINFMT);
		}
	} else
		extr_std_null_coll = 0;
#	ifdef GTM_CRYPT
	if ('5' <= hdr_lvl)
	{
		int	i, num_indexes;
		len = file_input_bin_get((char **)&ptr);
		hash_array = (muext_hash_hdr *)malloc(len);
		/* store hashes of all the files used during extract into muext_hash_hdr structure */
		memcpy((char *)hash_array, ptr, len);
		num_indexes = len / GTMCRYPT_HASH_LEN;
		encr_key_handles = (gtmcrypt_key_t *)malloc(SIZEOF(gtmcrypt_key_t) * num_indexes);
		INIT_PROC_ENCRYPTION(crypt_status);
		GC_BIN_LOAD_ERR(crypt_status);
		for (index = 0; index < num_indexes; index++)
		{
			if (0 == memcmp(hash_array[index].gtmcrypt_hash, EMPTY_GTMCRYPT_HASH, GTMCRYPT_HASH_LEN))
				continue;
			GTMCRYPT_GETKEY(hash_array[index].gtmcrypt_hash, encr_key_handles[index], crypt_status);
			GC_BIN_LOAD_ERR(crypt_status);
		}
	}
#	endif
	if ('2' < hdr_lvl)
	{
		len = file_input_bin_get((char **)&ptr);
		if (SIZEOF(coll_hdr) != len)
		{
			rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupt collation header"), ERR_LDBINFMT);
			mupip_exit(ERR_LDBINFMT);
		}
		extr_collhdr = *((coll_hdr *)(ptr));
		new_gvn = TRUE;
	} else
		gtm_putmsg(VARLSTCNT(3) ERR_OLDBINEXTRACT, 1, hdr_lvl - '0');
	if (begin < 2)
		begin = 2;
	for (iter = 2; iter < begin; iter++)
	{
		if (!(len = file_input_bin_get((char **)&ptr)))
		{
			gtm_putmsg(VARLSTCNT(3) ERR_LOADEOF, 1, begin);
			util_out_print("Error reading record number: !UL\n", TRUE, iter);
			mupip_error_occurred = TRUE;
			return;
		} else if (len == SIZEOF(coll_hdr))
		{
			extr_collhdr = *((coll_hdr *)(ptr));
			assert(hdr_lvl > '2');
			iter--;
		}
	}
	assert(iter == begin);
	util_out_print("Beginning LOAD at record number: !UL\n", TRUE, begin);
	max_data_len = 0;
	max_subsc_len = 0;
	global_key_count = key_count = 0;
	rec_count = begin - 1;
	extr_collseq = db_collseq = NULL;
	need_xlation = FALSE;
	assert(NULL == tmp_gvkey);	/* GVKEY_INIT macro relies on this */
	GVKEY_INIT(tmp_gvkey, DBKEYSIZE(MAX_KEY_SZ));	/* tmp_gvkey will point to malloced memory after this */
	for (; !mupip_DB_full ;)
	{
		if (++rec_count > end)
			break;
		next_cmpc = 0;
		mupip_error_occurred = FALSE;
		if (mu_ctrly_occurred)
			break;
		if (mu_ctrlc_occurred)
		{
			util_out_print("!AD:!_  Key cnt: !UL  max subsc len: !UL  max data len: !UL", TRUE,
				LEN_AND_LIT(gt_lit), key_count, max_subsc_len, max_data_len);
			util_out_print("Last LOAD record number: !UL", TRUE, key_count ? (rec_count - 1) : 0);
			mu_gvis();
			util_out_print(0, TRUE);
			mu_ctrlc_occurred = FALSE;
		}
		/* reset the stringpool for every record in order to avoid garbage collection */
		stringpool.free = stringpool.base;
		if (!(len = file_input_bin_get((char **)&ptr)) || mupip_error_occurred)
			break;
		else if (len == SIZEOF(coll_hdr))
		{
			extr_collhdr = *((coll_hdr *)(ptr));
			assert(hdr_lvl > '2');
			new_gvn = TRUE;			/* next record will contain a new gvn */
			rec_count--;	/* Decrement as this record does not count as a record for loading purposes */
			continue;
		}
		rp = (rec_hdr*)(ptr);
#		ifdef GTM_CRYPT
		if ('5' <= hdr_lvl)
		{	/* Getting index value from the extracted file. It indicates which database file this record belongs to */
			GET_LONG(index, ptr);
			if (-1 != index) /* Indicates that the record is encrypted. */
			{
				req_dec_blk_size = len - SIZEOF(int4);
				inbuf = (char *)(ptr + SIZEOF(int4));
				GTMCRYPT_DECODE_FAST(encr_key_handles[index], inbuf, req_dec_blk_size, NULL, crypt_status);
				GC_BIN_LOAD_ERR(crypt_status);
			}
			rp = (rec_hdr*)(ptr + SIZEOF(int4));
		}
#		endif
		btop = ptr + len;
		cp1 = (unsigned char*)(rp + 1);
		v.str.addr = (char*)cp1;
		while (*cp1++)
			;
		v.str.len =INTCAST((char*)cp1 - v.str.addr - 1);
		if (('2' >= hdr_lvl) || new_gvn)
		{
			if ((HASHT_GBLNAME_LEN == v.str.len) &&	(0 == memcmp(v.str.addr, HASHT_GBLNAME, HASHT_GBLNAME_LEN)))
				continue;
			bin_call_db(BIN_BIND, (INTPTR_T)gd_header, (INTPTR_T)&v.str);
			max_key = gv_cur_region->max_key_size;
			db_collhdr.act = gv_target->act;
			db_collhdr.ver = gv_target->ver;
			db_collhdr.nct = gv_target->nct;
		}
		GET_USHORT(rec_len, &rp->rsiz);
		if (rp->cmpc != 0 || v.str.len > rec_len || mupip_error_occurred)
		{
			bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
			mu_gvis();
			util_out_print(0, TRUE);
			continue;
		}
		if (new_gvn)
		{
			global_key_count = 1;
			if ((db_collhdr.act != extr_collhdr.act || db_collhdr.ver != extr_collhdr.ver
				|| db_collhdr.nct != extr_collhdr.nct
				|| gv_cur_region->std_null_coll != extr_std_null_coll))
			{
				if (extr_collhdr.act)
				{
					if (extr_collseq = ready_collseq((int)extr_collhdr.act))
					{
						if (!do_verify(extr_collseq, extr_collhdr.act, extr_collhdr.ver))
						{
							gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, extr_collhdr.act,
								extr_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
							mupip_exit(ERR_COLLTYPVERSION);
						}
					} else
					{
						gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, extr_collhdr.act,
							ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
						mupip_exit(ERR_COLLATIONUNDEF);
					}
				}
				if (db_collhdr.act)
				{
					if (db_collseq = ready_collseq((int)db_collhdr.act))
					{
						if (!do_verify(db_collseq, db_collhdr.act, db_collhdr.ver))
						{
							gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, db_collhdr.act,
								db_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
							mupip_exit(ERR_COLLTYPVERSION);
						}
					} else
					{
						gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, db_collhdr.act,
							ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
						mupip_exit(ERR_COLLATIONUNDEF);
					}
				}
				need_xlation = TRUE;
			} else
				need_xlation = FALSE;
		}
		new_gvn = FALSE;
		for (; rp < (rec_hdr*)btop; rp = (rec_hdr*)((unsigned char *)rp + rec_len))
		{
			GET_USHORT(rec_len, &rp->rsiz);
			if (rec_len + (unsigned char *)rp > btop)
			{
				bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
				mu_gvis();
				util_out_print(0, TRUE);
				break;
			}
			cp1 =  (unsigned char*)(rp + 1);
			cp2 = gv_currkey->base + rp->cmpc;
			current = 1;
			for (;;)
			{
				last = current;
				current = *cp2++ = *cp1++;
				if (0 == last && 0 == current)
					break;
				if (cp1 > (unsigned char *)rp + rec_len ||
				    cp2 > (unsigned char *)gv_currkey + gv_currkey->top)
				{
					bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
					mu_gvis();
					util_out_print(0, TRUE);
					break;
				}
			}
			if (mupip_error_occurred)
				break;
			gv_currkey->end = cp2 - gv_currkey->base - 1;
			if (need_xlation)
			{
				assert(hdr_lvl >= '3');
				assert(extr_collhdr.act || db_collhdr.act || extr_collhdr.nct || db_collhdr.nct ||
				 	extr_std_null_coll != gv_cur_region->std_null_coll);
							/* gv_currkey would have been modified/translated in the earlier put */
				memcpy(gv_currkey->base, cmpc_str, next_cmpc);
				next_rp = (rec_hdr *)((unsigned char*)rp + rec_len);
				if ((unsigned char*)next_rp < btop)
				{
					next_cmpc = next_rp->cmpc;
					assert(next_cmpc <= gv_currkey->end);
					memcpy(cmpc_str, gv_currkey->base, next_cmpc);
				} else
					next_cmpc = 0;
							/* length of the key might change (due to nct variation),
							 * so get a copy of the original key from the extract */
				memcpy(dup_key_str, gv_currkey->base, gv_currkey->end + 1);
				gvkey_char_ptr = dup_key_str;
				while (*gvkey_char_ptr++)
					;
				gv_currkey->prev = 0;
				gv_currkey->end = gvkey_char_ptr - dup_key_str;
				assert(gv_keysize <= tmp_gvkey->top);
				while (*gvkey_char_ptr)
				{
						/* get next subscript (in GT.M internal subsc format) */
					subsc_len = 0;
					tmp_ptr = src_buff;
					while (*gvkey_char_ptr)
						*tmp_ptr++ = *gvkey_char_ptr++;
					subsc_len = tmp_ptr - src_buff;
					src_buff[subsc_len] = '\0';
					if (extr_collseq)
					{
						/* undo the extract time collation */
						TREF(transform) = TRUE;
						save_gv_target_collseq = gv_target->collseq;
						gv_target->collseq = extr_collseq;
					} else
						TREF(transform) = FALSE;
						/* convert the subscript to string format */
					end_buff = gvsub2str(src_buff, dest_buff, FALSE);
						/* transform the string to the current subsc format */
					TREF(transform) = TRUE;
					tmp_mval.mvtype = MV_STR;
                                	tmp_mval.str.addr = (char *)dest_buff;
                                	tmp_mval.str.len = INTCAST(end_buff - dest_buff);
					tmp_gvkey->prev = 0;
					tmp_gvkey->end = 0;
					if (extr_collseq)
						gv_target->collseq = save_gv_target_collseq;
					mval2subsc(&tmp_mval, tmp_gvkey);
						/* we now have the correctly transformed subscript */
					tmp_key_ptr = gv_currkey->base + gv_currkey->end;
					memcpy(tmp_key_ptr, tmp_gvkey->base, tmp_gvkey->end + 1);
					gv_currkey->prev = gv_currkey->end;
					gv_currkey->end += tmp_gvkey->end;
					gvkey_char_ptr++;
				}
				if ( gv_cur_region->std_null_coll != extr_std_null_coll && gv_currkey->prev)
				{
					if (extr_std_null_coll == 0)
					{
						GTM2STDNULLCOLL(gv_currkey->base, gv_currkey->end);
					} else
					{
						STD2GTMNULLCOLL(gv_currkey->base, gv_currkey->end);
					}
				}
			}
			if (gv_currkey->end >= max_key)
			{
				bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
				mu_gvis();
				util_out_print(0, TRUE);
				continue;
			}
			if (max_subsc_len < (gv_currkey->end + 1))
				max_subsc_len = gv_currkey->end + 1;
			v.str.addr = (char*)cp1;
			v.str.len =INTCAST(rec_len - (cp1 - (unsigned char *)rp));
			if (max_data_len < v.str.len)
				max_data_len = v.str.len;
			bin_call_db(BIN_PUT, (INTPTR_T)&v, 0);
			if (mupip_error_occurred)
			{
				if (!mupip_DB_full)
				{
					bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
					util_out_print(0, TRUE);
				}
				break;
			}
			key_count++;
			global_key_count++;
		}
	}
	GTMCRYPT_ONLY(
		if (NULL != hash_array)
			free(hash_array);
	)
int gtmrecv_start_helpers(int n_readers, int n_writers)
{ /* Set flag in recvpool telling the receiver server to start n_readers and n_writers helper processes.
   * Wait for receiver server to complete the process - completed successfully, or terminated with error
   */
	upd_helper_ctl_ptr_t	upd_helper_ctl;
	upd_helper_entry_ptr_t	helper, helper_top;
	char			err_str[BUFSIZ];
	int			avail_slots, started_readers, started_writers;

	error_def(ERR_REPLERR);
	error_def(ERR_REPLINFO);
	error_def(ERR_REPLWARN);

	assert(0 != n_readers || 0 != n_writers);
	upd_helper_ctl = recvpool.upd_helper_ctl;

	/* let's clean up dead helpers first so we get an accurate count of available slots */
	upd_helper_ctl->reap_helpers = HELPER_REAP_NOWAIT;
	while (HELPER_REAP_NONE != upd_helper_ctl->reap_helpers && SRV_ALIVE == is_recv_srv_alive())
		SHORT_SLEEP(GTMRECV_WAIT_FOR_UPD_SHUTDOWN);
	upd_helper_ctl->reap_helpers = HELPER_REAP_NONE; /* just in case recvr died */

	/* count available slots so receiver doesn't have to */
	for (avail_slots = 0, helper = upd_helper_ctl->helper_list, helper_top = helper + MAX_UPD_HELPERS;
		helper < helper_top; helper++)
	{
		if (0 == helper->helper_pid)
		{
			avail_slots++;
			helper->helper_pid_prev = 0; /* force out abnormally terminated helpers as well */
			helper->helper_shutdown = NO_SHUTDOWN; /* clean state */
		}
	}
	if (avail_slots < n_readers + n_writers)
	{
		SNPRINTF(err_str, SIZEOF(err_str),
				"%d helpers will exceed the maximum allowed (%d), limit the helpers to %d\n",
				n_readers + n_writers, MAX_UPD_HELPERS, avail_slots);
		gtm_putmsg(VARLSTCNT(4) ERR_REPLERR, 2, LEN_AND_STR(err_str));
		return ABNORMAL_SHUTDOWN;
	}

	upd_helper_ctl->start_n_readers = n_readers;
	upd_helper_ctl->start_n_writers = n_writers;
	SHM_WRITE_MEMORY_BARRIER;
	upd_helper_ctl->start_helpers = TRUE; /* hey receiver, let's go, start 'em up */
	while (upd_helper_ctl->start_helpers && SRV_ALIVE == is_recv_srv_alive())
		SHORT_SLEEP(GTMRECV_WAIT_FOR_SRV_START);
	if (!upd_helper_ctl->start_helpers)
	{
		started_readers = upd_helper_ctl->start_n_readers;
		started_writers = upd_helper_ctl->start_n_writers;
		SNPRINTF(err_str, SIZEOF(err_str), "%s %d out of %d readers and %d out of %d writers started",
				((started_readers + started_writers) == (n_readers + n_writers)) ? "All" : "Only",
				started_readers, n_readers, started_writers, n_writers);
		if ((started_readers + started_writers) == (n_readers + n_writers))
		{
			gtm_putmsg(VARLSTCNT(4) ERR_REPLINFO, 2, LEN_AND_STR(err_str));
			return NORMAL_SHUTDOWN;
		}
		gtm_putmsg(VARLSTCNT(4) ERR_REPLWARN, 2, LEN_AND_STR(err_str));
		return ABNORMAL_SHUTDOWN;
	}
	gtm_putmsg(VARLSTCNT(4) ERR_REPLERR, 2,
			LEN_AND_LIT("Receiver server is not alive to start helpers. Start receiver server first"));
	return ABNORMAL_SHUTDOWN;
}
void deferred_signal_handler(void)
{
	void (*signal_routine)();
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	/* To avoid nested calls to this routine, we set forced_exit to FALSE at the very beginning */
	forced_exit = FALSE;

	if (exit_handler_active)
	{
		assert(FALSE);	/* at this point in time (June 2003) there is no way we know of to get here, hence the assert */
		return;	/* since anyway we are exiting currently, resume exit handling instead of reissuing another one */
	}
	/* For signals that get a delayed response so we can get out of crit, we also delay the messages.
	 * This routine will output those delayed messages from the appropriate structures to both the
	 * user and the system console.
	 */
	/* note can't use switch here because ERR_xxx are not defined as constants */
	if (ERR_KILLBYSIG == forced_exit_err)
	{
		send_msg(VARLSTCNT(6) ERR_KILLBYSIG, 4, GTMIMAGENAMETXT(image_type), process_id, signal_info.signal);
		gtm_putmsg(VARLSTCNT(6) ERR_KILLBYSIG, 4, GTMIMAGENAMETXT(image_type), process_id, signal_info.signal);
	} else if (ERR_KILLBYSIGUINFO == forced_exit_err)
	{
		send_msg(VARLSTCNT(8) ERR_KILLBYSIGUINFO, 6, GTMIMAGENAMETXT(image_type), process_id,
						signal_info.signal, signal_info.send_pid, signal_info.send_uid);
		gtm_putmsg(VARLSTCNT(8) ERR_KILLBYSIGUINFO, 6, GTMIMAGENAMETXT(image_type), process_id,
						signal_info.signal, signal_info.send_pid, signal_info.send_uid);
	} else if (ERR_KILLBYSIGSINFO1 == forced_exit_err)
	{
		send_msg(VARLSTCNT(8) ERR_KILLBYSIGSINFO1, 6, GTMIMAGENAMETXT(image_type),
			 process_id, signal_info.signal, signal_info.int_iadr, signal_info.bad_vadr);
		gtm_putmsg(VARLSTCNT(8) ERR_KILLBYSIGSINFO1, 6, GTMIMAGENAMETXT(image_type),
			   process_id, signal_info.signal, signal_info.int_iadr, signal_info.bad_vadr);
	} else if (ERR_KILLBYSIGSINFO2 == forced_exit_err)
	{
		send_msg(VARLSTCNT(7) ERR_KILLBYSIGSINFO2, 5, GTMIMAGENAMETXT(image_type),
			 process_id, signal_info.signal, signal_info.int_iadr);
		gtm_putmsg(VARLSTCNT(7) ERR_KILLBYSIGSINFO2, 5, GTMIMAGENAMETXT(image_type),
			   process_id, signal_info.signal, signal_info.int_iadr);
	} else if (ERR_KILLBYSIGSINFO3 == forced_exit_err)
	{
		send_msg(VARLSTCNT(7) ERR_KILLBYSIGSINFO3, 5, GTMIMAGENAMETXT(image_type),
			 process_id, signal_info.signal, signal_info.bad_vadr);
		gtm_putmsg(VARLSTCNT(7) ERR_KILLBYSIGSINFO3, 5, GTMIMAGENAMETXT(image_type),
			   process_id, signal_info.signal, signal_info.bad_vadr);
	} else if (ERR_FORCEDHALT != forced_exit_err || !gtm_quiet_halt)
	{	/* No HALT messages if quiet halt is requested */
		send_msg(VARLSTCNT(1) forced_exit_err);
		gtm_putmsg(VARLSTCNT(1) forced_exit_err);
	}
	assert(OK_TO_INTERRUPT);
	/* Signal intent to exit BEFORE driving condition handlers. This avoids checks that will otherwise fail (for example
	 * if mdb_condition_handler/preemptive_ch gets called below, that could invoke the RESET_GV_TARGET macro which in turn
	 * would assert that gv_target->gd_csa is equal to cs_addrs. This could not be true in case we were in mainline code
	 * that was interrupted by the flush timer for a different region which in turn was interrupted by an external signal
	 * that would drive us to exit. Setting the "process_exiting" variable causes those csa checks to pass.
	 */
	SET_PROCESS_EXITING_TRUE;
#	ifdef DEBUG
	if (gtm_white_box_test_case_enabled && (WBTEST_DEFERRED_TIMERS == gtm_white_box_test_case_number)
		&& (2 == gtm_white_box_test_case_count))
	{
		DEFER_INTERRUPTS(INTRPT_NO_TIMER_EVENTS);
		DBGFPF((stderr, "DEFERRED_SIGNAL_HANDLER: will sleep for 20 seconds\n"));
		LONG_SLEEP(20);
		DBGFPF((stderr, "DEFERRED_SIGNAL_HANDLER: done sleeping\n"));
		ENABLE_INTERRUPTS(INTRPT_NO_TIMER_EVENTS);
	}
#	endif
	/* If any special routines are registered to be driven on a signal, drive them now */
	if ((0 != exi_condition) && (NULL != call_on_signal))
	{
		signal_routine = call_on_signal;
		call_on_signal = NULL;		/* So we don't recursively call ourselves */
		(*signal_routine)();
	}
	/* Note, we do not drive create_fatal_error zshow_dmp() in this routine since any deferrable signals are
	 * by definition not fatal.
	 */
	exit(-exi_condition);
}
Exemple #28
0
void gtm_startup(struct startup_vector *svec)
/* Note: various references to data copied from *svec could profitably be referenced directly */
{
	unsigned char	*mstack_ptr;
	void		gtm_ret_code();
	static readonly unsigned char init_break[1] = {'B'};
	int4		lct;
	int		i;
	static char 	other_mode_buf[] = "OTHER";
	mstr		log_name;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	assert(INVALID_IMAGE != image_type);
	assert(svec->argcnt == SIZEOF(*svec));
	IA64_ONLY(init_xfer_table());
	get_page_size();
	cache_table_relobjs = &cache_table_rebuild;
	ht_rhash_ch = &hashtab_rehash_ch;
	jbxm_dump_ch = &jobexam_dump_ch;
	heartbeat_timer_ptr = &heartbeat_timer;
	stpgc_ch = &stp_gcol_ch;
	rtn_fst_table = rtn_names = (rtn_tabent *)svec->rtn_start;
	rtn_names_end = rtn_names_top = (rtn_tabent *)svec->rtn_end;
	if (svec->user_stack_size < 4096)
		svec->user_stack_size = 4096;
	if (svec->user_stack_size > 8388608)
		svec->user_stack_size = 8388608;
	mstack_ptr = (unsigned char *)malloc(svec->user_stack_size);
	msp = stackbase = mstack_ptr + svec->user_stack_size - mvs_size[MVST_STORIG];
	/* mark the stack base so that if error occur during call-in gtm_init(), the unwind
	 * logic in gtmci_ch() will get rid of the stack completely
	 */
	fgncal_stack = stackbase;
	mv_chain = (mv_stent *)msp;
	mv_chain->mv_st_type = MVST_STORIG;	/* Initialize first (anchor) mv_stent so doesn't do anything */
	mv_chain->mv_st_next = 0;
	mv_chain->mv_st_cont.mvs_storig = 0;
	stacktop = mstack_ptr + 2 * mvs_size[MVST_NTAB];
	stackwarn = stacktop + (16 * 1024);
	break_message_mask = svec->break_message_mask;
	if (svec->user_strpl_size < STP_INITSIZE)
		svec->user_strpl_size = STP_INITSIZE;
	else if (svec->user_strpl_size > STP_MAXINITSIZE)
		svec->user_strpl_size = STP_MAXINITSIZE;
	stp_init(svec->user_strpl_size);
	if (svec->user_indrcache_size > MAX_INDIRECTION_NESTING || svec->user_indrcache_size < MIN_INDIRECTION_NESTING)
		svec->user_indrcache_size = MIN_INDIRECTION_NESTING;
	TREF(ind_result_array) = (mval **)malloc(SIZEOF(mval *) * svec->user_indrcache_size);
	TREF(ind_source_array) = (mval **)malloc(SIZEOF(mval *) * svec->user_indrcache_size);
	TREF(ind_result_sp) = TREF(ind_result_array);
	TREF(ind_result_top) = TREF(ind_result_sp) + svec->user_indrcache_size;
	TREF(ind_source_sp) = TREF(ind_source_array);
	TREF(ind_source_top) = TREF(ind_source_sp) + svec->user_indrcache_size;
	rts_stringpool = stringpool;
	TREF(compile_time) = FALSE;
	/* assert that is_replicator and run_time is properly set by gtm_imagetype_init invoked at process entry */
#	ifdef DEBUG
	switch (image_type)
	{
		case GTM_IMAGE:
		case GTM_SVC_DAL_IMAGE:
			assert(is_replicator && run_time);
			break;
		case MUPIP_IMAGE:
			assert(!is_replicator && !run_time);
			break;
		default:
			assert(FALSE);
	}
#	endif
	gtm_utf8_init(); /* Initialize the runtime for Unicode */
	/* Initialize alignment requirement for the runtime stringpool */
	log_name.addr = DISABLE_ALIGN_STRINGS;
	log_name.len = STR_LIT_LEN(DISABLE_ALIGN_STRINGS);
	/* mstr_native_align = logical_truth_value(&log_name, FALSE, NULL) ? FALSE : TRUE; */
	mstr_native_align = FALSE; /* TODO: remove this line and uncomment the above line */
	getjobname();
	INVOKE_INIT_SECSHR_ADDRS;
	getzprocess();
	getzmode();
	geteditor();
	zcall_init();
	cmd_qlf.qlf = glb_cmd_qlf.qlf;
	cache_init();
#	ifdef __sun
	if (NULL != GETENV(PACKAGE_ENV_TYPE))	/* chose xcall (default) or rpc zcall */
		xfer_table[xf_fnfgncal] = (xfer_entry_t)op_fnfgncal_rpc;  /* using RPC */
#	endif
	msp -= SIZEOF(stack_frame);
	frame_pointer = (stack_frame *)msp;
	memset(frame_pointer,0, SIZEOF(stack_frame));
	frame_pointer->temps_ptr = (unsigned char *)frame_pointer;
	frame_pointer->ctxt = GTM_CONTEXT(gtm_ret_code);
	frame_pointer->mpc = CODE_ADDRESS(gtm_ret_code);
	frame_pointer->type = SFT_COUNT;
	frame_pointer->rvector = (rhdtyp*)malloc(SIZEOF(rhdtyp));
	memset(frame_pointer->rvector, 0, SIZEOF(rhdtyp));
	symbinit();
	/* Variables for supporting $ZSEARCH sorting and wildcard expansion */
	TREF(zsearch_var) = lv_getslot(curr_symval);
	TREF(zsearch_dir1) = lv_getslot(curr_symval);
	TREF(zsearch_dir2) = lv_getslot(curr_symval);
	LVVAL_INIT((TREF(zsearch_var)), curr_symval);
	LVVAL_INIT((TREF(zsearch_dir1)), curr_symval);
	LVVAL_INIT((TREF(zsearch_dir2)), curr_symval);
	/* Initialize global pointer to control-C handler. Also used in iott_use */
	ctrlc_handler_ptr = &ctrlc_handler;
	io_init(IS_MUPIP_IMAGE);		/* starts with nocenable for GT.M runtime, enabled for MUPIP */
	if (!IS_MUPIP_IMAGE)
	{
		sig_init(generic_signal_handler, ctrlc_handler_ptr, suspsigs_handler, continue_handler);
		atexit(gtm_exit_handler);
		cenable();	/* cenable unless the environment indicates otherwise - 2 steps because this can report errors */
	}
	jobinterrupt_init();
	getzdir();
	dpzgbini();
	zco_init();
	/* a base addr of 0 indicates a gtm_init call from an rpc server */
	if ((GTM_IMAGE == image_type) && (NULL != svec->base_addr))
		jobchild_init();
	else
	{	/* Trigger enabled utilities will enable through here */
		(TREF(dollar_zmode)).mvtype = MV_STR;
		(TREF(dollar_zmode)).str.addr = other_mode_buf;
		(TREF(dollar_zmode)).str.len = SIZEOF(other_mode_buf) -1;
	}
	svec->frm_ptr = (unsigned char *)frame_pointer;
	dollar_ztrap.mvtype = MV_STR;
	dollar_ztrap.str.len = SIZEOF(init_break);
	dollar_ztrap.str.addr = (char *)init_break;
	dollar_zstatus.mvtype = MV_STR;
	dollar_zstatus.str.len = 0;
	dollar_zstatus.str.addr = NULL;
	ecode_init();
	zyerror_init();
	ztrap_form_init();
	ztrap_new_init();
	zdate_form_init(svec);
	dollar_system_init(svec);
	init_callin_functable();
	gtm_env_xlate_init();
	SET_LATCH_GLOBAL(&defer_latch, LOCK_AVAILABLE);
	curr_pattern = pattern_list = &mumps_pattern;
	pattern_typemask = mumps_pattern.typemask;
	initialize_pattern_table();
	ce_init();	/* initialize compiler escape processing */
	/* Initialize local collating sequence */
	TREF(transform) = TRUE;
	lct = find_local_colltype();
	if (lct != 0)
	{
		TREF(local_collseq) = ready_collseq(lct);
		if (!TREF(local_collseq))
		{
			exi_condition = -ERR_COLLATIONUNDEF;
			gtm_putmsg(VARLSTCNT(3) ERR_COLLATIONUNDEF, 1, lct);
			exit(exi_condition);
		}
	} else
		TREF(local_collseq) = 0;
	prealloc_gt_timers();
	gt_timers_add_safe_hndlrs();
	for (i = 0; FNPC_MAX > i; i++)
	{	/* Initialize cache structure for $Piece function */
		(TREF(fnpca)).fnpcs[i].pcoffmax = &(TREF(fnpca)).fnpcs[i].pstart[FNPC_ELEM_MAX];
		(TREF(fnpca)).fnpcs[i].indx = i;
	}
	(TREF(fnpca)).fnpcsteal = (TREF(fnpca)).fnpcs;		/* Starting place to look for cache reuse */
	(TREF(fnpca)).fnpcmax = &(TREF(fnpca)).fnpcs[FNPC_MAX - 1];	/* The last element */
	/* Initialize zwrite subsystem. Better to do it now when we have storage to allocate than
	 * if we fail and storage allocation may not be possible. To that end, pretend we have
	 * seen alias acitivity so those structures are initialized as well.
	 */
	assert(FALSE == curr_symval->alias_activity);
	curr_symval->alias_activity = TRUE;
	lvzwr_init((enum zwr_init_types)0, (mval *)NULL);
	curr_symval->alias_activity = FALSE;
	if ((NULL != (TREF(mprof_env_gbl_name)).str.addr))
		turn_tracing_on(TADR(mprof_env_gbl_name), TRUE, (TREF(mprof_env_gbl_name)).str.len > 0);
	return;
}
Exemple #29
0
void gv_select(char *cli_buff, int n_len, boolean_t freeze, char opname[], glist *gl_head,
	       int *reg_max_rec, int *reg_max_key, int *reg_max_blk)
{
	bool				stashed = FALSE;
	int				num_quote, len, gmap_size, new_gmap_size, estimated_entries, count, rslt;
	char				*ptr, *ptr1, *c;
	mstr				gmap[512], *gmap_ptr, *gmap_ptr_base, gmap_beg, gmap_end;
	mval				val, curr_gbl_name;
	glist				*gl_tail, *gl_ptr;
#ifdef GTM64
	hash_table_int8	        	ext_hash;
	ht_ent_int8                   	*tabent;
#else
	hash_table_int4	        	ext_hash;
	ht_ent_int4                   	*tabent;
#endif /* GTM64 */

	error_def(ERR_FREEZE);
	error_def(ERR_DBRDONLY);
	error_def(ERR_SELECTSYNTAX);
	error_def(ERR_MUNOFINISH);
	error_def(ERR_MUNOACTION);
	error_def(ERR_FREEZECTRL);

	memset(gmap, 0, SIZEOF(gmap));
	gmap_size = SIZEOF(gmap) / SIZEOF(gmap[0]);
	gmap_ptr_base = &gmap[0];
	/* "estimated_entries" is a conservative estimate of the # of entries that could be used up in the gmap array */
	estimated_entries = 1;	/* take into account the NULL gmap entry at the end of the array */
	for (ptr = cli_buff; *ptr; ptr = ptr1)
	{
		for (ptr1 = ptr; ; ptr1++)
		{
			if (',' == *ptr1)
			{
				len = (int)(ptr1 - ptr);
				ptr1++;
				break;
			} else if (!*ptr1)
			{
				len = (int)(ptr1 - ptr);
				break;
			}
		}
		gmap_beg.addr = ptr;
		c = gmap_beg.addr + len - 1;
		num_quote = 0;
		while ('"' == *c)
		{
			len--;
			c--;
			num_quote++;
		}
		if (0 >= len)
		{
			gtm_putmsg(VARLSTCNT(4) ERR_SELECTSYNTAX, 2, LEN_AND_STR(opname));
			mupip_exit(ERR_MUNOACTION);
		}
		c = gmap_beg.addr;
		while (0 < num_quote)
		{
			if ('"' == *c)
			{
				c++;
				len--;
			} else
			{
				gtm_putmsg(VARLSTCNT(4) ERR_SELECTSYNTAX, 2, LEN_AND_STR(opname));
				mupip_exit(ERR_MUNOACTION);
			}
			num_quote--;
		}
		gmap_beg.addr = c;
		if ('^' == *c)
		{
			gmap_beg.addr++;
			len--;
		}
		gmap_beg.len = len;
		c = mu_extr_ident(&gmap_beg);
		len -= INTCAST(c - gmap_beg.addr);
		assert(len >= 0);
		if (0 == len)
			gmap_end = gmap_beg;
		else if (gmap_beg.len == 1 && '*' == *c)
		{
			gmap_beg.addr = (char*)&percent_lit;
			gmap_beg.len = SIZEOF(percent_lit);
			gmap_end.addr =  (char*)&tilde_lit;
			gmap_end.len = SIZEOF(tilde_lit);
		} else if (1 == len && '*' == *c)
		{
			gmap_end = gmap_beg;
			gmap_beg.len--;
			*c = '~';
		} else if (':' != *c)
		{
			gtm_putmsg(VARLSTCNT(4) ERR_SELECTSYNTAX, 2, LEN_AND_STR(opname));
			mupip_exit(ERR_MUNOACTION);
		} else
		{
			gmap_beg.len = INTCAST(c - gmap_beg.addr);
			c++;
			gmap_end.addr = c;
			gmap_end.len = len - 1;
			if ('^' == *c)
			{
				gmap_end.addr++;
				gmap_end.len--;
			}
			c = mu_extr_ident(&gmap_end);
			MSTR_CMP(gmap_beg, gmap_end, rslt);
			if (((c - gmap_end.addr) != gmap_end.len) || (0 < rslt))
			{
				gtm_putmsg(VARLSTCNT(4) ERR_SELECTSYNTAX, 2, LEN_AND_STR(opname));
				mupip_exit(ERR_MUNOACTION);
			}
		}
		/* "estimated_entries" is the maximum number of entries that could be used up in the gmap array including the
		 * next global_map call. The actual number of used entries could be much lower than this.
		 * But since determining the actual number would mean scanning the gmap array for the first NULL pointer (a
		 * performance overhead), we do an approximate check instead.
		 */
		estimated_entries += MAX_GMAP_ENTRIES_PER_ITER;
		if (estimated_entries >= gmap_size)
		{	/* Current gmap array does not have enough space. Double size before calling global_map */
			new_gmap_size = gmap_size * 2;	/* double size of gmap array */
			gmap_ptr = (mstr *)malloc(SIZEOF(mstr) * new_gmap_size);
			memcpy(gmap_ptr, gmap_ptr_base, SIZEOF(mstr) * gmap_size);
			if (gmap_ptr_base != &gmap[0])
				free(gmap_ptr_base);
			gmap_size = new_gmap_size;
			gmap_ptr_base = gmap_ptr;
		}
		global_map(gmap_ptr_base, &gmap_beg, &gmap_end);
		DEBUG_ONLY(
			count = 1;
			for (gmap_ptr = gmap_ptr_base; gmap_ptr->addr; gmap_ptr++)
				count++;
			assert(count < gmap_size);
		)
	}
	if (freeze)
	{
		GTM64_ONLY(init_hashtab_int8(&ext_hash, 0, HASHTAB_COMPACT, HASHTAB_SPARE_TABLE);)
		NON_GTM64_ONLY(init_hashtab_int4(&ext_hash, 0, HASHTAB_COMPACT, HASHTAB_SPARE_TABLE);)
	}
Exemple #30
0
void go_load(uint4 begin, uint4 end)
{
	char		*ptr;
	int		len, fmt, keylength, keystate;
	uint4	        iter, max_data_len, max_subsc_len, key_count, max_rec_size;
	mstr            src, des;
	unsigned char   *rec_buff, ch;
	boolean_t	utf8_extract, format_error = FALSE, hasht_ignored = FALSE, hasht_gbl = FALSE;
	char		*val_off;
	int 		val_len, val_off1, val_len1;
	boolean_t	is_setextract;

	gvinit();

	max_rec_size = DEFAULT_MAX_REC_SIZE;
	rec_buff = (unsigned char *)malloc(max_rec_size);

	fmt = MU_FMT_ZWR;	/* by default, the extract format is ZWR (not GO) */
	len = file_input_get(&ptr);
	if (mupip_error_occurred)
	{
		free(rec_buff);
		return;
	}
	if (len >= 0)
	{
		util_out_print("!AD", TRUE, len, ptr);
		utf8_extract = ((len >= STR_LIT_LEN(UTF8_NAME)) &&
				(0 == MEMCMP_LIT(ptr + len - STR_LIT_LEN("UTF-8"), "UTF-8"))) ? TRUE : FALSE;
		if ((utf8_extract && !gtm_utf8_mode) || (!utf8_extract && gtm_utf8_mode))
		{ /* extract CHSET doesn't match $ZCHSET */
			if (utf8_extract)
				gtm_putmsg(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("UTF-8"));
			else
				gtm_putmsg(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("M"));
			mupip_error_occurred = TRUE;
			free(rec_buff);
			return;
		}
	} else
		mupip_exit(ERR_LOADFILERR);
	len = file_input_get(&ptr);
	if (mupip_error_occurred)
	{
		free(rec_buff);
		return;
	}
	if (len >= 0)
	{
		util_out_print("!AD", TRUE, len, ptr);
		fmt = (0 == memcmp(ptr + len - STR_LIT_LEN("ZWR"), "ZWR", STR_LIT_LEN("ZWR"))) ? MU_FMT_ZWR : MU_FMT_GO;
	} else
		mupip_exit(ERR_LOADFILERR);
	if (begin < 3)
		begin = 3;
	for (iter = 3; iter < begin; iter++)
	{
		len = file_input_get(&ptr);
		if (len < 0)	/* The IO device has signalled an end of file */
		{
			gtm_putmsg(VARLSTCNT(3) ERR_LOADEOF, 1, begin);
			mupip_error_occurred = TRUE;
		}
		if (mupip_error_occurred)
		{
			util_out_print("Error reading record number: !UL\n", TRUE, iter);
			free(rec_buff);
			return;
		}
	}
	assert(iter == begin);
	util_out_print("Beginning LOAD at record number: !UL\n", TRUE, begin);
	max_data_len = 0;
	max_subsc_len = 0;
	key_count = 0;
	for (iter = begin - 1; ; )
	{
		if (++iter > end)
			break;
		if (mu_ctrly_occurred)
			break;
		if (mu_ctrlc_occurred)
		{
			util_out_print("!AD:!_  Key cnt: !UL  max subsc len: !UL  max data len: !UL", TRUE,
				LEN_AND_LIT(gt_lit), key_count, max_subsc_len, max_data_len);
			util_out_print("Last LOAD record number: !UL", TRUE, key_count ? iter : 0);
			mu_gvis();
			util_out_print(0, TRUE);
			mu_ctrlc_occurred = FALSE;
		}
		if (0 > (len = file_input_get(&ptr)))
			break;
		if (mupip_error_occurred)
		{
		        mu_gvis();
			break;
		}
		if ('\n' == *ptr)
		{
			if ('\n' == *(ptr+1))
				break;
			ptr++;
		}
		if (0 == len)
			continue;
		if (MU_FMT_GO != fmt)
		{
			/* Determine if the ZWR has $extract format */
			if ('$' == *ptr)
			{
				keylength = zwrkeyvallen(ptr, len, &val_off, &val_len, &val_off1, &val_len1);
				ptr = ptr + 4; /* Skip first 4 character '$','z','e','(' */
				is_setextract = TRUE;
			} else
			{
				/* Determine the ZWR key length. -1 (SIZEOF(=)) is needed since ZWR allows '^x(1,2)='*/
				keylength = zwrkeyvallen(ptr, len, &val_off, &val_len, NULL, NULL);
				is_setextract = FALSE;
			}
			ISSUE_TRIGDATAIGNORE_IF_NEEDED(keylength, ptr, hasht_gbl);
			if (hasht_gbl)
			{
				hasht_gbl = FALSE;
				continue;
			}
			go_call_db(GO_PUT_SUB, ptr, keylength, 0, 0);
			if (mupip_error_occurred)
			{
			        mu_gvis();
				util_out_print("Error loading record number: !UL\n", TRUE, iter);
				mupip_error_occurred = FALSE;
				continue;
			}
			assert(keylength < len - 1);
			if (max_subsc_len < (gv_currkey->end + 1))
				max_subsc_len = gv_currkey->end + 1;
			src.len = val_len;
			src.addr = val_off;
			des.len = 0;
			if (src.len > max_rec_size)
			{
			        max_rec_size = src.len;
				free(rec_buff);
				rec_buff = (unsigned char *)malloc(max_rec_size);
			}
			des.addr = (char *)rec_buff;
			if (FALSE == zwr2format(&src, &des))
			{
				util_out_print("Format error in record number !8UL: !/!AD", TRUE, iter, src.len, src.addr);
				format_error = TRUE;
				continue;
			}
			if (max_data_len < des.len)
			        max_data_len = des.len;
			(is_setextract) ? go_call_db(GO_SET_EXTRACT, des.addr, des.len, val_off1, val_len1)
					: go_call_db(GO_PUT_DATA, (char *)rec_buff, des.len, 0, 0);
			if (mupip_error_occurred)
			{
			        mu_gvis();
				util_out_print("Error loading record number: !UL\n", TRUE, iter);
				mupip_error_occurred = FALSE;
				continue;
			}
			key_count++;
		} else
		{
			ISSUE_TRIGDATAIGNORE_IF_NEEDED(len, ptr, hasht_gbl);
			if (hasht_gbl)
			{
				if (0 > (len = file_input_get(&ptr)))
					break;
				iter++;
				hasht_gbl = FALSE;
				continue;
			}
		        go_call_db(GO_PUT_SUB, ptr, len, 0, 0);
			if (mupip_error_occurred)
			{
			        mu_gvis();
				util_out_print("Error loading record number: !UL\n", TRUE, iter);
				mupip_error_occurred = FALSE;
				continue;
			}
			if (max_subsc_len < (gv_currkey->end + 1))
				max_subsc_len = gv_currkey->end + 1;
			if (++iter > end)
			{
			        iter--;	/* Decrement as didn't load key */
				break;
			}
			if ((len = file_input_get(&ptr)) < 0)
			        break;
			if (mupip_error_occurred)
			{
			        mu_gvis();
				util_out_print("Error loading record number: !UL\n", TRUE, iter);
				break;
			}
			stringpool.free = stringpool.base;
			if (max_data_len < len)
			        max_data_len = len;
			go_call_db(GO_PUT_DATA, ptr, len, 0, 0);
			if (mupip_error_occurred)
			{
			        mu_gvis();
				util_out_print("Error loading record number: !UL\n", TRUE, iter);
				mupip_error_occurred = FALSE;
				continue;
			}
			key_count++;
		}
	}
	free(rec_buff);
	file_input_close();
	if (mu_ctrly_occurred)
	{
		gtm_putmsg(VARLSTCNT(1) ERR_LOADCTRLY);
		mupip_exit(ERR_MUNOFINISH);
	}
	util_out_print("LOAD TOTAL!_!_Key Cnt: !UL  Max Subsc Len: !UL  Max Data Len: !UL",TRUE,key_count,max_subsc_len,
			max_data_len);
	util_out_print("Last LOAD record number: !UL\n", TRUE, key_count ? (iter - 1) : 0);
	if (format_error)
		mupip_exit(ERR_LOADFILERR);
}