Option: only one word key per file.
[idzebra-moved-to-github.git] / index / extract.c
1 /*
2  * Copyright (C) 1994-1995, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: extract.c,v $
7  * Revision 1.5  1995-09-06 16:11:16  adam
8  * Option: only one word key per file.
9  *
10  * Revision 1.4  1995/09/05  15:28:39  adam
11  * More work on search engine.
12  *
13  * Revision 1.3  1995/09/04  12:33:41  adam
14  * Various cleanup. YAZ util used instead.
15  *
16  * Revision 1.2  1995/09/04  09:10:34  adam
17  * More work on index add/del/update.
18  * Merge sort implemented.
19  * Initial work on z39 server.
20  *
21  * Revision 1.1  1995/09/01  14:06:35  adam
22  * Split of work into more files.
23  *
24  */
25 #include <stdio.h>
26 #include <assert.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <ctype.h>
30
31 #include <alexutil.h>
32 #include "index.h"
33
34 #define KEY_BUF_SIZE 100000
35
36 static Dict file_idx;
37 static SYSNO sysno_next;
38 static int key_fd = -1;
39 static int sys_idx_fd = -1;
40 static char *key_buf;
41 static int key_offset;
42
43 void key_open (const char *fname)
44 {
45     void *file_key;
46     if (key_fd != -1)
47         return;
48     if ((key_fd = open (fname, O_RDWR|O_CREAT, 0666)) == -1)
49     {
50         logf (LOG_FATAL|LOG_ERRNO, "open %s", fname);
51         exit (1);
52     }
53     logf (LOG_DEBUG, "key_open of %s", fname);
54     if (!(key_buf = malloc (KEY_BUF_SIZE)))
55     {
56         logf (LOG_FATAL|LOG_ERRNO, "malloc");
57         exit (1);
58     }
59     key_offset = 0;
60     if (!(file_idx = dict_open (FNAME_FILE_DICT, 40, 1)))
61     {
62         logf (LOG_FATAL, "dict_open fail of %s", "fileidx");
63         exit (1);
64     }
65     file_key = dict_lookup (file_idx, ".");
66     if (file_key)
67         memcpy (&sysno_next, (char*)file_key+1, sizeof(sysno_next));
68     else
69         sysno_next = 1;
70     if ((sys_idx_fd = open (FNAME_SYS_IDX, O_RDWR|O_CREAT, 0666)) == -1)
71     {
72         logf (LOG_FATAL|LOG_ERRNO, "open %s", FNAME_SYS_IDX);
73         exit (1);
74     }
75 }
76
77 int key_close (void)
78 {
79     if (key_fd == -1)
80     {
81         logf (LOG_DEBUG, "key_close - but no file");
82         return 0;
83     }
84     close (key_fd);
85     close (sys_idx_fd);
86     dict_insert (file_idx, ".", sizeof(sysno_next), &sysno_next);
87     dict_close (file_idx);
88     key_fd = -1;
89     logf (LOG_DEBUG, "key close - key file exist");
90     return 1;
91 }
92
93 void key_flush (void)
94 {
95     size_t i = 0;
96     int w;
97
98     if (key_fd == -1)
99         return; 
100     while (i < key_offset)
101     {
102         w = write (key_fd, key_buf + i, key_offset - i);
103         if (w == -1)
104         {
105             logf (LOG_FATAL|LOG_ERRNO, "Write key fail");
106             exit (1);
107         }
108         i += w;
109     }
110     key_offset = 0;
111 }
112
113 void key_write (int cmd, struct it_key *k, const char *str)
114 {
115     char x;
116     size_t slen = strlen(str);
117
118     if (key_offset + sizeof(*k) + slen >= KEY_BUF_SIZE - 2)
119         key_flush ();
120     x = (cmd == 'a') ? 1 : 0;
121     memcpy (key_buf + key_offset, str, slen+1);
122     key_offset += slen+1;
123     memcpy (key_buf + key_offset, &x, 1);
124     key_offset++;
125     memcpy (key_buf + key_offset, k, sizeof(*k));
126     key_offset += sizeof(*k);
127 }
128
129 void key_write_x (struct strtab *t, int cmd, struct it_key *k, const char *str)
130 {
131     void **oldinfo;
132
133     if (strtab_src (t, str, &oldinfo))
134         ((struct it_key *) *oldinfo)->seqno++;
135     else
136     {
137         *oldinfo = xmalloc (sizeof(*k));
138         memcpy (*oldinfo, k, sizeof(*k));
139         ((struct it_key *) *oldinfo)->seqno = 1;
140     }
141 }
142
143 void key_rec_flush (const char *str, void *info, void *data)
144 {
145     key_write (*((int*) data), (struct it_key *)info, str);
146     xfree (info);
147 }
148
149 void text_extract (struct strtab *t, SYSNO sysno, int cmd, const char *fname)
150 {
151     FILE *inf;
152     struct it_key k;
153     int seqno = 1;
154     int c;
155     char w[256];
156
157     logf (LOG_DEBUG, "Text extract of %d", sysno);
158     k.sysno = sysno;
159     inf = fopen (fname, "r");
160     if (!inf)
161     {
162         logf (LOG_WARN|LOG_ERRNO, "open %s", fname);
163         return;
164     }
165     while ((c=getc (inf)) != EOF)
166     {
167         int i = 0;
168         while (i < 254 && c != EOF && isalnum(c))
169         {
170             w[i++] = c;
171             c = getc (inf);
172         }
173         if (i)
174         {
175             w[i] = 0;
176             
177             k.seqno = seqno++;
178 #if IT_KEY_HAVE_FIELD
179             k.field = 0;
180 #endif
181             key_write_x (t, cmd, &k, w);
182         }
183         if (c == EOF)
184             break;
185     }
186     fclose (inf);
187 }
188
189 void file_extract (int cmd, const char *fname, const char *kname)
190 {
191     int i;
192     char ext[128];
193     SYSNO sysno;
194     char ext_res[128];
195     const char *file_type;
196     void *file_info;
197     struct strtab *t;
198
199     logf (LOG_DEBUG, "%c %s k=%s", cmd, fname, kname);
200     for (i = strlen(fname); --i >= 0; )
201         if (fname[i] == '/')
202         {
203             strcpy (ext, "");
204             break;
205         }
206         else if (fname[i] == '.')
207         {
208             strcpy (ext, fname+i+1);
209             break;
210         }
211     sprintf (ext_res, "fileExtension.%s", ext);
212     if (!(file_type = res_get (common_resource, ext_res)))
213         return;
214     
215     file_info = dict_lookup (file_idx, kname);
216     if (!file_info)
217     {
218         sysno = sysno_next++;
219         dict_insert (file_idx, kname, sizeof(sysno), &sysno);
220         lseek (sys_idx_fd, sysno * SYS_IDX_ENTRY_LEN, SEEK_SET);
221         write (sys_idx_fd, kname, strlen(kname)+1);
222     }
223     else
224         memcpy (&sysno, (char*) file_info+1, sizeof(sysno));
225     t = strtab_mk ();
226     if (!strcmp (file_type, "text"))
227         text_extract (t, sysno, cmd, fname);
228     strtab_del (t, key_rec_flush, &cmd);
229 }
230
231