Updated WIN32 code specific sections. Changed header.
[idzebra-moved-to-github.git] / bfile / bfile.c
1 /*
2  * Copyright (C) 1994-1999, Index Data
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: bfile.c,v $
7  * Revision 1.27  1999-02-02 14:50:01  adam
8  * Updated WIN32 code specific sections. Changed header.
9  *
10  * Revision 1.26  1998/02/17 10:32:52  adam
11  * Fixed bug: binary files weren't opened with flag b on NT.
12  *
13  * Revision 1.25  1997/10/27 14:25:38  adam
14  * Fixed memory leaks.
15  *
16  * Revision 1.24  1997/09/18 08:59:16  adam
17  * Extra generic handle for the character mapping routines.
18  *
19  * Revision 1.23  1997/09/17 12:19:06  adam
20  * Zebra version corresponds to YAZ version 1.4.
21  * Changed Zebra server so that it doesn't depend on global common_resource.
22  *
23  * Revision 1.22  1997/09/09 13:37:52  adam
24  * Partial port to WIN95/NT.
25  *
26  * Revision 1.21  1996/10/29 13:56:13  adam
27  * Include of zebrautl.h instead of alexutil.h.
28  *
29  * Revision 1.20  1996/03/26 15:59:04  adam
30  * The directory of the shadow table file can be specified by the new
31  * bf_lockDir call.
32  *
33  * Revision 1.19  1996/02/05  12:28:58  adam
34  * Removed a LOG_LOG message.
35  *
36  * Revision 1.18  1996/01/02  08:59:06  quinn
37  * Changed "commit" setting to "shadow".
38  *
39  * Revision 1.17  1995/12/11  09:03:51  adam
40  * New function: cf_unlink.
41  * New member of commit file head: state (0) deleted, (1) hash file.
42  *
43  * Revision 1.16  1995/12/08  16:21:13  adam
44  * Work on commit/update.
45  *
46  * Revision 1.15  1995/12/01  16:24:28  adam
47  * Commit files use separate meta file area.
48  *
49  * Revision 1.14  1995/12/01  11:37:21  adam
50  * Cached/commit files implemented as meta-files.
51  *
52  * Revision 1.13  1995/11/30  17:00:49  adam
53  * Several bug fixes. Commit system runs now.
54  *
55  * Revision 1.12  1995/11/30  08:33:10  adam
56  * Started work on commit facility.
57  *
58  * Revision 1.11  1995/09/04  12:33:21  adam
59  * Various cleanup. YAZ util used instead.
60  *
61  * Revision 1.10  1994/08/25  10:15:54  quinn
62  * Trivial
63  *
64  * Revision 1.9  1994/08/24  08:45:48  quinn
65  * Using mfile.
66  *
67  * Revision 1.8  1994/08/23  15:03:34  quinn
68  * *** empty log message ***
69  *
70  * Revision 1.7  1994/08/23  14:25:45  quinn
71  * Added O_CREAT because some geek wanted it. Sheesh.
72  *
73  * Revision 1.6  1994/08/23  14:21:38  quinn
74  * Fixed call to log
75  *
76  * Revision 1.5  1994/08/18  08:10:08  quinn
77  * Minimal changes
78  *
79  * Revision 1.4  1994/08/17  14:27:32  quinn
80  * last mods
81  *
82  * Revision 1.2  1994/08/17  14:09:32  quinn
83  * Compiles cleanly (still only dummy).
84  *
85  * Revision 1.1  1994/08/17  13:55:08  quinn
86  * New blocksystem. dummy only
87  *
88  */
89
90 #include <stdio.h>
91 #include <stdlib.h>
92 #include <string.h>
93 #include <assert.h>
94 #ifdef WIN32
95 #include <io.h>
96 #else
97 #include <unistd.h>
98 #endif
99
100 #include <zebrautl.h>
101 #include <bfile.h>
102 #include "cfile.h"
103
104 struct BFiles_struct {
105     MFile_area commit_area;
106     MFile_area_struct *register_area;
107     char *lockDir;
108 };
109
110 BFiles bfs_create (const char *spec)
111 {
112     BFiles bfs = xmalloc (sizeof(*bfs));
113     bfs->commit_area = NULL;
114     bfs->register_area = mf_init("register", spec);
115     bfs->lockDir = NULL;
116     return bfs;
117 }
118
119 void bfs_destroy (BFiles bfs)
120 {
121     xfree (bfs->lockDir);
122     mf_destroy (bfs->commit_area);
123     mf_destroy (bfs->register_area);
124     xfree (bfs);
125 }
126
127 static FILE *open_cache (BFiles bfs, const char *flags)
128 {
129     char cacheFilename[1024];
130     FILE *file;
131
132     sprintf (cacheFilename, "%scache",
133              bfs->lockDir ? bfs->lockDir : "");
134     file = fopen (cacheFilename, flags);
135     return file;
136 }
137
138 static void unlink_cache (BFiles bfs)
139 {
140     char cacheFilename[1024];
141
142     sprintf (cacheFilename, "%scache",
143              bfs->lockDir ? bfs->lockDir : "");
144     unlink (cacheFilename);
145 }
146
147 void bf_lockDir (BFiles bfs, const char *lockDir)
148 {
149     size_t len;
150     
151     xfree (bfs->lockDir);
152     if (lockDir == NULL)
153         lockDir = "";
154     len = strlen(lockDir);
155     bfs->lockDir = xmalloc (len+2);
156     strcpy (bfs->lockDir, lockDir);
157     
158     if (len > 0 && bfs->lockDir[len-1] != '/')
159         strcpy (bfs->lockDir + len, "/");
160 }
161
162 void bf_cache (BFiles bfs, const char *spec)
163 {
164     if (spec)
165     {
166         if (!bfs->commit_area)
167             bfs->commit_area = mf_init ("shadow", spec);
168     }
169     else
170         bfs->commit_area = NULL;
171 }
172
173 int bf_close (BFile bf)
174 {
175     if (bf->cf)
176         cf_close (bf->cf);
177     mf_close (bf->mf);
178     xfree (bf);
179     return 0;
180 }
181
182 BFile bf_open (BFiles bfs, const char *name, int block_size, int wflag)
183 {
184     BFile tmp = xmalloc(sizeof(BFile_struct));
185
186     if (bfs->commit_area)
187     {
188         int first_time;
189
190         tmp->mf = mf_open (bfs->register_area, name, block_size, 0);
191         tmp->cf = cf_open (tmp->mf, bfs->commit_area, name, block_size,
192                            wflag, &first_time);
193         if (first_time)
194         {
195             FILE *outf;
196
197             outf = open_cache (bfs, "ab");
198             if (!outf)
199             {
200                 logf (LOG_FATAL|LOG_ERRNO, "open %scache",
201                       bfs->lockDir ? bfs->lockDir : "");
202                 exit (1);
203             }
204             fprintf (outf, "%s %d\n", name, block_size);
205             fclose (outf);
206         }
207     }
208     else
209     {
210         tmp->mf = mf_open(bfs->register_area, name, block_size, wflag);
211         tmp->cf = NULL;
212     }
213     if (!tmp->mf)
214     {
215         logf (LOG_FATAL, "mf_open failed for %s", name);
216         xfree (tmp);
217         return 0;
218     }
219     return(tmp);
220 }
221
222 int bf_read (BFile bf, int no, int offset, int num, void *buf)
223 {
224     int r;
225
226     if (bf->cf && (r=cf_read (bf->cf, no, offset, num, buf)) != -1)
227         return r;
228     return mf_read (bf->mf, no, offset, num, buf);
229 }
230
231 int bf_write (BFile bf, int no, int offset, int num, const void *buf)
232 {
233     if (bf->cf)
234         return cf_write (bf->cf, no, offset, num, buf);
235     return mf_write (bf->mf, no, offset, num, buf);
236 }
237
238 int bf_commitExists (BFiles bfs)
239 {
240     FILE *inf;
241
242     inf = open_cache (bfs, "rb");
243     if (inf)
244     {
245         fclose (inf);
246         return 1;
247     }
248     return 0;
249 }
250
251 void bf_commitExec (BFiles bfs)
252 {
253     FILE *inf;
254     int block_size;
255     char path[256];
256     MFile mf;
257     CFile cf;
258     int first_time;
259
260     assert (bfs->commit_area);
261     if (!(inf = open_cache (bfs, "rb")))
262     {
263         logf (LOG_LOG, "No commit file");
264         return ;
265     }
266     while (fscanf (inf, "%s %d", path, &block_size) == 2)
267     {
268         mf = mf_open (bfs->register_area, path, block_size, 1);
269         cf = cf_open (mf, bfs->commit_area, path, block_size, 0, &first_time);
270
271         cf_commit (cf);
272
273         cf_close (cf);
274         mf_close (mf);
275     }
276     fclose (inf);
277 }
278
279 void bf_commitClean (BFiles bfs, const char *spec)
280 {
281     FILE *inf;
282     int block_size;
283     char path[256];
284     MFile mf;
285     CFile cf;
286     int mustDisable = 0;
287     int firstTime;
288
289     if (!bfs->commit_area)
290     {
291         bf_cache (bfs, spec);
292         mustDisable = 1;
293     }
294
295     if (!(inf = open_cache (bfs, "rb")))
296         return ;
297     while (fscanf (inf, "%s %d", path, &block_size) == 2)
298     {
299         mf = mf_open (bfs->register_area, path, block_size, 0);
300         cf = cf_open (mf, bfs->commit_area, path, block_size, 1, &firstTime);
301         cf_unlink (cf);
302         cf_close (cf);
303         mf_close (mf);
304     }
305     fclose (inf);
306     unlink_cache (bfs);
307     if (mustDisable)
308         bf_cache (bfs, 0);
309 }