📄 aosvs.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*//*--------------------------------------------------------------------------- aosvs.c AOS/VS-specific routines for use with Info-ZIP's UnZip 5.2 and later.[GRR: copied from unix.c -> undoubtedly has unnecessary stuff: delete at will] Contains: readdir() do_wild() open_outfile() mapattr() mapname() checkdir() close_outfile() version() <-- GRR: needs work! (Unix, not AOS/VS) zvs_create() zvs_credir() ux_to_vs_name() dgdate() ---------------------------------------------------------------------------*/#define UNZIP_INTERNAL#include "unzip.h"#include "aosvs/aosvs.h"#include <packets/create.h>#include <sys_calls.h>#include <paru.h>#define symlink(resname,linkname) \ zvs_create(linkname,-1L,-1L,-1L,ux_to_vs_name(vs_resname,resname),$FLNK,-1,-1) * file type */#ifdef DIRENT# include <dirent.h>#else# ifdef SYSV# ifdef SYSNDIR# include <sys/ndir.h># else# include <ndir.h># endif# else /* !SYSV */# ifndef NO_SYSDIR# include <sys/dir.h># endif# endif /* ?SYSV */# ifndef dirent# define dirent direct# endif#endif /* ?DIRENT */static int created_dir; /* used in mapname(), checkdir() */static int renamed_fullpath; /* ditto */static ZEXTRAFLD zzextrafld; /* buffer for extra field containing * ?FSTAT packet & ACL buffer */static char vs_resname[2*$MXPL];static char vs_path[2*$MXPL]; /* buf for AOS/VS pathname */static char Vs_path[512]; /* should be big enough [GRR: ?] */static P_CTIM zztimeblock; /* time block for file creation */static ZVSCREATE_STRU zzcreatepacket; /* packet for sys_create(), any/***************************//* Strings used in aosvs.c *//***************************/static ZCONST char Far CannotDeleteOldFile[] = "error: cannot delete old %s\n";static ZCONST char Far CannotCreateFile[] = "error: cannot create %s\n";#ifndef SFX#ifdef NO_DIR /* for AT&T 3B1 */#define opendir(path) fopen(path,"r")#define closedir(dir) fclose(dir)typedef FILE DIR;/* * Apparently originally by Rich Salz. * Cleaned up and modified by James W. Birdsall. */struct dirent *readdir(dirp) DIR *dirp;{ static struct dirent entry; if (dirp == NULL) return NULL; for (;;) if (fread(&entry, sizeof (struct dirent), 1, dirp) == 0) return (struct dirent *)NULL; else if (entry.d_ino) return &entry;} /* end function readdir() */#endif /* NO_DIR *//**********************//* 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; /* 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; dir = NULL; return matchname; } /* break the wildspec into a directory part and a wildcard filename */ if ((wildname = strrchr(wildspec, '/')) == (ZCONST char *)NULL) { dirname = "."; dirnamelen = 1; have_dirname = FALSE; wildname = wildspec; } else { ++wildname; /* point at character after '/' */ dirnamelen = wildname - 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 */ } strncpy(dirname, wildspec, dirnamelen); dirname[dirnamelen] = '\0'; /* terminate for strcpy below */ have_dirname = TRUE; } 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. */ 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; } } 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 open_outfile() *//***************************/int open_outfile(__G) /* return 1 if fail */ __GDEF{ int errc = 1; /* init to show no success with AOS/VS info */ long dmm, ddd, dyy, dhh, dmin, dss;#ifdef DLL if (G.redirect_data) return redirect_outfile(__G)==FALSE;#endif if (stat(G.filename, &G.statbuf) == 0 && unlink(G.filename) < 0) { Info(slide, 0x401, ((char *)slide, LoadFarString(CannotDeleteOldFile), FnFilter1(G.filename))); return 1; }/*--------------------------------------------------------------------------- If the file didn't already exist, we created it earlier. But we just deleted it, which we still had to do in case we are overwriting an exis- ting file. So we must create it now, again, to set the creation time properly. (The creation time is the best functional approximation of the Unix mtime. Really!) If we stored this with an AOS/VS Zip that set the extra field to contain the ?FSTAT packet and the ACL, we should use info from the ?FSTAT call now. Otherwise (or if that fails), we should create anyway as best we can from the normal Zip info. In theory, we should look through an entire series of extra fields that might exist for the same file, but we're not going to bother. If we set up other types of extra fields, or if other environments we run into may add their own stuff to existing entries in Zip files, we'll have to. Note that all the packet types for sys_fstat() are the same size & mostly have the same structure, with some fields being unused, etc. Ditto for sys_create(). Thus, we assume a normal one here, not a dir/cpd or device or IPC file, & make little adjustments as necessary. We will set ACLs later (to reduce the chance of lacking access to what we create now); note that for links the resolution name should be stored in the ACL field (once we get Zip recognizing links OK). ---------------------------------------------------------------------------*/ if (G.extra_field != NULL) { memcpy((char *) &zzextrafld, G.extra_field, sizeof(zzextrafld)); if (!memcmp(ZEXTRA_HEADID, zzextrafld.extra_header_id, sizeof(zzextrafld.extra_header_id)) && !memcmp(ZEXTRA_SENTINEL, zzextrafld.extra_sentinel), sizeof(zzextrafld.extra_sentinel)) { zzcreatepacket.norm_create_packet.cftyp_format = zzextrafld.fstat_packet.norm_fstat_packet.styp_format; zzcreatepacket.norm_create_packet.cftyp_entry = zzextrafld.fstat_packet.norm_fstat_packet.styp_type; /* for DIRS/CPDs, the next one will give the hash frame size; for * IPCs it will give the port number */ zzcreatepacket.norm_create_packet.ccps = zzextrafld.fstat_packet.norm_fstat_packet.scps; zzcreatepacket.norm_create_packet.ctim = &zztimeblock; zztimeblock.tcth = zzextrafld.fstat_packet.norm_fstat_packet.stch; /* access & modification times default to current */ zztimeblock.tath.long_time = zztimeblock.tmth.long_time = -1; /* give it current process's ACL unless link; then give it * resolution name */ zzcreatepacket.norm_create_packet.cacp = (char *)(-1); if (zzcreatepacket.norm_create_packet.cftyp_entry == $FLNK) zzcreatepacket.norm_create_packet.cacp = zzextrafld.aclbuf; zzcreatepacket.dir_create_packet.cmsh = zzextrafld.fstat_packet.dir_fstat_packet.scsh; if (zzcreatepacket.norm_create_packet.cftyp_entry != $FCPD) { /* element size for normal files */ zzcreatepacket.norm_create_packet.cdel = zzextrafld.fstat_packet.norm_fstat_packet.sdeh; } zzcreatepacket.norm_create_packet.cmil = zzextrafld.fstat_packet.norm_fstat_packet.smil; if ((errc = sys_create(ux_to_vs_name(vs_path, G.filename), &zzcreatepacket)) != 0) Info(slide, 0x201, ((char *)slide, "error creating %s with AOS/VS info -\n\ will try again with ordinary Zip info\n", FnFilter1(G.filename))); } } /* do it the hard way if no AOS/VS info was stored or if we had problems */ if (errc) { dyy = (G.lrec.last_mod_dos_datetime >> 25) + 1980; dmm = (G.lrec.last_mod_dos_datetime >> 21) & 0x0f; ddd = (G.lrec.last_mod_dos_datetime >> 16) & 0x1f; dhh = (G.lrec.last_mod_dos_datetime >> 11) & 0x1f; dmin = (G.lrec.last_mod_dos_datetime >> 5) & 0x3f; dss = (G.lrec.last_mod_dos_datetime << 1) & 0x3e; if (zvs_create(G.filename, (((ulg)dgdate(dmm, ddd, dyy)) << 16) | (dhh*1800L + dmin*30L + dss/2L), -1L, -1L, (char *) -1, -1, -1, -1)) { Info(slide, 0x201, ((char *)slide, "error: %s: cannot create\n", FnFilter1(G.filename))); return 1; } } 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)));#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() *//**********************/int mapattr(__G) __GDEF{ ulg tmp = G.crec.external_file_attributes; G.pInfo->file_attr = 0; /* initialized to 0 for check in "default" branch below... */ switch (G.pInfo->hostnum) { case AMIGA_: tmp = (unsigned)(tmp>>17 & 7); /* Amiga RWE bits */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -