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