📄 msdos.c
字号:
/*---------------------------------------------------------------------------
msdos.c
MSDOS-specific routines for use with Info-ZIP's UnZip 5.1 and later.
Contains: Opendir() (from zip)
Readdir() (from zip)
do_wild()
mapattr()
mapname()
checkdir()
isfloppy()
volumelabel() (non-djgpp, non-emx)
close_outfile()
dateformat()
version()
_dos_getcountryinfo() (djgpp, emx)
_dos_setftime() (djgpp, emx)
_dos_setfileattr() (djgpp, emx)
_dos_getdrive() (djgpp, emx)
_dos_creat() (djgpp, emx)
_dos_close() (djgpp, emx)
volumelabel() (djgpp, emx)
---------------------------------------------------------------------------*/
#include "unzip.h"
#undef FILENAME /* BC++ 3.1 and djgpp 1.11 define FILENAME in <dir.h> */
static int isfloppy OF((int nDrive));
static int volumelabel OF((char *newlabel));
static int created_dir; /* used by mapname(), checkdir() */
static int renamed_fullpath; /* ditto */
static unsigned nLabelDrive; /* ditto, plus volumelabel() */
#if (defined(__GO32__) || defined(__EMX__))
# define MKDIR(path,mode) mkdir(path,mode)
# include <dirent.h> /* use readdir() */
# define direct dirent
# define Opendir opendir
# define Readdir readdir
# ifdef __EMX__
# include <dos.h>
# define GETDRIVE(d) d = _getdrive()
# define FA_LABEL A_LABEL
# else
# define GETDRIVE(d) _dos_getdrive(&d)
# endif
#else /* !(__GO32__ || __EMX__) */
# define MKDIR(path,mode) mkdir(path)
# ifdef __TURBOC__
# define FATTR FA_HIDDEN+FA_SYSTEM+FA_DIREC
# define FVOLID FA_VOLID
# define FFIRST(n,d,a) findfirst(n,(struct ffblk *)d,a)
# define FNEXT(d) findnext((struct ffblk *)d)
# define GETDRIVE(d) d=getdisk()+1
# include <dir.h>
# else /* !__TURBOC__ */
# define FATTR _A_HIDDEN+_A_SYSTEM+_A_SUBDIR
# define FVOLID _A_VOLID
# define FFIRST(n,d,a) _dos_findfirst(n,a,(struct find_t *)d)
# define FNEXT(d) _dos_findnext((struct find_t *)d)
# define GETDRIVE(d) _dos_getdrive(&d)
# include <direct.h>
# endif /* ?__TURBOC__ */
typedef struct direct {
char d_reserved[30];
char d_name[13];
int d_first;
} DIR;
# define closedir free
DIR *Opendir OF((const char *));
struct direct *Readdir OF((DIR *));
#ifndef SFX
/**********************/ /* Borland C++ 3.x has its own opendir/readdir */
/* Function Opendir() */ /* library routines, but earlier versions don't, */
/**********************/ /* so use ours regardless */
DIR *Opendir(name)
const char *name; /* name of directory to open */
{
DIR *dirp; /* malloc'd return value */
char *nbuf; /* malloc'd temporary string */
int len = strlen(name); /* path length to avoid strlens and strcats */
if ((dirp = (DIR *)malloc(sizeof(DIR))) == (DIR *)NULL)
return (DIR *)NULL;
if ((nbuf = malloc(len + 5)) == (char *)NULL) {
free(dirp);
return (DIR *)NULL;
}
strcpy(nbuf, name);
if (nbuf[len-1] == ':') {
nbuf[len++] = '.';
} else if (nbuf[len-1] == '/' || nbuf[len-1] == '\\')
--len;
strcpy(nbuf+len, "/*.*");
Trace((stderr, "opendir: nbuf = [%s]\n", nbuf));
if (FFIRST(nbuf, dirp, FATTR)) {
free((voidp *)nbuf);
return (DIR *)NULL;
}
free((voidp *)nbuf);
dirp->d_first = 1;
return dirp;
}
/**********************/
/* Function Readdir() */
/**********************/
struct direct *Readdir(d)
DIR *d; /* directory stream from which to read */
{
/* Return pointer to first or next directory entry, or NULL if end. */
if (d->d_first)
d->d_first = 0;
else
if (FNEXT(d))
return (struct direct *)NULL;
return (struct direct *)d;
}
#endif /* !SFX */
#endif /* ?(__GO32__ || __EMX__) */
#ifndef SFX
/************************/
/* Function do_wild() */ /* identical to OS/2 version */
/************************/
char *do_wild(wildspec)
char *wildspec; /* only used first time on a given dir */
{
static DIR *dir = (DIR *)NULL;
static char *dirname, *wildname, matchname[FILNAMSIZ];
static char Far CantAllocateWildcard[] =
"warning: can't allocate wildcard buffers\n";
static int firstcall=TRUE, have_dirname, dirnamelen;
struct direct *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 (firstcall) { /* first call: must initialize everything */
firstcall = FALSE;
/* break the wildspec into a directory part and a wildcard filename */
if ((wildname = strrchr(wildspec, '/')) == (char *)NULL &&
(wildname = strrchr(wildspec, ':')) == (char *)NULL) {
dirname = ".";
dirnamelen = 1;
have_dirname = FALSE;
wildname = wildspec;
} else {
++wildname; /* point at character after '/' or ':' */
dirnamelen = wildname - wildspec;
if ((dirname = (char *)malloc(dirnamelen+1)) == (char *)NULL) {
FPRINTF(stderr, LoadFarString(CantAllocateWildcard));
strcpy(matchname, wildspec);
return matchname; /* but maybe filespec was not a wildcard */
}
/* GRR: can't strip trailing char for opendir since might be "d:/" or "d:"
* (would have to check for "./" at end--let opendir handle it instead) */
strncpy(dirname, wildspec, dirnamelen);
dirname[dirnamelen] = '\0'; /* terminate for strcpy below */
have_dirname = TRUE;
}
Trace((stderr, "do_wild: dirname = [%s]\n", dirname));
if ((dir = Opendir(dirname)) != (DIR *)NULL) {
while ((file = Readdir(dir)) != (struct direct *)NULL) {
Trace((stderr, "do_wild: readdir returns %s\n", file->d_name));
if (match(file->d_name, wildname, 1)) { /* 1 == ignore case */
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(dir);
dir = (DIR *)NULL;
}
Trace((stderr, "do_wild: opendir(%s) returns NULL\n", dirname));
/* return the raw wildspec in case that works (e.g., directory not
* searchable, but filespec was not wild and file is readable) */
strcpy(matchname, wildspec);
return matchname;
}
/* last time through, might have failed opendir but returned raw wildspec */
if (dir == (DIR *)NULL) {
firstcall = TRUE; /* 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(dir)) != (struct direct *)NULL)
if (match(file->d_name, wildname, 1)) { /* 1 == ignore case */
if (have_dirname) {
/* strcpy(matchname, dirname); */
strcpy(matchname+dirnamelen, file->d_name);
} else
strcpy(matchname, file->d_name);
return matchname;
}
closedir(dir); /* have read at least one dir entry; nothing left */
dir = (DIR *)NULL;
firstcall = TRUE; /* reset for new wildspec */
if (have_dirname)
free(dirname);
return (char *)NULL;
} /* end function do_wild() */
#endif /* !SFX */
/**********************/
/* Function mapattr() */
/**********************/
int mapattr()
{
/* set archive bit (file is not backed up): */
pInfo->file_attr = (unsigned)(crec.external_file_attributes | 32) & 0xff;
return 0;
} /* end function mapattr() */
/*****************************/
/* Strings used in msdos.c */
/*****************************/
static char Far ConversionFailed[] = "mapname: conversion of %s failed\n";
static char Far ErrSetVolLabel[] = "mapname: error setting volume label\n";
static char Far PathTooLong[] = "checkdir error: path too long: %s\n";
static char Far CantCreateDir[] = "checkdir error: can't create %s\n\
unable to process %s.\n";
static char Far DirIsntDirectory[] =
"checkdir error: %s exists but is not directory\n\
unable to process %s.\n";
static char Far PathTooLongTrunc[] =
"checkdir warning: path too long; truncating\n %s\n\
-> %s\n";
#if (!defined(SFX) || defined(SFX_EXDIR))
static char Far CantCreateExtractDir[] =
"checkdir: can't create extraction directory: %s\n";
#endif
/************************/
/* Function mapname() */
/************************/
int mapname(renamed) /* return 0 if no error, 1 if caution (filename trunc), */
int renamed; /* 2 if warning (skip file because dir doesn't exist), */
{ /* 3 if error (skip file), 10 if no memory (skip file) */
char pathcomp[FILNAMSIZ]; /* path-component buffer */
char *pp, *cp=(char *)NULL; /* character pointers */
char *lastsemi=(char *)NULL; /* pointer to last semi-colon in pathcomp */
char *last_dot=(char *)NULL; /* last dot not converted to underscore */
int quote = FALSE; /* flag: next char is literal */
int dotname = FALSE; /* flag: path component begins with dot */
int error = 0;
register unsigned workch; /* hold the character being tested */
/*---------------------------------------------------------------------------
Initialize various pointers and counters and stuff.
---------------------------------------------------------------------------*/
/* can create path as long as not just freshening, or if user told us */
create_dirs = (!fflag || renamed);
created_dir = FALSE; /* not yet */
renamed_fullpath = FALSE;
/* GRR: for VMS, convert to internal format now or later? or never? */
if (renamed) {
cp = filename - 1; /* point to beginning of renamed name... */
while (*++cp)
if (*cp == '\\') /* convert backslashes to forward */
*cp = '/';
cp = filename;
/* use temporary rootpath if user gave full pathname */
if (filename[0] == '/') {
renamed_fullpath = TRUE;
pathcomp[0] = '/'; /* copy the '/' and terminate */
pathcomp[1] = '\0';
++cp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -