2 * Copyright (C) 1994-2002, Index Data
5 * $Id: trav.c,v 1.39 2002-04-04 20:50:37 adam Exp $
11 #include <sys/types.h>
15 #define S_ISREG(x) (x & _S_IFREG)
16 #define S_ISDIR(x) (x & _S_IFDIR)
26 static int repComp (const char *a, const char *b, size_t len)
30 return memcmp (a, b, len);
33 static void repositoryExtractR (ZebraHandle zh, int deleteFlag, char *rep,
34 struct recordGroup *rGroup,
39 size_t rep_len = strlen (rep);
41 e = dir_open (rep, zh->path_reg);
44 logf (LOG_LOG, "dir %s", rep);
45 if (rep[rep_len-1] != '/')
50 for (i=0; e[i].name; i++)
53 strcpy (rep +rep_len+1, e[i].name);
54 if ((ecp = strrchr (e[i].name, '/')))
56 if (level == 0 && rGroup->databaseNamePath)
57 rGroup->databaseName = e[i].name;
62 fileExtract (zh, NULL, rep, rGroup, deleteFlag);
65 repositoryExtractR (zh, deleteFlag, rep, rGroup, level+1);
73 static void fileDeleteR (ZebraHandle zh,
74 struct dirs_info *di, struct dirs_entry *dst,
75 const char *base, char *src,
76 struct recordGroup *rGroup)
79 size_t src_len = strlen (src);
81 while (dst && !repComp (dst->path, src, src_len+1))
86 sprintf (tmppath, "%s%s", base, dst->path);
87 fileExtract (zh, &dst->sysno, tmppath, rGroup, 1);
89 strcpy (tmppath, dst->path);
91 dirs_del (di, tmppath);
94 strcpy (tmppath, dst->path);
96 dirs_rmdir (di, tmppath);
104 static void fileUpdateR (ZebraHandle zh,
105 struct dirs_info *di, struct dirs_entry *dst,
106 const char *base, char *src,
107 struct recordGroup *rGroup,
110 struct dir_entry *e_src;
112 static char tmppath[1024];
113 size_t src_len = strlen (src);
115 sprintf (tmppath, "%s%s", base, src);
116 e_src = dir_open (tmppath, zh->path_reg);
117 logf (LOG_LOG, "dir %s", tmppath);
120 if (!dst || repComp (dst->path, src, src_len))
122 if (!dst || strcmp (dst->path, src))
128 if (src_len && src[src_len-1] != '/')
131 src[++src_len] = '\0';
133 dirs_mkdir (di, src, 0);
134 if (dst && repComp (dst->path, src, src_len))
139 strcpy (src, dst->path);
140 fileDeleteR (zh, di, dst, base, src, rGroup);
145 if (src_len && src[src_len-1] != '/')
148 src[++src_len] = '\0';
150 dst = dirs_read (di);
158 if (dst && !repComp (dst->path, src, src_len))
160 if (e_src[i_src].name)
162 logf (LOG_DEBUG, "dst=%s src=%s", dst->path + src_len,
164 sd = strcmp (dst->path + src_len, e_src[i_src].name);
169 else if (e_src[i_src].name)
173 logf (LOG_DEBUG, "trav sd=%d", sd);
175 if (level == 0 && rGroup->databaseNamePath)
176 rGroup->databaseName = e_src[i_src].name;
179 strcpy (src + src_len, e_src[i_src].name);
180 sprintf (tmppath, "%s%s", base, src);
182 switch (e_src[i_src].kind)
185 if (e_src[i_src].mtime > dst->mtime)
187 if (fileExtract (zh, &dst->sysno, tmppath, rGroup, 0))
189 dirs_add (di, src, dst->sysno, e_src[i_src].mtime);
191 logf (LOG_DEBUG, "old: %s", ctime (&dst->mtime));
192 logf (LOG_DEBUG, "new: %s", ctime (&e_src[i_src].mtime));
194 dst = dirs_read (di);
197 fileUpdateR (zh, di, dst, base, src, rGroup, level+1);
198 dst = dirs_last (di);
199 logf (LOG_DEBUG, "last is %s", dst ? dst->path : "null");
202 dst = dirs_read (di);
209 strcpy (src + src_len, e_src[i_src].name);
210 sprintf (tmppath, "%s%s", base, src);
212 switch (e_src[i_src].kind)
215 if (fileExtract (zh, &sysno, tmppath, rGroup, 0))
216 dirs_add (di, src, sysno, e_src[i_src].mtime);
219 fileUpdateR (zh, di, dst, base, src, rGroup, level+1);
221 dst = dirs_last (di);
228 strcpy (src, dst->path);
229 sprintf (tmppath, "%s%s", base, dst->path);
234 fileExtract (zh, &dst->sysno, tmppath, rGroup, 1);
235 dirs_del (di, dst->path);
236 dst = dirs_read (di);
239 fileDeleteR (zh, di, dst, base, src, rGroup);
240 dst = dirs_last (di);
247 static void groupRes (ZebraHandle zh, struct recordGroup *rGroup)
252 if (!rGroup->groupName || !*rGroup->groupName)
255 sprintf (gPrefix, "%s.", rGroup->groupName);
257 sprintf (resStr, "%srecordId", gPrefix);
258 rGroup->recordId = res_get (zh->res, resStr);
259 sprintf (resStr, "%sdatabasePath", gPrefix);
260 rGroup->databaseNamePath =
261 atoi (res_get_def (zh->res, resStr, "0"));
264 void repositoryShow (ZebraHandle zh)
267 struct recordGroup *rGroup = &zh->rGroup;
270 struct dirs_entry *dst;
272 struct dirs_info *di;
274 if (!(dict = dict_open (zh->reg->bfs, FMATCH_DICT, 50, 0, 0)))
276 logf (LOG_FATAL, "dict_open fail of %s", FMATCH_DICT);
280 assert (rGroup->path);
281 strcpy (src, rGroup->path);
282 src_len = strlen (src);
284 if (src_len && src[src_len-1] != '/')
287 src[++src_len] = '\0';
290 di = dirs_open (dict, src, rGroup->flagRw);
292 while ( (dst = dirs_read (di)) )
293 logf (LOG_LOG, "%s", dst->path);
298 static void fileUpdate (ZebraHandle zh,
299 Dict dict, struct recordGroup *rGroup,
302 struct dirs_info *di;
310 if (zh->path_reg && !yaz_is_abspath(path))
312 strcpy (src, zh->path_reg);
321 src_len = strlen (src);
323 if (S_ISREG(sbuf.st_mode))
325 struct dirs_entry *e_dst;
326 di = dirs_fopen (dict, src);
328 e_dst = dirs_read (di);
331 if (sbuf.st_mtime > e_dst->mtime)
332 if (fileExtract (zh, &e_dst->sysno, src, rGroup, 0))
333 dirs_add (di, src, e_dst->sysno, sbuf.st_mtime);
338 if (fileExtract (zh, &sysno, src, rGroup, 0))
339 dirs_add (di, src, sysno, sbuf.st_mtime);
343 else if (S_ISDIR(sbuf.st_mode))
345 if (src_len && src[src_len-1] != '/')
348 src[++src_len] = '\0';
350 di = dirs_open (dict, src, rGroup->flagRw);
352 fileUpdateR (zh, di, dirs_read (di), src, dst, rGroup, 0);
357 logf (LOG_WARN, "Ignoring path %s", src);
362 static void repositoryExtract (ZebraHandle zh,
363 int deleteFlag, struct recordGroup *rGroup,
371 if (zh->path_reg && !yaz_is_abspath(path))
373 strcpy (src, zh->path_reg);
383 if (S_ISREG(sbuf.st_mode))
384 fileExtract (zh, NULL, src, rGroup, deleteFlag);
385 else if (S_ISDIR(sbuf.st_mode))
386 repositoryExtractR (zh, deleteFlag, src, rGroup, 0);
388 logf (LOG_WARN, "Ignoring path %s", src);
391 static void repositoryExtractG (ZebraHandle zh,
392 int deleteFlag, struct recordGroup *rGroup)
394 if (*rGroup->path == '\0' || !strcmp(rGroup->path, "-"))
398 while (scanf ("%1020s", src) == 1)
399 repositoryExtract (zh, deleteFlag, rGroup, src);
402 repositoryExtract (zh, deleteFlag, rGroup, rGroup->path);
405 void repositoryUpdate (ZebraHandle zh)
407 struct recordGroup *rGroup = &zh->rGroup;
408 groupRes (zh, rGroup);
409 assert (rGroup->path);
410 if (rGroup->recordId && !strcmp (rGroup->recordId, "file"))
413 if (!(dict = dict_open (zh->reg->bfs, FMATCH_DICT, 50,
416 logf (LOG_FATAL, "dict_open fail of %s", FMATCH_DICT);
419 if (*rGroup->path == '\0' || !strcmp(rGroup->path, "-"))
422 while (scanf ("%s", src) == 1)
423 fileUpdate (zh, dict, rGroup, src);
426 fileUpdate (zh, dict, rGroup, rGroup->path);
430 repositoryExtractG (zh, 0, rGroup);
433 void repositoryDelete (ZebraHandle zh)
435 repositoryExtractG (zh, 1, &zh->rGroup);