1 /* This file is part of the Zebra server.
2 Copyright (C) 1994-2011 Index Data
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 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, action_delete);
79 strcpy(tmppath, dst->path);
81 dirs_del(di, tmppath);
84 strcpy(tmppath, dst->path);
86 dirs_rmdir(di, tmppath);
94 static void file_update_r(ZebraHandle zh,
95 struct dirs_info *di, struct dirs_entry *dst,
96 const char *base, char *src,
99 struct dir_entry *e_src;
101 static char tmppath[1024];
102 size_t src_len = strlen(src);
104 sprintf(tmppath, "%s%s", base, src);
105 e_src = dir_open(tmppath, zh->path_reg, zh->m_follow_links);
106 yaz_log(YLOG_LOG, "dir %s", tmppath);
109 if (!dst || repComp(dst->path, src, src_len))
111 if (!dst || strcmp(dst->path, src))
117 if (src_len && src[src_len-1] != '/')
120 src[++src_len] = '\0';
122 dirs_mkdir(di, src, 0);
123 if (dst && repComp(dst->path, src, src_len))
128 strcpy(src, dst->path);
129 fileDelete_r(zh, di, dst, base, src);
134 if (src_len && src[src_len-1] != '/')
137 src[++src_len] = '\0';
147 if (dst && !repComp(dst->path, src, src_len))
149 if (e_src[i_src].name)
151 yaz_log(YLOG_DEBUG, "dst=%s src=%s", dst->path + src_len,
153 sd = strcmp(dst->path + src_len, e_src[i_src].name);
158 else if (e_src[i_src].name)
162 yaz_log(YLOG_DEBUG, "trav sd=%d", sd);
166 strcpy(src + src_len, e_src[i_src].name);
167 sprintf(tmppath, "%s%s", base, src);
169 switch(e_src[i_src].kind)
172 if (e_src[i_src].mtime > dst->mtime)
174 if (zebra_extract_file(zh, &dst->sysno, tmppath, action_update) == ZEBRA_OK)
176 dirs_add(di, src, dst->sysno, e_src[i_src].mtime);
178 yaz_log(YLOG_DEBUG, "old: %s", ctime(&dst->mtime));
179 yaz_log(YLOG_DEBUG, "new: %s", ctime(&e_src[i_src].mtime));
184 file_update_r(zh, di, dst, base, src, level+1);
186 yaz_log(YLOG_DEBUG, "last is %s", dst ? dst->path : "null");
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 (zebra_extract_file(zh, &sysno, tmppath, action_update) == ZEBRA_OK)
203 dirs_add(di, src, sysno, e_src[i_src].mtime);
206 file_update_r(zh, di, dst, base, src, level+1);
215 strcpy(src, dst->path);
216 sprintf(tmppath, "%s%s", base, dst->path);
221 zebra_extract_file(zh, &dst->sysno, tmppath, action_delete);
222 dirs_del(di, dst->path);
226 fileDelete_r(zh, di, dst, base, src);
234 static void file_update_top(ZebraHandle zh, Dict dict, const char *path)
236 struct dirs_info *di;
244 if (zh->path_reg && !yaz_is_abspath(path))
246 strcpy(src, zh->path_reg);
252 ret = zebra_file_stat(src, &sbuf, zh->m_follow_links);
255 src_len = strlen(src);
259 yaz_log(YLOG_WARN|YLOG_ERRNO, "Cannot access path %s", src);
261 else if (S_ISREG(sbuf.st_mode))
263 struct dirs_entry *e_dst;
264 di = dirs_fopen(dict, src, zh->m_flag_rw);
266 e_dst = dirs_read(di);
269 if (sbuf.st_mtime > e_dst->mtime)
270 if (zebra_extract_file(zh, &e_dst->sysno, src, action_update) == ZEBRA_OK)
271 dirs_add(di, src, e_dst->sysno, sbuf.st_mtime);
276 if (zebra_extract_file(zh, &sysno, src, action_update) == ZEBRA_OK)
277 dirs_add(di, src, sysno, sbuf.st_mtime);
281 else if (S_ISDIR(sbuf.st_mode))
283 if (src_len && src[src_len-1] != '/')
286 src[++src_len] = '\0';
288 di = dirs_open(dict, src, zh->m_flag_rw);
290 file_update_r(zh, di, dirs_read(di), src, dst, 0);
295 yaz_log(YLOG_WARN, "Skipping path %s", src);
299 static ZEBRA_RES zebra_open_fmatch(ZebraHandle zh, Dict *dictp)
301 char fmatch_fname[1024];
304 ord = zebraExplain_get_database_ord(zh->reg->zei);
305 sprintf(fmatch_fname, FMATCH_DICT, ord);
306 if (!(*dictp = dict_open_res(zh->reg->bfs, fmatch_fname, 50,
307 zh->m_flag_rw, 0, zh->res)))
309 yaz_log(YLOG_FATAL, "dict_open fail of %s", fmatch_fname);
315 ZEBRA_RES zebra_remove_file_match(ZebraHandle zh)
319 if (zebra_open_fmatch(zh, &dict) != ZEBRA_OK)
328 ZEBRA_RES zebra_update_file_match(ZebraHandle zh, const char *path)
332 if (zebraExplain_curDatabase(zh->reg->zei, zh->basenames[0]))
334 if (zebraExplain_newDatabase(zh->reg->zei, zh->basenames[0], 0))
337 if (zebra_open_fmatch(zh, &dict) != ZEBRA_OK)
340 if (!strcmp(path, "") || !strcmp(path, "-"))
343 while (scanf("%s", src) == 1)
344 file_update_top(zh, dict, src);
347 file_update_top(zh, dict, path);
349 dump_file_dict(dict);
359 * c-file-style: "Stroustrup"
360 * indent-tabs-mode: nil
362 * vim: shiftwidth=4 tabstop=8 expandtab