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