+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)