// RCV 1.605 Added static void SetExclFilters(struct Globals *pG) { register int i; if (pG->pcount) { if ((pG->patterns = (struct plist*)MALLOC(pG->pcount *sizeof(struct plist))) == NULL) { ziperr(ZEN_MEM05, pG); return ; } for (i = 0; i < pG->pcount; i++) { register char *p = pG->ExternalList[i].zname; // Replace forward slashes. if (p) while (*p) if (*p++ == '/') *(p - 1) = '\\'; pG->patterns[i].zname = ex2in(pG->ExternalList[i].zname, NULL, pG); } } }
/* =========================================================================== * Process a name or wildcard expression to operate on (or exclude). * We will only arrive here if we do a Freshen or Delete. * Return an error code in the ZEN_ class. * ZEN_OK, ZEN_ABORT, ZEN_MISS03, ZEN_MISS04, ZEN_MISS05, ZEN_MEM22, ZEN_MEM23 *ArgName :: Name to process. */ int procname( char *ArgName, bool RecurseDir, struct Globals *pG ) { 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 */ int pnError; /* ProcName error */ struct stat StatRes; /* result of stat() */ struct zlist *z; /* steps through zfiles list */ // sprintf( ewemsg, "in procname name=>%s<= recurse=%d", ArgName, RecurseDir ); // diag( ewemsg ); m = 1; /* set dflt for success indicator (0=success) */ if ( pG->global_abort_sw ) return ZEN_ABORT; /* RCV changed was ZEN_MISS? */ if ( *ArgName == '\0' ) return ZEN_MISS03; /* LSSTAT returns 0 if it's arg is any kind of file (even a dir). */ /* IsShExp returns true if a wildcard symbol is found, or * NULL if none were found -- IsShExp is in util.c */ if ( LSSTAT( GetFullPath( pG, ArgName ), &StatRes ) || (IsShExp( ArgName ) != NULL) ) { // diag( "not a file or dir - 'ArgName' must be a wildcard fspec" ); // Upon finding a wildcard fspec, we need to mark entries in // the "zfiles" list that are included by the wildcard. /* convert the "external" (native) filename to an internal * ZIP-archive-compatible filename. */ p = ex2in( ArgName, (int *)NULL, pG ); /* shouldn't affect matching chars */ /* does any file already in the archive match this spec? */ /* Note that we need the pathname and filename together for this */ for ( z = pG->zfiles; z; z = z->nxt ) { if ( dosmatch( p, z->zname, pG ) ) { /* name is in archive - mark it for updating */ z->mark = pG->pcount ? filter( z->zname, pG ) : 1; FREE( z->name ); // RCV added + next 8 lines needed for FRESHEN mode. if ( (z->name = MALLOC( lstrlen( z->zname ) + 4 )) == NULL ) return ZEN_MEM34; z->name[0] = '\0'; //v1.55 if ( isalpha( ArgName[0] ) && ArgName[1] == ':' && ArgName[2] == '\\') { z->name[0] = ArgName[0]; z->name[1] = ArgName[1]; z->name[2] = ArgName[2]; z->name[3] = '\0'; } lstrcat( z->name, z->zname ); if ( pG->verbose ) printf( "%scluding %s\n", z->mark ? "in" : "ex", z->name ); m = 0; /* we had at least one file in the archive that we marked */ } } FREE( p ); /* returns 1 if no "zfiles" entries were marked, * 0 if at least one entry was marked */ if ( m ) { // diag( "returning ZEN_MISS04 from procname" ); return ZEN_MISS04; } // diag( "returning ZEN_OK from procname" ); return ZEN_OK; } /* end of "if (LSSTAT..." */ /* Existing and good filename or directory-- add the name if it's a file, recurse if directory */ // diag( "good entry to add, or a dir to go into" ); /* check the status returned by LSSTAT earlier to see if 'ArgName' is a dir */ pnError = ZEN_OK; if ( !(StatRes.st_mode & S_IFDIR) ) { /* it's not a directory - add file to found list */ sprintf( pG->ewemsg, "spot 1: Add file %s to found list", ArgName ); diag( pG->ewemsg, pG ); /* newname (fileio.c) adds to found list. If error m!=0 on return */ if ( (m = newname( ArgName, StatRes.st_size, pG )) != ZEN_OK ) { sprintf( pG->ewemsg, "returning %d from procname after newname call", m ); diag( pG->ewemsg, pG ); return m; } } else { /* It is a directory - Add trailing / to the directory name */ // diag( "Spot 2, directory found" ); if ( (p = MALLOC( lstrlen( ArgName )+ 2) ) == NULL ) return ZEN_MEM22; if ( !strcmp( ArgName, "." ) || !strcmp( ArgName, "\\." ) ) { // SLASH *p = '\0'; /* avoid "./" prefix and do not create zip entry */ } else { // diag( "spot 3" ); lstrcpy( p, ArgName ); a = p + lstrlen( p ); if ( a[-1] != '\\' ) lstrcpy( a, "\\" ); // SLASH /* newname (fileio.c) adds to found list. If error m != 0 on return */ if ( pG->dirnames && (m = newname( p, 0, pG )) != ZEN_OK ) { FREE( p ); sprintf( pG->ewemsg, "returning %d from procname after 2nd newname call", m ); diag( pG->ewemsg, pG ); return m; } } /* recurse into directory */ // diag( "spot 4: optional recurse into dir" ); if ( RecurseDir && ((d = Opendir( ArgName, pG )) != NULL) ) { /* Open new dir (like chdir) */ // diag( "good open of dir" ); while ( (e = readd( d, pG )) != NULL ) { if ( pG->global_abort_sw ) { // RCV changed error handling pnError = ZEN_ABORT; break; } /* e is pointing to the new filename we just read from dir */ /* ignore dir entries of . and .. */ if ( strcmp( e, "." ) && strcmp( e, ".." ) ) { /* get a new tmp buffer for the path and fname */ if ( (a = MALLOC( lstrlen( p ) + lstrlen( e ) + 1 )) == NULL ) { pnError = ZEN_MEM23; /* RCV error handling changed */ break; } /* form the new dir's pathname followed by the fname just read */ /* (we need to send in the dir and fname, or it won't be * detected as a valid file by LSSTAT) */ lstrcat( lstrcpy( a, p ), e ); // diag( "DOING RECURSIVE CALL TO PROCNAME FROM PROCNAME" ); if ( (m = procname( a, RecurseDir, pG )) != ZEN_OK ) { /* recursive call failed; return code not ZEN_OK */ if ( m != ZEN_OK && m != ZEN_MISS05 ) { /* unknown error; RCV error handling changed */ pnError = m; FREE( a ); break; } else if ( (int)(char)(m & 0xFF) == ZEN_MISS ) zipwarn( "name not matched: ", a ); } FREE( a ); } } /* end while */ Closedir( d ); } /* end if (spot 4) */ FREE( p ); } /* (StatRes.st_mode & S_IFDIR) == 0) */ // diag( "returning ZEN_ class from procname" ); return pnError; }