📄 msdos.c
字号:
/*--------------------------------------------------------------------------- msdos.c MSDOS-specific routines for use with Info-ZIP's UnZip 5.3 and later. Contains: Opendir() (from zip) Readdir() (from zip) do_wild() mapattr() mapname() map2fat() checkdir() isfloppy() z_dos_chmod() volumelabel() (non-djgpp, non-emx) close_outfile() stamp_file() (TIMESTAMP only) dateformat() version() _dos_getcountryinfo() (djgpp 1.x, emx) [_dos_getftime() (djgpp 1.x, emx) to be added] _dos_setftime() (djgpp 1.x, emx) _dos_setfileattr() (djgpp 1.x, emx) _dos_getdrive() (djgpp 1.x, emx) _dos_creat() (djgpp 1.x, emx) _dos_close() (djgpp 1.x, emx) volumelabel() (djgpp, emx) _dos_getcountryinfo() (djgpp 2.x) _is_executable() (djgpp 2.x) __crt0_glob_function() (djgpp 2.x) __crt0_load_environment_file() (djgpp 2.x) screenlines() (emx) screencolumns() (emx) int86x_realmode() (Watcom 32-bit) stat_bandaid() (Watcom) ---------------------------------------------------------------------------*/#define UNZIP_INTERNAL#include "unzip.h"#ifdef MAYBE_PLAIN_FAT static void map2fat OF((char *pathcomp, char *last_dot));#endifstatic int isfloppy OF((int nDrive));static int z_dos_chmod OF((__GPRO__ ZCONST char *fname, int attributes));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() *//*****************************//* Strings used in msdos.c *//*****************************/#ifndef SFX static ZCONST char Far CantAllocateWildcard[] = "warning: cannot allocate wildcard buffers\n";#endifstatic ZCONST char Far Creating[] = " creating: %s\n";static ZCONST char Far ConversionFailed[] = "mapname: conversion of %s failed\n";static ZCONST char Far Labelling[] = "labelling %c: %-22s\n";static ZCONST char Far ErrSetVolLabel[] = "mapname: error setting volume label\n";static ZCONST char Far PathTooLong[] = "checkdir error: path too long: %s\n";static ZCONST char Far CantCreateDir[] = "checkdir error: cannot create %s\n\ unable to process %s.\n";static ZCONST char Far DirIsntDirectory[] = "checkdir error: %s exists but is not directory\n\ unable to process %s.\n";static ZCONST char Far PathTooLongTrunc[] = "checkdir warning: path too long; truncating\n %s\n\ -> %s\n";#if (!defined(SFX) || defined(SFX_EXDIR)) static ZCONST char Far CantCreateExtractDir[] = "checkdir: cannot create extraction directory: %s\n";#endifstatic ZCONST char Far AttribsMayBeWrong[] = "\nwarning: file attributes may not be correct\n";/****************************//* Macros used in msdos.c *//****************************/#ifdef WATCOMC_386# define WREGS(v,r) (v##.w.##r)# define int86x int386x static int int86x_realmode(int inter_no, union REGS *in, union REGS *out, struct SREGS *seg);# define F_intdosx(ir,or,sr) int86x_realmode(0x21, ir, or, sr)# define XXX__MK_FP_IS_BROKEN#else# define WREGS(v,r) (v##.x.##r)# define F_intdosx(ir,or,sr) intdosx(ir, or, sr)#endif#if (defined(__GO32__) || defined(__EMX__))# include <dirent.h> /* use readdir() */# define MKDIR(path,mode) mkdir(path,mode)# define Opendir opendir# define Readdir readdir# define Closedir closedir# define zdirent dirent# define zDIR DIR# ifdef __EMX__# include <dos.h># define GETDRIVE(d) d = _getdrive()# define FA_LABEL A_LABEL# else# define GETDRIVE(d) _dos_getdrive(&d)# endif# if defined(_A_SUBDIR) /* MSC dos.h and compatibles */# define FSUBDIR _A_SUBDIR# elif defined(FA_DIREC) /* Borland dos.h and compatible variants */# define FSUBDIR FA_DIREC# elif defined(A_DIR) /* EMX dir.h (and dirent.h) */# define FSUBDIR A_DIR# else /* fallback definition */# define FSUBDIR 0x10# endif# if defined(_A_VOLID) /* MSC dos.h and compatibles */# define FVOLID _A_VOLID# elif defined(FA_LABEL) /* Borland dos.h and compatible variants */# define FVOLID FA_LABEL# elif defined(A_LABEL) /* EMX dir.h (and dirent.h) */# define FVOLID A_LABEL# else# define FVOLID 0x08# endif#else /* !(__GO32__ || __EMX__) */# define MKDIR(path,mode) mkdir(path)# ifdef __TURBOC__# define FATTR FA_HIDDEN+FA_SYSTEM+FA_DIREC# define FVOLID FA_LABEL# define FSUBDIR FA_DIREC# 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 FSUBDIR _A_SUBDIR# 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 zdirent { char d_reserved[30]; char d_name[13]; int d_first; } zDIR; zDIR *Opendir OF((const char *)); struct zdirent *Readdir OF((zDIR *));# define Closedir free#ifndef SFX/**********************/ /* Borland C++ 3.x has its own opendir/readdir *//* Function Opendir() */ /* library routines, but earlier versions don't, *//**********************/ /* so use ours regardless */zDIR *Opendir(name) const char *name; /* name of directory to open */{ zDIR *dirp; /* malloc'd return value */ char *nbuf; /* malloc'd temporary string */ extent len = strlen(name); /* path length to avoid strlens and strcats */ if ((dirp = (zDIR *)malloc(sizeof(zDIR))) == (zDIR *)NULL) return (zDIR *)NULL; if ((nbuf = malloc(len + 6)) == (char *)NULL) { free(dirp); return (zDIR *)NULL; } strcpy(nbuf, name); if (len > 0) { 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((zvoid *)nbuf); return (zDIR *)NULL; } free((zvoid *)nbuf); dirp->d_first = 1; return dirp;}/**********************//* Function Readdir() *//**********************/struct zdirent *Readdir(d) zDIR *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 zdirent *)NULL; return (struct zdirent *)d;}#endif /* !SFX */#endif /* ?(__GO32__ || __EMX__) */#ifndef SFX/************************//* Function do_wild() */ /* identical to OS/2 version *//************************/char *do_wild(__G__ wildspec) __GDEF char *wildspec; /* only used first time on a given dir */{ static zDIR *dir = (zDIR *)NULL; static char *dirname, *wildname, matchname[FILNAMSIZ]; static int firstcall=TRUE, have_dirname, dirnamelen; char *fnamestart; struct zdirent *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; if (!iswild(wildspec)) { strcpy(matchname, wildspec); have_dirname = FALSE; dir = NULL; return matchname; } /* 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 = (int)(wildname - wildspec); if ((dirname = (char *)malloc(dirnamelen+1)) == (char *)NULL) { Info(slide, 1, ((char *)slide, 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)) != (zDIR *)NULL) { if (have_dirname) { strcpy(matchname, dirname); fnamestart = matchname + dirnamelen; } else fnamestart = matchname; while ((file = Readdir(dir)) != (struct zdirent *)NULL) { Trace((stderr, "do_wild: readdir returns %s\n", file->d_name)); strcpy(fnamestart, file->d_name); if (strrchr(fnamestart, '.') == (char *)NULL) strcat(fnamestart, "."); if (match(fnamestart, wildname, 1) && /* 1 == ignore case */ /* skip "." and ".." directory entries */ strcmp(fnamestart, ".") && strcmp(fnamestart, "..")) { Trace((stderr, "do_wild: match() succeeds\n")); /* remove trailing dot */ fnamestart += strlen(fnamestart) - 1; if (*fnamestart == '.') *fnamestart = '\0'; return matchname; } } /* if we get to here directory is exhausted, so close it */ Closedir(dir); dir = (zDIR *)NULL; }#ifdef DEBUG else { Trace((stderr, "do_wild: Opendir(%s) returns NULL\n", dirname)); }#endif /* DEBUG */ /* 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 == (zDIR *)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. */ if (have_dirname) { /* strcpy(matchname, dirname); */ fnamestart = matchname + dirnamelen; } else fnamestart = matchname; while ((file = Readdir(dir)) != (struct zdirent *)NULL) { Trace((stderr, "do_wild: readdir returns %s\n", file->d_name)); strcpy(fnamestart, file->d_name); if (strrchr(fnamestart, '.') == (char *)NULL) strcat(fnamestart, "."); if (match(fnamestart, wildname, 1)) { /* 1 == ignore case */ Trace((stderr, "do_wild: match() succeeds\n")); /* remove trailing dot */ fnamestart += strlen(fnamestart) - 1; if (*fnamestart == '.') *fnamestart = '\0'; return matchname; } } Closedir(dir); /* have read at least one dir entry; nothing left */ dir = (zDIR *)NULL; firstcall = TRUE; /* reset for new wildspec */ if (have_dirname) free(dirname); return (char *)NULL;} /* end function do_wild() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -