/**************************************************************** * * * 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 #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; }