Beispiel #1
0
/* write ASCII characters converting to UTF16 if needed
 * 	returns bytes written
*/
int  iorm_write_utf_ascii(io_desc *iod, char *string, int len)
{
	int		outlen, mblen, status;
	wint_t		utf_code;
	unsigned char	*outstart, *out, *top, *outptr, *nextoutptr, *outptrtop, *nextmb;
	d_rm_struct	*rm_ptr;
	boolean_t	ch_set;

	ESTABLISH_RET_GTMIO_CH(&iod->pair, -1, ch_set);
	rm_ptr = (d_rm_struct *)iod->dev_sp;
	assert(NULL != rm_ptr);
	if (CHSET_UTF8 != iod->ochset)
	{
		outstart = outptr = &rm_ptr->outbuf[rm_ptr->out_bytes];
		outptrtop = rm_ptr->outbuf + rm_ptr->recordsize;	/* buffer is larger than recordsize to allow for EOL */
		assert(len <= (&rm_ptr->outbuf[rm_ptr->outbufsize] - outstart));
		for (out = (unsigned char*)string, top = out + len, outlen = 0; out < top && outptr <= outptrtop;
				out = nextmb, outptr = nextoutptr)
		{
			nextmb = UTF8_MBTOWC(out, top, utf_code);
			assert(nextmb == (out + 1));
			if (WEOF == utf_code)
			{
				iod->dollar.za = 9;
				UTF8_BADCHAR((int)(nextmb - out), out, top, 0, NULL);
			}
			if (CHSET_UTF16BE == iod->ochset)
				nextoutptr = UTF16BE_WCTOMB(utf_code, outptr);
			else
				nextoutptr = UTF16LE_WCTOMB(utf_code, outptr);
			if (nextoutptr == outptr)
			{	/* invalid codepoint */
				iod->dollar.za = 9;
				UTF8_BADCHAR((int)(nextmb - out), out, top, chset_names[iod->ochset].len,
						chset_names[iod->ochset].addr);
			}
			mblen = (int)(nextoutptr - outptr);
			outlen += mblen;
		}
	} else
	{
		outstart = (unsigned char *)string;
		outlen = len;
	}
	if (0 < outlen)
	{
		if (rm_ptr->output_encrypted)
		{
			REALLOC_CRYPTBUF_IF_NEEDED(outlen);
			WRITE_ENCRYPTED_DATA(rm_ptr, iod->trans_name, outstart, outlen, pvt_crypt_buf.addr);
			outptr = (unsigned char *)pvt_crypt_buf.addr;
		} else
			outptr = outstart;
		DOWRITERC_RM(rm_ptr, outptr, outlen, status);
		ISSUE_NOPRINCIO_IF_NEEDED_RM(status, ==, iod);
		rm_ptr->write_occurred = TRUE;
		rm_ptr->out_bytes += outlen;
	}
	REVERT_GTMIO_CH(&iod->pair, ch_set);
	return outlen;
}
void jnl_write_aimg_rec(sgmnt_addrs *csa, cw_set_element *cse, uint4 com_csum)
{
	struct_jrec_blk		aimg_record;
	int			tmp_jrec_size, jrec_size, zero_len;
	jnl_format_buffer 	blk_trailer;	/* partial record after the aimg block */
	char			local_buff[JNL_REC_START_BNDRY + JREC_SUFFIX_SIZE];
	jrec_suffix		*suffix;
	blk_hdr_ptr_t		buffer, save_buffer;
	jnl_private_control	*jpc;
	sgmnt_data_ptr_t	csd;
	uint4			cursum;
#	ifdef GTM_CRYPT
	char			*in, *out;
	int			in_len, gtmcrypt_errno;
	gd_segment		*seg;
#	endif

	csd = csa->hdr;
	assert(csa->now_crit);
	jpc = csa->jnl;
	assert(0 != jpc->pini_addr);
	aimg_record.prefix.jrec_type = JRT_AIMG;
	aimg_record.prefix.pini_addr = (0 == jpc->pini_addr) ? JNL_HDR_LEN : jpc->pini_addr;
	aimg_record.prefix.tn = csa->ti->curr_tn;
	/* At this point jgbl.gbl_jrec_time should be set by the caller */
	assert(jgbl.gbl_jrec_time);
	aimg_record.prefix.time = jgbl.gbl_jrec_time;
	aimg_record.prefix.checksum = INIT_CHECKSUM_SEED;
	aimg_record.blknum = cse->blk;
	/* in case we have a bad block-size, we dont want to write an AIMG larger than the GDS block size (maximum block size) */
	buffer = (blk_hdr_ptr_t)cse->new_buff;
	assert(buffer->bsiz <= csd->blk_size);
	assert(buffer->bsiz >= SIZEOF(blk_hdr));
	aimg_record.bsiz = MIN(csd->blk_size, buffer->bsiz);
	aimg_record.ondsk_blkver = cse->ondsk_blkver;
	tmp_jrec_size = (int)FIXED_AIMG_RECLEN + aimg_record.bsiz + JREC_SUFFIX_SIZE;
	jrec_size = ROUND_UP2(tmp_jrec_size, JNL_REC_START_BNDRY);
	zero_len = jrec_size - tmp_jrec_size;
	blk_trailer.buff = local_buff + (JNL_REC_START_BNDRY - zero_len);
	memset(blk_trailer.buff, 0, zero_len);
	blk_trailer.record_size = zero_len + JREC_SUFFIX_SIZE;
	suffix = (jrec_suffix *)&local_buff[JNL_REC_START_BNDRY];
	aimg_record.prefix.forwptr = suffix->backptr = jrec_size;
	suffix->suffix_code = JNL_REC_SUFFIX_CODE;
	assert(SIZEOF(uint4) == SIZEOF(jrec_suffix));
	save_buffer = buffer;
#	ifdef GTM_CRYPT
	in_len = aimg_record.bsiz - SIZEOF(*buffer);
	if (BLK_NEEDS_ENCRYPTION3(csd->is_encrypted, buffer->levl, in_len))
	{
		ASSERT_ENCRYPTION_INITIALIZED;
		assert(aimg_record.bsiz <= csa->hdr->blk_size);
		REALLOC_CRYPTBUF_IF_NEEDED(csa->hdr->blk_size);
		memcpy(pvt_crypt_buf.addr, buffer, SIZEOF(blk_hdr));	/* copy the block header */
		in = (char *)(buffer + 1);	/* + 1 because `buffer' is of type blk_hdr_ptr_t */
		out = pvt_crypt_buf.addr + SIZEOF(blk_hdr);
		GTMCRYPT_ENCRYPT(csa, csa->encr_key_handle, in, in_len, out, gtmcrypt_errno);
		if (0 != gtmcrypt_errno)
		{
			seg = csa->region->dyn.addr;
			GTMCRYPT_REPORT_ERROR(gtmcrypt_errno, rts_error, seg->fname_len, seg->fname);
		}
		buffer = (blk_hdr_ptr_t)pvt_crypt_buf.addr;
	}
#	endif
	cursum = jnl_get_checksum((uint4 *)buffer, NULL, aimg_record.bsiz);
	COMPUTE_AIMG_CHECKSUM(cursum, &aimg_record, com_csum, aimg_record.prefix.checksum);
	jnl_write(jpc, JRT_AIMG, (jnl_record *)&aimg_record, buffer, &blk_trailer);
	buffer = save_buffer;
}
Beispiel #3
0
void iorm_write_utf(mstr *v)
{
	int4		inchars, char_count;		/* in characters */
	int4		inlen, outbytes, mblen;		/* in bytes */
	int4		availwidth, usedwidth, mbwidth;	/* in display columns */
	int		status, padsize,fstat_res,save_errno;
	wint_t		utf_code;
	io_desc		*iod;
	d_rm_struct	*rm_ptr;
	unsigned char	*inptr, *top, *nextmb, *outptr, *nextoutptr, *outstart, temppad, temppadarray[2];
	char		*out_ptr;
	boolean_t	utf8_active = TRUE;		/* needed by GTM_IO_WCWIDTH macro */
	boolean_t	stream, wrap;
	struct stat	statbuf;
	boolean_t	ch_set;

	iod = io_curr_device.out;
	ESTABLISH_GTMIO_CH(&io_curr_device, ch_set);
	rm_ptr = (d_rm_struct *)iod->dev_sp;
	assert(NULL != rm_ptr);
	inptr = (unsigned char *)v->addr;
	inlen = v->len;
	top = inptr + inlen;
	if (!rm_ptr->fixed && 0 == iod->dollar.x)
		rm_ptr->out_bytes = 0;			/* user reset $X */
	inchars = UTF8_LEN_STRICT(v->addr, v->len);	/* validate and get good char count */
	if (0 >= inchars)
	{
		REVERT_GTMIO_CH(&io_curr_device, ch_set);
		return;
	}
	usedwidth = 0;
	stream = rm_ptr->stream;
	wrap = iod->wrap;
	if (stream && !wrap)
	{	/* For STREAM and NOWRAP, allow the entire record to be written without any record truncations/terminations */
		availwidth = inlen;	/* calculate worst case requirement of width (in chars) to write out input bytes */
		rm_ptr->out_bytes = 0;
	} else
		availwidth = iod->width - iod->dollar.x;
	outbytes = 0;
	if (CHSET_UTF8 != iod->ochset)
	{
		outstart = nextoutptr = outptr = &rm_ptr->outbuf[rm_ptr->out_bytes];
		if (!rm_ptr->done_1st_write)
		{	/* get the file size  */
			FSTAT_FILE(rm_ptr->fildes, &statbuf, fstat_res);
			if (-1 == fstat_res)
			{
				save_errno = errno;
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("fstat"),
					      CALLFROM, save_errno);
			}
			if (CHSET_UTF16 == iod->ochset)
			{	/* Write BOM but do not count it towards the bytes in the current record */
				/* write BOM if file is empty */
				if (0 == statbuf.st_size)
				{
					memcpy(outptr, UTF16BE_BOM, UTF16BE_BOM_LEN);
					outbytes = UTF16BE_BOM_LEN;
					if (rm_ptr->output_encrypted)
					{
						REALLOC_CRYPTBUF_IF_NEEDED(outbytes);
						WRITE_ENCRYPTED_DATA(rm_ptr, iod->trans_name, outstart, outbytes,
							pvt_crypt_buf.addr);
						out_ptr = pvt_crypt_buf.addr;
					} else
						out_ptr = (char *)outstart;
					DOWRITERC_RM(rm_ptr, out_ptr, outbytes, status);
					ISSUE_NOPRINCIO_IF_NEEDED_RM(status, ==, iod);
					rm_ptr->write_occurred = TRUE;
					outptr = outstart;
					rm_ptr->out_bytes = outbytes = 0;
					/* save UTF16BE_BOM_LEN in bom_num_bytes until bom is checked, but don't
					 indicate that bom has been checked - which still needs to be done for reading
					 the exception is if the file was opened WRITEONLY */
					rm_ptr->bom_num_bytes = UTF16BE_BOM_LEN;
					if (rm_ptr->write_only)
						rm_ptr->bom_checked = TRUE;
				}
				iod->ochset = CHSET_UTF16BE;
				get_chset_desc(&chset_names[iod->ochset]);
			}