?? fileio.c
字號:
return IZ_CTRLC; /* cancel operation by user request */#endif if (uO.tflag || size == 0L) /* testing or nothing to write: all done */ return PK_OK; if (G.disk_full) return PK_DISK; /* disk already full: ignore rest of file *//*--------------------------------------------------------------------------- Write the bytes rawbuf[0..size-1] to the output device, first converting end-of-lines and ASCII/EBCDIC as needed. If SMALL_MEM or MED_MEM are NOT defined, outbuf is assumed to be at least as large as rawbuf and is not necessarily checked for overflow. ---------------------------------------------------------------------------*/ if (!G.pInfo->textmode) { /* write raw binary data */ /* GRR: note that for standard MS-DOS compilers, size argument to * fwrite() can never be more than 65534, so WriteError macro will * have to be rewritten if size can ever be that large. For now, * never more than 32K. Also note that write() returns an int, which * doesn't necessarily limit size to 32767 bytes if write() is used * on 16-bit systems but does make it more of a pain; however, because * at least MSC 5.1 has a lousy implementation of fwrite() (as does * DEC Ultrix cc), write() is used anyway. */#ifdef DLL if (G.redirect_data) writeToMemory(__G__ rawbuf, (extent)size); else#endif if (!uO.cflag && WriteError(rawbuf, size, G.outfile)) return disk_error(__G); else if (uO.cflag && (*G.message)((zvoid *)&G, rawbuf, size, 0)) return PK_OK; } else { /* textmode: aflag is true */ if (unshrink) { /* rawbuf = outbuf */ transbuf = G.outbuf2;#if (defined(SMALL_MEM) || defined(MED_MEM) || defined(VMS_TEXT_CONV)) transbufsiz = TRANSBUFSIZ;#endif } else { /* rawbuf = slide */ transbuf = G.outbuf;#if (defined(SMALL_MEM) || defined(MED_MEM) || defined(VMS_TEXT_CONV)) transbufsiz = OUTBUFSIZ; Trace((stderr, "\ntransbufsiz = OUTBUFSIZ = %u\n", (unsigned)OUTBUFSIZ));#endif } if (G.newfile) {#ifdef VMS_TEXT_CONV if (G.pInfo->hostnum == VMS_ && G.extra_field && is_vms_varlen_txt(__G__ G.extra_field, G.lrec.extra_field_length)) G.VMS_line_state = 0; /* 0: ready to read line length */ else G.VMS_line_state = -1; /* -1: don't treat as VMS text */#endif G.didCRlast = FALSE; /* no previous buffers written */ G.newfile = FALSE; }#ifdef VMS_TEXT_CONV if (G.VMS_line_state >= 0) { /* GRR: really want to check for actual VMS extra field, and * ideally for variable-length record format *//* printf("\n>>>>>> GRR: file is VMS text and has an extra field\n"); */ p = rawbuf; q = transbuf; while (p < rawbuf+(unsigned)size) { switch (G.VMS_line_state) { /* 0: ready to read line length */ case 0: G.VMS_line_length = 0; if (p == rawbuf+(unsigned)size-1) { /* last char */ G.VMS_line_length = (unsigned)(*p++); G.VMS_line_state = 1; } else { G.VMS_line_length = makeword(p); p += 2; G.VMS_line_state = 2; } G.VMS_line_pad = ((G.VMS_line_length & 1) != 0); /* odd */ break; /* 1: read one byte of length, need second */ case 1: G.VMS_line_length += ((unsigned)(*p++) << 8); G.VMS_line_state = 2; break; /* 2: ready to read VMS_line_length chars */ case 2: { extent remaining = rawbuf+(unsigned)size-p; extent outroom; if (G.VMS_line_length < remaining) { remaining = G.VMS_line_length; G.VMS_line_state = 3; } outroom = transbuf+(unsigned)transbufsiz-q; if (remaining >= outroom) { remaining -= outroom; for (;outroom > 0; p++, outroom--) *q++ = native(*p);#ifdef DLL if (G.redirect_data) writeToMemory(__G__ transbuf, (extent)(q-transbuf)); else#endif if (!uO.cflag && WriteError(transbuf, (extent)(q-transbuf), G.outfile)) return disk_error(__G); else if (uO.cflag && (*G.message)((zvoid *)&G, transbuf, (ulg)(q-transbuf), 0)) return PK_OK; q = transbuf; /* fall through to normal case */ } G.VMS_line_length -= remaining; for (;remaining > 0; p++, remaining--) *q++ = native(*p); } break; /* 3: ready to PutNativeEOL */ case 3: if (q > transbuf+(unsigned)transbufsiz-lenEOL) {#ifdef DLL if (G.redirect_data) writeToMemory(__G__ transbuf, (extent)(q-transbuf)); else#endif if (!uO.cflag && WriteError(transbuf, (extent)(q-transbuf), G.outfile)) return disk_error(__G); else if (uO.cflag && (*G.message)((zvoid *)&G, transbuf, (ulg)(q-transbuf), 0)) return PK_OK; q = transbuf; } PutNativeEOL G.VMS_line_state = G.VMS_line_pad ? 4 : 0; break; /* 4: ready to read pad byte */ case 4: ++p; G.VMS_line_state = 0; break; } } /* end while */ } else#endif /* VMS_TEXT_CONV */ /*----------------------------------------------------------------------- Algorithm: CR/LF => native; lone CR => native; lone LF => native. This routine is only for non-raw-VMS, non-raw-VM/CMS files (i.e., stream-oriented files, not record-oriented). -----------------------------------------------------------------------*/ /* else not VMS text */ { p = rawbuf; if (*p == LF && G.didCRlast) ++p; G.didCRlast = FALSE; for (q = transbuf; p < rawbuf+(unsigned)size; ++p) { if (*p == CR) { /* lone CR or CR/LF: treat as EOL */ PutNativeEOL if (p == rawbuf+(unsigned)size-1) /* last char in buffer */ G.didCRlast = TRUE; else if (p[1] == LF) /* get rid of accompanying LF */ ++p; } else if (*p == LF) /* lone LF */ PutNativeEOL else#ifndef DOS_FLX_OS2_W32 if (*p != CTRLZ) /* lose all ^Z's */#endif *q++ = native(*p);#if (defined(SMALL_MEM) || defined(MED_MEM))# if (lenEOL == 1) /* don't check unshrink: both buffers small but equal */ if (!unshrink)# endif /* check for danger of buffer overflow and flush */ if (q > transbuf+(unsigned)transbufsiz-lenEOL) { Trace((stderr, "p - rawbuf = %u q-transbuf = %u size = %lu\n", (unsigned)(p-rawbuf), (unsigned)(q-transbuf), size)); if (!uO.cflag && WriteError(transbuf, (extent)(q-transbuf), G.outfile)) return disk_error(__G); else if (uO.cflag && (*G.message)((zvoid *)&G, transbuf, (ulg)(q-transbuf), 0)) return PK_OK; q = transbuf; continue; }#endif /* SMALL_MEM || MED_MEM */ } } /*----------------------------------------------------------------------- Done translating: write whatever we've got to file (or screen). -----------------------------------------------------------------------*/ Trace((stderr, "p - rawbuf = %u q-transbuf = %u size = %lu\n", (unsigned)(p-rawbuf), (unsigned)(q-transbuf), size)); if (q > transbuf) {#ifdef DLL if (G.redirect_data) writeToMemory(__G__ transbuf, (extent)(q-transbuf)); else#endif if (!uO.cflag && WriteError(transbuf, (extent)(q-transbuf), G.outfile)) return disk_error(__G); else if (uO.cflag && (*G.message)((zvoid *)&G, transbuf, (ulg)(q-transbuf), 0)) return PK_OK; } } return PK_OK;} /* end function flush() [resp. partflush() for 16-bit Deflate64 support] */#ifdef VMS_TEXT_CONV/********************************//* Function is_vms_varlen_txt() *//********************************/static int is_vms_varlen_txt(__G__ ef_buf, ef_len) __GDEF uch *ef_buf; /* buffer containing extra field */ unsigned ef_len; /* total length of extra field */{ unsigned eb_id; unsigned eb_len; uch *eb_data; unsigned eb_datlen;#define VMSREC_C_UNDEF 0#define VMSREC_C_VAR 2 uch vms_rectype = VMSREC_C_UNDEF; uch vms_fileorg = 0;#define VMSPK_ITEMID 0#define VMSPK_ITEMLEN 2#define VMSPK_ITEMHEADSZ 4#define VMSATR_C_RECATTR 4#define VMS_FABSIG 0x42414656 /* "VFAB" *//* offsets of interesting fields in VMS fabdef structure */#define VMSFAB_B_RFM 31 /* record format byte */#define VMSFAB_B_ORG 29 /* file organization byte */ if (ef_len == 0 || ef_buf == NULL) return FALSE; while (ef_len >= EB_HEADSIZE) { eb_id = makeword(EB_ID + ef_buf); eb_len = makeword(EB_LEN + ef_buf); if (eb_len > (ef_len - EB_HEADSIZE)) { /* discovered some extra field inconsistency! */ Trace((stderr, "is_vms_varlen_txt: block length %u > rest ef_size %u\n", eb_len, ef_len - EB_HEADSIZE)); break; } switch (eb_id) { case EF_PKVMS: /* The PKVMS e.f. raw data part consists of: * a) 4 bytes CRC checksum * b) list of uncompressed variable-length data items * Each data item is introduced by a fixed header * - 2 bytes data type ID * - 2 bytes <size> of data * - <size> bytes of actual attribute data */ /* get pointer to start of data and its total length */ eb_data = ef_buf+(EB_HEADSIZE+4); eb_datlen = eb_len-4; /* test the CRC checksum */ if (makelong(ef_buf+EB_HEADSIZE) != crc32(CRCVAL_INITIAL, eb_data, (extent)eb_datlen)) { Info(slide, 1, ((char *)slide, "[Warning: CRC error, discarding PKWARE extra field]\n")); /* skip over the data analysis code */ break; } /* scan through the attribute data items */ while (eb_datlen > 4) { unsigned fldsize = makeword(&eb_data[VMSPK_ITEMLEN]); /* check the item type word */ switch (makeword(&eb_data[VMSPK_ITEMID])) { case VMSATR_C_RECATTR: /* we have found the (currently only) interesting * data item */ if (fldsize >= 1) { vms_rectype = eb_data[VMSPK_ITEMHEADSZ] & 15; vms_fileorg = eb_data[VMSPK_ITEMHEADSZ] >> 4; } break; default: break; } /* skip to next data item */ eb_datlen -= fldsize + VMSPK_ITEMHEADSZ; eb_data += fldsize + VMSPK_ITEMHEADSZ; } break; case EF_IZVMS: if (makelong(ef_buf+EB_HEADSIZE) == VMS_FABSIG) { if ((eb_data = extract_izvms_block(__G__ ef_buf+EB_HEADSIZE, eb_len, &eb_datlen, NULL, 0)) != NULL) { if (eb_datlen >= VMSFAB_B_RFM+1) { vms_rectype = eb_data[VMSFAB_B_RFM] & 15; vms_fileorg = eb_data[VMSFAB_B_ORG] >> 4; } free(eb_data); } } break; default: break; } /* Skip this extra field block */ ef_buf += (eb_len + EB_HEADSIZE); ef_len -= (eb_len + EB_HEADSIZE); } return (vms_rectype == VMSREC_C_VAR);} /* end function is_vms_varlen_txtfile() */#endif /* VMS_TEXT_CONV *//*************************//* Function disk_error() *//*************************/static int disk_error(__G) __GDEF{ /* OK to use slide[] here because this file is finished regardless */ Info(slide, 0x4a1, ((char *)slide, LoadFarString(DiskFullQuery), FnFilter1(G.filename)));#ifndef WINDLL
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -