Work on new traversal.
[idzebra-moved-to-github.git] / index / dirs.c
1 /*
2  * Copyright (C) 1994-1995, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: dirs.c,v $
7  * Revision 1.2  1995-11-20 11:56:23  adam
8  * Work on new traversal.
9  *
10  * Revision 1.1  1995/11/17  15:54:42  adam
11  * Started work on virtual directory structure.
12  */
13 #include <stdio.h>
14 #include <assert.h>
15 #include <errno.h>
16 #include <fcntl.h>
17 #include <ctype.h>
18
19 #include <alexutil.h>
20 #include "index.h"
21
22 struct dirs_info {
23     Dict dict;
24     int no_read;
25     int no_cur;
26     int no_max;
27     struct dirs_entry *entries;
28     char nextpath[256];
29     char prefix[256];
30     int prelen;
31     struct dirs_entry *last_entry;
32 };
33
34 static int dirs_client_proc (Dict_char *name, const char *info, int pos,
35                              void *client)
36 {
37     struct dirs_info *ci = client;
38     struct dirs_entry *entry;
39
40     if (memcmp (name, ci->prefix, ci->prelen))
41         return 1;
42     if (ci->no_cur < 0)
43     {
44         ci->no_cur = 0;
45         return 0;
46     }
47     if (ci->no_cur == ci->no_max)
48     {
49         assert (0);
50     }
51     entry = ci->entries + ci->no_cur;
52     if (info[0] == sizeof(entry->sysno)+sizeof(entry->ctime))
53     {
54         strcpy (entry->path, name + ci->prelen); 
55         entry->kind = dirs_file;
56         memcpy (&entry->sysno, info+1, sizeof(entry->sysno));
57         memcpy (&entry->ctime, info+1+sizeof(entry->sysno), 
58                 sizeof(entry->ctime));
59         ci->no_cur++;
60     } 
61     else if (info[0] == sizeof(entry->ctime))
62     {
63         strcpy (entry->path, name + ci->prelen);
64         entry->kind = dirs_dir;
65         memcpy (&entry->ctime, info+1, sizeof(entry->ctime));
66         ci->no_cur++;
67     }
68     return 0;
69 }
70
71 struct dirs_info *dirs_open (Dict dict, const char *rep)
72 {
73     struct dirs_info *p;
74     int before = 0, after;
75
76     logf (LOG_DEBUG, "dirs_open %s", rep);
77     if (!(p = malloc (sizeof (*p))))
78     {
79         logf (LOG_FATAL|LOG_ERRNO, "malloc");
80         exit (1);
81     }
82     p->dict = dict;
83     strcpy (p->prefix, rep);
84     p->prelen = strlen(p->prefix);
85     strcpy (p->nextpath, rep);
86     p->no_read = p->no_cur = 0;
87     after = p->no_max = 400;
88     if (!(p->entries = malloc (sizeof(*p->entries) * (p->no_max))))
89     {
90         logf (LOG_FATAL|LOG_ERRNO, "malloc");
91         exit (1);
92     }
93     logf (LOG_DEBUG, "dirs_open first scan");
94     dict_scan (p->dict, p->nextpath, &before, &after, p, dirs_client_proc);
95     return p;
96 }
97
98 struct dirs_entry *dirs_read (struct dirs_info *p)
99 {
100     int before = 0, after = p->no_max;
101
102     if (p->no_read < p->no_cur)
103     {
104         logf (LOG_DEBUG, "dirs_read %d. returns %s", p->no_read,
105               (p->entries + p->no_read)->path);
106         return p->last_entry = p->entries + (p->no_read++);
107     }
108     if (p->no_cur < p->no_max)
109         return p->last_entry = NULL;
110 #if 0
111     strcpy (p->nextpath, p->prefix);
112     strcat (p->nextpath, (p->entries + p->no_max-1)->path);
113 #endif
114     p->no_cur = -1;
115     logf (LOG_DEBUG, "dirs_read rescan");
116     dict_scan (p->dict, p->nextpath, &before, &after, p, dirs_client_proc);
117     p->no_read = 1;
118     if (p->no_read < p->no_cur)
119         return p->last_entry = p->entries;
120     return p->last_entry = NULL;
121 }
122
123 struct dirs_entry *dirs_last (struct dirs_info *p)
124 {
125     return p->last_entry;
126 }
127
128 void dirs_mkdir (struct dirs_info *p, const char *src, int ctime)
129 {
130     char path[256];
131
132     sprintf (path, "%s%s", p->prefix, src);
133     logf (LOG_DEBUG, "dirs_mkdir %s", path);
134     dict_insert (p->dict, path, sizeof(ctime), &ctime);
135 }
136
137 void dirs_rmdir (struct dirs_info *p, const char *src)
138 {
139     char path[256];
140     char info[2];
141
142     sprintf (path, "%s%s", p->prefix, src);
143     logf (LOG_DEBUG, "dirs_rmdir %s", path);
144     info[0] = 'r';
145     dict_insert (p->dict, path, 1, info);
146 }
147
148 void dirs_add (struct dirs_info *p, const char *src, int sysno, int ctime)
149 {
150     char path[256];
151     char info[16];
152
153     sprintf (path, "%s%s", p->prefix, src);
154     logf (LOG_DEBUG, "dirs_add %s", path);
155     memcpy (info, &sysno, sizeof(sysno));
156     memcpy (info+sizeof(sysno), &ctime, sizeof(ctime));
157     dict_insert (p->dict, path, sizeof(sysno)+sizeof(ctime), info);
158 }
159
160 void dirs_del (struct dirs_info *p, const char *src)
161 {
162     char path[256];
163     char info[2];
164
165     sprintf (path, "%s%s", p->prefix, src);
166     logf (LOG_DEBUG, "dirs_del %s", path);
167     info[0] = 'r';
168     dict_insert (p->dict, path, 1, info);
169 }
170
171 void dirs_free (struct dirs_info **pp)
172 {
173     struct dirs_info *p = *pp;
174
175     free (p->entries);
176     free (p);
177     *pp = NULL;
178 }
179