1 /* $Id: trav.c,v 1.42 2003-03-25 19:56:01 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
25 #include <sys/types.h>
28 #define S_ISREG(x) (x & _S_IFREG)
29 #define S_ISDIR(x) (x & _S_IFDIR)
39 static int repComp (const char *a, const char *b, size_t len)
43 return memcmp (a, b, len);
46 static void repositoryExtractR (ZebraHandle zh, int deleteFlag, char *rep,
47 struct recordGroup *rGroup,
52 size_t rep_len = strlen (rep);
54 e = dir_open (rep, zh->path_reg, rGroup->followLinks);
57 logf (LOG_LOG, "dir %s", rep);
58 if (rep[rep_len-1] != '/')
63 for (i=0; e[i].name; i++)
66 strcpy (rep +rep_len+1, e[i].name);
67 if ((ecp = strrchr (e[i].name, '/')))
69 if (level == 0 && rGroup->databaseNamePath)
70 rGroup->databaseName = e[i].name;
75 fileExtract (zh, NULL, rep, rGroup, deleteFlag);
78 repositoryExtractR (zh, deleteFlag, rep, rGroup, level+1);
86 static void fileDeleteR (ZebraHandle zh,
87 struct dirs_info *di, struct dirs_entry *dst,
88 const char *base, char *src,
89 struct recordGroup *rGroup)
92 size_t src_len = strlen (src);
94 while (dst && !repComp (dst->path, src, src_len+1))
99 sprintf (tmppath, "%s%s", base, dst->path);
100 fileExtract (zh, &dst->sysno, tmppath, rGroup, 1);
102 strcpy (tmppath, dst->path);
103 dst = dirs_read (di);
104 dirs_del (di, tmppath);
107 strcpy (tmppath, dst->path);
108 dst = dirs_read (di);
109 dirs_rmdir (di, tmppath);
112 dst = dirs_read (di);
117 static void fileUpdateR (ZebraHandle zh,
118 struct dirs_info *di, struct dirs_entry *dst,
119 const char *base, char *src,
120 struct recordGroup *rGroup,
123 struct dir_entry *e_src;
125 static char tmppath[1024];
126 size_t src_len = strlen (src);
128 sprintf (tmppath, "%s%s", base, src);
129 e_src = dir_open (tmppath, zh->path_reg, rGroup->followLinks);
130 logf (LOG_LOG, "dir %s", tmppath);
133 if (!dst || repComp (dst->path, src, src_len))
135 if (!dst || strcmp (dst->path, src))
141 if (src_len && src[src_len-1] != '/')
144 src[++src_len] = '\0';
146 dirs_mkdir (di, src, 0);
147 if (dst && repComp (dst->path, src, src_len))
152 strcpy (src, dst->path);
153 fileDeleteR (zh, di, dst, base, src, rGroup);
158 if (src_len && src[src_len-1] != '/')
161 src[++src_len] = '\0';
163 dst = dirs_read (di);
171 if (dst && !repComp (dst->path, src, src_len))
173 if (e_src[i_src].name)
175 logf (LOG_DEBUG, "dst=%s src=%s", dst->path + src_len,
177 sd = strcmp (dst->path + src_len, e_src[i_src].name);
182 else if (e_src[i_src].name)
186 logf (LOG_DEBUG, "trav sd=%d", sd);
188 if (level == 0 && rGroup->databaseNamePath)
189 rGroup->databaseName = e_src[i_src].name;
192 strcpy (src + src_len, e_src[i_src].name);
193 sprintf (tmppath, "%s%s", base, src);
195 switch (e_src[i_src].kind)
198 if (e_src[i_src].mtime > dst->mtime)
200 if (fileExtract (zh, &dst->sysno, tmppath, rGroup, 0))
202 dirs_add (di, src, dst->sysno, e_src[i_src].mtime);
204 logf (LOG_DEBUG, "old: %s", ctime (&dst->mtime));
205 logf (LOG_DEBUG, "new: %s", ctime (&e_src[i_src].mtime));
207 dst = dirs_read (di);
210 fileUpdateR (zh, di, dst, base, src, rGroup, level+1);
211 dst = dirs_last (di);
212 logf (LOG_DEBUG, "last is %s", dst ? dst->path : "null");
215 dst = dirs_read (di);
222 strcpy (src + src_len, e_src[i_src].name);
223 sprintf (tmppath, "%s%s", base, src);
225 switch (e_src[i_src].kind)
228 if (fileExtract (zh, &sysno, tmppath, rGroup, 0))
229 dirs_add (di, src, sysno, e_src[i_src].mtime);
232 fileUpdateR (zh, di, dst, base, src, rGroup, level+1);
234 dst = dirs_last (di);
241 strcpy (src, dst->path);
242 sprintf (tmppath, "%s%s", base, dst->path);
247 fileExtract (zh, &dst->sysno, tmppath, rGroup, 1);
248 dirs_del (di, dst->path);
249 dst = dirs_read (di);
252 fileDeleteR (zh, di, dst, base, src, rGroup);
253 dst = dirs_last (di);
260 static void groupRes (ZebraHandle zh, struct recordGroup *rGroup)
265 if (!rGroup->groupName || !*rGroup->groupName)
268 sprintf (gPrefix, "%s.", rGroup->groupName);
270 sprintf (resStr, "%srecordId", gPrefix);
271 rGroup->recordId = res_get (zh->res, resStr);
272 sprintf (resStr, "%sdatabasePath", gPrefix);
273 rGroup->databaseNamePath =
274 atoi (res_get_def (zh->res, resStr, "0"));
276 rGroup->databaseNamePath =
277 atoi (res_get_def (zh->res, resStr, "0"));
279 if (rGroup->followLinks == -1)
281 sprintf (resStr, "%sfollowLinks", gPrefix);
282 rGroup->followLinks =
283 atoi (res_get_def (zh->res, resStr, "1"));
287 void repositoryShow (ZebraHandle zh)
290 struct recordGroup *rGroup = &zh->rGroup;
293 struct dirs_entry *dst;
295 struct dirs_info *di;
297 if (!(dict = dict_open (zh->reg->bfs, FMATCH_DICT, 50, 0, 0)))
299 logf (LOG_FATAL, "dict_open fail of %s", FMATCH_DICT);
303 assert (rGroup->path);
304 strcpy (src, rGroup->path);
305 src_len = strlen (src);
307 if (src_len && src[src_len-1] != '/')
310 src[++src_len] = '\0';
313 di = dirs_open (dict, src, rGroup->flagRw);
315 while ( (dst = dirs_read (di)) )
316 logf (LOG_LOG, "%s", dst->path);
321 static void fileUpdate (ZebraHandle zh,
322 Dict dict, struct recordGroup *rGroup,
325 struct dirs_info *di;
333 if (zh->path_reg && !yaz_is_abspath(path))
335 strcpy (src, zh->path_reg);
341 zebra_file_stat (src, &sbuf, rGroup->followLinks);
344 src_len = strlen (src);
346 if (S_ISREG(sbuf.st_mode))
348 struct dirs_entry *e_dst;
349 di = dirs_fopen (dict, src);
351 e_dst = dirs_read (di);
354 if (sbuf.st_mtime > e_dst->mtime)
355 if (fileExtract (zh, &e_dst->sysno, src, rGroup, 0))
356 dirs_add (di, src, e_dst->sysno, sbuf.st_mtime);
361 if (fileExtract (zh, &sysno, src, rGroup, 0))
362 dirs_add (di, src, sysno, sbuf.st_mtime);
366 else if (S_ISDIR(sbuf.st_mode))
368 if (src_len && src[src_len-1] != '/')
371 src[++src_len] = '\0';
373 di = dirs_open (dict, src, rGroup->flagRw);
375 fileUpdateR (zh, di, dirs_read (di), src, dst, rGroup, 0);
380 logf (LOG_WARN, "Ignoring path %s", src);
385 static void repositoryExtract (ZebraHandle zh,
386 int deleteFlag, struct recordGroup *rGroup,
394 if (zh->path_reg && !yaz_is_abspath(path))
396 strcpy (src, zh->path_reg);
402 zebra_file_stat (src, &sbuf, rGroup->followLinks);
406 if (S_ISREG(sbuf.st_mode))
407 fileExtract (zh, NULL, src, rGroup, deleteFlag);
408 else if (S_ISDIR(sbuf.st_mode))
409 repositoryExtractR (zh, deleteFlag, src, rGroup, 0);
411 logf (LOG_WARN, "Ignoring path %s", src);
414 static void repositoryExtractG (ZebraHandle zh,
415 int deleteFlag, struct recordGroup *rGroup)
417 if (*rGroup->path == '\0' || !strcmp(rGroup->path, "-"))
421 while (scanf ("%1020s", src) == 1)
422 repositoryExtract (zh, deleteFlag, rGroup, src);
425 repositoryExtract (zh, deleteFlag, rGroup, rGroup->path);
428 void repositoryUpdate (ZebraHandle zh)
430 struct recordGroup *rGroup = &zh->rGroup;
431 groupRes (zh, rGroup);
432 assert (rGroup->path);
433 if (rGroup->recordId && !strcmp (rGroup->recordId, "file"))
436 if (!(dict = dict_open (zh->reg->bfs, FMATCH_DICT, 50,
439 logf (LOG_FATAL, "dict_open fail of %s", FMATCH_DICT);
442 if (*rGroup->path == '\0' || !strcmp(rGroup->path, "-"))
445 while (scanf ("%s", src) == 1)
446 fileUpdate (zh, dict, rGroup, src);
449 fileUpdate (zh, dict, rGroup, rGroup->path);
453 repositoryExtractG (zh, 0, rGroup);
456 void repositoryDelete (ZebraHandle zh)
458 struct recordGroup *rGroup = &zh->rGroup;
459 groupRes (zh, rGroup);
460 assert (rGroup->path);
461 repositoryExtractG (zh, 1, rGroup);