📄 vmszip.c
字号:
/* Copyright (C) 1990-1997 Mark Adler, Richard B. Wales, Jean-loup Gailly, Kai Uwe Rommel, Onno van der Linden, Christian Spieler 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.*/#include "zip.h"#include <time.h>#include <unixlib.h>#include <descrip.h>#include <rms.h>#include <ssdef.h>#include <starlet.h>#define PATH_START '['#define PATH_END ']'#define PATH_START2 '<'#define PATH_END2 '>'#define MATCH shmatch#include "vms/vmsmunch.h"/* Extra malloc() space in names for cutpath() */#define PAD 5 /* may have to change .FOO] to ]FOO.DIR;1 */typedef struct dirent { int d_wild; /* flag for wildcard vs. non-wild */ struct FAB fab; struct NAM nam; char d_qualwildname[NAM$C_MAXRSS + 1]; char d_name[NAM$C_MAXRSS + 1];} DIR;/* Library functions not in (most) header files */#ifndef UTIL /* the companion #endif is a bit of ways down ... */extern char *label;local ulg label_time = 0;local ulg label_mode = 0;local time_t label_utim = 0;/* Local functions */local void vms_wild OF((char *, DIR *));DIR *opendir OF((ZCONST char *));struct dirent *readdir OF((DIR *));local char *readd OF((DIR *));local char *strlower OF((char *));local char *strupper OF((char *));/*--------------------------------------------------------------------------- _vms_findfirst() and _vms_findnext(), based on public-domain DECUS C fwild() and fnext() routines (originally written by Martin Minow, poss- ibly modified by Jerry Leichter for bintnxvms.c), were written by Greg Roelofs and are still in the public domain. Routines approximate the behavior of MS-DOS (MSC and Turbo C) findfirst and findnext functions. ---------------------------------------------------------------------------*/static char wild_version_part[10]="\0";local void vms_wild(p, d)char *p;DIR *d;{ /* * Do wildcard setup */ /* set up the FAB and NAM blocks. */ d->fab = cc$rms_fab; /* initialize fab */ d->nam = cc$rms_nam; /* initialize nam */ d->fab.fab$l_nam = &d->nam; /* fab -> nam */ d->fab.fab$l_fna = p; /* argument wild name */ d->fab.fab$b_fns = strlen(p); /* length */ d->fab.fab$l_dna = "sys$disk:[]"; /* Default fspec */ d->fab.fab$b_dns = sizeof("sys$disk:[]")-1; d->nam.nam$l_esa = d->d_qualwildname; /* qualified wild name */ d->nam.nam$b_ess = NAM$C_MAXRSS; /* max length */ d->nam.nam$l_rsa = d->d_name; /* matching file name */ d->nam.nam$b_rss = NAM$C_MAXRSS; /* max length */ /* parse the file name */ if (sys$parse(&d->fab) != RMS$_NORMAL) return; /* Does this replace d->fab.fab$l_fna with a new string in its own space? I sure hope so, since p is free'ed before this routine returns. */ /* have qualified wild name (i.e., disk:[dir.subdir]*.*); null-terminate * and set wild-flag */ d->d_qualwildname[d->nam.nam$b_esl] = '\0'; d->d_wild = (d->nam.nam$l_fnb & NAM$M_WILDCARD)? 1 : 0; /* not used... */#ifdef DEBUG fprintf(mesg, " incoming wildname: %s\n", p); fprintf(mesg, " qualified wildname: %s\n", d->d_qualwildname);#endif /* DEBUG */}DIR *opendir(n)ZCONST char *n; /* directory to open *//* Start searching for files in the VMS directory n */{ char *c; /* scans VMS path */ DIR *d; /* malloc'd return value */ int m; /* length of name */ char *p; /* malloc'd temporary string */ if ((d = (DIR *)malloc(sizeof(DIR))) == NULL || (p = malloc((m = strlen(n)) + 4)) == NULL) { if (d != NULL) free((zvoid *)d); return NULL; } /* Directory may be in form "[DIR.SUB1.SUB2]" or "[DIR.SUB1]SUB2.DIR;1". If latter, convert to former. */ if (m > 0 && *(c = strcpy(p,n)+m-1) != ']') { while (--c > p && *c != ';') ; if (c-p < 5 || strncmp(c-4, ".DIR", 4)) { free((zvoid *)d); free((zvoid *)p); return NULL; } c -= 3; *c-- = '\0'; /* terminate at "DIR;#" */ *c = ']'; /* "." --> "]" */ while (c > p && *--c != ']') ; *c = '.'; /* "]" --> "." */ } strcat(p, "*.*"); strcat(p, wild_version_part); vms_wild(p, d); /* set up wildcard */ free((zvoid *)p); return d;}struct dirent *readdir(d)DIR *d; /* directory stream to read from *//* Return pointer to first or next directory entry, or NULL if end. */{ int r; /* return code */ do { d->fab.fab$w_ifi = 0; /* internal file index: what does this do? */ /* get next match to possible wildcard */ if ((r = sys$search(&d->fab)) == RMS$_NORMAL) { d->d_name[d->nam.nam$b_rsl] = '\0'; /* null terminate */ return (struct dirent *)d; /* OK */ } } while (r == RMS$_PRV); return NULL;}#define closedir freelocal char *readd(d)DIR *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 dirent *e; /* directory entry read */ e = readdir(d); return e == NULL ? (char *)NULL : e->d_name;}int wild(p)char *p; /* path/pattern to match *//* Expand the pattern based on the contents of the file system. Return an error code in the ZE_ class. */{ DIR *d; /* stream for reading directory */ char *e; /* name found in directory */ int f; /* true if there was a match */ /* special handling of stdin request */ if (strcmp(p, "-") == 0) /* if compressing stdin */ return newname(p, 0); /* Search given pattern for matching names */ if ((d = (DIR *)malloc(sizeof(DIR))) == NULL) return ZE_MEM; vms_wild(p, d); /* pattern may be more than just directory name */ /* * Save version specified by user to use in recursive drops into * subdirectories. */ strncpy(wild_version_part,d->nam.nam$l_ver,d->nam.nam$b_ver); wild_version_part[d->nam.nam$b_ver] = '\0'; f = 0; while ((e = readd(d)) != NULL) /* "dosmatch" is already built in */ if (procname(e) == ZE_OK) f = 1; closedir(d); /* Done */ return f ? ZE_OK : ZE_MISS;}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. */{ DIR *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)#if defined(__TURBOC__) || defined(VMS) || defined(__WATCOMC__) /* For these 3 compilers, stat() succeeds on wild card names! */ || 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 */ if ((s.st_mode & S_IFDIR) == 0) { /* add or remove name of file */ if ((m = newname(n, 0)) != ZE_OK) return m; } else { if (dirnames && (m = newname(n, 1)) != ZE_OK) { return m; } /* recurse into directory */ if (recurse && (d = opendir(n)) != NULL) { while ((e = readd(d)) != NULL) { if ((m = procname(e)) != ZE_OK) /* recurse on name */ { closedir(d); return m; } } closedir(d); } } /* (s.st_mode & S_IFDIR) == 0) */ return ZE_OK;}local char *strlower(s)char *s; /* string to convert *//* Convert all uppercase letters to lowercase in string s */{ char *p; /* scans string */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -