2 * Copyright (C) 1994-1995, Index Data I/S
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.9 1995-11-21 09:20:32 adam
8 * Yet more work on record match.
10 * Revision 1.8 1995/11/20 16:59:46 adam
11 * New update method: the 'old' keys are saved for each records.
13 * Revision 1.7 1995/11/20 11:56:28 adam
14 * Work on new traversal.
16 * Revision 1.6 1995/11/17 15:54:42 adam
17 * Started work on virtual directory structure.
19 * Revision 1.5 1995/10/17 18:02:09 adam
20 * New feature: databases. Implemented as prefix to words in dictionary.
22 * Revision 1.4 1995/09/28 09:19:46 adam
23 * xfree/xmalloc used everywhere.
24 * Extract/retrieve method seems to work for text records.
26 * Revision 1.3 1995/09/06 16:11:18 adam
27 * Option: only one word key per file.
29 * Revision 1.2 1995/09/04 12:33:43 adam
30 * Various cleanup. YAZ util used instead.
32 * Revision 1.1 1995/09/01 14:06:36 adam
33 * Split of work into more files.
41 #include <sys/types.h>
49 static void repository_extract_r (int cmd, char *rep, char *databaseName)
54 size_t rep_len = strlen (rep);
59 if (rep[rep_len-1] != '/')
63 for (i=0; e[i].name; i++)
65 strcpy (rep +rep_len+1, e[i].name);
67 switch (fs.st_mode & S_IFMT)
70 file_extract (cmd, rep, rep, databaseName);
73 repository_extract_r (cmd, rep, databaseName);
80 void copy_file (const char *dst, const char *src)
82 int d_fd = open (dst, O_WRONLY|O_CREAT, 0666);
83 int s_fd = open (src, O_RDONLY);
89 logf (LOG_FATAL|LOG_ERRNO, "Cannot create %s", dst);
94 logf (LOG_FATAL|LOG_ERRNO, "Cannot open %s", src);
98 while ((r=read (s_fd, buf, 4096))>0)
99 for (w = 0; w < r; w += i)
101 i = write (d_fd, buf + w, r - w);
104 logf (LOG_FATAL|LOG_ERRNO, "write");
110 logf (LOG_FATAL|LOG_ERRNO, "read");
118 void del_file (const char *dst)
123 void del_dir (const char *dst)
125 logf (LOG_DEBUG, "rmdir of %s", dst);
126 if (rmdir (dst) == -1)
127 logf (LOG_ERRNO|LOG_WARN, "rmdir");
130 void repository_update_r (int cmd, char *dst, char *src, char *databaseName);
132 void repository_add_tree (int cmd, char *dst, char *src, char *databaseName)
135 repository_update_r (cmd, dst, src, databaseName);
138 void repository_del_tree (int cmd, char *dst, char *src, char *databaseName)
140 size_t dst_len = strlen (dst);
141 size_t src_len = strlen (src);
142 struct dir_entry *e_dst;
146 e_dst = dir_open (dst);
150 if (src[src_len-1] != '/')
154 if (dst[dst_len-1] != '/')
158 while (e_dst[i_dst].name)
160 strcpy (dst +dst_len+1, e_dst[i_dst].name);
161 strcpy (src +src_len+1, e_dst[i_dst].name);
164 switch (fs_dst.st_mode & S_IFMT)
167 file_extract ('d', dst, dst, databaseName);
171 repository_del_tree (cmd, dst, src, databaseName);
184 void repository_update_r (int cmd, char *dst, char *src, char *databaseName)
186 struct dir_entry *e_dst, *e_src;
187 int i_dst = 0, i_src = 0;
188 struct stat fs_dst, fs_src;
189 size_t dst_len = strlen (dst);
190 size_t src_len = strlen (src);
192 e_dst = dir_open (dst);
193 e_src = dir_open (src);
195 if (!e_dst && !e_src)
200 repository_add_tree (cmd, dst, src, databaseName);
206 repository_del_tree (cmd, dst, src, databaseName);
213 if (src[src_len-1] != '/')
217 if (dst[dst_len-1] != '/')
221 while (e_dst[i_dst].name || e_src[i_src].name)
225 if (e_dst[i_dst].name && e_src[i_src].name)
226 sd = strcmp (e_dst[i_dst].name, e_src[i_src].name);
227 else if (e_src[i_src].name)
234 strcpy (dst +dst_len+1, e_dst[i_dst].name);
235 strcpy (src +src_len+1, e_src[i_src].name);
237 /* check type, date, length */
242 switch (fs_dst.st_mode & S_IFMT)
245 if (fs_src.st_ctime > fs_dst.st_ctime)
247 file_extract ('d', dst, dst, databaseName);
248 file_extract ('a', src, dst, databaseName);
249 copy_file (dst, src);
253 repository_update_r (cmd, dst, src, databaseName);
261 strcpy (dst +dst_len+1, e_src[i_src].name);
262 strcpy (src +src_len+1, e_src[i_src].name);
265 switch (fs_src.st_mode & S_IFMT)
268 file_extract ('a', src, dst, databaseName);
269 copy_file (dst, src);
272 repository_add_tree (cmd, dst, src, databaseName);
279 strcpy (dst +dst_len+1, e_dst[i_dst].name);
280 strcpy (src +src_len+1, e_dst[i_dst].name);
283 switch (fs_dst.st_mode & S_IFMT)
286 file_extract ('d', dst, dst, databaseName);
290 repository_del_tree (cmd, dst, src, databaseName);
300 void repository (int cmd, const char *rep, const char *base_path,
306 strcpy (rep_tmp1, rep);
309 strcpy (rep_tmp2, base_path);
310 repository_update_r (cmd, rep_tmp2, rep_tmp1, databaseName);
313 repository_extract_r (cmd, rep_tmp1, databaseName);
317 static int repComp (const char *a, const char *b, size_t len)
321 return memcmp (a, b, len);
324 static void repositoryUpdateR (struct dirs_info *di, struct dirs_entry *dst,
325 const char *base, char *src, char *databaseName)
327 struct dir_entry *e_src;
329 static char tmppath[256];
330 size_t src_len = strlen (src);
332 sprintf (tmppath, "%s%s", base, src);
333 e_src = dir_open (tmppath);
336 if (!dst || repComp (dst->path, src, src_len))
338 if (!dst || strcmp (dst->path, src))
343 if (src_len && src[src_len-1] == '/')
347 src[src_len+1] = '\0';
348 dirs_mkdir (di, src, 0);
353 /* delete tree dst */
358 if (src_len && src[src_len-1] == '/')
362 src[src_len+1] = '\0';
363 dst = dirs_read (di);
371 if (dst && !repComp (dst->path, src, src_len+1))
373 if (e_src[i_src].name)
375 logf (LOG_DEBUG, "dst=%s src=%s", dst->path + src_len+1,
377 sd = strcmp (dst->path + src_len+1, e_src[i_src].name);
382 else if (e_src[i_src].name)
386 logf (LOG_DEBUG, "trav sd=%d", sd);
389 strcpy (src + src_len+1, e_src[i_src].name);
390 sprintf (tmppath, "%s%s", base, src);
392 switch (e_src[i_src].kind)
395 if (e_src[i_src].ctime > dst->ctime)
397 if (fileExtract (&dst->sysno, tmppath, databaseName, 0))
398 dirs_add (di, src, dst->sysno, e_src[i_src].ctime);
400 dst = dirs_read (di);
403 repositoryUpdateR (di, dst, base, src, databaseName);
404 dst = dirs_last (di);
405 logf (LOG_DEBUG, "last is %s", dst ? dst->path : "null");
408 dst = dirs_read (di);
415 strcpy (src + src_len+1, e_src[i_src].name);
416 sprintf (tmppath, "%s%s", base, src);
418 switch (e_src[i_src].kind)
421 if (fileExtract (&sysno, tmppath, databaseName, 0))
422 dirs_add (di, src, sysno, e_src[i_src].ctime);
425 repositoryUpdateR (di, dst, base, src, databaseName);
427 dst = dirs_last (di);
440 void repositoryUpdate (const char *path, char *databaseName)
442 struct dirs_info *di;
446 dict = dict_open ("repdict", 40, 1);
448 di = dirs_open (dict, path);
450 repositoryUpdateR (di, dirs_read (di), path, src, databaseName);