home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR3 / EQTREE.ZIP / TREELOAD.C < prev    next >
C/C++ Source or Header  |  1994-01-18  |  6KB  |  278 lines

  1. /*
  2.  * TREELOAD.c
  3.  *
  4.  * Routinen zum einlesen und Bearbeiten von
  5.  * Verzeichnisbäumen.
  6.  *
  7.  * Autor: SG
  8.  * Stand: 25.1.93
  9.  *
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14.  
  15. #define INCL_BASE
  16. #define INCL_DOS
  17. #define INCL_NOPM
  18. #include <os2.h>
  19. #include <stdlib.h>
  20. #include <direct.h>
  21. #include <ctype.h>
  22.  
  23. #include "logfile.h"
  24. #include "treeload.h"
  25.  
  26. static unsigned long Date2Days(FDATE date)
  27. {
  28.     return date.year * 365 + date.month *31 + date.day;
  29. }
  30.  
  31. static unsigned long Time2Secs(FTIME time)
  32. {
  33.     return time.hours * 3600l + time.minutes * 60 + time.twosecs * 2;
  34. }
  35.  
  36. int TRFree(TRTree *tree)
  37. {
  38.     TREntry *help;
  39.  
  40.     if (tree)
  41.     {
  42.     if (tree->Entries)
  43.     {
  44.         while (tree->Entries)
  45.         {
  46.         help = tree->Entries;
  47.         tree->Entries = tree->Entries->next;
  48.         free(help);
  49.         }
  50.     }
  51.     else
  52.     {
  53.         free(tree);
  54.         return 0;
  55.     }
  56.     free(tree);
  57.     return 1;
  58.     }
  59.     return 0;
  60. }
  61.  
  62. static TRTree *TRMalloc(void)
  63. {
  64.     TRTree *work = (TRTree *)malloc(sizeof(TRTree));
  65.  
  66.     if (work == NULL)
  67.     return NULL;
  68.  
  69.     work->Entries = NULL;
  70.     work->EntryCount = 0;
  71.     work->LastPos = NULL;
  72.     work->Base = NULL;
  73.     work->BaseLen = 0;
  74.     return work;
  75. }
  76.  
  77. int TRIsDir(TREntry *entry)
  78. {   return entry->Attrib & FILE_DIRECTORY; }
  79.  
  80. static char *TRDate2Str(FDATE date)
  81. {
  82.     static char buf[20];
  83.  
  84.     sprintf(buf,"%d.%d.%d",date.day,date.month,date.year+1980);
  85.     return buf;
  86. }
  87.  
  88. static TREntry *TRAddEntry(TRTree *tree,PFILEFINDBUF findbuf,const char *Root)
  89. {
  90.     register TREntry *entry;
  91.  
  92.     entry = malloc(sizeof(TREntry));
  93.     if (entry == NULL)
  94.     ERFatal("Not enough memory for tree");
  95.     entry->File = malloc(strlen(Root)+strlen(findbuf->achName)+1+1);
  96.     if (entry->File == NULL)
  97.     {
  98.     free(entry);
  99.     ERFatal("Not enough memory for tree");
  100.     }
  101.     strcpy(entry->File,(char *)Root);
  102.     strcat(entry->File,"\\");
  103.     strcat(entry->File,findbuf->achName);
  104.     entry->Attrib = findbuf->attrFile;
  105.     entry->Date   = findbuf->fdateLastWrite;
  106.     entry->Time   = findbuf->ftimeLastWrite;
  107.     entry->next   = NULL;
  108.  
  109.     if (TRIsDir(entry))
  110.        fprintf(stdout,"%s %s  \r",entry->File,TRDate2Str(entry->Date));
  111.  
  112.     entry->next = tree->Entries;
  113.     tree->Entries = entry;
  114.  
  115.     tree->EntryCount++;
  116.  
  117.     return entry;
  118. }
  119.  
  120. int TRRecLoad(TRTree *tree,char *Root)
  121. {
  122.     register int fresult;
  123.     HDIR     DirHandle = HDIR_CREATE;
  124.     FILEFINDBUF  findbuf;
  125.     USHORT     Search;
  126.  
  127.     if (Root[1] == ':')
  128.     if (_chdrive(toupper(Root[0])-'A'+1)!=0)
  129.         ERFatal("Can't change to drive %c:",toupper(Root[0]));
  130.  
  131.     if ((strlen(Root)==2) && (Root[1]==':'))
  132.     chdir("\\");
  133.     else
  134.     if (chdir(Root)!=0)
  135.        ERFatal("Can't change directory to '%s'",Root);
  136.  
  137.     Search = 1;
  138.     fresult = DosFindFirst("*",&DirHandle,
  139.         FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED,
  140.         &findbuf,sizeof(findbuf),&Search,0);
  141.  
  142.     while (fresult==0)
  143.     {
  144.     if (*findbuf.achName != '.')
  145.     {
  146.         register TREntry *newentry;
  147.  
  148.         newentry = TRAddEntry(tree,&findbuf,Root);
  149.         if (findbuf.attrFile & FILE_DIRECTORY)
  150.         {
  151.         TRRecLoad(tree,newentry->File);
  152.         }
  153.     }
  154.     fresult = DosFindNext(DirHandle,&findbuf,sizeof(findbuf),&Search);
  155.     }
  156.     DosFindClose(DirHandle);
  157.     return 1;
  158. }
  159.  
  160. TRTree *TRLoadTree(const char *Directory)
  161. {
  162.     TRTree *work;
  163.  
  164.     LOItem("Scanning directorytree of '%s'",Directory);
  165.  
  166.     if ((work = TRMalloc())==NULL)
  167.     {
  168.     ERFatal("Not enough memory for tree");
  169.     return NULL;
  170.     }
  171.     work->Base = Directory;
  172.     work->BaseLen = strlen(Directory);
  173.     if (TRRecLoad(work,(char *)Directory))
  174.     {
  175.     LOItem("Scanned %lu entries                                    ",work->EntryCount);
  176.     return work;
  177.     }
  178.  
  179.     free(work);
  180.     return NULL;
  181. }
  182.  
  183. static TREntry    *TRSearch(TRTree *tree,char *File,size_t Base2)
  184. {
  185.     register TREntry *walk;
  186.  
  187.     if (tree->LastPos)
  188.     walk = tree->LastPos;
  189.     else
  190.     walk = tree->Entries;
  191.  
  192.     while (walk)
  193.     {
  194.     if (strcmp(walk->File+tree->BaseLen,File+Base2)==0)
  195.     {
  196.         tree->LastPos = walk->next;
  197.         return walk;
  198.     }
  199.     walk = walk->next;
  200.     }
  201.     tree->LastPos = NULL;
  202.     return NULL;
  203. }
  204.  
  205. extern unsigned long    Date2Days(FDATE date);
  206. extern unsigned long    Time2Secs(FTIME time);
  207.  
  208. int DateCompare(TREntry *Source,TREntry *Dest)
  209. {
  210.     if ((Date2Days(Source->Date) == Date2Days(Dest->Date)) &&
  211.     (Time2Secs(Source->Time) == Time2Secs(Dest->Time)))
  212.     return 0;
  213.     if (Date2Days(Source->Date) == Date2Days(Dest->Date))
  214.     { /* Gleicher Tag. Vergleiche Uhrzeit */
  215.     if (Time2Secs(Source->Time) > Time2Secs(Dest->Time))
  216.         return 1;
  217.     else
  218.         return 2;
  219.     }
  220.     /* Datum ist unterschiedlich, Datumsvergleich reicht */
  221.     if (Date2Days(Source->Date) > Date2Days(Dest->Date))
  222.     return 1;
  223.     else
  224.     return 2;
  225. }
  226.  
  227. int TRForEach(TRTree *Tree,TRForEachFunc Function)
  228. {
  229.     register TREntry *walk;
  230.  
  231.     walk = Tree->Entries;
  232.     Tree->LastPos = NULL;
  233.     while (walk)
  234.     {
  235.     (*Function)(Tree,walk);
  236.     walk = walk->next;
  237.     }
  238.     return 1;
  239. }
  240.  
  241. int TRCompare(TRTree *Source,TRTree *Dest,TRFuncEntry Functions[])
  242. {
  243.     register TREntry *walk,*help;
  244.  
  245.     /* Suche aller Dateien, die in Dest noch vorhanden sind, in Source
  246.        aber nicht mehr */
  247.     walk = Dest->Entries;
  248.     Source->LastPos = NULL;
  249.     while (walk)
  250.     {
  251.     if (TRSearch(Source,walk->File,Dest->BaseLen)==NULL)
  252.         (*(Functions[TRNEWDEST]))(Source,NULL,Dest,walk);
  253.     walk = walk->next;
  254.     }
  255.     walk = Source->Entries;
  256.     Dest->LastPos = NULL;
  257.     while (walk)
  258.     {
  259.     help = TRSearch(Dest,walk->File,Source->BaseLen);
  260.     if (help == NULL)
  261.     { /* Im Zielverzeichnis ist die Datei nicht vorhanden */
  262.         (*(Functions[TRNEWSRC]))(Source,walk,Dest,NULL); /* Hack! Tree wird fuer Basis benoetigt */
  263.     }
  264.     else
  265.     {
  266.         switch (DateCompare(walk,help))
  267.         {
  268.         case 0: (*(Functions[TREQUAL]))(Source,walk,Dest,help); break;
  269.         case 1: (*(Functions[TRNEWER]))(Source,walk,Dest,help); break;
  270.         case 2: (*(Functions[TROLDER]))(Source,walk,Dest,help); break;
  271.         }
  272.     }
  273.     walk = walk->next;
  274.     }
  275.  
  276.     return 1;
  277. }
  278.