1 /* This file is part of the Zebra server.
2 Copyright (C) 1994-2010 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
22 #include <sys/types.h>
25 #define S_ISREG(x) (x & _S_IFREG)
26 #define S_ISDIR(x) (x & _S_IFDIR)
38 static int dump_file_dict_func(char *name, const char *info, int pos,
41 yaz_log(YLOG_LOG, "%s", name);
44 static void dump_file_dict(Dict dict)
51 dict_scan(dict, term, &before, &after, 0, dump_file_dict_func);
55 static int repComp(const char *a, const char *b, size_t len)
59 return memcmp(a, b, len);
62 static void fileDelete_r(ZebraHandle zh,
63 struct dirs_info *di, struct dirs_entry *dst,
64 const char *base, char *src)
67 size_t src_len = strlen(src);
69 while (dst && !repComp(dst->path, src, src_len+1))
74 sprintf(tmppath, "%s%s", base, dst->path);
75 zebra_extract_file(zh, &dst->sysno, tmppath, action_delete);
76 strcpy(tmppath, dst->path);
78 dirs_del(di, tmppath);
81 strcpy(tmppath, dst->path);
83 dirs_rmdir(di, tmppath);
91 static void file_update_r(ZebraHandle zh,
92 struct dirs_info *di, struct dirs_entry *dst,
93 const char *base, char *src,
96 struct dir_entry *e_src;
98 static char tmppath[1024];
99 size_t src_len = strlen(src);
101 sprintf(tmppath, "%s%s", base, src);
102 e_src = dir_open(tmppath, zh->path_reg, zh->m_follow_links);
103 yaz_log(YLOG_LOG, "dir %s", tmppath);
106 if (!dst || repComp(dst->path, src, src_len))
108 if (!dst || strcmp(dst->path, src))
114 if (src_len && src[src_len-1] != '/')
117 src[++src_len] = '\0';
119 dirs_mkdir(di, src, 0);
120 if (dst && repComp(dst->path, src, src_len))
125 strcpy(src, dst->path);
126 fileDelete_r(zh, di, dst, base, src);
131 if (src_len && src[src_len-1] != '/')
134 src[++src_len] = '\0';
144 if (dst && !repComp(dst->path, src, src_len))
146 if (e_src[i_src].name)
148 yaz_log(YLOG_DEBUG, "dst=%s src=%s", dst->path + src_len,
150 sd = strcmp(dst->path + src_len, e_src[i_src].name);
155 else if (e_src[i_src].name)
159 yaz_log(YLOG_DEBUG, "trav sd=%d", sd);
163 strcpy(src + src_len, e_src[i_src].name);
164 sprintf(tmppath, "%s%s", base, src);
166 switch(e_src[i_src].kind)
169 if (e_src[i_src].mtime > dst->mtime)
171 if (zebra_extract_file(zh, &dst->sysno, tmppath, action_update) == ZEBRA_OK)
173 dirs_add(di, src, dst->sysno, e_src[i_src].mtime);
175 yaz_log(YLOG_DEBUG, "old: %s", ctime(&dst->mtime));
176 yaz_log(YLOG_DEBUG, "new: %s", ctime(&e_src[i_src].mtime));
181 file_update_r(zh, di, dst, base, src, level+1);
183 yaz_log(YLOG_DEBUG, "last is %s", dst ? dst->path : "null");
193 strcpy(src + src_len, e_src[i_src].name);
194 sprintf(tmppath, "%s%s", base, src);
196 switch (e_src[i_src].kind)
199 if (zebra_extract_file(zh, &sysno, tmppath, action_update) == ZEBRA_OK)
200 dirs_add(di, src, sysno, e_src[i_src].mtime);
203 file_update_r(zh, di, dst, base, src, level+1);
212 strcpy(src, dst->path);
213 sprintf(tmppath, "%s%s", base, dst->path);
218 zebra_extract_file(zh, &dst->sysno, tmppath, action_delete);
219 dirs_del(di, dst->path);
223 fileDelete_r(zh, di, dst, base, src);
231 static void file_update_top(ZebraHandle zh, Dict dict, const char *path)
233 struct dirs_info *di;
241 if (zh->path_reg && !yaz_is_abspath(path))
243 strcpy(src, zh->path_reg);
249 ret = zebra_file_stat(src, &sbuf, zh->m_follow_links);
252 src_len = strlen(src);
256 yaz_log(YLOG_WARN|YLOG_ERRNO, "Cannot access path %s", src);
258 else if (S_ISREG(sbuf.st_mode))
260 struct dirs_entry *e_dst;
261 di = dirs_fopen(dict, src, zh->m_flag_rw);
263 e_dst = dirs_read(di);
266 if (sbuf.st_mtime > e_dst->mtime)
267 if (zebra_extract_file(zh, &e_dst->sysno, src, action_update) == ZEBRA_OK)
268 dirs_add(di, src, e_dst->sysno, sbuf.st_mtime);
273 if (zebra_extract_file(zh, &sysno, src, action_update) == ZEBRA_OK)
274 dirs_add(di, src, sysno, sbuf.st_mtime);
278 else if (S_ISDIR(sbuf.st_mode))
280 if (src_len && src[src_len-1] != '/')
283 src[++src_len] = '\0';
285 di = dirs_open(dict, src, zh->m_flag_rw);
287 file_update_r(zh, di, dirs_read(di), src, dst, 0);
292 yaz_log(YLOG_WARN, "Skipping path %s", src);
296 static ZEBRA_RES zebra_open_fmatch(ZebraHandle zh, Dict *dictp)
298 char fmatch_fname[1024];
301 ord = zebraExplain_get_database_ord(zh->reg->zei);
302 sprintf(fmatch_fname, FMATCH_DICT, ord);
303 if (!(*dictp = dict_open_res(zh->reg->bfs, fmatch_fname, 50,
304 zh->m_flag_rw, 0, zh->res)))
306 yaz_log(YLOG_FATAL, "dict_open fail of %s", fmatch_fname);
312 ZEBRA_RES zebra_remove_file_match(ZebraHandle zh)
316 if (zebra_open_fmatch(zh, &dict) != ZEBRA_OK)
325 ZEBRA_RES zebra_update_file_match(ZebraHandle zh, const char *path)
329 if (zebraExplain_curDatabase(zh->reg->zei, zh->basenames[0]))
331 if (zebraExplain_newDatabase(zh->reg->zei, zh->basenames[0], 0))
334 if (zebra_open_fmatch(zh, &dict) != ZEBRA_OK)
337 if (!strcmp(path, "") || !strcmp(path, "-"))
340 while (scanf("%s", src) == 1)
341 file_update_top(zh, dict, src);
344 file_update_top(zh, dict, path);
346 dump_file_dict(dict);
356 * c-file-style: "Stroustrup"
357 * indent-tabs-mode: nil
359 * vim: shiftwidth=4 tabstop=8 expandtab