New simple file index tool.
[idzebra-moved-to-github.git] / index / main.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: main.c,v $
7  * Revision 1.1  1995-08-31 14:50:24  adam
8  * New simple file index tool.
9  *
10  */
11 #include <stdio.h>
12 #include <assert.h>
13 #include <unistd.h>
14 #include <dirent.h>
15 #include <sys/stat.h>
16 #include <sys/types.h>
17 #include <fcntl.h>
18 #include <ctype.h>
19
20 #include <util.h>
21 #include "index.h"
22
23 char *prog;
24
25 static int key_fd = -1;
26 #define KEY_BUF_SIZE 100000
27 static char *key_buf;
28 int key_offset;
29 SYSNO sysno_next;
30 Dict file_idx;
31 static char *base_path = NULL;
32
33 void key_open (const char *fname)
34 {
35     void *file_key;
36     if (key_fd != -1)
37         return;
38     if ((key_fd = open (fname, O_RDWR|O_CREAT, 0666)) == -1)
39     {
40         log (LOG_FATAL|LOG_ERRNO, "Creat %s", fname);
41         exit (1);
42     }
43     if (!(key_buf = malloc (KEY_BUF_SIZE)))
44     {
45         log (LOG_FATAL|LOG_ERRNO, "malloc");
46         exit (1);
47     }
48     key_offset = 0;
49     if (!(file_idx = dict_open ("fileidx", 10, 1)))
50     {
51         log (LOG_FATAL, "dict_open fail of %s", "fileidx");
52         exit (1);
53     }
54     file_key = dict_lookup (file_idx, ".");
55     if (file_key)
56         memcpy (&sysno_next, (char*)file_key+1, sizeof(sysno_next));
57     else
58         sysno_next = 1;
59 }
60
61 void key_close (void)
62 {
63     if (key_fd == -1)
64         return;
65     close (key_fd);
66     dict_insert (file_idx, ".", sizeof(sysno_next), &sysno_next);
67     dict_close (file_idx);
68     key_fd = -1;
69 }
70
71 void key_flush (void)
72 {
73     size_t i = 0;
74     int w;
75     
76     while (i < key_offset)
77     {
78         w = write (key_fd, key_buf + i, key_offset - i);
79         if (w == -1)
80         {
81             log (LOG_FATAL|LOG_ERRNO, "Write key fail");
82             exit (1);
83         }
84         i += w;
85     }
86     key_offset = 0;
87 }
88
89 void key_write (int cmd, struct it_key *k, const char *str)
90 {
91     char x = cmd;
92     size_t slen = strlen(str);
93
94     if (key_offset + sizeof(*k) + slen >= KEY_BUF_SIZE - 2)
95         key_flush ();
96     memcpy (key_buf + key_offset, &x, 1);
97     key_offset++;
98     memcpy (key_buf + key_offset, k, sizeof(*k));
99     key_offset += sizeof(*k);
100     memcpy (key_buf + key_offset, str, slen+1);
101     key_offset += slen+1;
102 }
103
104 void text_extract (SYSNO sysno, int cmd, const char *fname)
105 {
106     FILE *inf;
107     struct it_key k;
108     int seqno = 1;
109     int c;
110     char w[256];
111
112     log (LOG_DEBUG, "Text extract of %d", sysno);
113     k.sysno = sysno;
114     inf = fopen (fname, "r");
115     if (!inf)
116     {
117         log (LOG_WARN|LOG_ERRNO, "open %s", fname);
118         return;
119     }
120     while ((c=getc (inf)) != EOF)
121     {
122         int i = 0;
123         while (i < 254 && c != EOF && isalnum(c))
124         {
125             w[i++] = c;
126             c = getc (inf);
127         }
128         if (i)
129         {
130             w[i] = 0;
131             
132             k.seqno = seqno++;
133             k.field = 0;
134             key_write (cmd, &k, w);
135         }
136         if (c == EOF)
137             break;
138     }
139     fclose (inf);
140 }
141
142 void file_extract (int cmd, struct stat *fs, const char *fname)
143 {
144     int i;
145     char ext[128];
146     SYSNO sysno;
147     char ext_res[128];
148     const char *file_type;
149     void *file_info;
150
151     log (LOG_DEBUG, "%c %s", cmd, fname);
152     for (i = strlen(fname); --i >= 0; )
153         if (fname[i] == '/')
154         {
155             strcpy (ext, "");
156             break;
157         }
158         else if (fname[i] == '.')
159         {
160             strcpy (ext, fname+i+1);
161             break;
162         }
163     sprintf (ext_res, "fileExtension.%s", ext);
164     if (!(file_type = res_get (common_resource, ext_res)))
165         return;
166     
167     file_info = dict_lookup (file_idx, fname);
168     if (!file_info)
169     {
170         sysno = sysno_next++;
171         dict_insert (file_idx, fname, sizeof(sysno), &sysno);
172     }
173     else
174         memcpy (&sysno, (char*) file_info+1, sizeof(sysno));
175     if (!strcmp (file_type, "text"))
176         text_extract (sysno, cmd, fname);
177 }
178
179 static void repository_extract_r (int cmd, char *rep)
180 {
181     DIR *dir;
182     size_t rep_len;
183     struct dirent *dent;
184     struct stat fs;
185
186     rep_len = strlen(rep);
187     dir = opendir(rep);
188     if (!dir)
189     {
190         if (errno == ENOENT)
191         {
192             log (LOG_WARN|LOG_ERRNO, "opendir %s", rep);
193             return;
194         }
195         log (LOG_FATAL|LOG_ERRNO, "opendir %s", rep);
196         exit (1);
197     }
198     if (rep[rep_len-1] != '/')
199         rep[rep_len] = '/';
200     else
201         --rep_len;
202     while ((dent = readdir (dir)))
203     {
204         strcpy (rep +rep_len+1, dent->d_name);
205         stat (rep, &fs);
206         switch (fs.st_mode & S_IFMT)
207         {
208         case S_IFREG:
209             file_extract (cmd, &fs, rep);
210             break;
211         case S_IFDIR:
212             if (strcmp (dent->d_name, ".") && strcmp(dent->d_name, ".."))
213                 repository_extract_r (cmd, rep);
214             break;
215         }
216     }
217     closedir (dir);
218 }
219
220 void repository_update_r (int cmd, const char *rep, const char *with_rep)
221 {
222
223 }
224
225 void repository_traverse (int cmd, const char *rep)
226 {
227     char rep_tmp1[2048];
228     char rep_tmp2[2048];
229
230     strcpy (rep_tmp1, rep);
231     if (base_path)
232     {
233         strcpy (rep_tmp2, base_path);
234         repository_update_r (cmd, rep_tmp1, rep_tmp2);
235     }
236     else
237         repository_extract_r (cmd, rep_tmp1);
238 }
239
240
241 int main (int argc, char **argv)
242 {
243     int ret;
244     int cmd = 0;
245     char *arg;
246     char *base_name;
247
248     prog = *argv;
249     while ((ret = options ("b:v:", argv, argc, &arg)) != -2)
250     {
251         if (ret == 0)
252         {
253             if (!base_name)
254             {
255                 base_name = arg;
256
257                 common_resource = res_open (base_name);
258                 if (!common_resource)
259                 {
260                     log (LOG_FATAL, "Cannot open resource `%s'", base_name);
261                     exit (1);
262                 }
263             }
264             else if(cmd == 0) /* command */
265             {
266                 if (!strcmp (arg, "add"))
267                 {
268                     cmd = 'a';
269                 }
270                 else if (!strcmp (arg, "del"))
271                 {
272                     cmd = 'd';
273                 }
274                 else
275                 {
276                     log (LOG_FATAL, "Unknown command: %s", arg);
277                     exit (1);
278                 }
279             }
280             else
281             {
282                 key_open ("keys.tmp");
283                 repository_traverse (cmd, arg);
284                 cmd = 0;
285             }
286         }
287         else if (ret == 'v')
288         {
289             log_init (log_mask_str(arg), prog, NULL);
290         }
291         else if (ret == 'b')
292         {
293             base_path = arg;
294         }
295         else
296         {
297             log (LOG_FATAL, "Unknown option '-%s'", arg);
298             exit (1);
299         }
300     }
301     key_flush ();
302     key_close ();
303     exit (0);
304 }