1 /* $Id: trav.c,v 1.40 2002-08-02 19:26:55 adam Exp $
2 Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
5 This file is part of the Zebra server.
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra. If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
28 #include <sys/types.h>
32 #define S_ISREG(x) (x & _S_IFREG)
33 #define S_ISDIR(x) (x & _S_IFDIR)
43 static int repComp (const char *a, const char *b, size_t len)
47 return memcmp (a, b, len);
50 static void repositoryExtractR (ZebraHandle zh, int deleteFlag, char *rep,
51 struct recordGroup *rGroup,
56 size_t rep_len = strlen (rep);
58 e = dir_open (rep, zh->path_reg);
61 logf (LOG_LOG, "dir %s", rep);
62 if (rep[rep_len-1] != '/')
67 for (i=0; e[i].name; i++)
70 strcpy (rep +rep_len+1, e[i].name);
71 if ((ecp = strrchr (e[i].name, '/')))
73 if (level == 0 && rGroup->databaseNamePath)
74 rGroup->databaseName = e[i].name;
79 fileExtract (zh, NULL, rep, rGroup, deleteFlag);
82 repositoryExtractR (zh, deleteFlag, rep, rGroup, level+1);
90 static void fileDeleteR (ZebraHandle zh,
91 struct dirs_info *di, struct dirs_entry *dst,
92 const char *base, char *src,
93 struct recordGroup *rGroup)
96 size_t src_len = strlen (src);
98 while (dst && !repComp (dst->path, src, src_len+1))
103 sprintf (tmppath, "%s%s", base, dst->path);
104 fileExtract (zh, &dst->sysno, tmppath, rGroup, 1);
106 strcpy (tmppath, dst->path);
107 dst = dirs_read (di);
108 dirs_del (di, tmppath);
111 strcpy (tmppath, dst->path);
112 dst = dirs_read (di);
113 dirs_rmdir (di, tmppath);
116 dst = dirs_read (di);
121 static void fileUpdateR (ZebraHandle zh,
122 struct dirs_info *di, struct dirs_entry *dst,
123 const char *base, char *src,
124 struct recordGroup *rGroup,
127 struct dir_entry *e_src;
129 static char tmppath[1024];
130 size_t src_len = strlen (src);
132 sprintf (tmppath, "%s%s", base, src);
133 e_src = dir_open (tmppath, zh->path_reg);
134 logf (LOG_LOG, "dir %s", tmppath);
137 if (!dst || repComp (dst->path, src, src_len))
139 if (!dst || strcmp (dst->path, src))
145 if (src_len && src[src_len-1] != '/')
148 src[++src_len] = '\0';
150 dirs_mkdir (di, src, 0);
151 if (dst && repComp (dst->path, src, src_len))
156 strcpy (src, dst->path);
157 fileDeleteR (zh, di, dst, base, src, rGroup);
162 if (src_len && src[src_len-1] != '/')
165 src[++src_len] = '\0';
167 dst = dirs_read (di);
175 if (dst && !repComp (dst->path, src, src_len))
177 if (e_src[i_src].name)
179 logf (LOG_DEBUG, "dst=%s src=%s", dst->path + src_len,
181 sd = strcmp (dst->path + src_len, e_src[i_src].name);
186 else if (e_src[i_src].name)
190 logf (LOG_DEBUG, "trav sd=%d", sd);
192 if (level == 0 && rGroup->databaseNamePath)
193 rGroup->databaseName = e_src[i_src].name;
196 strcpy (src + src_len, e_src[i_src].name);
197 sprintf (tmppath, "%s%s", base, src);
199 switch (e_src[i_src].kind)
202 if (e_src[i_src].mtime > dst->mtime)
204 if (fileExtract (zh, &dst->sysno, tmppath, rGroup, 0))
206 dirs_add (di, src, dst->sysno, e_src[i_src].mtime);
208 logf (LOG_DEBUG, "old: %s", ctime (&dst->mtime));
209 logf (LOG_DEBUG, "new: %s", ctime (&e_src[i_src].mtime));
211 dst = dirs_read (di);
214 fileUpdateR (zh, di, dst, base, src, rGroup, level+1);
215 dst = dirs_last (di);
216 logf (LOG_DEBUG, "last is %s", dst ? dst->path : "null");
219 dst = dirs_read (di);
226 strcpy (src + src_len, e_src[i_src].name);
227 sprintf (tmppath, "%s%s", base, src);
229 switch (e_src[i_src].kind)
232 if (fileExtract (zh, &sysno, tmppath, rGroup, 0))
233 dirs_add (di, src, sysno, e_src[i_src].mtime);
236 fileUpdateR (zh, di, dst, base, src, rGroup, level+1);
238 dst = dirs_last (di);
245 strcpy (src, dst->path);
246 sprintf (tmppath, "%s%s", base, dst->path);
251 fileExtract (zh, &dst->sysno, tmppath, rGroup, 1);
252 dirs_del (di, dst->path);
253 dst = dirs_read (di);
256 fileDeleteR (zh, di, dst, base, src, rGroup);
257 dst = dirs_last (di);
264 static void groupRes (ZebraHandle zh, struct recordGroup *rGroup)
269 if (!rGroup->groupName || !*rGroup->groupName)
272 sprintf (gPrefix, "%s.", rGroup->groupName);
274 sprintf (resStr, "%srecordId", gPrefix);
275 rGroup->recordId = res_get (zh->res, resStr);
276 sprintf (resStr, "%sdatabasePath", gPrefix);
277 rGroup->databaseNamePath =
278 atoi (res_get_def (zh->res, resStr, "0"));
281 void repositoryShow (ZebraHandle zh)
284 struct recordGroup *rGroup = &zh->rGroup;
287 struct dirs_entry *dst;
289 struct dirs_info *di;
291 if (!(dict = dict_open (zh->reg->bfs, FMATCH_DICT, 50, 0, 0)))
293 logf (LOG_FATAL, "dict_open fail of %s", FMATCH_DICT);
297 assert (rGroup->path);
298 strcpy (src, rGroup->path);
299 src_len = strlen (src);
301 if (src_len && src[src_len-1] != '/')
304 src[++src_len] = '\0';
307 di = dirs_open (dict, src, rGroup->flagRw);
309 while ( (dst = dirs_read (di)) )
310 logf (LOG_LOG, "%s", dst->path);
315 static void fileUpdate (ZebraHandle zh,
316 Dict dict, struct recordGroup *rGroup,
319 struct dirs_info *di;
327 if (zh->path_reg && !yaz_is_abspath(path))
329 strcpy (src, zh->path_reg);
338 src_len = strlen (src);
340 if (S_ISREG(sbuf.st_mode))
342 struct dirs_entry *e_dst;
343 di = dirs_fopen (dict, src);
345 e_dst = dirs_read (di);
348 if (sbuf.st_mtime > e_dst->mtime)
349 if (fileExtract (zh, &e_dst->sysno, src, rGroup, 0))
350 dirs_add (di, src, e_dst->sysno, sbuf.st_mtime);
355 if (fileExtract (zh, &sysno, src, rGroup, 0))
356 dirs_add (di, src, sysno, sbuf.st_mtime);
360 else if (S_ISDIR(sbuf.st_mode))
362 if (src_len && src[src_len-1] != '/')
365 src[++src_len] = '\0';
367 di = dirs_open (dict, src, rGroup->flagRw);
369 fileUpdateR (zh, di, dirs_read (di), src, dst, rGroup, 0);
374 logf (LOG_WARN, "Ignoring path %s", src);
379 static void repositoryExtract (ZebraHandle zh,
380 int deleteFlag, struct recordGroup *rGroup,
388 if (zh->path_reg && !yaz_is_abspath(path))
390 strcpy (src, zh->path_reg);
400 if (S_ISREG(sbuf.st_mode))
401 fileExtract (zh, NULL, src, rGroup, deleteFlag);
402 else if (S_ISDIR(sbuf.st_mode))
403 repositoryExtractR (zh, deleteFlag, src, rGroup, 0);
405 logf (LOG_WARN, "Ignoring path %s", src);
408 static void repositoryExtractG (ZebraHandle zh,
409 int deleteFlag, struct recordGroup *rGroup)
411 if (*rGroup->path == '\0' || !strcmp(rGroup->path, "-"))
415 while (scanf ("%1020s", src) == 1)
416 repositoryExtract (zh, deleteFlag, rGroup, src);
419 repositoryExtract (zh, deleteFlag, rGroup, rGroup->path);
422 void repositoryUpdate (ZebraHandle zh)
424 struct recordGroup *rGroup = &zh->rGroup;
425 groupRes (zh, rGroup);
426 assert (rGroup->path);
427 if (rGroup->recordId && !strcmp (rGroup->recordId, "file"))
430 if (!(dict = dict_open (zh->reg->bfs, FMATCH_DICT, 50,
433 logf (LOG_FATAL, "dict_open fail of %s", FMATCH_DICT);
436 if (*rGroup->path == '\0' || !strcmp(rGroup->path, "-"))
439 while (scanf ("%s", src) == 1)
440 fileUpdate (zh, dict, rGroup, src);
443 fileUpdate (zh, dict, rGroup, rGroup->path);
447 repositoryExtractG (zh, 0, rGroup);
450 void repositoryDelete (ZebraHandle zh)
452 repositoryExtractG (zh, 1, &zh->rGroup);