123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- /*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
- (the contents of which are also included in zip.h) for terms of use.
- If, for some reason, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
- */
- /*
- * MVS specific things
- */
- #include "zip.h"
- #include "mvs.h"
- #include <errno.h>
- static int gen_node( DIR *dirp, RECORD *recptr )
- {
- char *ptr, *name, ttr[TTRLEN];
- int skip, count = 2;
- unsigned int info_byte, alias, ttrn;
- struct dirent *new;
- ptr = recptr->rest;
- while (count < recptr->count) {
- if (!memcmp( ptr, endmark, NAMELEN ))
- return 1;
- name = ptr; /* member name */
- ptr += NAMELEN;
- memcpy( ttr, ptr, TTRLEN ); /* ttr name */
- ptr += TTRLEN;
- info_byte = (unsigned int) (*ptr); /* info byte */
- if ( !(info_byte & ALIAS_MASK) ) { /* no alias */
- new = malloc( sizeof(struct dirent) );
- if (dirp->D_list == NULL)
- dirp->D_list = dirp->D_curpos = new;
- else
- dirp->D_curpos = (dirp->D_curpos->d_next = new);
- new->d_next = NULL;
- memcpy( new->d_name, name, NAMELEN );
- new->d_name[NAMELEN] = '\0';
- if ((name = strchr( new->d_name, ' ' )) != NULL)
- *name = '\0'; /* skip trailing blanks */
- }
- skip = (info_byte & SKIP_MASK) * 2 + 1;
- ptr += skip;
- count += (TTRLEN + NAMELEN + skip);
- }
- return 0;
- }
- DIR *opendir(const char *dirname)
- {
- int bytes, list_end = 0;
- DIR *dirp;
- FILE *fp;
- RECORD rec;
- fp = fopen( dirname, "rb" );
- if (fp != NULL) {
- dirp = malloc( sizeof(DIR) );
- if (dirp != NULL) {
- dirp->D_list = dirp->D_curpos = NULL;
- strcpy( dirp->D_path, dirname );
- do {
- bytes = fread( &rec, 1, sizeof(rec), fp );
- if (bytes == sizeof(rec))
- list_end = gen_node( dirp, &rec );
- } while (!feof(fp) && !list_end);
- fclose( fp );
- dirp->D_curpos = dirp->D_list;
- return dirp;
- }
- fclose( fp );
- }
- return NULL;
- }
- struct dirent *readdir(DIR *dirp)
- {
- struct dirent *cur;
- cur = dirp->D_curpos;
- dirp->D_curpos = dirp->D_curpos->d_next;
- return cur;
- }
- void rewinddir(DIR *dirp)
- {
- dirp->D_curpos = dirp->D_list;
- }
- int closedir(DIR *dirp)
- {
- struct dirent *node;
- while (dirp->D_list != NULL) {
- node = dirp->D_list;
- dirp->D_list = dirp->D_list->d_next;
- free( node );
- }
- free( dirp );
- return 0;
- }
- local 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;
- e = readdir(d);
- return e == NULL ? (char *) NULL : e->d_name;
- }
- int procname(n, caseflag)
- char *n; /* name to process */
- int caseflag; /* true to force case-sensitive match */
- /* 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 */
- 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 */
- int exists; /* 1 if file exists */
- if (strcmp(n, "-") == 0) /* if compressing stdin */
- return newname(n, 0, caseflag);
- else if (!(exists = (LSSTAT(n, &s) == 0)))
- {
- #ifdef MVS
- /* special case for MVS. stat does not work on non-HFS files so if
- * stat fails with ENOENT, try to open the file for reading anyway.
- * If the user has no OMVS segment, stat gets an initialization error,
- * even on external files.
- */
- if (errno == ENOENT || errno == EMVSINITIAL) {
- FILE *f = fopen(n, "r");
- if (f) {
- /* stat got ENOENT but fopen worked, external file */
- fclose(f);
- exists = 1;
- memset(&s, '\0', sizeof(s)); /* stat data is unreliable for externals */
- s.st_mode = S_IFREG; /* fudge it */
- }
- }
- #endif /* MVS */
- }
- if (! exists) {
- /* 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, caseflag))
- {
- z->mark = pcount ? filter(z->zname, caseflag) : 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_ISDIR(s.st_mode))
- {
- /* add or remove name of file */
- if ((m = newname(n, 0, caseflag)) != 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) {
- *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, caseflag)) != 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);
- return ZE_MEM;
- }
- strcat(strcpy(a, p), e);
- if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */
- {
- if (m == ZE_MISS)
- zipwarn("name not matched: ", a);
- else
- ziperr(m, a);
- }
- free((zvoid *)a);
- }
- }
- closedir(d);
- }
- free((zvoid *)p);
- } /* (s.st_mode & S_IFDIR) == 0) */
- return ZE_OK;
- }
|