1 /* $Id: update_file.c,v 1.3 2006-09-11 22:57:54 adam Exp $
2 Copyright (C) 1995-2006
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 this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include <sys/types.h>
28 #define S_ISREG(x) (x & _S_IFREG)
29 #define S_ISDIR(x) (x & _S_IFDIR)
41 static int dump_file_dict_func(char *name, const char *info, int pos,
44 yaz_log(YLOG_LOG, "%s", name);
47 static void dump_file_dict(Dict dict)
54 dict_scan (dict, term, &before, &after, 0, dump_file_dict_func);
58 static int repComp (const char *a, const char *b, size_t len)
62 return memcmp (a, b, len);
65 static void fileDelete_r(ZebraHandle zh,
66 struct dirs_info *di, struct dirs_entry *dst,
67 const char *base, char *src)
70 size_t src_len = strlen (src);
72 while (dst && !repComp (dst->path, src, src_len+1))
77 sprintf (tmppath, "%s%s", base, dst->path);
78 zebra_extract_file (zh, &dst->sysno, tmppath, 1);
80 strcpy (tmppath, dst->path);
82 dirs_del (di, tmppath);
85 strcpy (tmppath, dst->path);
87 dirs_rmdir (di, tmppath);
95 static void file_update_r(ZebraHandle zh,
96 struct dirs_info *di, struct dirs_entry *dst,
97 const char *base, char *src,
100 struct dir_entry *e_src;
102 static char tmppath[1024];
103 size_t src_len = strlen (src);
105 sprintf (tmppath, "%s%s", base, src);
106 e_src = dir_open (tmppath, zh->path_reg, zh->m_follow_links);
107 yaz_log (YLOG_LOG, "dir %s", tmppath);
110 if (!dst || repComp (dst->path, src, src_len))
112 if (!dst || strcmp (dst->path, src))
118 if (src_len && src[src_len-1] != '/')
121 src[++src_len] = '\0';
123 dirs_mkdir (di, src, 0);
124 if (dst && repComp (dst->path, src, src_len))
129 strcpy (src, dst->path);
130 fileDelete_r(zh, di, dst, base, src);
135 if (src_len && src[src_len-1] != '/')
138 src[++src_len] = '\0';
140 dst = dirs_read (di);
148 if (dst && !repComp (dst->path, src, src_len))
150 if (e_src[i_src].name)
152 yaz_log (YLOG_DEBUG, "dst=%s src=%s", dst->path + src_len,
154 sd = strcmp (dst->path + src_len, e_src[i_src].name);
159 else if (e_src[i_src].name)
163 yaz_log (YLOG_DEBUG, "trav sd=%d", sd);
167 strcpy (src + src_len, e_src[i_src].name);
168 sprintf (tmppath, "%s%s", base, src);
170 switch (e_src[i_src].kind)
173 if (e_src[i_src].mtime > dst->mtime)
175 if (zebra_extract_file (zh, &dst->sysno, tmppath, 0) == ZEBRA_OK)
177 dirs_add (di, src, dst->sysno, e_src[i_src].mtime);
179 yaz_log (YLOG_DEBUG, "old: %s", ctime (&dst->mtime));
180 yaz_log (YLOG_DEBUG, "new: %s", ctime (&e_src[i_src].mtime));
182 dst = dirs_read (di);
185 file_update_r(zh, di, dst, base, src, level+1);
186 dst = dirs_last (di);
187 yaz_log (YLOG_DEBUG, "last is %s", dst ? dst->path : "null");
190 dst = dirs_read (di);
197 strcpy (src + src_len, e_src[i_src].name);
198 sprintf (tmppath, "%s%s", base, src);
200 switch (e_src[i_src].kind)
203 if (zebra_extract_file (zh, &sysno, tmppath, 0) == ZEBRA_OK)
204 dirs_add (di, src, sysno, e_src[i_src].mtime);
207 file_update_r(zh, di, dst, base, src, level+1);
209 dst = dirs_last (di);
216 strcpy (src, dst->path);
217 sprintf (tmppath, "%s%s", base, dst->path);
222 zebra_extract_file (zh, &dst->sysno, tmppath, 1);
223 dirs_del (di, dst->path);
224 dst = dirs_read (di);
227 fileDelete_r(zh, di, dst, base, src);
228 dst = dirs_last (di);
235 static void file_update_top(ZebraHandle zh, Dict dict, const char *path)
237 struct dirs_info *di;
245 if (zh->path_reg && !yaz_is_abspath(path))
247 strcpy (src, zh->path_reg);
253 ret = zebra_file_stat (src, &sbuf, zh->m_follow_links);
256 src_len = strlen (src);
260 yaz_log (YLOG_WARN|YLOG_ERRNO, "Cannot access path %s", src);
262 else if (S_ISREG(sbuf.st_mode))
264 struct dirs_entry *e_dst;
265 di = dirs_fopen (dict, src, zh->m_flag_rw);
267 e_dst = dirs_read (di);
270 if (sbuf.st_mtime > e_dst->mtime)
271 if (zebra_extract_file (zh, &e_dst->sysno, src, 0) == ZEBRA_OK)
272 dirs_add (di, src, e_dst->sysno, sbuf.st_mtime);
277 if (zebra_extract_file (zh, &sysno, src, 0) == ZEBRA_OK)
278 dirs_add (di, src, sysno, sbuf.st_mtime);
282 else if (S_ISDIR(sbuf.st_mode))
284 if (src_len && src[src_len-1] != '/')
287 src[++src_len] = '\0';
289 di = dirs_open (dict, src, zh->m_flag_rw);
291 file_update_r(zh, di, dirs_read (di), src, dst, 0);
296 yaz_log (YLOG_WARN, "Skipping path %s", src);
300 static ZEBRA_RES zebra_open_fmatch(ZebraHandle zh, Dict *dictp)
302 char fmatch_fname[1024];
305 ord = zebraExplain_get_database_ord(zh->reg->zei);
306 sprintf(fmatch_fname, FMATCH_DICT, ord);
307 if (!(*dictp = dict_open_res (zh->reg->bfs, fmatch_fname, 50,
308 zh->m_flag_rw, 0, zh->res)))
310 yaz_log (YLOG_FATAL, "dict_open fail of %s", fmatch_fname);
316 ZEBRA_RES zebra_remove_file_match(ZebraHandle zh)
320 if (zebra_open_fmatch(zh, &dict) != ZEBRA_OK)
329 ZEBRA_RES zebra_update_file_match(ZebraHandle zh, const char *path)
333 if (zebraExplain_curDatabase (zh->reg->zei, zh->basenames[0]))
335 if (zebraExplain_newDatabase(zh->reg->zei, zh->basenames[0], 0))
338 if (zebra_open_fmatch(zh, &dict) != ZEBRA_OK)
341 if (!strcmp(path, "") || !strcmp(path, "-"))
344 while (scanf ("%s", src) == 1)
345 file_update_top(zh, dict, src);
348 file_update_top(zh, dict, path);
350 dump_file_dict(dict);
360 * indent-tabs-mode: nil
362 * vim: shiftwidth=4 tabstop=8 expandtab