📄 win32zip.c
字号:
/* Copyright (C) 1990-1997 Mark Adler, Richard B. Wales, Jean-loup Gailly, Kai Uwe Rommel, Onno van der Linden and Igor Mandrichenko. Permission is granted to any individual or institution to use, copy, or redistribute this software so long as all of the original files are included, that it is not sold for profit, and that this copyright notice is retained.*/#ifndef UTIL /* this file contains nothing used by UTIL */#include "zip.h"#ifndef __EMX__#include <direct.h> /* for rmdir() */#endif#include <time.h>#ifndef __BORLANDC__#include <sys/utime.h>#else#include <utime.h>#endif#include <windows.h> /* for findfirst/findnext stuff */#ifdef __RSXNT__# include "win32/rsxntwin.h"#endifchar *GetLongPathEA OF((char *name));#include <io.h>#define MATCH dosmatch#define PAD 0#define PATH_END '/'#define HIDD_SYS_BITS (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)typedef struct zdirent { ush d_date, d_time; ulg d_size; char d_attr; char d_name[MAX_PATH]; int d_first; HANDLE d_hFindFile;} zDIR;#include "win32/win32zip.h"#include "win32/nt.h"/* Local functions */local zDIR *Opendir OF((ZCONST char *n));local struct zdirent *Readdir OF((zDIR *d));local void Closedir OF((zDIR *d));local char *readd OF((zDIR *));local int wild_recurse OF((char *, char *));#ifdef NTSD_EAS local void GetSD OF((char *path, char **bufptr, size_t *size, char **cbufptr, size_t *csize));#endif#ifdef USE_EF_UT_TIME local int GetExtraTime OF((struct zlist far *z, iztimes *z_utim));#endif/* Module level variables */extern char *label /* = NULL */ ; /* defined in fileio.c */local ulg label_time = 0;local ulg label_mode = 0;local time_t label_utim = 0;/* Module level constants */local ZCONST char wild_match_all[] = "*.*";local zDIR *Opendir(n)ZCONST char *n; /* directory to open *//* Start searching for files in the MSDOS directory n */{ zDIR *d; /* malloc'd return value */ char *p; /* malloc'd temporary string */ char *q; WIN32_FIND_DATA fd; if ((d = (zDIR *)malloc(sizeof(zDIR))) == NULL || (p = malloc(strlen(n) + 5)) == NULL) { if (d != NULL) free((zvoid *)d); return NULL; } strcpy(p, n); q = p + strlen(p); if (q[-1] == ':') *q++ = '.'; if ((q - p) > 0 && *(q - 1) != '/') *q++ = '/'; strcpy(q, wild_match_all);#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ OemToAnsi(p, p);#endif d->d_hFindFile = FindFirstFile(p, &fd); free((zvoid *)p); if (d->d_hFindFile == INVALID_HANDLE_VALUE) { free((zvoid *)d); return NULL; } strcpy(d->d_name, fd.cFileName); d->d_attr = (unsigned char) fd.dwFileAttributes; d->d_first = 1; return d;}local struct zdirent *Readdir(d)zDIR *d; /* directory stream to read from *//* Return pointer to first or next directory entry, or NULL if end. */{ if (d->d_first) d->d_first = 0; else { WIN32_FIND_DATA fd; if (!FindNextFile(d->d_hFindFile, &fd)) return NULL; strcpy(d->d_name, fd.cFileName); d->d_attr = (unsigned char) fd.dwFileAttributes; }#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */ AnsiToOem(d->d_name, d->d_name);#endif return (struct zdirent *)d;}local void Closedir(d)zDIR *d; /* directory stream to close */{ FindClose(d->d_hFindFile); free((zvoid *)d);}local char *readd(d)zDIR *d; /* directory stream to read from *//* Return a pointer to the next name in the directory stream d, or NULL if no more entries or an error occurs. */{ struct zdirent *e; do e = Readdir(d); while (!hidden_files && e && e->d_attr & HIDD_SYS_BITS); return e == NULL ? (char *) NULL : e->d_name;}#define ONENAMELEN 255/* whole is a pathname with wildcards, wildtail points somewhere in the *//* middle of it. All wildcards to be expanded must come AFTER wildtail. */local int wild_recurse(whole, wildtail)char *whole;char *wildtail;{ zDIR *dir; char *subwild, *name, *newwhole = NULL, *glue = NULL, plug = 0, plug2; ush newlen, amatch = 0; int e = ZE_MISS; if (!isshexp(wildtail)) if (GetFileAttributes(whole) != 0xFFFFFFFF) /* file exists? */ return procname(whole); else return ZE_MISS; /* woops, no wildcards! */ /* back up thru path components till existing dir found */ do { name = wildtail + strlen(wildtail) - 1; for (;;) if (name-- <= wildtail || *name == PATH_END) { subwild = name + 1; plug2 = *subwild; *subwild = 0; break; } if (glue) *glue = plug; glue = subwild; plug = plug2; dir = Opendir(whole); } while (!dir && subwild > wildtail); wildtail = subwild; /* skip past non-wild components */ if ((subwild = strchr(wildtail + 1, PATH_END)) != NULL) { /* this "+ 1" dodges the ^^^ hole left by *glue == 0 */ *(subwild++) = 0; /* wildtail = one component pattern */ newlen = strlen(whole) + strlen(subwild) + ONENAMELEN + 2; } else newlen = strlen(whole) + ONENAMELEN + 1; if (!dir || ((newwhole = malloc(newlen)) == NULL)) { if (glue) *glue = plug; e = dir ? ZE_MEM : ZE_MISS; goto ohforgetit; } strcpy(newwhole, whole); newlen = strlen(newwhole); if (glue) *glue = plug; /* repair damage to whole */ if (!isshexp(wildtail)) { e = ZE_MISS; /* non-wild name not found */ goto ohforgetit; } while ((name = readd(dir)) != NULL) { if (strcmp(name, ".") && strcmp(name, "..") && MATCH(wildtail, name)) { strcpy(newwhole + newlen, name); if (subwild) { name = newwhole + strlen(newwhole); *(name++) = PATH_END; strcpy(name, subwild); e = wild_recurse(newwhole, name); } else e = procname(newwhole); newwhole[newlen] = 0; if (e == ZE_OK) amatch = 1; else if (e != ZE_MISS) break; } } ohforgetit: if (dir) Closedir(dir); if (subwild) *--subwild = PATH_END; if (newwhole) free(newwhole); if (e == ZE_MISS && amatch) e = ZE_OK; return e;}int wild(w)char *w; /* path/pattern to match *//* If not in exclude mode, expand the pattern based on the contents of the file system. Return an error code in the ZE_ class. */{ char *p; /* path */ char *q; /* diskless path */ int e; /* result */ if (volume_label == 1) { volume_label = 2; label = getVolumeLabel((w != NULL && w[1] == ':') ? to_up(w[0]) : '\0', &label_time, &label_mode, &label_utim); if (label != NULL) (void)newname(label, 0); if (w == NULL || (w[1] == ':' && w[2] == '\0')) return ZE_OK; /* "zip -$ foo a:" can be used to force drive name */ } /* special handling of stdin request */ if (strcmp(w, "-") == 0) /* if compressing stdin */ return newname(w, 0); /* Allocate and copy pattern, leaving room to add "." if needed */ if ((p = malloc(strlen(w) + 2)) == NULL) return ZE_MEM; strcpy(p, w); /* Normalize path delimiter as '/' */ for (q = p; *q; q++) /* use / consistently */ if (*q == '\\') *q = '/'; /* Separate the disk part of the path */ if ((q = strchr(p, ':')) != NULL) { if (strchr(++q, ':')) /* sanity check for safety of wild_recurse */ return ZE_MISS; } else q = p; /* Normalize bare disk names */ if (q > p && !*q) strcpy(q, "."); /* Here we go */ e = wild_recurse(p, q); free((zvoid *)p); return e;}int procname(n)char *n; /* name to process *//* Process a name or sh expression to operate on (or exclude). Return an error code in the ZE_ class. */{ char *a; /* path and name for recursion */ zDIR *d; /* directory stream from opendir() */ char *e; /* pointer to name from readd() */ int m; /* matched flag */ char *p; /* path for recursion */ struct stat s; /* result of stat() */ struct zlist far *z; /* steps through zfiles list */ if (strcmp(n, "-") == 0) /* if compressing stdin */ return newname(n, 0); else if (LSSTAT(n, &s)#ifdef __TURBOC__ /* For this compiler, stat() succeeds on wild card names! */ /* Unfortunately, this causes failure on names containing */ /* square bracket characters, which are legal in win32. */ || isshexp(n)#endif ) { /* Not a file or directory--search for shell expression in zip file */ p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ m = 1; for (z = zfiles; z != NULL; z = z->nxt) { if (MATCH(p, z->iname)) { z->mark = pcount ? filter(z->zname) : 1; if (verbose) fprintf(mesg, "zip diagnostic: %scluding %s\n", z->mark ? "in" : "ex", z->name); m = 0; } } free((zvoid *)p); return m ? ZE_MISS : ZE_OK; } /* Live name--use if file, recurse if directory */ for (p = n; *p; p++) /* use / consistently */ if (*p == '\\') *p = '/'; if ((s.st_mode & S_IFDIR) == 0) { /* add or remove name of file */ if ((m = newname(n, 0)) != ZE_OK) return m; } else { /* Add trailing / to the directory name */ if ((p = malloc(strlen(n)+2)) == NULL) return ZE_MEM; if (strcmp(n, ".") == 0 || strcmp(n, "/.") == 0) { *p = '\0'; /* avoid "./" prefix and do not create zip entry */ } else { strcpy(p, n); a = p + strlen(p); if (a[-1] != '/') strcpy(a, "/"); if (dirnames && (m = newname(p, 1)) != ZE_OK) { free((zvoid *)p); return m; } } /* recurse into directory */ if (recurse && (d = Opendir(n)) != NULL) { while ((e = readd(d)) != NULL) { if (strcmp(e, ".") && strcmp(e, "..")) { if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) { Closedir(d); free((zvoid *)p);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -