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