Started work on virtual directory structure.
[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.1  1995-11-17 15:54:42  adam
8  * Started work on virtual directory structure.
9  *
10  * Revision 1.9  1995/10/30  13:42:12  adam
11  * Added errno.h
12  *
13  * Revision 1.8  1995/10/10  13:59:23  adam
14  * Function rset_open changed its wflag parameter to general flags.
15  *
16  * Revision 1.7  1995/09/28  09:19:40  adam
17  * xfree/xmalloc used everywhere.
18  * Extract/retrieve method seems to work for text records.
19  *
20  * Revision 1.6  1995/09/08  14:52:26  adam
21  * Minor changes. Dictionary is lower case now.
22  *
23  * Revision 1.5  1995/09/06  16:11:16  adam
24  * Option: only one word key per file.
25  *
26  * Revision 1.4  1995/09/04  12:33:41  adam
27  * Various cleanup. YAZ util used instead.
28  *
29  * Revision 1.3  1995/09/01  14:06:35  adam
30  * Split of work into more files.
31  *
32  * Revision 1.2  1995/09/01  10:57:07  adam
33  * Minor changes.
34  *
35  * Revision 1.1  1995/09/01  10:34:51  adam
36  * Added dir.c
37  *
38  */
39 #include <stdio.h>
40 #include <assert.h>
41 #include <errno.h>
42 #include <fcntl.h>
43 #include <ctype.h>
44
45 #include <alexutil.h>
46 #include "index.h"
47
48 struct dirs_entry {
49     char path[160];
50     int sysno;
51 };
52
53 struct dirs_info {
54     int no;
55     struct dirs_entry *entries;
56 };
57
58 struct dirs_client_info {
59     struct dirs_info *di;
60     int no_max;
61     char *prefix;
62     int prelen;
63 };
64
65 static int dirs_client_proc (Dict_char *name, const char *info, int pos,
66                              void *client)
67 {
68     struct dirs_client_info *ci = client;
69
70     if (memcmp (name, ci->prefix, ci->prelen))
71         return 1;
72     if (ci->di->no == ci->no_max)
73     {
74         if (ci->no_max > 0)
75         {
76             struct dirs_entry *arn;
77
78             ci->no_max += 1000;
79             arn = malloc (sizeof(*arn) * (ci->no_max));
80             if (!arn)
81             {
82                 logf (LOG_FATAL|LOG_ERRNO, "malloc");
83                 exit (1);
84             }
85             memcpy (arn, ci->di->entries, ci->di->no * sizeof(*arn));
86             free (ci->di->entries);
87             ci->di->entries = arn;
88         }
89     }
90     strcpy ((ci->di->entries + ci->di->no)->path, name); 
91     memcpy (&(ci->di->entries + ci->di->no)->sysno, info+1, *info);
92     assert (*info == sizeof(ci->di->entries->sysno));
93     ++(ci->di->no);
94     return 0;
95 }
96
97 struct dirs_info *dirs_open (Dict dict, const char *rep)
98 {
99     static char wname[200];
100     static char pname[200];
101     int dirid;
102     char *dinfo;
103     struct dirs_client_info dirs_client_info;
104     struct dirs_info *p;
105     int before, after;
106
107     sprintf (wname, "d%s", rep);
108     dinfo = dict_lookup (dict, wname);
109     if (!dinfo)
110         return NULL;
111     if (!(p = malloc (sizeof (*p))))
112     {
113         logf (LOG_FATAL|LOG_ERRNO, "malloc");
114         exit (1);
115     }
116     memcpy (&dirid, dinfo+1, sizeof(dirid));
117     sprintf (wname, "%d.", dirid);
118     strcpy (pname, wname);
119
120     p->no = 0;
121     dirs_client_info.di = p;
122     dirs_client_info.no_max = 0;
123     dirs_client_info.prefix = wname;
124     dirs_client_info.prelen = strlen(wname);
125     strcpy (pname, wname);
126     dict_scan (dict, pname, &before, &after, &dirs_client_info,
127                dirs_client_proc);
128
129     return p;
130 }
131
132 void dirs_free (struct dirs_info **pp)
133 {
134     struct dirs_info *p = *pp;
135
136     free (p->entries);
137     free (p);
138     *pp = NULL;
139 }