home *** CD-ROM | disk | FTP | other *** search
- // NextFile.c
- // 28 Jul 1996 18:35:19
-
- #ifndef BACKUP_INCLUDE
- #include "IncludeAll.c"
- #endif
- #include "Backup.h"
- #include "FileSelect.h"
- #include "Backup_proto.h"
- #include "BackupStrings.h"
-
- // #define d(x) x
- #define d(x) ;
-
-
- #define USE_EXALL 0 // wenn TRUE, dann wird ExAll() zum Scannen benutzt
-
- #define EXALL_BUFFSIZE 65536l // Buffergröße für ExAll()
-
-
- static void DeleteDir(struct MinList *List);
- static void DeleteDirEntry(struct DirEntry *Dir);
- static struct FSDir *NextFSDir(struct NextFileInfo *Info);
- static struct FSDirEntry *NextFSEntry(struct NextFileInfo *Info, struct FSDir **theDir);
- static BOOL ExamineName(const char *Name, struct FileInfoBlock *fib);
- static BOOL NextFSFile(struct NextFileInfo *Info, struct FileInfoBlock *fib);
- static BOOL NextDEFile(struct NextFileInfo *Info, struct FileInfoBlock *fib,
- struct MinList *DirList);
- static struct DirEntry *NewSubDir(struct DirEntry *Parent, const char *name, BOOL temp);
- static BOOL FileMatch(struct BackupOptions *Opt, struct FileInfoBlock *fib, BOOL TellSkips);
- static BOOL FibIsFile(const struct FileInfoBlock *fib, BPTR DirLock);
- static BOOL NFExNext(struct NextFileInfo *nfInfo, struct FileInfoBlock *fib);
-
-
- // aus Backup.c
- extern struct BackupOptions myOptions; // Einstellungen für die aktuelle Sicherung
- extern char __far NormalizedAktPath[FMSIZE]; // AktPath normalisiert
-
-
- BOOL NextFileAbort; // Abbruch-Flag für NextFile
-
-
- void CleanupNextFileInfo(struct NextFileInfo *Info)
- {
- ASSERT_VALID(Info);
-
- if (Info->nfi_eaControl && Info->nfi_eaBuffer && Info->nfi_eaMore)
- {
- // ExAll() war noch nicht fertig
- ExAllEnd(Info->nfi_DirLock, Info->nfi_eaBuffer,
- EXALL_BUFFSIZE, ED_COMMENT, Info->nfi_eaControl);
- }
- if (Info->nfi_eaControl)
- {
- FreeDosObject(DOS_EXALLCONTROL, Info->nfi_eaControl);
- Info->nfi_eaControl = NULL;
- }
- if (Info->nfi_eaBuffer)
- {
- free(Info->nfi_eaBuffer);
- Info->nfi_eaBuffer = NULL;
- }
- if (Info->nfi_DirLock != NULL)
- {
- UnLock(Info->nfi_DirLock);
- Info->nfi_DirLock = NULL;
- }
-
- d(kprintf("deleting Directory tree\n");)
- DeleteDir(&Info->nfi_FirstDir); // Directory-Baum auflösen
- }
-
-
- // Angelegten Directory-Baum wieder auflösen
- static void DeleteDir(struct MinList *List)
- {
- struct DirEntry *dir;
-
- ASSERT_VALID(List);
- d(kprintf("Beginn DeleteDir dir=%08lx\n", dir);)
-
- while (!IsListEmpty((struct List *) List))
- {
- dir = (struct DirEntry *) List->mlh_Head;
-
- DeleteDir(&dir->Sub);
- DeleteDirEntry(dir);
- }
- d(kprintf("End DeleteDir\n");)
- }
-
-
- static void DeleteDirEntry(struct DirEntry *Dir)
- {
- ASSERT_VALID(Dir);
-
- Remove((struct Node *) Dir);
-
- if (Dir->Temporary)
- free(Dir);
- }
-
-
- void SetupNextFileInfo(struct NextFileInfo *Info, struct BackupOptions *Opt,
- void (*DirDisp)())
- {
- ASSERT_VALID(Info);
- ASSERT_VALID(Opt);
-
- Info->nfi_DirLock = NULL;
-
- Info->nfi_FSDirIndex = 0;
- Info->nfi_FSDirListDone = FALSE;
- Info->nfi_VisibleIndex = 0;
- Info->nfi_Dir = NULL;
-
- Info->nfi_eaControl = NULL;
- Info->nfi_eaBuffer = NULL;
- Info->nfi_eaData = NULL;
- Info->nfi_eaMore = FALSE;
-
- NewList((struct List *) &Info->nfi_FirstDir);
- Info->nfi_Opt = Opt;
-
- Info->nfi_DirDisplay = DirDisp;
-
- NextFileAbort = FALSE;
-
- InitSearchPattern(Opt);
-
- #if USE_EXALL
- Info->nfi_eaControl = AllocDosObject(DOS_EXALLCONTROL, NULL);
- Info->nfi_eaBuffer = malloc(EXALL_BUFFSIZE);
-
- Info->nfi_eaControl->eac_LastKey = 0;
- #endif
- }
-
-
- static struct FSDir *NextFSDir(struct NextFileInfo *Info)
- {
- struct FSDir *Dir = NULL;
- struct DirEntry *aktdir;
-
- ASSERT_VALID(Info);
-
- // Neues Directory suchen
- while (!Info->nfi_FSDirListDone && (Dir == NULL || (ManualSelectCount(Dir) == 0)))
- {
- Info->nfi_FSDirListDone = Info->nfi_FSDirIndex >= Info->nfi_Opt->bo_FSDirCount;
-
- if (Info->nfi_FSDirListDone)
- Dir = NULL;
- else
- Dir = Info->nfi_Opt->bo_FSDirList[Info->nfi_FSDirIndex++];
- }
-
- if (Dir)
- {
- aktdir = NewDir(&Info->nfi_FirstDir, Dir->fsd_Name, 1);
- SetupNewDir(Info, "", aktdir);
-
- if (Info->nfi_DirDisplay)
- (*Info->nfi_DirDisplay)(aktdir);
- aktdir->Done = TRUE; // Dir in NextDEFile() nicht bearbeiten!
- }
-
- return Dir;
- }
-
-
- static struct FSDirEntry *NextFSEntry(struct NextFileInfo *Info,
- struct FSDir **theDir)
- {
- struct FSDirEntry *FSe;
-
- ASSERT_VALID(Info);
- ASSERT_VALID(theDir);
-
- do {
- if (Info->nfi_Dir == NULL)
- {
- // Neues Directory suchen
- Info->nfi_Dir = NextFSDir(Info);
-
- Info->nfi_VisibleIndex = 0;
- }
-
- // Ausgang wenn alle Directories durch
- if (Info->nfi_Dir == NULL)
- return NULL;
-
- do {
- // nächsten selektierten Eintrag suchen
-
- if (Info->nfi_VisibleIndex < Info->nfi_Dir->fsd_DirCount)
- FSe = Info->nfi_Dir->fsd_EntryList[Info->nfi_VisibleIndex++];
- else
- {
- Info->nfi_Dir = NULL;
- FSe = NULL;
- }
- } while (FSe && (FSe->fse_Selected != ST_Selected));
- } while (FSe == NULL);
-
- if (FSe)
- *theDir = Info->nfi_Dir;
-
- return FSe;
- }
-
-
- BOOL NextFile(struct NextFileInfo *Info, struct FileInfoBlock *fib)
- {
- BOOL Result;
-
- ASSERT_VALID(Info);
- ASSERT_VALID(fib);
-
- Result = (BOOL) (NextFSFile(Info, fib) || NextDEFile(Info, fib, &Info->nfi_FirstDir));
-
- #ifdef NFDEBUG
- if (Result)
- printf("%6ld %8ld %s\n", fib->fib_DirEntryType, fib->fib_Size, fib->fib_FileName);
- #endif
-
- return Result;
- }
-
-
- static BOOL ExamineName(const char *Name, struct FileInfoBlock *fib)
- {
- BPTR FileLock;
- BOOL found;
-
- ASSERT_VALID(Name);
- ASSERT_VALID(fib);
-
- FileLock = Lock((STRPTR) Name, ACCESS_READ);
- found = FileLock && Examine(FileLock, fib);
- if (FileLock)
- UnLock(FileLock);
-
- return found;
- }
-
-
- static BOOL NextFSFile(struct NextFileInfo *Info, struct FileInfoBlock *fib)
- {
- struct FSDir *Dir;
- struct FSDirEntry *FSe;
- char *Name;
- BOOL found;
-
- ASSERT_VALID(Info);
- ASSERT_VALID(fib);
-
- do {
- FSe = NextFSEntry(Info, &Dir);
- found = FALSE;
- if (FSe)
- {
- Name = ConcatDirName(Dir->fsd_Name, FSe->fse_Name);
-
- switch (FSe->fse_Typ)
- {
- case Device:
- // Partition sichern
- fib->fib_DirEntryType = LONG_MIN;
- fib->fib_Size = FSe->fse_Size;
- fib->fib_NumBlocks = ~0;
- DateStamp(&fib->fib_Date);
- stccpy(fib->fib_FileName, FSe->fse_Name, sizeof(fib->fib_FileName));
- strcpy(fib->fib_Comment, "");
- found = TRUE;
- break;
-
- case HardLinkDir:
- if (Info->nfi_Opt->bo_SaveHardLinks)
- {
- // behandeln als Subdirectory
- if (ManualSelectCount(SearchFSDir(Name)) == 0)
- NewDir(&Info->nfi_FirstDir, Name, 1);
- }
- else
- {
- // behandeln als Link
- found = ExamineName(Name, fib);
- strcpy(fib->fib_FileName, FSe->fse_Name);
- }
- fib->fib_DirEntryType = ST_LINKDIR;
- break;
-
- case Directory:
- case Assign:
- case Volume:
- // SubDir nur eintragen wenn nicht schon
- // explizit erwähnt und dort manuell markiert!
- if (ManualSelectCount(SearchFSDir(Name)) == 0
- && ManualSelectCount(FSe->fse_Contents) == 0)
- {
- NewDir(&Info->nfi_FirstDir, Name, 1);
- }
- break;
-
- case SoftLinkDir:
- if (Info->nfi_Opt->bo_SaveSoftLinks)
- {
- // behandeln als Subdirectory
- if (ManualSelectCount(SearchFSDir(Name)) == 0)
- NewDir(&Info->nfi_FirstDir, Name, 1);
- }
- else
- {
- // behandeln als Link
- found = ExamineName(Name, fib);
- strcpy(fib->fib_FileName, FSe->fse_Name);
- }
- fib->fib_DirEntryType = ST_SOFTLINK;
- break;
-
- case SoftLinkFile:
- found = ExamineName(Name, fib);
- strcpy(fib->fib_FileName, FSe->fse_Name);
- fib->fib_DirEntryType = ST_SOFTLINK;
- break;
-
- case HardLinkFile:
- found = ExamineName(Name, fib);
- fib->fib_DirEntryType = ST_LINKFILE;
- stccpy(fib->fib_FileName, FSe->fse_Name, sizeof(fib->fib_FileName));
- break;
- case File:
- found = ExamineName(Name, fib);
- break;
- }
-
- free(Name);
- }
- } while (FSe && !found);
-
- return found;
- }
-
-
- static BOOL NextDEFile(struct NextFileInfo *Info, struct FileInfoBlock *fib,
- struct MinList *DirList)
- {
- static struct FileInfoBlock __aligned DirFib;
- struct DirEntry *aktdir;
- BOOL found = FALSE;
-
- ASSERT_VALID(Info);
- ASSERT_VALID(fib);
- ASSERT_VALID(DirList);
-
- if (IsListEmpty((struct List *) DirList) || Info->nfi_Opt->bo_IncludeFile.RawName[0] == '\0')
- return FALSE;
-
- aktdir = (struct DirEntry *) DirList->mlh_Head; // erster Eintrag in der Liste
-
- if (!aktdir->Done)
- {
- if (aktdir->Virgin)
- {
- SetupNewDir(Info, Info->nfi_Opt->bo_IncludeFile.RawName, aktdir);
- if (Info->nfi_DirDisplay)
- (*Info->nfi_DirDisplay)(aktdir);
-
- found = Examine(Info->nfi_DirLock, &DirFib); // Liefert immer das aktuelle Directory
-
- #if USE_EXALL
- // ein neuer ExAll() Scan beginnt hier (neues Directory)
- Info->nfi_eaControl->eac_LastKey = 0;
- ExAllNFInfo(Info, ED_COMMENT);
- #endif
- *fib = DirFib;
-
- if (found)
- {
- if (FileMatch(Info->nfi_Opt, fib, Info->nfi_TellSkips))
- {
- fib->fib_FileName[0] = '\0'; // Name des Directories steckt schon in AktPath
- found = TRUE;
-
- return found;
- }
- else
- found = NFExNext(Info, fib);
- }
-
- aktdir->Done |= !found;
- }
- else if (Info->nfi_DirLock)
- found = NFExNext(Info, fib);
-
- if (found)
- aktdir->Contents++;
-
- // Subdirectories und nicht ausgewählte Files überspringen :
- // Link-Dir's (Soft oder Hard) werden je nach den Flags bo_SaveSoftLinks
- // und bo_SaveHardLinks behandelt. Ist das entsprechende Flag gesetzt,
- // dann werden die Links als Files behandelt.
-
- while (found && !NextFileAbort && ( !FibIsFile(fib, Info->nfi_DirLock)
- || !FileMatch(Info->nfi_Opt, fib, Info->nfi_TellSkips) ))
- {
- if (Info->nfi_Opt->bo_IncludeSubDirs && fib->fib_DirEntryType > 0)
- // Subdirectories nicht zurückmelden, sondern merken
- {
- NewSubDir(aktdir, fib->fib_FileName, 1);
- }
- found = NFExNext(Info, fib);
-
- chkinput();
- }
-
- aktdir->Done |= !found;
- }
-
- if (!found && !NextFileAbort && !IsListEmpty((struct List *) &aktdir->Sub))
- {
- // Subdirectories von aktdir durchsuchen
- found = NextDEFile(Info, fib, &aktdir->Sub);
- }
-
- if (!found && !NextFileAbort && !IsListEmpty((struct List *) DirList))
- {
- DeleteDirEntry(aktdir);
- found = NextDEFile(Info, fib, DirList);
- }
-
- return found;
- }
-
-
-
- static struct DirEntry *NewSubDir(struct DirEntry *Parent, const char *name, BOOL temp)
- {
- struct DirEntry *akt;
-
- ASSERT_VALID(Parent);
- ASSERT_VALID(name);
-
- akt = NewDir(&Parent->Sub, name, temp);
- akt->Root = Parent;
-
- return akt;
- }
-
-
- BOOL FSFileMatch(struct BackupOptions *Opt, const struct FSDirEntry *FSe)
- {
- struct FileInfoBlock fib;
-
- ASSERT_VALID(Opt);
- ASSERT_VALID(FSe);
-
- fib.fib_Size = FSe->fse_Size;
- fib.fib_Protection = FSe->fse_Protection;
- fib.fib_Date = FSe->fse_Date;
- stccpy(fib.fib_FileName, FSe->fse_Name, sizeof(fib.fib_FileName));
-
- InitSearchPattern(Opt);
-
- return FileMatch(Opt, &fib, FALSE);
- }
-
-
- static BOOL FileMatch(struct BackupOptions *Opt, struct FileInfoBlock *fib, BOOL TellSkips)
- {
- char SkippedPath[FMSIZE];
- ASSERT_VALID(Opt);
- ASSERT_VALID(fib);
-
- // Protokollfile hier nicht mitsichern !
- if (isProtFile(NormalizedAktPath, fib->fib_FileName))
- {
- stccpy(SkippedPath, NormalizedAktPath, sizeof(SkippedPath));
- AddPart(SkippedPath, fib->fib_FileName, sizeof(SkippedPath));
-
- if (TellSkips)
- PostError(TRUE, MSGPRI_Info, GetString(MSG_FILE_SKIPPED), SkippedPath);
- return FALSE;
- }
-
- // DiskSave-File auch nicht mitsichern
- if (isDiskSaveFile(NormalizedAktPath, fib->fib_FileName))
- {
- stccpy(SkippedPath, NormalizedAktPath, sizeof(SkippedPath));
- AddPart(SkippedPath, fib->fib_FileName, sizeof(SkippedPath));
-
- if (TellSkips)
- PostError(TRUE, MSGPRI_Info, GetString(MSG_FILE_SKIPPED), SkippedPath);
- return FALSE;
- }
-
- if (Opt->bo_UseGrepPattern && Opt->bo_IncludeFile.isParsed)
- {
- if (!MatchPatternNoCase(Opt->bo_IncludeFile.ParsedPattern, fib->fib_FileName))
- return FALSE;
- }
- else
- {
- if (!FileNamePatternMatch(Opt->bo_IncludeFile.RawName, fib))
- return FALSE;
- }
-
- // hier evtl. abkürzen, da meist sowieso bo_ExcludeFile leer ist!
- if (Opt->bo_ExcludeFile.RawName[0])
- {
- if (Opt->bo_UseGrepPattern && Opt->bo_ExcludeFile.isParsed)
- {
- if (MatchPatternNoCase(Opt->bo_ExcludeFile.ParsedPattern, fib->fib_FileName))
- return FALSE;
- }
- else
- {
- if (FileNamePatternMatch(Opt->bo_ExcludeFile.RawName, fib))
- return FALSE;
- }
- }
-
- if (Opt->bo_UseArc == Set && !(fib->fib_Protection & FIBF_ARCHIVE))
- return FALSE;
-
- if (Opt->bo_UseArc == Reset && (fib->fib_Protection & FIBF_ARCHIVE))
- return FALSE;
-
- if ( Opt->bo_UseFirstDate && (fib->fib_Date.ds_Days < Opt->bo_FirstDate))
- return FALSE;
-
- if ( Opt->bo_UseLastDate && (fib->fib_Date.ds_Days > Opt->bo_LastDate))
- return FALSE;
-
- return TRUE;
- }
-
-
- // liefert TRUE wenn info->fib_FileName mit suchname übereinstimmt
- BOOL FileNamePatternMatch(char *suchname, const struct FileInfoBlock *info)
- {
- BOOL cmperg = TRUE;
- const char *fnp;
- char c;
-
- ASSERT_VALID(info);
- ASSERT_VALID0(suchname);
-
- if (suchname == NULL || *suchname == '\0')
- return FALSE; // nichts finden bei leerem Pattern
-
- fnp = info->fib_FileName;
- while ( (c = *suchname) && cmperg)
- {
- ++suchname;
-
- switch (c)
- {
- case '?':
- if (*fnp)
- fnp++;
- break;
- case '*':
- if (*suchname == '\0')
- {
- // Ans Ende des Namens
- while (*fnp)
- fnp++;
- }
- else
- {
- const char *found;
- char *str;
- char origc;
-
- // Zeichen zählen in suchname bis zum Ende oder bis
- // zum nächsten Wildcard
- for (str=suchname; *str && *str != '?' && *str != '*'; str++);
- origc = *str;
- *str = '\0'; // Suchstring provisorisch abschließen
-
- found = myindex(fnp, suchname);
-
- if (found)
- {
- // Weiter ab Ende des gefundenen Stücks
- fnp = found + strlen(suchname);
- suchname = str;
- }
- else
- cmperg = FALSE; // nicht gefunden !
-
- *str = origc; // Suchname restaurieren
- }
- break;
- default:
- cmperg &= toupper(c) == toupper(*fnp);
- fnp++;
- }
- }
-
- // Name muß auch zu Ende sein !
- if (*fnp)
- cmperg = FALSE;
-
- return cmperg;
- }
-
-
- const char *myindex(const char *s, const char *t)
- {
- short i, j, k;
-
- ASSERT_VALID(s);
- ASSERT_VALID(t);
-
- for (i=0; s[i]; i++)
- {
- for (j=i, k=0; t[k] && toupper(s[j]) == toupper(t[k]); j++, k++);
- if (t[k] == '\0')
- return &s[i];
- }
- return NULL;
- }
-
-
- static BOOL FibIsFile(const struct FileInfoBlock *fib, BPTR DirLock)
- {
- BOOL result;
-
- ASSERT_VALID(fib);
- ASSERT_VALID(BADDR(DirLock));
-
- switch (fib->fib_DirEntryType)
- {
- case ST_SOFTLINK:
- result = myOptions.bo_SaveSoftLinks ?
- (SoftLinkType((STRPTR) fib->fib_FileName, DirLock) == SoftLinkFile) : 1;
- break;
- case ST_LINKFILE:
- result = 1;
- break;
- case ST_LINKDIR:
- result = !myOptions.bo_SaveHardLinks;
- break;
- default:
- result = fib->fib_DirEntryType < 0;
- }
-
- return result;
- }
-
-
- static BOOL NFExNext(struct NextFileInfo *nfInfo, struct FileInfoBlock *fib)
- {
- BOOL found;
-
- #if USE_EXALL
- found = FALSE;
-
- while (NULL == nfInfo->nfi_eaData && nfInfo->nfi_eaMore)
- {
- ExAllNFInfo(nfInfo, ED_COMMENT);
- }
-
- if (nfInfo->nfi_eaData)
- {
- // die gefundenen Werte werden in den FileInfoBlock eingetragen
-
- if (nfInfo->nfi_eaData->ed_Comment)
- stccpy(fib->fib_Comment, nfInfo->nfi_eaData->ed_Comment, sizeof(fib->fib_Comment));
- else
- strcpy(fib->fib_Comment, "");
-
- stccpy(fib->fib_FileName, nfInfo->nfi_eaData->ed_Name, sizeof(fib->fib_FileName));
-
- fib->fib_Protection = nfInfo->nfi_eaData->ed_Prot;
- fib->fib_Size = nfInfo->nfi_eaData->ed_Size;
- fib->fib_DirEntryType = nfInfo->nfi_eaData->ed_Type;
-
- fib->fib_Date.ds_Days = nfInfo->nfi_eaData->ed_Days;
- fib->fib_Date.ds_Minute = nfInfo->nfi_eaData->ed_Mins;
- fib->fib_Date.ds_Tick = nfInfo->nfi_eaData->ed_Ticks;
-
- found = TRUE;
-
- nfInfo->nfi_eaData = nfInfo->nfi_eaData->ed_Next;
- }
- #else
- found = ExNext(nfInfo->nfi_DirLock, fib);
- #endif
-
- return found;
- }
-
-
- void ExAllNFInfo(struct NextFileInfo *NFInfo, long ExAllType)
- {
- NFInfo->nfi_eaMore = ExAll(NFInfo->nfi_DirLock, NFInfo->nfi_eaBuffer,
- EXALL_BUFFSIZE, ExAllType, NFInfo->nfi_eaControl);
-
- NFInfo->nfi_eaData = NFInfo->nfi_eaControl->eac_Entries ? (struct ExAllData *) NFInfo->nfi_eaBuffer : NULL;
- }
-