📄 fileio.c
字号:
if (G.outfile == (FILE *)NULL) { Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile), FnFilter1(G.filename))); return 1; }#else /* !MTS */#ifdef DEBUG Info(slide, 1, ((char *)slide, "open_outfile: doing fopen(%s) for reading\n", FnFilter1(G.filename))); if ((G.outfile = fopen(G.filename, FOPR)) == (FILE *)NULL) Info(slide, 1, ((char *)slide, "open_outfile: fopen(%s) for reading failed: does not exist\n", FnFilter1(G.filename))); else { Info(slide, 1, ((char *)slide, "open_outfile: fopen(%s) for reading succeeded: file exists\n", FnFilter1(G.filename))); fclose(G.outfile); }#endif /* DEBUG */#ifdef NOVELL_BUG_FAILSAFE if (G.dne && ((G.outfile = fopen(G.filename, FOPR)) != (FILE *)NULL)) { Info(slide, 0x401, ((char *)slide, LoadFarString(NovellBug), FnFilter1(G.filename))); fclose(G.outfile); return 1; /* with "./" fix in checkdir(), should never reach here */ }#endif /* NOVELL_BUG_FAILSAFE */ Trace((stderr, "open_outfile: doing fopen(%s) for writing\n", FnFilter1(G.filename))); if ((G.outfile = fopen(G.filename, FOPW)) == (FILE *)NULL) { Info(slide, 0x401, ((char *)slide, LoadFarString(CannotCreateFile), FnFilter1(G.filename))); return 1; } Trace((stderr, "open_outfile: fopen(%s) for writing succeeded\n", FnFilter1(G.filename)));#endif /* !MTS */#endif /* !TOPS20 */#ifdef USE_FWRITE#ifdef DOS_NLM_OS2_W32 /* 16-bit MSC: buffer size must be strictly LESS than 32K (WSIZE): bogus */ setbuf(G.outfile, (char *)NULL); /* make output unbuffered */#else /* !DOS_NLM_OS2_W32 */#ifndef RISCOS#ifdef _IOFBF /* make output fully buffered (works just about like write()) */ setvbuf(G.outfile, (char *)slide, _IOFBF, WSIZE);#else setbuf(G.outfile, (char *)slide);#endif#endif /* !RISCOS */#endif /* ?DOS_NLM_OS2_W32 */#endif /* USE_FWRITE */#ifdef OS2_W32 /* preallocate the final file size to prevent file fragmentation */ SetFileSize(G.outfile, G.lrec.ucsize);#endif return 0;} /* end function open_outfile() */#endif /* !TANDEM */#endif /* !VMS && !AOS_VS && !CMS_MVS && !MACOS *//* * These functions allow NEXTBYTE to function without needing two bounds * checks. Call defer_leftover_input() if you ever have filled G.inbuf * by some means other than readbyte(), and you then want to start using * NEXTBYTE. When going back to processing bytes without NEXTBYTE, call * undefer_input(). For example, extract_or_test_member brackets its * central section that does the decompression with these two functions. * If you need to check the number of bytes remaining in the current * file while using NEXTBYTE, check (G.csize + G.incnt), not G.csize. *//****************************//* function undefer_input() *//****************************/void undefer_input(__G) __GDEF{ if (G.incnt > 0) G.csize += G.incnt; if (G.incnt_leftover > 0) { /* We know that "(G.csize < MAXINT)" so we can cast G.csize to int: * This condition was checked when G.incnt_leftover was set > 0 in * defer_leftover_input(), and it is NOT allowed to touch G.csize * before calling undefer_input() when (G.incnt_leftover > 0) * (single exception: see read_byte()'s "G.csize <= 0" handling) !! */ G.incnt = G.incnt_leftover + (int)G.csize; G.inptr = G.inptr_leftover - (int)G.csize; G.incnt_leftover = 0; } else if (G.incnt < 0) G.incnt = 0;} /* end function undefer_input() *//***********************************//* function defer_leftover_input() *//***********************************/void defer_leftover_input(__G) __GDEF{ if ((long)G.incnt > G.csize) { /* (G.csize < MAXINT), we can safely cast it to int !! */ if (G.csize < 0L) G.csize = 0L; G.inptr_leftover = G.inptr + (int)G.csize; G.incnt_leftover = G.incnt - (int)G.csize; G.incnt = (int)G.csize; } else G.incnt_leftover = 0; G.csize -= G.incnt;} /* end function defer_leftover_input() *//**********************//* Function readbuf() *//**********************/unsigned readbuf(__G__ buf, size) /* return number of bytes read into buf */ __GDEF char *buf; register unsigned size;{ register unsigned count; unsigned n; n = size; while (size) { if (G.incnt <= 0) { if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0) return (n-size); else if (G.incnt < 0) { /* another hack, but no real harm copying same thing twice */ (*G.message)((zvoid *)&G, (uch *)LoadFarString(ReadError), /* CANNOT use slide */ (ulg)strlen(LoadFarString(ReadError)), 0x401); return 0; /* discarding some data; better than lock-up */ } /* buffer ALWAYS starts on a block boundary: */ G.cur_zipfile_bufstart += INBUFSIZ; G.inptr = G.inbuf; } count = MIN(size, (unsigned)G.incnt); memcpy(buf, G.inptr, count); buf += count; G.inptr += count; G.incnt -= count; size -= count; } return n;} /* end function readbuf() *//***********************//* Function readbyte() *//***********************/int readbyte(__G) /* refill inbuf and return a byte if available, else EOF */ __GDEF{ if (G.mem_mode) return EOF; if (G.csize <= 0) { G.csize--; /* for tests done after exploding */ G.incnt = 0; return EOF; } if (G.incnt <= 0) { if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) == 0) { G.incnt = 0; /* do not allow negative value to affect stuff */ return EOF; } else if (G.incnt < 0) { /* "fail" (abort, retry, ...) returns this */ /* another hack, but no real harm copying same thing twice */ (*G.message)((zvoid *)&G, (uch *)LoadFarString(ReadError), (ulg)strlen(LoadFarString(ReadError)), 0x401); echon();#ifdef WINDLL longjmp(dll_error_return, 1);#else DESTROYGLOBALS(); EXIT(PK_BADERR); /* totally bailing; better than lock-up */#endif } G.cur_zipfile_bufstart += INBUFSIZ; /* always starts on block bndry */ G.inptr = G.inbuf; defer_leftover_input(__G); /* decrements G.csize */ }#if CRYPT if (G.pInfo->encrypted) { uch *p; int n; /* This was previously set to decrypt one byte beyond G.csize, when * incnt reached that far. GRR said, "but it's required: why?" This * was a bug in fillinbuf() -- was it also a bug here? */ for (n = G.incnt, p = G.inptr; n--; p++) zdecode(*p); }#endif /* CRYPT */ --G.incnt; return *G.inptr++;} /* end function readbyte() */#ifdef USE_ZLIB/************************//* Function fillinbuf() *//************************/int fillinbuf(__G) /* like readbyte() except returns number of bytes in inbuf */ __GDEF{ if (G.mem_mode || (G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0) return 0; G.cur_zipfile_bufstart += INBUFSIZ; /* always starts on a block boundary */ G.inptr = G.inbuf; defer_leftover_input(__G); /* decrements G.csize */#if CRYPT if (G.pInfo->encrypted) { uch *p; int n; for (n = G.incnt, p = G.inptr; n--; p++) zdecode(*p); }#endif /* CRYPT */ return G.incnt;} /* end function fillinbuf() */#endif /* USE_ZLIB *//************************//* Function seek_zipf() *//************************/int seek_zipf(__G__ abs_offset) __GDEF Z_OFF_T abs_offset;{/* * Seek to the block boundary of the block which includes abs_offset, * then read block into input buffer and set pointers appropriately. * If block is already in the buffer, just set the pointers. This function * is used by do_seekable (process.c), extract_or_test_entrylist (extract.c) * and do_string (fileio.c). Also, a slightly modified version is embedded * within extract_or_test_entrylist (extract.c). readbyte() and readbuf() * (fileio.c) are compatible. NOTE THAT abs_offset is intended to be the * "proper offset" (i.e., if there were no extra bytes prepended); * cur_zipfile_bufstart contains the corrected offset. * * Since seek_zipf() is never used during decompression, it is safe to * use the slide[] buffer for the error message. * * returns PK error codes: * PK_BADERR if effective offset in zipfile is negative * PK_EOF if seeking past end of zipfile * PK_OK when seek was successful */ Z_OFF_T request = abs_offset + G.extra_bytes; Z_OFF_T inbuf_offset = request % INBUFSIZ; Z_OFF_T bufstart = request - inbuf_offset; if (request < 0) { Info(slide, 1, ((char *)slide, LoadFarStringSmall(SeekMsg), G.zipfn, LoadFarString(ReportMsg))); return(PK_BADERR); } else if (bufstart != G.cur_zipfile_bufstart) { Trace((stderr, "fpos_zip: abs_offset = %ld, G.extra_bytes = %ld\n", abs_offset, G.extra_bytes));#ifdef USE_STRM_INPUT fseek(G.zipfd, bufstart, SEEK_SET); G.cur_zipfile_bufstart = ftell(G.zipfd);#else /* !USE_STRM_INPUT */ G.cur_zipfile_bufstart = lseek(G.zipfd, bufstart, SEEK_SET);#endif /* ?USE_STRM_INPUT */ Trace((stderr, " request = %ld, (abs+extra) = %ld, inbuf_offset = %ld\n", request, (abs_offset+G.extra_bytes), inbuf_offset)); Trace((stderr, " bufstart = %ld, cur_zipfile_bufstart = %ld\n", bufstart, G.cur_zipfile_bufstart)); if ((G.incnt = read(G.zipfd, (char *)G.inbuf, INBUFSIZ)) <= 0) return(PK_EOF); G.incnt -= (int)inbuf_offset; G.inptr = G.inbuf + (int)inbuf_offset; } else { G.incnt += (G.inptr-G.inbuf) - (int)inbuf_offset; G.inptr = G.inbuf + (int)inbuf_offset; } return(PK_OK);} /* end function seek_zipf() */#ifndef VMS /* for VMS use code in vms.c *//********************//* Function flush() */ /* returns PK error codes: *//********************/ /* if cflag => always 0; PK_DISK if write error */int flush(__G__ rawbuf, size, unshrink) __GDEF uch *rawbuf; ulg size; int unshrink;#if (defined(USE_DEFLATE64) && defined(__16BIT__)){ int ret; /* On 16-bit systems (MSDOS, OS/2 1.x), the standard C library functions * cannot handle writes of 64k blocks at once. For these systems, the * blocks to flush are split into pieces of 32k or less. */ while (size > 0x8000L) { ret = partflush(__G__ rawbuf, 0x8000L, unshrink); if (ret != PK_OK) return ret; size -= 0x8000L; rawbuf += (extent)0x8000; } return partflush(__G__ rawbuf, size, unshrink);} /* end function flush() *//************************//* Function partflush() */ /* returns PK error codes: *//************************/ /* if cflag => always 0; PK_DISK if write error */static int partflush(__G__ rawbuf, size, unshrink) __GDEF uch *rawbuf; /* cannot be ZCONST, gets passed to (*G.message)() */ ulg size; int unshrink;#endif /* USE_DEFLATE64 && __16BIT__ */{ register uch *p; register uch *q; uch *transbuf;#if (defined(SMALL_MEM) || defined(MED_MEM) || defined(VMS_TEXT_CONV)) ulg transbufsiz;#endif /* static int didCRlast = FALSE; moved to globals.h *//*--------------------------------------------------------------------------- Compute the CRC first; if testing or if disk is full, that's it.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -