Work on new traversal.
[idzebra-moved-to-github.git] / index / trav.c
index b87dbab..faf7571 100644 (file)
@@ -4,7 +4,20 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: trav.c,v $
- * Revision 1.3  1995-09-06 16:11:18  adam
+ * Revision 1.7  1995-11-20 11:56:28  adam
+ * Work on new traversal.
+ *
+ * Revision 1.6  1995/11/17  15:54:42  adam
+ * Started work on virtual directory structure.
+ *
+ * Revision 1.5  1995/10/17  18:02:09  adam
+ * New feature: databases. Implemented as prefix to words in dictionary.
+ *
+ * Revision 1.4  1995/09/28  09:19:46  adam
+ * xfree/xmalloc used everywhere.
+ * Extract/retrieve method seems to work for text records.
+ *
+ * Revision 1.3  1995/09/06  16:11:18  adam
  * Option: only one word key per file.
  *
  * Revision 1.2  1995/09/04  12:33:43  adam
@@ -26,7 +39,7 @@
 #include <alexutil.h>
 #include "index.h"
 
-static void repository_extract_r (int cmd, char *rep)
+static void repository_extract_r (int cmd, char *rep, char *databaseName)
 {
     struct dir_entry *e;
     int i;
@@ -47,10 +60,10 @@ static void repository_extract_r (int cmd, char *rep)
         switch (fs.st_mode & S_IFMT)
         {
         case S_IFREG:
-            file_extract (cmd, rep, rep);
+            file_extract (cmd, rep, rep, databaseName);
             break;
         case S_IFDIR:
-            repository_extract_r (cmd, rep);
+            repository_extract_r (cmd, rep, databaseName);
             break;
         }
     }
@@ -74,11 +87,7 @@ void copy_file (const char *dst, const char *src)
         logf (LOG_FATAL|LOG_ERRNO, "Cannot open %s", src);
         exit (1);
     }
-    if (!(buf = malloc (4096)))
-    {
-        logf (LOG_FATAL|LOG_ERRNO, "malloc");
-        exit (1);
-    }
+    buf = xmalloc (4096);
     while ((r=read (s_fd, buf, 4096))>0)
         for (w = 0; w < r; w += i)
         {
@@ -94,7 +103,7 @@ void copy_file (const char *dst, const char *src)
         logf (LOG_FATAL|LOG_ERRNO, "read");
         exit (1);
     }
-    free (buf);
+    xfree (buf);
     close (d_fd);
     close (s_fd);
 }
@@ -111,15 +120,15 @@ void del_dir (const char *dst)
         logf (LOG_ERRNO|LOG_WARN, "rmdir");
 }
 
-void repository_update_r (int cmd, char *dst, char *src);
+void repository_update_r (int cmd, char *dst, char *src, char *databaseName);
 
-void repository_add_tree (int cmd, char *dst, char *src)
+void repository_add_tree (int cmd, char *dst, char *src, char *databaseName)
 {
     mkdir (dst, 0755);
-    repository_update_r (cmd, dst, src);
+    repository_update_r (cmd, dst, src, databaseName);
 }
 
-void repository_del_tree (int cmd, char *dst, char *src)
+void repository_del_tree (int cmd, char *dst, char *src, char *databaseName)
 {
     size_t dst_len = strlen (dst);
     size_t src_len = strlen (src);
@@ -148,11 +157,11 @@ void repository_del_tree (int cmd, char *dst, char *src)
         switch (fs_dst.st_mode & S_IFMT)
         {
         case S_IFREG:
-            file_extract ('d', dst, dst);
+            file_extract ('d', dst, dst, databaseName);
             del_file (dst);
             break;
         case S_IFDIR:
-            repository_del_tree (cmd, dst, src);
+            repository_del_tree (cmd, dst, src, databaseName);
             break;
         }
         i_dst++;
@@ -165,7 +174,7 @@ void repository_del_tree (int cmd, char *dst, char *src)
     }
 }
 
-void repository_update_r (int cmd, char *dst, char *src)
+void repository_update_r (int cmd, char *dst, char *src, char *databaseName)
 {
     struct dir_entry *e_dst, *e_src;
     int i_dst = 0, i_src = 0;
@@ -181,13 +190,13 @@ void repository_update_r (int cmd, char *dst, char *src)
     if (!e_dst)
     {
         dir_free (&e_src);
-        repository_add_tree (cmd, dst, src);
+        repository_add_tree (cmd, dst, src, databaseName);
         return;
     }
     else if (!e_src)
     {
         dir_free (&e_dst);
-        repository_del_tree (cmd, dst, src);
+        repository_del_tree (cmd, dst, src, databaseName);
         return;
     }
 
@@ -228,13 +237,13 @@ void repository_update_r (int cmd, char *dst, char *src)
             case S_IFREG:
                 if (fs_src.st_ctime > fs_dst.st_ctime)
                 {
-                    file_extract ('d', dst, dst);
-                    file_extract ('a', src, dst);
+                    file_extract ('d', dst, dst, databaseName);
+                    file_extract ('a', src, dst, databaseName);
                     copy_file (dst, src);
                 }
                 break;
             case S_IFDIR:
-                repository_update_r (cmd, dst, src);
+                repository_update_r (cmd, dst, src, databaseName);
                 break;
             }
             i_src++;
@@ -249,11 +258,11 @@ void repository_update_r (int cmd, char *dst, char *src)
             switch (fs_src.st_mode & S_IFMT)
             {
             case S_IFREG:
-                file_extract ('a', src, dst);
+                file_extract ('a', src, dst, databaseName);
                 copy_file (dst, src);
                 break;
             case S_IFDIR:
-                repository_add_tree (cmd, dst, src);
+                repository_add_tree (cmd, dst, src, databaseName);
                 break;
             }
             i_src++;
@@ -267,11 +276,11 @@ void repository_update_r (int cmd, char *dst, char *src)
             switch (fs_dst.st_mode & S_IFMT)
             {
             case S_IFREG:
-                file_extract ('d', dst, dst);
+                file_extract ('d', dst, dst, databaseName);
                 del_file (dst);
                 break;
             case S_IFDIR:
-                repository_del_tree (cmd, dst, src);
+                repository_del_tree (cmd, dst, src, databaseName);
                 break;
             }
             i_dst++;
@@ -281,7 +290,150 @@ void repository_update_r (int cmd, char *dst, char *src)
     dir_free (&e_src);
 }
 
-void repository (int cmd, const char *rep, const char *base_path)
+static int repComp (const char *a, const char *b, size_t len)
+{
+    if (!len)
+        return 0;
+    return memcmp (a, b, len);
+}
+
+static void repositoryUpdateR (struct dirs_info *di, struct dirs_entry *dst,
+                               const char *base, char *src, char *databaseName)
+{
+    struct dir_entry *e_src;
+    int i_src = 0;
+    static char tmppath[256];
+    size_t src_len = strlen (src);
+
+    sprintf (tmppath, "%s%s", base, src);
+    e_src = dir_open (tmppath);
+
+#if 1
+    if (!dst || repComp (dst->path, src, src_len))
+#else
+    if (!dst || strcmp (dst->path, src))
+#endif
+    {
+        if (!e_src)
+            return;
+#if 1
+        if (src_len && src[src_len-1] == '/')
+            --src_len;
+        else
+            src[src_len] = '/';
+        src[src_len+1] = '\0';
+#endif
+        dirs_mkdir (di, src, 0);
+        dst = NULL;
+    }
+    else if (!e_src)
+    {
+        /* delete tree dst */
+        return;
+    }
+    else
+    {
+#if 1
+        if (src_len && src[src_len-1] == '/')
+            --src_len;
+        else
+            src[src_len] = '/';
+        src[src_len+1] = '\0';
+#endif
+        dst = dirs_read (di); 
+    }
+    dir_sort (e_src);
+
+    while (1)
+    {
+        int sd;
+
+        if (dst && !repComp (dst->path, src, src_len))
+        {
+            if (e_src[i_src].name)
+            {
+                logf (LOG_DEBUG, "dst=%s src=%s", dst->path + src_len+1, 
+                     e_src[i_src].name);
+                sd = strcmp (dst->path + src_len+1, e_src[i_src].name);
+            }
+            else
+                sd = -1;
+        }
+        else if (e_src[i_src].name)
+            sd = 1;
+        else
+            break;
+        logf (LOG_DEBUG, "trav sd=%d", sd);
+        if (sd == 0)
+        {
+            strcpy (src + src_len+1, e_src[i_src].name);
+            sprintf (tmppath, "%s%s", base, src);
+            
+            switch (e_src[i_src].kind)
+            {
+            case dirs_file:
+                if (e_src[i_src].ctime > dst->ctime)
+                {
+                    file_extract ('d', tmppath, tmppath, databaseName);
+                    file_extract ('a', tmppath, tmppath, databaseName);
+                    dirs_add (di, src, dst->sysno, e_src[i_src].ctime);
+                }
+                dst = dirs_read (di); 
+                break;
+            case dirs_dir:
+                repositoryUpdateR (di, dst, base, src, databaseName);
+                dst = dirs_last (di);
+                logf (LOG_DEBUG, "last is %s", dst ? dst->path : "null");
+                break;
+            default:
+                dst = dirs_read (di); 
+            }
+            i_src++;
+        }
+        else if (sd > 0)
+        {
+            SYSNO sysno;
+            strcpy (src + src_len+1, e_src[i_src].name);
+            sprintf (tmppath, "%s%s", base, src);
+
+            switch (e_src[i_src].kind)
+            {
+            case dirs_file:
+                sysno = file_extract ('a', tmppath, tmppath, databaseName);
+                dirs_add (di, src, sysno, e_src[i_src].ctime);            
+                break;
+            case dirs_dir:
+                repositoryUpdateR (di, dst, base, src, databaseName);
+                break;
+            }
+            i_src++;
+        }
+        else  /* sd < 0 */
+        {
+            assert (0);
+        }
+    }
+    dir_free (&e_src);
+}
+
+void repositoryUpdate (const char *path, char *databaseName)
+{
+    struct dirs_info *di;
+    char src[256];
+    Dict dict;
+
+    dict = dict_open ("repdict", 40, 1);
+    
+    di = dirs_open (dict, path);
+    strcpy (src, "");
+    repositoryUpdateR (di, dirs_read (di), path, src, databaseName);
+    dirs_free (&di);
+
+    dict_close (dict);
+}
+
+void repository (int cmd, const char *rep, const char *base_path,
+                 char *databaseName)
 {
     char rep_tmp1[2048];
     char rep_tmp2[2048];
@@ -290,9 +442,9 @@ void repository (int cmd, const char *rep, const char *base_path)
     if (base_path)
     {
         strcpy (rep_tmp2, base_path);
-        repository_update_r (cmd, rep_tmp2, rep_tmp1);
+        repository_update_r (cmd, rep_tmp2, rep_tmp1, databaseName);
     }
     else
-        repository_extract_r (cmd, rep_tmp1);
+        repository_extract_r (cmd, rep_tmp1, databaseName);
 }