393 lines
10 KiB
C
393 lines
10 KiB
C
|
/****************************************************************
|
||
|
* *
|
||
|
* Copyright 2001, 2009 Fidelity Information Services, Inc *
|
||
|
* *
|
||
|
* This source code contains the intellectual property *
|
||
|
* of its copyright holder(s), and is made available *
|
||
|
* under a license. If you do not know the terms of *
|
||
|
* the license, please stop and do not read further. *
|
||
|
* *
|
||
|
****************************************************************/
|
||
|
|
||
|
/* iomt_open.c UNIX - allocate and initialize open buffers, verify open
|
||
|
* parameters.
|
||
|
*/
|
||
|
#include "mdef.h"
|
||
|
|
||
|
#include "gtm_string.h"
|
||
|
#include "gtm_stdio.h"
|
||
|
|
||
|
#include <errno.h>
|
||
|
|
||
|
#include "copy.h"
|
||
|
#include "io.h"
|
||
|
#include "iottdef.h"
|
||
|
#include "iomtdef.h"
|
||
|
#include "iosp.h"
|
||
|
#include "io_params.h"
|
||
|
#include "nametabtyp.h"
|
||
|
#include "toktyp.h"
|
||
|
#include "stringpool.h"
|
||
|
#include "namelook.h"
|
||
|
|
||
|
static readonly nametabent mtlab_names[] =
|
||
|
{
|
||
|
{3, "ANS"}, {4, "ANSI"}, {3, "DOS"}, {5, "DOS11"}
|
||
|
};
|
||
|
static readonly unsigned char mtlab_index[27] =
|
||
|
{
|
||
|
0, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4
|
||
|
,4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
|
||
|
,4, 4, 4
|
||
|
};
|
||
|
|
||
|
LITDEF unsigned char LIB_AB_ASC_EBC[256] =
|
||
|
{
|
||
|
0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14,
|
||
|
15, 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30,
|
||
|
31, 64, 79, 127, 123, 91, 108, 80, 125, 77, 93, 92, 78, 107, 96, 75,
|
||
|
97, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 122, 94, 76, 126, 110,
|
||
|
111, 124, 193, 194, 195, 196, 197, 198, 199, 200, 201, 209, 210, 211, 212, 213,
|
||
|
214, 215, 216, 217, 226, 227, 228, 229, 230, 231, 232, 233, 74, 224, 90, 95,
|
||
|
109, 121, 129, 130, 131, 132, 133, 134, 135, 136, 137, 145, 146, 147, 148, 149,
|
||
|
150, 151, 152, 153, 162, 163, 164, 165, 166, 167, 168, 169, 192, 106, 208, 161,
|
||
|
7, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
|
||
|
63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
|
||
|
63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
|
||
|
63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
|
||
|
63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
|
||
|
63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
|
||
|
63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
|
||
|
63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 255
|
||
|
};
|
||
|
|
||
|
LITDEF unsigned char LIB_AB_EBC_ASC[256] =
|
||
|
{
|
||
|
0, 1, 2, 3, 92, 9, 92, 127, 92, 92, 92, 11, 12, 13, 14,
|
||
|
15, 16, 17, 18, 19, 92, 92, 8, 92, 24, 25, 92, 92, 28, 29, 30,
|
||
|
31, 92, 92, 92, 92, 92, 10, 23, 27, 92, 92, 92, 92, 92, 5, 6,
|
||
|
7, 92, 92, 22, 92, 92, 92, 92, 4, 92, 92, 92, 92, 20, 21, 92,
|
||
|
26, 32, 92, 92, 92, 92, 92, 92, 92, 92, 92, 91, 46, 60, 40, 43,
|
||
|
33, 38, 92, 92, 92, 92, 92, 92, 92, 92, 92, 93, 36, 42, 41, 59,
|
||
|
94, 45, 47, 92, 92, 92, 92, 92, 92, 92, 92, 124, 44, 37, 95, 62,
|
||
|
63, 92, 92, 92, 92, 92, 92, 92, 92, 92, 96, 58, 35, 64, 39, 61,
|
||
|
34, 92, 97, 98, 99, 100, 101, 102, 103, 104, 105, 92, 92, 92, 92, 92,
|
||
|
92, 92, 106, 107, 108, 109, 110, 111, 112, 113, 114, 92, 92, 92, 92, 92,
|
||
|
92, 92, 126, 115, 116, 117, 118, 119, 120, 121, 122, 92, 92, 92, 92, 92,
|
||
|
92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
|
||
|
92, 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, 92, 92, 92, 92, 92,
|
||
|
92, 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, 92, 92, 92, 92, 92,
|
||
|
92, 92, 92, 83, 84, 85, 86, 87, 88, 89, 90, 92, 92, 92, 92, 92,
|
||
|
92, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 92, 92, 92, 92, 92, 255
|
||
|
};
|
||
|
|
||
|
LITREF unsigned char io_params_size[];
|
||
|
|
||
|
static readonly char mtlab_type[] = {MTLAB_ANSI, MTLAB_ANSI, MTLAB_DOS11, MTLAB_DOS11};
|
||
|
|
||
|
#define VREC_HDR_LEN 4
|
||
|
|
||
|
short iomt_open(io_log_name *dev_name, mval *pp, int fd, mval *mspace, int4 timeout)
|
||
|
{
|
||
|
bool do_rewind, do_erase;
|
||
|
int lab_type;
|
||
|
unsigned char ch, *buff;
|
||
|
int len;
|
||
|
int4 blocksize, recordsize, length;
|
||
|
uint4 status;
|
||
|
d_mt_struct *mt, newmt;
|
||
|
iosb io_status_blk;
|
||
|
io_desc *ioptr;
|
||
|
char *tab;
|
||
|
int p_offset;
|
||
|
|
||
|
error_def(ERR_MTRECTOOBIG);
|
||
|
error_def(ERR_MTRECGTRBLK);
|
||
|
error_def(ERR_MTBLKTOOBIG);
|
||
|
error_def(ERR_MTBLKTOOSM);
|
||
|
error_def(ERR_MTFIXRECSZ);
|
||
|
error_def(ERR_MTRECTOOSM);
|
||
|
error_def(ERR_VARRECBLKSZ);
|
||
|
error_def(ERR_MTINVLAB);
|
||
|
error_def(ERR_MTDOSFOR);
|
||
|
error_def(ERR_MTANSIFOR);
|
||
|
error_def(ERR_MTIS);
|
||
|
error_def(ERR_DEVPARMNEG);
|
||
|
error_def(ERR_MTIOERR);
|
||
|
|
||
|
#ifdef DP
|
||
|
FPRINTF(stderr, ">> iomt_open(%d)\n", fd);
|
||
|
#endif
|
||
|
ioptr = dev_name->iod;
|
||
|
buff = 0;
|
||
|
memset(&newmt, 0, SIZEOF(newmt)); /* zero structure to start */
|
||
|
if (ioptr->state == dev_never_opened)
|
||
|
ioptr->dev_sp = (void *)(malloc(SIZEOF(d_mt_struct)));
|
||
|
mt = (d_mt_struct *)dev_name->iod->dev_sp;
|
||
|
if (ioptr->state == dev_open && mt->buffer)
|
||
|
{
|
||
|
if (mt->bufftoggle < 0)
|
||
|
buff = (mt->buffer + mt->bufftoggle);
|
||
|
else
|
||
|
buff = (mt->buffer);
|
||
|
}
|
||
|
do_rewind = do_erase = FALSE;
|
||
|
if (ioptr->state == dev_never_opened)
|
||
|
{
|
||
|
length = DEF_MT_LENGTH;
|
||
|
newmt.read_mask = IO_READLBLK;
|
||
|
newmt.write_mask = IO_WRITELBLK;
|
||
|
newmt.block_sz = MTDEF_BUF_SZ;
|
||
|
newmt.record_sz = MTDEF_REC_SZ;
|
||
|
newmt.ebcdic = FALSE;
|
||
|
newmt.labeled = FALSE;
|
||
|
newmt.fixed = FALSE;
|
||
|
newmt.stream = FALSE;
|
||
|
newmt.read_only = FALSE;
|
||
|
newmt.newversion = FALSE;
|
||
|
newmt.last_op = mt_null;
|
||
|
newmt.wrap = TRUE;
|
||
|
} else
|
||
|
{
|
||
|
length = ioptr->length;
|
||
|
newmt = *mt;
|
||
|
}
|
||
|
p_offset = 0;
|
||
|
while (*(pp->str.addr + p_offset) != iop_eol)
|
||
|
{
|
||
|
switch (ch = *(pp->str.addr + p_offset++))
|
||
|
{
|
||
|
case iop_blocksize:
|
||
|
GET_LONG(blocksize, (pp->str.addr + p_offset));
|
||
|
if (blocksize < 0)
|
||
|
rts_error(VARLSTCNT(1) ERR_DEVPARMNEG);
|
||
|
if (blocksize > MAX_BLK_SZ)
|
||
|
rts_error(VARLSTCNT(1) ERR_MTBLKTOOBIG);
|
||
|
newmt.block_sz = blocksize;
|
||
|
break;
|
||
|
case iop_recordsize:
|
||
|
GET_LONG(recordsize, (pp->str.addr + p_offset));
|
||
|
if (recordsize < 0)
|
||
|
rts_error(VARLSTCNT(1) ERR_DEVPARMNEG);
|
||
|
if (recordsize > MAX_REC_SZ)
|
||
|
rts_error(VARLSTCNT(1) ERR_MTRECTOOBIG);
|
||
|
newmt.record_sz = recordsize;
|
||
|
break;
|
||
|
case iop_rewind:
|
||
|
do_rewind = TRUE;
|
||
|
break;
|
||
|
case iop_erasetape:
|
||
|
do_erase = TRUE;
|
||
|
break;
|
||
|
case iop_newversion:
|
||
|
newmt.newversion = TRUE;
|
||
|
break;
|
||
|
case iop_readonly:
|
||
|
newmt.read_only = TRUE;
|
||
|
break;
|
||
|
case iop_noreadonly:
|
||
|
newmt.read_only = FALSE;
|
||
|
break;
|
||
|
case iop_ebcdic:
|
||
|
newmt.ebcdic = TRUE;
|
||
|
break;
|
||
|
case iop_noebcdic:
|
||
|
newmt.ebcdic = FALSE;
|
||
|
break;
|
||
|
case iop_nolabel:
|
||
|
newmt.labeled = FALSE;
|
||
|
break;
|
||
|
case iop_label:
|
||
|
len = *(pp->str.addr + p_offset);
|
||
|
tab = pp->str.addr + p_offset + 1;
|
||
|
if ((lab_type = namelook(mtlab_index, mtlab_names, tab, len)) < 0)
|
||
|
{
|
||
|
iomt_closesp(fd);
|
||
|
rts_error(VARLSTCNT(1) ERR_MTINVLAB);
|
||
|
return FALSE;
|
||
|
}
|
||
|
newmt.labeled = mtlab_type[lab_type];
|
||
|
break;
|
||
|
case iop_fixed:
|
||
|
newmt.fixed = TRUE;
|
||
|
break;
|
||
|
case iop_nofixed:
|
||
|
newmt.fixed = FALSE;
|
||
|
break;
|
||
|
case iop_rdcheckdata:
|
||
|
newmt.read_mask |= IO_M_DATACHECK;
|
||
|
break;
|
||
|
case iop_nordcheckdata:
|
||
|
newmt.read_mask &= (~(IO_M_DATACHECK));
|
||
|
break;
|
||
|
case iop_wtcheckdata:
|
||
|
newmt.write_mask |= IO_M_DATACHECK;
|
||
|
break;
|
||
|
case iop_nowtcheckdata:
|
||
|
newmt.write_mask &= (~(IO_M_DATACHECK));
|
||
|
break;
|
||
|
case iop_inhretry:
|
||
|
newmt.write_mask |= IO_M_INHRETRY;
|
||
|
newmt.read_mask |= IO_M_INHRETRY;
|
||
|
break;
|
||
|
case iop_retry:
|
||
|
newmt.write_mask &= ~IO_M_INHRETRY;
|
||
|
newmt.read_mask &= ~IO_M_INHRETRY;
|
||
|
break;
|
||
|
case iop_inhextgap:
|
||
|
newmt.write_mask |= IO_M_INHEXTGAP;
|
||
|
break;
|
||
|
case iop_extgap:
|
||
|
newmt.write_mask &= ~IO_M_INHEXTGAP;
|
||
|
break;
|
||
|
case iop_stream:
|
||
|
newmt.stream = TRUE;
|
||
|
break;
|
||
|
case iop_nostream:
|
||
|
newmt.stream = FALSE;
|
||
|
break;
|
||
|
case iop_wrap:
|
||
|
newmt.wrap = TRUE;
|
||
|
break;
|
||
|
case iop_nowrap:
|
||
|
newmt.wrap = FALSE;
|
||
|
break;
|
||
|
case iop_length:
|
||
|
GET_LONG(length, (pp->str.addr + p_offset));
|
||
|
if (length < 0)
|
||
|
{
|
||
|
iomt_closesp(fd);
|
||
|
rts_error(VARLSTCNT(1) ERR_DEVPARMNEG);
|
||
|
}
|
||
|
break;
|
||
|
case iop_exception:
|
||
|
ioptr->error_handler.len = *(pp->str.addr + p_offset);
|
||
|
ioptr->error_handler.addr = (char *)(pp->str.addr + p_offset + 1);
|
||
|
s2pool(&ioptr->error_handler);
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
p_offset += ((IOP_VAR_SIZE == io_params_size[ch]) ?
|
||
|
(unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[ch]);
|
||
|
}
|
||
|
if (newmt.labeled == MTLAB_DOS11)
|
||
|
{
|
||
|
if (!newmt.stream)
|
||
|
{
|
||
|
iomt_closesp(fd);
|
||
|
rts_error(VARLSTCNT(6) ERR_MTDOSFOR, 0, ERR_MTIS, 2,
|
||
|
ioptr->trans_name->len, ioptr->trans_name->dollar_io);
|
||
|
}
|
||
|
}
|
||
|
if (newmt.labeled == MTLAB_ANSI)
|
||
|
{
|
||
|
if (newmt.stream)
|
||
|
{
|
||
|
iomt_closesp(fd);
|
||
|
rts_error(VARLSTCNT(6) ERR_MTANSIFOR, 0, ERR_MTIS, 2,
|
||
|
ioptr->trans_name->len, ioptr->trans_name->dollar_io);
|
||
|
}
|
||
|
}
|
||
|
if (newmt.stream)
|
||
|
{
|
||
|
newmt.wrap = TRUE;
|
||
|
newmt.fixed = FALSE;
|
||
|
}
|
||
|
if (newmt.fixed)
|
||
|
{
|
||
|
if (newmt.record_sz < MIN_FIXREC_SZ)
|
||
|
{
|
||
|
iomt_closesp(fd);
|
||
|
rts_error(VARLSTCNT(1) ERR_MTRECTOOSM);
|
||
|
}
|
||
|
if (newmt.block_sz / newmt.record_sz * newmt.record_sz != newmt.block_sz)
|
||
|
{
|
||
|
iomt_closesp(fd);
|
||
|
rts_error(VARLSTCNT(3) ERR_MTFIXRECSZ, newmt.block_sz, newmt.record_sz);
|
||
|
}
|
||
|
} else
|
||
|
{
|
||
|
if (newmt.record_sz > MAX_VARREC_SZ)
|
||
|
{
|
||
|
iomt_closesp(fd);
|
||
|
rts_error(VARLSTCNT(1) ERR_MTRECTOOBIG);
|
||
|
}
|
||
|
if (newmt.record_sz < MIN_VARREC_SZ)
|
||
|
{
|
||
|
iomt_closesp(fd);
|
||
|
rts_error(VARLSTCNT(1) ERR_MTRECTOOSM);
|
||
|
}
|
||
|
if ((int)newmt.block_sz < (int)newmt.record_sz + (newmt.stream ? 2 : VREC_HDR_LEN))
|
||
|
{
|
||
|
iomt_closesp(fd);
|
||
|
rts_error(VARLSTCNT(1) ERR_VARRECBLKSZ);
|
||
|
}
|
||
|
}
|
||
|
if (newmt.record_sz > newmt.block_sz)
|
||
|
{
|
||
|
iomt_closesp(fd);
|
||
|
rts_error(VARLSTCNT(1) ERR_MTRECGTRBLK);
|
||
|
}
|
||
|
if (ioptr->state != dev_open)
|
||
|
{
|
||
|
newmt.filepos = newmt.recpos = 0;
|
||
|
newmt.mode = MT_M_READ;
|
||
|
newmt.access_id = fd;
|
||
|
/* get mag tape characteristics */
|
||
|
if (!iomt_info(&newmt))
|
||
|
{
|
||
|
status = errno;
|
||
|
iomt_closesp(fd);
|
||
|
rts_error(VARLSTCNT(5) ERR_MTIOERR, 2, ioptr->trans_name->len, ioptr->trans_name->dollar_io, status);
|
||
|
}
|
||
|
}
|
||
|
if ((int4)newmt.block_sz < newmt.cap.block_size)
|
||
|
{
|
||
|
iomt_closesp(fd);
|
||
|
rts_error(VARLSTCNT(3) ERR_MTBLKTOOSM, 1,
|
||
|
(int4)newmt.cap.block_size);
|
||
|
}
|
||
|
if (newmt.fixed)
|
||
|
{
|
||
|
newmt.buffer = (unsigned char *)malloc(newmt.block_sz);
|
||
|
newmt.bufftoggle = 0;
|
||
|
} else
|
||
|
{
|
||
|
newmt.buffer = (unsigned char *)malloc(newmt.block_sz * 2);
|
||
|
newmt.bufftoggle = newmt.block_sz;
|
||
|
}
|
||
|
if (buff)
|
||
|
free(buff);
|
||
|
newmt.bufftop = newmt.buffptr = newmt.buffer;
|
||
|
newmt.last_op = mt_null;
|
||
|
ioptr->state = dev_open;
|
||
|
*mt = newmt;
|
||
|
ioptr->width = newmt.record_sz;
|
||
|
ioptr->length = length;
|
||
|
ioptr->dollar.zeof = FALSE;
|
||
|
ioptr->dollar.x = 0;
|
||
|
ioptr->dollar.y = 0;
|
||
|
if (do_erase)
|
||
|
iomt_erase(ioptr);
|
||
|
if (do_rewind)
|
||
|
iomt_rewind(ioptr);
|
||
|
if (mt->labeled)
|
||
|
{
|
||
|
status = iomt_sense(mt, &io_status_blk);
|
||
|
if (status != SS_NORMAL)
|
||
|
{
|
||
|
ioptr->dollar.za = 9;
|
||
|
iomt_closesp(fd);
|
||
|
rts_error(VARLSTCNT(5) status,
|
||
|
ERR_MTIS, 2, ioptr->trans_name->len, ioptr->trans_name->dollar_io);
|
||
|
}
|
||
|
if (io_status_blk.dev_dep_info & MT_M_BOT)
|
||
|
mt->last_op = mt_rewind;
|
||
|
}
|
||
|
#ifdef DP
|
||
|
FPRINTF(stderr, "<< iomt_open\n");
|
||
|
#endif
|
||
|
return TRUE;
|
||
|
}
|