int IsFileSystemOldFAT(char *dir) { static char lastDrive = '\0'; /* cached drive of last GetVolumeInformation call */ static int lastDriveOldFAT = 0; /* cached OldFAT value of last GetVolumeInformation call */ char root[4]; DWORD vfnsize; DWORD vfsflags; /* * We separate FAT and HPFS+other file systems here. * I consider other systems to be similar to HPFS/NTFS, i.e. * support for long file names and being case sensitive to some extent. */ strncpy(root, dir, 3); if ( isalpha((uch)root[0]) && (root[1] == ':') ) { root[0] = to_up(dir[0]); root[2] = '\\'; root[3] = 0; } else { root[0] = '\\'; root[1] = 0; } if (lastDrive == root[0]) { return lastDriveOldFAT; } if ( !GetVolumeInformation(root, NULL, 0, NULL, &vfnsize, &vfsflags, NULL, 0)) { fprintf(mesg, "zip diagnostic: GetVolumeInformation failed\n"); return(FALSE); } lastDrive = root[0]; lastDriveOldFAT = vfnsize <= 12; return lastDriveOldFAT; }
int IsFileSystemOldFAT(char *dir) { char root[4]; char vname[128]; DWORD vnamesize = sizeof(vname); DWORD vserial; DWORD vfnsize; DWORD vfsflags; char vfsname[128]; DWORD vfsnamesize = sizeof(vfsname); /* * We separate FAT and HPFS+other file systems here. * I consider other systems to be similar to HPFS/NTFS, i.e. * support for long file names and being case sensitive to some extent. */ strncpy(root, dir, 3); if ( isalpha(root[0]) && (root[1] == ':') ) { root[0] = to_up(dir[0]); root[2] = '\\'; root[3] = 0; } else { root[0] = '\\'; root[1] = 0; } if ( !GetVolumeInformation(root, vname, vnamesize, &vserial, &vfnsize, &vfsflags, vfsname, vfsnamesize)) { fprintf(mesg, "zip diagnostic: GetVolumeInformation failed\n"); return(FALSE); } return vfnsize <= 12; }
/* =========================================================================== * If not in exclude mode, expand the pattern based on the contents * of the file system. * This function is used while gathering filenames to be added or updated *w :: Path/pattern to match. Possible return values: ZEN_MISS, ZEN_OK, ZEN_ABORT, ZEN_MEM or ZEN_PARMS. */ int Wild( char *w, struct Globals *pG ) { zDIR *d; /* Stream for reading directory */ char *e; /* File or directory name found. */ char *n; /* Constructed name from directory */ int WError; /* Result of Wild() */ char *p, *a; /* path originale and fixed. */ char *q; /* Filename / pattern. */ int r; /* Result / temp var. */ char v[5]; /* space for device current directory.*/ bool StopRecurs = false; /* No recursion if filespec is file. */ // sprintf( pG->ewemsg, "in Wild of win32zip.c, pattern=%s recurse=%d", w, pG->recurse ); // diag( pG->ewemsg, pG ); // "zip -$ foo a:" can be used to force a drive name once. // v1.6017 if ( pG->volume_label == 1 ) { pG->volume_label = 2; pG->label = getVolumeLabel( pG, (w != NULL && w[ 1 ] == ':') ? to_up( w[ 0 ] ) : '\0', &pG->label_time, &pG->label_mode, &pG->label_utim ); if ( pG->label != NULL ) (void)newname( pG->label, 0, pG ); if ( w == NULL || (w[1] == ':' && w[2] == '\0') ) return ZEN_OK; } /* Allocate and copy pattern */ if ( (p = a = MALLOC( lstrlen( w ) + 1) ) == NULL ) return ZEN_MEM19; lstrcpy( p, w ); /* Separate path and name into p and q */ // We have '\' or '\name' or 'path1\path2\name2' or 'C:\path\name' but NOT 'C:\name' if ( (q = strrchr( p, '\\' )) != NULL && (q == p || q[-1] != ':') ) { // SLASH *q++ = '\0'; if ( *p == '\0' ) p = lstrcpy( v, "\\." ); /* if path is just '\' SLASH */ } else if ( (q = strrchr( p, ':' )) != NULL ) { /* We have 'C:' or 'C:\' or 'C:\name' */ *q++ = '\0'; p = lstrcat( lstrcpy( v, p ), ":" ); /* copy device as path eg. 'C:' */ if ( *q == '\\' ) { /* -> device:/., name eg. 'C:\.' SLASH */ lstrcat( p, "\\" ); // SLASH q++; /* name or nothing. */ } lstrcat( p, "." ); /* eg. 'C:.' or 'C:\.' */ } else if ( pG->recurse && (!strcmp( p, "." ) || !strcmp( p, ".." )) ) { /* current or parent directory */ /* Get "zip -r foo ." to work. Allow the dubious "zip -r foo .." but * reject "zip -r -m foo ..". "dispose" means wipe out source path. */ if ( pG->dispose && !strcmp( p, ".." ) ) ziperr( ZEN_PARMS15, pG ); q = (char *)pG->wild_match_all; } else { /* no path or device */ q = p; p = lstrcpy( v, "." ); } if ( pG->recurse && *q == '\0' ) q = (char *)pG->wild_match_all; /* take out a possibly redundant dir name of "." */ if ( (r = lstrlen( p )) > 1 && (strcmp( p + r - 2, ":." ) == 0 || strcmp( p + r - 2, "\\." ) == 0) ) // SLASH *(p + r - 1) = '\0'; /* Only filename (not the path) can have special matching characters */ if ( IsShExp( p ) ) { diag( "path has illegal chars", pG ); FREE( a ); return ZEN_PARMS16; } // sprintf( ewemsg, "at break up place in Wild: path=%s name=%s", p, q ); // diag( ewemsg ); if ( !IsShExp( q ) ) { // Speed up checking if file exits in case there are no wildcards struct stat s; // and no recursion and no archiving v1.6016 if ( !pG->recurse && !pG->ArchiveFiles ) { if ( !LSSTAT( GetFullPath( pG, w ), &s ) ) /* file exists ? */ return procname( w, false, pG ); return ZEN_MISS02; /* woops, no wildcards where is the file! */ } if ( pG->norecursefiles ) StopRecurs = true; } /* Now that we have a dir spec, along with an fspec, we'll step * in the dir specified to see if there's any matches against the fspec. */ WError = ZEN_MISS02; if ( (d = Opendir( p, pG )) != NULL ) { while ( (e = readd( d, pG )) != NULL ) { if ( pG->global_abort_sw ) { WError = ZEN_ABORT; break; } // sprintf( ewemsg, "Found %s: %s", d->d_attr & FILE_ATTRIBUTE_DIRECTORY ? "directory" : "file", e ); // diag( ewemsg ); /* if e is NOT '.' or '..', and is a dir or match fspec. */ if ( strcmp( e, "." ) && strcmp( e, ".." ) && (d->d_attr & FILE_ATTRIBUTE_DIRECTORY || dosmatch( q, e, pG )) ) { // diag( "Matched" ); /* we matched fspec or it's a dir and entry is not '.' or '..' */ if ( d->d_attr & FILE_ATTRIBUTE_DIRECTORY ) { // We do not save dirs or go into dirs if norecursefiles==1 and we a file without * or ? specs. if ( !StopRecurs && (pG->dirnames || pG->recurse) ) { if ( (n = MALLOC( lstrlen( p ) + lstrlen( e ) + lstrlen( q ) + 3 )) == NULL ) { WError = ZEN_MEM20; break; } *n = '\0'; if ( *p != '.' ) AddSlash( lstrcpy( n, p ) ); // No ./ as first dir. lstrcat( n, e ); if ( pG->dirnames ) { // Save directory names also. r = procname( n, false, pG ); if ( (int)(char)(r & 0xFF) > ZEN_OK || !pG->recurse ) FREE( n ); if ( (int)(char)(r & 0xFF) > (int)(char)(WError & 0xFF) ) WError = r; if ( (int)(char)(r & 0xFF) > ZEN_OK ) break; } if ( pG->recurse ) { // Recursively go into dir and check for other pattern matches. r = Wild( lstrcat( AddSlash( n ), q ), pG ); // Add the original pattern. FREE( n ); // We keep a ZEN_OK even when ZEN_MISS occurs. if ( (int)(char)(r & 0xFF) > (int)(char)(WError & 0xFF) ) WError = r; if ( (int)(char)(r & 0xFF) > ZEN_OK ) break; // An error, stop processing. } } } else { if ( (n = MALLOC( lstrlen( p ) + lstrlen( e ) + 2 )) == NULL ) { WError = ZEN_MEM21; break; } if ( !strcmp( p, "." ) ) r = procname( e, false, pG ); else r = procname( lstrcat( AddSlash( lstrcpy( n, p ) ), e ), false, pG ); FREE( n ); if ( (int)(char)(r & 0xFF) > (int)(char)(WError & 0xFF) ) WError = r; if ( (int)(char)(r & 0xFF) > ZEN_OK ) break; } } /* end "if (strcmp..." */ } /* end while */ Closedir( d ); } else diag( "can't open dir", pG ); FREE( a ); // sprintf( ewemsg, "Wild returned: %d", WError ); // diag( ewemsg ); return WError; }