📄 fileio.c
字号:
/*--------------------------------------------------------------------------- fileio.c This file contains routines for doing direct but relatively generic input/ output, file-related sorts of things, plus some miscellaneous stuff. Most of the stuff has to do with opening, closing, reading and/or writing files. Contains: open_input_file() open_outfile() (non-VMS, non-AOS/VS, non-CMS_MVS) undefer_input() defer_leftover_input() readbuf() readbyte() fillinbuf() flush() (non-VMS) disk_error() (non-VMS) UzpMessagePrnt() UzpMessageNull() (DLL only) UzpInput() UzpMorePause() UzpPassword() (non-WINDLL) handler() dos_to_unix_time() (non-VMS, non-VM/CMS, non-MVS) check_for_newer() (non-VMS, non-OS/2, non-VM/CMS, non-MVS) do_string() makeword() makelong() str2iso() (CRYPT && NEED_STR2ISO, only) str2oem() (CRYPT && NEED_STR2OEM, only) memset() (ZMEM only) memcpy() (ZMEM only) zstrnicmp() zstat() (REGULUS only) fLoadFarString() (SMALL_MEM only) fLoadFarStringSmall() (SMALL_MEM only) fLoadFarStringSmall2() (SMALL_MEM only) zfstrcpy() (SMALL_MEM only) ---------------------------------------------------------------------------*/#define FILEIO_C#define UNZIP_INTERNAL#include "unzip.h"#ifdef WINDLL# include "windll/windll.h"# include <setjmp.h>#endif#include "crypt.h"#include "ttyio.h"/* setup of codepage conversion for decryption passwords */#if CRYPT# if (defined(CRYP_USES_ISO2OEM) && !defined(IZ_ISO2OEM_ARRAY))# define IZ_ISO2OEM_ARRAY /* pull in iso2oem[] table */# endif# if (defined(CRYP_USES_OEM2ISO) && !defined(IZ_OEM2ISO_ARRAY))# define IZ_OEM2ISO_ARRAY /* pull in oem2iso[] table */# endif#endif#include "ebcdic.h" /* definition/initialization of ebcdic[] *//* Note: Under Windows, the maximum size of the buffer that can be used with any of the *printf calls is 16,384, so win_fprintf was used to feed the fprintf clone no more than 16K chunks at a time. This should be valid for anything up to 64K (and probably beyond, assuming your buffers are that big).*/#ifdef WINDLL# define WriteError(buf,len,strm) \ (win_fprintf(pG, strm, (extent)len, (char far *)buf) != (int)(len))#else /* !WINDLL */# ifdef USE_FWRITE# define WriteError(buf,len,strm) \ ((extent)fwrite((char *)(buf),1,(extent)(len),strm) != (extent)(len))# else# define WriteError(buf,len,strm) \ ((extent)write(fileno(strm),(char *)(buf),(extent)(len)) != (extent)(len))# endif#endif /* ?WINDLL */static int disk_error OF((__GPRO));/****************************//* Strings used in fileio.c *//****************************/#if (defined(UNIX) || defined(DOS_FLX_OS2_W32) || defined(__BEOS__)) static ZCONST char Far CannotDeleteOldFile[] = "error: cannot delete old %s\n";#ifdef UNIXBACKUP static ZCONST char Far CannotRenameOldFile[] = "error: cannot rename old %s\n"; static ZCONST char Far BackupSuffix[] = "~";#endif#endif /* UNIX || DOS_FLX_OS2_W32 || __BEOS__ */static ZCONST char Far CannotOpenZipfile[] = "error: cannot open zipfile [ %s ]\n";#if (!defined(VMS) && !defined(AOS_VS) && !defined(CMS_MVS) && !defined(MACOS)) static ZCONST char Far CannotCreateFile[] = "error: cannot create %s\n";#endif#ifdef NOVELL_BUG_FAILSAFE static ZCONST char Far NovellBug[] = "error: %s: stat() says does not exist, but fopen() found anyway\n";#endifstatic ZCONST char Far ReadError[] = "error: zipfile read error\n";static ZCONST char Far FilenameTooLongTrunc[] = "warning: filename too long--truncating.\n";static ZCONST char Far ExtraFieldTooLong[] = "warning: extra field too long (%d). Ignoring...\n";#ifdef WINDLL static ZCONST char Far DiskFullQuery[] = "%s: write error (disk full?).\n";#else static ZCONST char Far DiskFullQuery[] = "%s: write error (disk full?). Continue? (y/n/^C) "; static ZCONST char Far ZipfileCorrupt[] = "error: zipfile probably corrupt (%s)\n";# ifdef SYMLINKS static ZCONST char Far FileIsSymLink[] = "%s exists and is a symbolic link%s.\n";# endif# ifdef MORE static ZCONST char Far MorePrompt[] = "--More--(%lu)";# endif static ZCONST char Far QuitPrompt[] = "--- Press `Q' to quit, or any other key to continue ---"; static ZCONST char Far HidePrompt[] = /* "\r \r"; */ "\r \r";# if CRYPT# ifdef MACOS /* SPC: are names on MacOS REALLY so much longer than elsewhere ??? */ static ZCONST char Far PasswPrompt[] = "[%s]\n %s password: ";# else static ZCONST char Far PasswPrompt[] = "[%s] %s password: ";# endif static ZCONST char Far PasswPrompt2[] = "Enter password: "; static ZCONST char Far PasswRetry[] = "password incorrect--reenter: ";# endif /* CRYPT */#endif /* !WINDLL *//******************************//* Function open_input_file() *//******************************/int open_input_file(__G) /* return 1 if open failed */ __GDEF{ /* * open the zipfile for reading and in BINARY mode to prevent cr/lf * translation, which would corrupt the bitstreams */#if (defined(UNIX) || defined(TOPS20) || defined(AOS_VS) || defined(__BEOS__)) G.zipfd = open(G.zipfn, O_RDONLY);#else /* !(UNIX || TOPS20 || AOS_VS || __BEOS__) */#ifdef VMS G.zipfd = open(G.zipfn, O_RDONLY, 0, "ctx=stm");#else /* !VMS */#ifdef MACOS G.zipfd = open(G.zipfn, 0);#else /* !MACOS */#ifdef RISCOS G.zipfd = fopen(G.zipfn, "rb");#else /* !RISCOS */#ifdef CMS_MVS G.zipfd = vmmvs_open_infile(__G);#else /* !CMS_MVS */ G.zipfd = open(G.zipfn, O_RDONLY | O_BINARY);#endif /* ?CMS_MVS */#endif /* ?RISCOS */#endif /* ?MACOS */#endif /* ?VMS */#endif /* ?(UNIX || TOPS20 || AOS_VS || __BEOS__) */#ifdef USE_STRM_INPUT if (G.zipfd == NULL)#else /* if (G.zipfd < 0) */ /* no good for Windows CE port */ if (G.zipfd == -1)#endif { Info(slide, 0x401, ((char *)slide, LoadFarString(CannotOpenZipfile), G.zipfn)); return 1; } return 0;} /* end function open_input_file() */#if (!defined(VMS) && !defined(AOS_VS) && !defined(CMS_MVS) && !defined(MACOS))/***************************//* Function open_outfile() *//***************************/int open_outfile(__G) /* return 1 if fail */ __GDEF{#ifdef DLL if (G.redirect_data) return (redirect_outfile(__G) == FALSE);#endif#ifdef QDOS QFilename(__G__ G.filename);#endif#if (defined(DOS_FLX_OS2_W32) || defined(UNIX) || defined(__BEOS__))#ifdef BORLAND_STAT_BUG /* Borland 5.0's stat() barfs if the filename has no extension and the * file doesn't exist. */ if (access(G.filename, 0) == -1) { FILE *tmp = fopen(G.filename, "wb+"); /* file doesn't exist, so create a dummy file to keep stat() from * failing (will be over-written anyway) */ fputc('0', tmp); /* just to have something in the file */ fclose(tmp); }#endif /* BORLAND_STAT_BUG */#ifdef SYMLINKS if (SSTAT(G.filename, &G.statbuf) == 0 || lstat(G.filename,&G.statbuf) == 0)#else if (SSTAT(G.filename, &G.statbuf) == 0)#endif /* ?SYMLINKS */ { Trace((stderr, "open_outfile: stat(%s) returns 0: file exists\n", FnFilter1(G.filename)));#ifdef UNIXBACKUP if (uO.B_flag) { /* do backup */ char *tname; int blen, flen, tlen; blen = strlen(BackupSuffix); flen = strlen(G.filename); tlen = flen + blen + 1; if (tlen >= FILNAMSIZ) { /* in case name is too long, truncate */ tname = (char *)malloc(FILNAMSIZ); if (tname == NULL) return 1; /* in case we run out of space */ tlen = FILNAMSIZ - 1 - blen; strcpy(tname, G.filename); /* make backup name */ tname[tlen] = '\0'; } else { tname = (char *)malloc(tlen); if (tname == NULL) return 1; /* in case we run out of space */ strcpy(tname, G.filename); /* make backup name */ } strcpy(tname+flen, BackupSuffix); /* GRR: should check if backup file exists, apply -n/-o to that */ if (rename(G.filename, tname) < 0) { /* move file */ Info(slide, 0x401, ((char *)slide, LoadFarString(CannotRenameOldFile), FnFilter1(G.filename))); free(tname); return 1; } free(tname); } else#endif /* UNIXBACKUP */#ifdef DOS_FLX_OS2_W32 if (!(G.statbuf.st_mode & S_IWRITE)) { Trace((stderr, "open_outfile: existing file %s is read-only\n", FnFilter1(G.filename))); chmod(G.filename, S_IREAD | S_IWRITE); Trace((stderr, "open_outfile: %s now writable\n", FnFilter1(G.filename))); }#endif /* DOS_FLX_OS2_W32 */ if (unlink(G.filename) != 0) { Info(slide, 0x401, ((char *)slide, LoadFarString(CannotDeleteOldFile), FnFilter1(G.filename))); return 1; } Trace((stderr, "open_outfile: %s now deleted\n", FnFilter1(G.filename))); }#endif /* DOS_FLX_OS2_W32 || UNIX || __BEOS__ */#ifdef RISCOS if (SWI_OS_File_7(G.filename,0xDEADDEAD,0xDEADDEAD,G.lrec.ucsize)!=NULL) { Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile), FnFilter1(G.filename))); return 1; }#endif /* RISCOS */#ifdef TOPS20 char *tfilnam; if ((tfilnam = (char *)malloc(2*strlen(G.filename)+1)) == (char *)NULL) return 1; strcpy(tfilnam, G.filename); upper(tfilnam); enquote(tfilnam); if ((G.outfile = fopen(tfilnam, FOPW)) == (FILE *)NULL) { Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile), tfilnam)); free(tfilnam); return 1; } free(tfilnam);#else /* !TOPS20 */#ifdef MTS if (uO.aflag) G.outfile = fopen(G.filename, FOPWT); else G.outfile = fopen(G.filename, FOPW); if (G.outfile == (FILE *)NULL) { Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile), FnFilter1(G.filename))); return 1; }#else /* !MTS */#ifdef TANDEM if (SSTAT(G.filename, &G.statbuf) == 0) { Trace((stderr, "open_outfile: stat(%s) returns 0 (file exists)\n", FnFilter1(G.filename))); if (unlink(G.filename) != 0) { Trace((stderr, "open_outfile: existing file %s is read-only\n", FnFilter1(G.filename))); chmod(G.filename, S_IRUSR | S_IWUSR); Trace((stderr, "open_outfile: %s now writable\n", FnFilter1(G.filename))); if (unlink(G.filename) != 0) return 1; } Trace((stderr, "open_outfile: %s now deleted\n", FnFilter1(G.filename))); } if (G.pInfo->textmode) G.outfile = fopen(G.filename, FOPWT); else G.outfile = fopen(G.filename, FOPW); if (G.outfile == (FILE *)NULL) { Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile), FnFilter1(G.filename))); return 1; }#else /* !TANDEM */#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)));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -