📄 tanunz.c
字号:
/* Copyright (c) 1990-2005 Info-ZIP. All rights reserved. See the accompanying file LICENSE, version 2000-Apr-09 or later (the contents of which are also included in unzip.h) for terms of use. If, for some reason, all these files are missing, the Info-ZIP license also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html*//*--------------------------------------------------------------------------- tanunz.c Tandem/NSK routines for use with Info-ZIP's UnZip 5.3 and later. Contains: do_wild() <-- generic enough to put in fileio.c? ef_scan_for_tandem() open_outfile() mapattr() mapname() checkdir() mkdir() close_outfile() version() ---------------------------------------------------------------------------*/#define UNZIP_INTERNAL#include "unzip.h"#include <tal.h>#include "$system.zsysdefs.zsysc" nolist#include <cextdecs> nolist#include "tannsk.h"char *in2ex OF((__GPRO__ char *));static nsk_file_attrs *ef_scan_for_tandem ( uch *ef_buf, unsigned ef_len );static int created_dir; /* used in mapname(), checkdir() */static int renamed_fullpath; /* ditto *//****************************//* Strings used in tanunz.c *//****************************/static ZCONST char Far CannotDeleteOldFile[] = "error: cannot delete old %s\n";static ZCONST char Far CannotCreateFile[] = "error: cannot create %s\n";#ifndef SFX/**********************//* Function do_wild() */ /* for porting: dir separator; match(ignore_case) *//**********************/char *do_wild(__G__ wildspec) __GDEF ZCONST char *wildspec; /* only used first time on a given dir */{ static DIR *wild_dir = (DIR *)NULL; static ZCONST char *wildname; static char *dirname, matchname[FILNAMSIZ]; static int notfirstcall=FALSE, have_dirname, dirnamelen; struct dirent *file; static char *intname; int isdir = 0; int pdosflag = 0; /* Even when we're just returning wildspec, we *always* do so in * matchname[]--calling routine is allowed to append four characters * to the returned string, and wildspec may be a pointer to argv[]. */ if (!notfirstcall) { /* first call: must initialize everything */ notfirstcall = TRUE; if (!iswild(wildspec)) { strncpy(matchname, wildspec, FILNAMSIZ); matchname[FILNAMSIZ-1] = '\0'; have_dirname = FALSE; wild_dir = NULL; return matchname; } dirnamelen = strlen(wildspec); if ((dirname = (char *)malloc(dirnamelen+1)) == (char *)NULL) { Info(slide, 0x201, ((char *)slide, "warning: cannot allocate wildcard buffers\n")); strncpy(matchname, wildspec, FILNAMSIZ); matchname[FILNAMSIZ-1] = '\0'; return matchname; /* but maybe filespec was not a wildcard */ } strcpy(dirname, wildspec); wildname = wildspec; have_dirname = FALSE; if ((wild_dir = opendir(dirname)) != (DIR *)NULL) { while ((file = readdir(wild_dir)) != (struct dirent *)NULL) { Trace((stderr, "do_wild: readdir returns %s\n", FnFilter1(file->d_name))); if (file->d_name[0] == '.' && wildname[0] != '.') continue; /* Unix: '*' and '?' do not match leading dot */ if (match(file->d_name, wildname, 0 WISEP) && /* 0=case sens.*/ /* skip "." and ".." directory entries */ strcmp(file->d_name, ".") && strcmp(file->d_name, "..")) { Trace((stderr, "do_wild: match() succeeds\n")); if (have_dirname) { strcpy(matchname, dirname); strcpy(matchname+dirnamelen, file->d_name); } else strcpy(matchname, file->d_name); return matchname; } } /* if we get to here directory is exhausted, so close it */ closedir(wild_dir); wild_dir = (DIR *)NULL; } /* return the raw wildspec in case that works (e.g., directory not * searchable, but filespec was not wild and file is readable) */ strncpy(matchname, wildspec, FILNAMSIZ); matchname[FILNAMSIZ-1] = '\0'; return matchname; } /* last time through, might have failed opendir but returned raw wildspec */ if (wild_dir == (DIR *)NULL) { notfirstcall = FALSE; /* nothing left to try--reset for new wildspec */ if (have_dirname) free(dirname); return (char *)NULL; } /* If we've gotten this far, we've read and matched at least one entry * successfully (in a previous call), so dirname has been copied into * matchname already. */ while ((file = readdir(wild_dir)) != (struct dirent *)NULL) { Trace((stderr, "do_wild: readdir returns %s\n", FnFilter1(file->d_name))); if (file->d_name[0] == '.' && wildname[0] != '.') continue; /* Unix: '*' and '?' do not match leading dot */ if (match(file->d_name, wildname, 0 WISEP)) { /* 0 == case sens. */ if (have_dirname) { /* strcpy(matchname, dirname); */ strcpy(matchname+dirnamelen, file->d_name); } else strcpy(matchname, file->d_name); return matchname; } } closedir(wild_dir); /* have read at least one entry; nothing left */ wild_dir = (DIR *)NULL; notfirstcall = FALSE; /* reset for new wildspec */ if (have_dirname) free(dirname); return (char *)NULL;} /* end function do_wild() */#endif /* !SFX *//*********************************//* Function ef_scan_for_tandem() *//*********************************/static nsk_file_attrs *ef_scan_for_tandem(ef_buf, ef_len) uch *ef_buf; /* buffer containing extra field */ unsigned ef_len; /* total length of extra field */{ unsigned eb_id; unsigned eb_len; /*--------------------------------------------------------------------------- This function scans the extra field for EF_TANDEM -------------------------------------------------------------------------*/ if (ef_buf == NULL) return NULL; 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! */ TTrace((stderr, "ef_scan_for_tandem: block length %u > rest ef_size %u\n", eb_len, ef_len - EB_HEADSIZE)); break; } switch (eb_id) { case EF_TANDEM: return (nsk_file_attrs *)(char *)(ef_buf + EB_HEADSIZE); break; default: break; } /* Skip this extra field block */ ef_buf += (eb_len + EB_HEADSIZE); ef_len -= (eb_len + EB_HEADSIZE); } return NULL;}/***************************//* Function open_outfile() *//***************************/int open_outfile(__G) /* return 1 if fail */ __GDEF{ int fdesc; short fnum, err, len; int priext, secext; short maxext, filecode, blocksize; #define alist_items 1 #define vlist_bytes 2 short alist[alist_items]={42}; unsigned short vlist[alist_items]; short extra, *err_item=&extra; nsk_file_attrs *znsk_attr; ulg eof, pages; char nsk_work[FILENAME_MAX + 1], *nsk_fname=&nsk_work[0];#ifdef DLL if (G.redirect_data) return (redirect_outfile(__G) == FALSE);#endif 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) { Info(slide, 0x401, ((char *)slide, LoadFarString(CannotDeleteOldFile), FnFilter1(G.filename))); return 1; } } Trace((stderr, "open_outfile: %s now deleted\n", FnFilter1(G.filename))); } /* Set up Tandem specific file information if present */ znsk_attr = ef_scan_for_tandem(G.extra_field, G.lrec.extra_field_length); if (znsk_attr != NULL) { /* Set extent sizes */ priext = znsk_attr->priext; secext = znsk_attr->secext; maxext = (int) znsk_attr->maxext; /* If original file was Enscribe and text then recreate as Edit */ filecode = (znsk_attr->filetype != NSK_UNSTRUCTURED ? (G.pInfo->textmode ? NSK_EDITFILECODE : NSK_UNSTRUCTURED) : znsk_attr->filecode); blocksize = znsk_attr->block; } else { /* Try to work out some decent sizes based on how big the file is */ eof = G.lrec.ucsize; pages = (eof/2048) + 2; if (pages <= 500) { priext = pages; /* fits into one extent */ maxext = 16; } else { priext = 500; /* Try and fit into 500 page chunks */ maxext = pages/(priext - 50); /* Allow for Enscribe overhead */ if (maxext > 978) { priext = eof >> 10; /* 512 equal extents */ maxext = 978; /* 2048 * 512 == 2^10 */ } } secext = priext; filecode = (G.pInfo->textmode ? NSK_EDITFILECODE : NSK_UNSTRUCTURED); blocksize = TANDEM_BLOCKSIZE; } if ((fdesc = creat(G.filename,,priext,secext)) != -1){ fnum = fdtogfn ((short)fdesc); err = (SETMODE (fnum, SET_FILE_BUFFERSIZE, blocksize) != CCE); err = (SETMODE (fnum, SET_FILE_BUFFERED, 0, 0) != CCE); err = (SETMODE (fnum, SET_FILE_BUFFERED, 0, 1) != CCE); err = (SETMODE (fnum, SET_FILE_MAXEXTENTS, maxext) != CCE); err = close(fdesc); vlist[0] = filecode; /* Note that FILE_ALTERLIST_ expects uppercase names */ /* Need to call strlen and upshift */ len = strlen(G.filename); err = STRING_UPSHIFT_(G.filename, len, nsk_fname, len); err = FILE_ALTERLIST_(nsk_fname, len, alist, alist_items, vlist, vlist_bytes, , err_item); }; G.outfile = fopen(G.filename, (G.pInfo->textmode ? FOPWT : FOPW)); if (G.outfile == (FILE *)NULL) { Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile), FnFilter1(G.filename))); return 1; }#ifdef USE_FWRITE#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 /* USE_FWRITE */ return 0;} /* end function open_outfile() *//**********************//* Function mapattr() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -