Include zebrautl.h instead of alexutil.h.
[idzebra-moved-to-github.git] / index / dirs.c
1 /*
2  * Copyright (C) 1994-1996, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: dirs.c,v $
7  * Revision 1.11  1996-10-29 14:06:47  adam
8  * Include zebrautl.h instead of alexutil.h.
9  *
10  * Revision 1.10  1996/06/04 10:18:58  adam
11  * Minor changes - removed include of ctype.h.
12  *
13  * Revision 1.9  1996/04/23  12:39:07  adam
14  * Bug fix: In function dirs_del dict_delete is used to remove a file
15  * rather than a bogus dict_insert.
16  *
17  * Revision 1.8  1996/04/12  07:02:21  adam
18  * File update of single files.
19  *
20  * Revision 1.7  1996/03/21 14:50:09  adam
21  * File update uses modify-time instead of change-time.
22  *
23  * Revision 1.6  1996/02/02  13:44:43  adam
24  * The public dictionary functions simply use char instead of Dict_char
25  * to represent search strings. Dict_char is used internally only.
26  *
27  * Revision 1.5  1996/01/17  14:54:44  adam
28  * Function dirs_rmdir uses dict_delete.
29  *
30  * Revision 1.4  1995/11/30  08:34:27  adam
31  * Started work on commit facility.
32  * Changed a few malloc/free to xmalloc/xfree.
33  *
34  * Revision 1.3  1995/11/20  16:59:45  adam
35  * New update method: the 'old' keys are saved for each records.
36  *
37  * Revision 1.2  1995/11/20  11:56:23  adam
38  * Work on new traversal.
39  *
40  * Revision 1.1  1995/11/17  15:54:42  adam
41  * Started work on virtual directory structure.
42  */
43 #include <stdio.h>
44 #include <assert.h>
45 #include <errno.h>
46 #include <fcntl.h>
47
48 #include "index.h"
49
50 struct dirs_info {
51     Dict dict;
52     int no_read;
53     int no_cur;
54     int no_max;
55     struct dirs_entry *entries;
56     char nextpath[256];
57     char prefix[256];
58     int prelen;
59     struct dirs_entry *last_entry;
60 };
61
62 static int dirs_client_proc (char *name, const char *info, int pos,
63                              void *client)
64 {
65     struct dirs_info *ci = client;
66     struct dirs_entry *entry;
67
68     if (memcmp (name, ci->prefix, ci->prelen))
69         return 1;
70     if (ci->no_cur < 0)
71     {
72         ci->no_cur = 0;
73         return 0;
74     }
75     if (ci->no_cur == ci->no_max)
76     {
77         assert (0);
78     }
79     entry = ci->entries + ci->no_cur;
80     if (info[0] == sizeof(entry->sysno)+sizeof(entry->mtime))
81     {
82         strcpy (entry->path, name + ci->prelen); 
83         entry->kind = dirs_file;
84         memcpy (&entry->sysno, info+1, sizeof(entry->sysno));
85         memcpy (&entry->mtime, info+1+sizeof(entry->sysno), 
86                 sizeof(entry->mtime));
87         ci->no_cur++;
88     } 
89     else if (info[0] == sizeof(entry->mtime))
90     {
91         strcpy (entry->path, name + ci->prelen);
92         entry->kind = dirs_dir;
93         memcpy (&entry->mtime, info+1, sizeof(entry->mtime));
94         ci->no_cur++;
95     }
96     return 0;
97 }
98
99 struct dirs_info *dirs_open (Dict dict, const char *rep)
100 {
101     struct dirs_info *p;
102     int before = 0, after;
103
104     logf (LOG_DEBUG, "dirs_open %s", rep);
105     p = xmalloc (sizeof (*p));
106     p->dict = dict;
107     strcpy (p->prefix, rep);
108     p->prelen = strlen(p->prefix);
109     strcpy (p->nextpath, rep);
110     p->no_read = p->no_cur = 0;
111     after = p->no_max = 400;
112     p->entries = xmalloc (sizeof(*p->entries) * (p->no_max));
113     logf (LOG_DEBUG, "dirs_open first scan");
114     dict_scan (p->dict, p->nextpath, &before, &after, p, dirs_client_proc);
115     return p;
116 }
117
118 struct dirs_info *dirs_fopen (Dict dict, const char *path)
119 {
120     struct dirs_info *p;
121     struct dirs_entry *entry;
122     char *info;
123
124     p = xmalloc (sizeof(*p));
125     p->dict = dict;
126     *p->prefix = '\0';
127     p->entries = xmalloc (sizeof(*p->entries));
128     p->no_read = 0;
129     p->no_cur = 0;
130     p->no_max = 2;
131
132     entry = p->entries;
133     info = dict_lookup (dict, path);
134     if (info && info[0] == sizeof(entry->sysno)+sizeof(entry->mtime))
135     {
136         strcpy (entry->path, path); 
137         entry->kind = dirs_file;
138         memcpy (&entry->sysno, info+1, sizeof(entry->sysno));
139         memcpy (&entry->mtime, info+1+sizeof(entry->sysno), 
140                 sizeof(entry->mtime));
141         p->no_cur++;
142     }
143     return p;
144 }
145
146 struct dirs_entry *dirs_read (struct dirs_info *p)
147 {
148     int before = 0, after = p->no_max+1;
149
150     if (p->no_read < p->no_cur)
151     {
152         logf (LOG_DEBUG, "dirs_read %d. returns %s", p->no_read,
153               (p->entries + p->no_read)->path);
154         return p->last_entry = p->entries + (p->no_read++);
155     }
156     if (p->no_cur < p->no_max)
157         return p->last_entry = NULL;
158     p->no_cur = -1;
159     logf (LOG_DEBUG, "dirs_read rescan");
160     dict_scan (p->dict, p->nextpath, &before, &after, p, dirs_client_proc);
161     p->no_read = 1;
162     if (p->no_read < p->no_cur)
163         return p->last_entry = p->entries;
164     return p->last_entry = NULL;
165 }
166
167 struct dirs_entry *dirs_last (struct dirs_info *p)
168 {
169     return p->last_entry;
170 }
171
172 void dirs_mkdir (struct dirs_info *p, const char *src, time_t mtime)
173 {
174     char path[256];
175
176     sprintf (path, "%s%s", p->prefix, src);
177     logf (LOG_DEBUG, "dirs_mkdir %s", path);
178     dict_insert (p->dict, path, sizeof(mtime), &mtime);
179 }
180
181 void dirs_rmdir (struct dirs_info *p, const char *src)
182 {
183     char path[256];
184
185     sprintf (path, "%s%s", p->prefix, src);
186     logf (LOG_DEBUG, "dirs_rmdir %s", path);
187     dict_delete (p->dict, path);
188 }
189
190 void dirs_add (struct dirs_info *p, const char *src, int sysno, time_t mtime)
191 {
192     char path[256];
193     char info[16];
194
195     sprintf (path, "%s%s", p->prefix, src);
196     logf (LOG_DEBUG, "dirs_add %s", path);
197     memcpy (info, &sysno, sizeof(sysno));
198     memcpy (info+sizeof(sysno), &mtime, sizeof(mtime));
199     dict_insert (p->dict, path, sizeof(sysno)+sizeof(mtime), info);
200 }
201
202 void dirs_del (struct dirs_info *p, const char *src)
203 {
204     char path[256];
205
206     sprintf (path, "%s%s", p->prefix, src);
207     logf (LOG_DEBUG, "dirs_del %s", path);
208     dict_delete (p->dict, path);
209 }
210
211 void dirs_free (struct dirs_info **pp)
212 {
213     struct dirs_info *p = *pp;
214
215     xfree (p->entries);
216     xfree (p);
217     *pp = NULL;
218 }
219