1 /* $Id: trav.c,v 1.50 2006-04-05 02:11:44 adam Exp $
2 Copyright (C) 1995-2005
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)
40 static int repComp (const char *a, const char *b, size_t len)
44 return memcmp (a, b, len);
47 static void repositoryExtractR (ZebraHandle zh, int deleteFlag, char *rep,
52 size_t rep_len = strlen (rep);
54 e = dir_open (rep, zh->path_reg, zh->m_follow_links);
57 yaz_log (YLOG_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, '/')))
73 zebra_extract_file (zh, NULL, rep, deleteFlag);
76 repositoryExtractR (zh, deleteFlag, rep, level+1);
84 static void fileDeleteR (ZebraHandle zh,
85 struct dirs_info *di, struct dirs_entry *dst,
86 const char *base, char *src)
89 size_t src_len = strlen (src);
91 while (dst && !repComp (dst->path, src, src_len+1))
96 sprintf (tmppath, "%s%s", base, dst->path);
97 zebra_extract_file (zh, &dst->sysno, tmppath, 1);
99 strcpy (tmppath, dst->path);
100 dst = dirs_read (di);
101 dirs_del (di, tmppath);
104 strcpy (tmppath, dst->path);
105 dst = dirs_read (di);
106 dirs_rmdir (di, tmppath);
109 dst = dirs_read (di);
114 static void fileUpdateR (ZebraHandle zh,
115 struct dirs_info *di, struct dirs_entry *dst,
116 const char *base, char *src,
119 struct dir_entry *e_src;
121 static char tmppath[1024];
122 size_t src_len = strlen (src);
124 sprintf (tmppath, "%s%s", base, src);
125 e_src = dir_open (tmppath, zh->path_reg, zh->m_follow_links);
126 yaz_log (YLOG_LOG, "dir %s", tmppath);
129 if (!dst || repComp (dst->path, src, src_len))
131 if (!dst || strcmp (dst->path, src))
137 if (src_len && src[src_len-1] != '/')
140 src[++src_len] = '\0';
142 dirs_mkdir (di, src, 0);
143 if (dst && repComp (dst->path, src, src_len))
148 strcpy (src, dst->path);
149 fileDeleteR (zh, di, dst, base, src);
154 if (src_len && src[src_len-1] != '/')
157 src[++src_len] = '\0';
159 dst = dirs_read (di);
167 if (dst && !repComp (dst->path, src, src_len))
169 if (e_src[i_src].name)
171 yaz_log (YLOG_DEBUG, "dst=%s src=%s", dst->path + src_len,
173 sd = strcmp (dst->path + src_len, e_src[i_src].name);
178 else if (e_src[i_src].name)
182 yaz_log (YLOG_DEBUG, "trav sd=%d", sd);
186 strcpy (src + src_len, e_src[i_src].name);
187 sprintf (tmppath, "%s%s", base, src);
189 switch (e_src[i_src].kind)
192 if (e_src[i_src].mtime > dst->mtime)
194 if (zebra_extract_file (zh, &dst->sysno, tmppath, 0) == ZEBRA_OK)
196 dirs_add (di, src, dst->sysno, e_src[i_src].mtime);
198 yaz_log (YLOG_DEBUG, "old: %s", ctime (&dst->mtime));
199 yaz_log (YLOG_DEBUG, "new: %s", ctime (&e_src[i_src].mtime));
201 dst = dirs_read (di);
204 fileUpdateR (zh, di, dst, base, src, level+1);
205 dst = dirs_last (di);
206 yaz_log (YLOG_DEBUG, "last is %s", dst ? dst->path : "null");
209 dst = dirs_read (di);
216 strcpy (src + src_len, e_src[i_src].name);
217 sprintf (tmppath, "%s%s", base, src);
219 switch (e_src[i_src].kind)
222 if (zebra_extract_file (zh, &sysno, tmppath, 0) == ZEBRA_OK)
223 dirs_add (di, src, sysno, e_src[i_src].mtime);
226 fileUpdateR (zh, di, dst, base, src, level+1);
228 dst = dirs_last (di);
235 strcpy (src, dst->path);
236 sprintf (tmppath, "%s%s", base, dst->path);
241 zebra_extract_file (zh, &dst->sysno, tmppath, 1);
242 dirs_del (di, dst->path);
243 dst = dirs_read (di);
246 fileDeleteR (zh, di, dst, base, src);
247 dst = dirs_last (di);
254 void repositoryShow (ZebraHandle zh, const char *path)
258 struct dirs_entry *dst;
260 struct dirs_info *di;
262 if (!(dict = dict_open_res (zh->reg->bfs, FMATCH_DICT, 50, 0, 0, zh->res)))
264 yaz_log (YLOG_FATAL, "dict_open fail of %s", FMATCH_DICT);
268 strncpy(src, path, sizeof(src)-1);
269 src[sizeof(src)-1]='\0';
270 src_len = strlen (src);
272 if (src_len && src[src_len-1] != '/')
275 src[++src_len] = '\0';
278 di = dirs_open (dict, src, zh->m_flag_rw);
280 while ( (dst = dirs_read (di)) )
281 yaz_log (YLOG_LOG, "%s", dst->path);
286 static void fileUpdate (ZebraHandle zh, Dict dict, const char *path)
288 struct dirs_info *di;
296 if (zh->path_reg && !yaz_is_abspath(path))
298 strcpy (src, zh->path_reg);
304 ret = zebra_file_stat (src, &sbuf, zh->m_follow_links);
307 src_len = strlen (src);
311 yaz_log (YLOG_WARN|YLOG_ERRNO, "Cannot access path %s", src);
313 else if (S_ISREG(sbuf.st_mode))
315 struct dirs_entry *e_dst;
316 di = dirs_fopen (dict, src, zh->m_flag_rw);
318 e_dst = dirs_read (di);
321 if (sbuf.st_mtime > e_dst->mtime)
322 if (zebra_extract_file (zh, &e_dst->sysno, src, 0) == ZEBRA_OK)
323 dirs_add (di, src, e_dst->sysno, sbuf.st_mtime);
328 if (zebra_extract_file (zh, &sysno, src, 0) == ZEBRA_OK)
329 dirs_add (di, src, sysno, sbuf.st_mtime);
333 else if (S_ISDIR(sbuf.st_mode))
335 if (src_len && src[src_len-1] != '/')
338 src[++src_len] = '\0';
340 di = dirs_open (dict, src, zh->m_flag_rw);
342 fileUpdateR (zh, di, dirs_read (di), src, dst, 0);
347 yaz_log (YLOG_WARN, "Skipping path %s", src);
351 static void repositoryExtract (ZebraHandle zh,
352 int deleteFlag, const char *path)
360 if (zh->path_reg && !yaz_is_abspath(path))
362 strcpy (src, zh->path_reg);
368 ret = zebra_file_stat (src, &sbuf, zh->m_follow_links);
373 yaz_log (YLOG_WARN|YLOG_ERRNO, "Cannot access path %s", src);
374 else if (S_ISREG(sbuf.st_mode))
375 zebra_extract_file (zh, NULL, src, deleteFlag);
376 else if (S_ISDIR(sbuf.st_mode))
377 repositoryExtractR (zh, deleteFlag, src, 0);
379 yaz_log (YLOG_WARN, "Skipping path %s", src);
382 static void repositoryExtractG (ZebraHandle zh, const char *path,
385 if (!strcmp(path, "") || !strcmp(path, "-"))
389 while (scanf ("%1020s", src) == 1)
390 repositoryExtract (zh, deleteFlag, src);
393 repositoryExtract (zh, deleteFlag, path);
397 static int dump_file_dict_func(char *name, const char *info, int pos,
400 yaz_log(YLOG_LOG, "%s", name);
403 static void dump_file_dict(Dict dict)
410 dict_scan (dict, term, &before, &after, 0, dump_file_dict_func);
414 void repositoryUpdate (ZebraHandle zh, const char *path)
417 if (zh->m_record_id && !strcmp (zh->m_record_id, "file"))
420 if (!(dict = dict_open_res (zh->reg->bfs, FMATCH_DICT, 50,
421 zh->m_flag_rw, 0, zh->res)))
423 yaz_log (YLOG_FATAL, "dict_open fail of %s", FMATCH_DICT);
426 if (!strcmp(path, "") || !strcmp(path, "-"))
429 while (scanf ("%s", src) == 1)
430 fileUpdate (zh, dict, src);
433 fileUpdate (zh, dict, path);
435 dump_file_dict(dict);
441 repositoryExtractG (zh, path, 0);
444 void repositoryDelete (ZebraHandle zh, const char *path)
447 repositoryExtractG (zh, path, 1);