IDZEBRA 2.2.8
update_file.c
Go to the documentation of this file.
1/* This file is part of the Zebra server.
2 Copyright (C) Index Data
3
4Zebra is free software; you can redistribute it and/or modify it under
5the terms of the GNU General Public License as published by the Free
6Software Foundation; either version 2, or (at your option) any later
7version.
8
9Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10WARRANTY; without even the implied warranty of MERCHANTABILITY or
11FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
18*/
19
20#if HAVE_CONFIG_H
21#include <config.h>
22#endif
23#include <stdio.h>
24#include <assert.h>
25#include <sys/types.h>
26#ifdef WIN32
27#include <io.h>
28#define S_ISREG(x) (x & _S_IFREG)
29#define S_ISDIR(x) (x & _S_IFDIR)
30#endif
31#if HAVE_UNISTD_H
32#include <unistd.h>
33#endif
34#include <direntz.h>
35#include <fcntl.h>
36#include <time.h>
37#include <yaz/snprintf.h>
38
39#include "index.h"
40
41static int repComp(const char *a, const char *b, size_t len)
42{
43 if (!len)
44 return 0;
45 return memcmp(a, b, len);
46}
47
49 struct dirs_info *di, struct dirs_entry *dst,
50 const char *base, char *src)
51{
52 char tmppath[1024];
53 size_t src_len = strlen(src);
54
55 while (dst && !repComp(dst->path, src, src_len+1))
56 {
57 switch (dst->kind)
58 {
59 case dirs_file:
60 yaz_snprintf(tmppath, sizeof(tmppath), "%s%s", base, dst->path);
61 zebra_extract_file(zh, &dst->sysno, tmppath, action_delete);
62 strcpy(tmppath, dst->path);
63 dst = dirs_read(di);
64 dirs_del(di, tmppath);
65 break;
66 case dirs_dir:
67 strcpy(tmppath, dst->path);
68 dst = dirs_read(di);
69 dirs_rmdir(di, tmppath);
70 break;
71 default:
72 dst = dirs_read(di);
73 }
74 }
75}
76
78 struct dirs_info *di, struct dirs_entry *dst,
79 const char *base, char *src,
80 int level)
81{
82 struct dir_entry *e_src;
83 int i_src = 0;
84 static char tmppath[1024];
85 size_t src_len = strlen(src);
86
87 yaz_snprintf(tmppath, sizeof(tmppath), "%s%s", base, src);
88 e_src = dir_open(tmppath, zh->path_reg, zh->m_follow_links);
89 yaz_log(YLOG_LOG, "dir %s", tmppath);
90
91 if (!dst || strcmp(dst->path, src))
92 {
93 if (!e_src)
94 return;
95
96 if (src_len && src[src_len-1] != '/')
97 {
98 src[src_len] = '/';
99 src[++src_len] = '\0';
100 }
101 dirs_mkdir(di, src, 0);
102 if (dst && repComp(dst->path, src, src_len))
103 dst = NULL;
104 }
105 else if (!e_src)
106 {
107 strcpy(src, dst->path);
108 fileDelete_r(zh, di, dst, base, src);
109 return;
110 }
111 else
112 {
113 if (src_len && src[src_len-1] != '/')
114 {
115 src[src_len] = '/';
116 src[++src_len] = '\0';
117 }
118 dst = dirs_read(di);
119 }
120 dir_sort(e_src);
121
122 while (1)
123 {
124 int sd;
125
126 if (dst && !repComp(dst->path, src, src_len))
127 {
128 if (e_src[i_src].name)
129 {
130 yaz_log(YLOG_DEBUG, "dst=%s src=%s", dst->path + src_len,
131 e_src[i_src].name);
132 sd = strcmp(dst->path + src_len, e_src[i_src].name);
133 }
134 else
135 sd = -1;
136 }
137 else if (e_src[i_src].name)
138 sd = 1;
139 else
140 break;
141 yaz_log(YLOG_DEBUG, "trav sd=%d", sd);
142
143 if (sd == 0)
144 {
145 strcpy(src + src_len, e_src[i_src].name);
146 yaz_snprintf(tmppath, sizeof(tmppath), "%s%s", base, src);
147
148 switch(e_src[i_src].kind)
149 {
150 case dirs_file:
151 if (e_src[i_src].mtime > dst->mtime)
152 {
153 if (zebra_extract_file(zh, &dst->sysno, tmppath, action_update) == ZEBRA_OK)
154 {
155 dirs_add(di, src, dst->sysno, e_src[i_src].mtime);
156 }
157 yaz_log(YLOG_DEBUG, "old: %s", ctime(&dst->mtime));
158 yaz_log(YLOG_DEBUG, "new: %s", ctime(&e_src[i_src].mtime));
159 }
160 dst = dirs_read(di);
161 break;
162 case dirs_dir:
163 file_update_r(zh, di, dst, base, src, level+1);
164 dst = dirs_last(di);
165 yaz_log(YLOG_DEBUG, "last is %s", dst ? dst->path : "null");
166 break;
167 default:
168 dst = dirs_read(di);
169 }
170 i_src++;
171 }
172 else if (sd > 0)
173 {
174 zint sysno = 0;
175 strcpy(src + src_len, e_src[i_src].name);
176 yaz_snprintf(tmppath, sizeof(tmppath), "%s%s", base, src);
177
178 switch (e_src[i_src].kind)
179 {
180 case dirs_file:
181 if (zebra_extract_file(zh, &sysno, tmppath, action_update) == ZEBRA_OK)
182 dirs_add(di, src, sysno, e_src[i_src].mtime);
183 break;
184 case dirs_dir:
185 file_update_r(zh, di, dst, base, src, level+1);
186 if (dst)
187 dst = dirs_last(di);
188 break;
189 }
190 i_src++;
191 }
192 else /* sd < 0 */
193 {
194 strcpy(src, dst->path);
195 yaz_snprintf(tmppath, sizeof(tmppath), "%s%s", base, dst->path);
196
197 switch (dst->kind)
198 {
199 case dirs_file:
200 zebra_extract_file(zh, &dst->sysno, tmppath, action_delete);
201 dirs_del(di, dst->path);
202 dst = dirs_read(di);
203 break;
204 case dirs_dir:
205 fileDelete_r(zh, di, dst, base, src);
206 dst = dirs_last(di);
207 }
208 }
209 }
210 dir_free(&e_src);
211}
212
213static void file_update_top(ZebraHandle zh, Dict dict, const char *path)
214{
215 struct dirs_info *di;
216 struct stat sbuf;
217 char src[1024];
218 char dst[1024];
219 int src_len, ret;
220
221 assert(path);
222
223 if (zh->path_reg && !yaz_is_abspath(path))
224 {
225 strcpy(src, zh->path_reg);
226 strcat(src, "/");
227 }
228 else
229 *src = '\0';
230 strcat(src, path);
231 ret = zebra_file_stat(src, &sbuf, zh->m_follow_links);
232
233 strcpy(src, path);
234 src_len = strlen(src);
235
236 if (ret == -1)
237 {
238 yaz_log(YLOG_WARN|YLOG_ERRNO, "Cannot access path %s", src);
239 }
240 else if (S_ISREG(sbuf.st_mode))
241 {
242 struct dirs_entry *e_dst;
243 di = dirs_fopen(dict, src, zh->m_flag_rw);
244
245 e_dst = dirs_read(di);
246 if (e_dst)
247 {
248 if (sbuf.st_mtime > e_dst->mtime)
249 if (zebra_extract_file(zh, &e_dst->sysno, src, action_update) == ZEBRA_OK)
250 dirs_add(di, src, e_dst->sysno, sbuf.st_mtime);
251 }
252 else
253 {
254 zint sysno = 0;
256 dirs_add(di, src, sysno, sbuf.st_mtime);
257 }
258 dirs_free(&di);
259 }
260 else if (S_ISDIR(sbuf.st_mode))
261 {
262 if (src_len && src[src_len-1] != '/')
263 {
264 src[src_len] = '/';
265 src[++src_len] = '\0';
266 }
267 di = dirs_open(dict, src, zh->m_flag_rw);
268 *dst = '\0';
269 file_update_r(zh, di, dirs_read(di), src, dst, 0);
270 dirs_free (&di);
271 }
272 else
273 {
274 yaz_log(YLOG_WARN, "Skipping path %s", src);
275 }
276}
277
279{
280 char fmatch_fname[1024];
281 int ord;
282
284 yaz_snprintf(fmatch_fname, sizeof(fmatch_fname), FMATCH_DICT, ord);
285 if (!(*dictp = dict_open_res(zh->reg->bfs, fmatch_fname, 50,
286 zh->m_flag_rw, 0, zh->res)))
287 {
288 yaz_log(YLOG_FATAL, "dict_open fail of %s", fmatch_fname);
289 return ZEBRA_FAIL;
290 }
291 return ZEBRA_OK;
292}
293
295{
296 Dict dict;
297
298 if (zebra_open_fmatch(zh, &dict) != ZEBRA_OK)
299 return ZEBRA_FAIL;
300
303
304 return ZEBRA_OK;
305}
306
308{
309 Dict dict;
310
311 if (zebraExplain_curDatabase(zh->reg->zei, zh->basenames[0]))
312 {
313 if (zebraExplain_newDatabase(zh->reg->zei, zh->basenames[0], 0))
314 return ZEBRA_FAIL;
315 }
316 if (zebra_open_fmatch(zh, &dict) != ZEBRA_OK)
317 return ZEBRA_FAIL;
318
319 if (!strcmp(path, "") || !strcmp(path, "-"))
320 {
321 char src[1024];
322 while (scanf("%s", src) == 1)
323 file_update_top(zh, dict, src);
324 }
325 else
327#if 0
328 dump_file_dict(dict);
329#endif
331 return ZEBRA_OK;
332}
333
334
335/*
336 * Local variables:
337 * c-basic-offset: 4
338 * c-file-style: "Stroustrup"
339 * indent-tabs-mode: nil
340 * End:
341 * vim: shiftwidth=4 tabstop=8 expandtab
342 */
343
void dict_clean(Dict dict)
reset Dictionary (makes it empty)
Definition open.c:31
int dict_close(Dict dict)
closes dictionary
Definition close.c:32
static Dict dict
Definition dicttest.c:35
void dir_sort(struct dir_entry *e)
Definition dir.c:138
struct dir_entry * dir_open(const char *rep, const char *base, int follow_links)
Definition dir.c:48
int zebra_file_stat(const char *file_name, struct stat *buf, int follow_links)
Definition dir.c:38
void dir_free(struct dir_entry **e_p)
Definition dir.c:146
void dirs_mkdir(struct dirs_info *p, const char *src, time_t mtime)
Definition dirs.c:170
void dirs_rmdir(struct dirs_info *p, const char *src)
Definition dirs.c:180
void dirs_add(struct dirs_info *p, const char *src, zint sysno, time_t mtime)
Definition dirs.c:190
struct dirs_info * dirs_fopen(Dict dict, const char *path, int rw)
Definition dirs.c:105
void dirs_free(struct dirs_info **pp)
Definition dirs.c:217
struct dirs_info * dirs_open(Dict dict, const char *rep, int rw)
Definition dirs.c:83
struct dirs_entry * dirs_read(struct dirs_info *p)
Definition dirs.c:134
struct dirs_entry * dirs_last(struct dirs_info *p)
Definition dirs.c:165
void dirs_del(struct dirs_info *p, const char *src)
Definition dirs.c:203
ZEBRA_RES zebra_extract_file(ZebraHandle zh, zint *sysno, const char *fname, enum zebra_recctrl_action_t action)
Definition extract.c:609
Dict dict_open_res(BFiles bfs, const char *name, int cache, int rw, int compact_flag, Res res)
Definition zebraapi.c:321
#define FMATCH_DICT
Definition index.h:105
@ dirs_file
Definition index.h:55
@ dirs_dir
Definition index.h:55
@ action_delete
Definition recctrl.h:93
@ action_update
Definition recctrl.h:95
Definition index.h:57
time_t mtime
Definition index.h:60
enum dirsKind kind
Definition index.h:58
char * name
Definition index.h:59
Definition index.h:63
zint sysno
Definition index.h:66
enum dirsKind kind
Definition index.h:64
char path[256]
Definition index.h:65
time_t mtime
Definition index.h:67
ZebraExplainInfo zei
Definition index.h:139
BFiles bfs
Definition index.h:137
struct zebra_register * reg
Definition index.h:174
char ** basenames
Definition index.h:178
int m_flag_rw
Definition index.h:225
char * path_reg
Definition index.h:182
int m_follow_links
Definition index.h:218
static ZEBRA_RES zebra_open_fmatch(ZebraHandle zh, Dict *dictp)
static void fileDelete_r(ZebraHandle zh, struct dirs_info *di, struct dirs_entry *dst, const char *base, char *src)
Definition update_file.c:48
ZEBRA_RES zebra_remove_file_match(ZebraHandle zh)
ZEBRA_RES zebra_update_file_match(ZebraHandle zh, const char *path)
static void file_update_top(ZebraHandle zh, Dict dict, const char *path)
static void file_update_r(ZebraHandle zh, struct dirs_info *di, struct dirs_entry *dst, const char *base, char *src, int level)
Definition update_file.c:77
static int repComp(const char *a, const char *b, size_t len)
Definition update_file.c:41
long zint
Zebra integer.
Definition util.h:66
#define ZEBRA_FAIL
Definition util.h:81
#define ZEBRA_OK
Definition util.h:82
short ZEBRA_RES
Common return type for Zebra API.
Definition util.h:80
int zebraExplain_curDatabase(ZebraExplainInfo zei, const char *database)
Definition zinfo.c:790
int zebraExplain_get_database_ord(ZebraExplainInfo zei)
Definition zinfo.c:1620
int zebraExplain_newDatabase(ZebraExplainInfo zei, const char *database, int explain_database)
Definition zinfo.c:882