Fixes stat() #include
[akaros.git] / user / ndblib / ndbopen.c
1 /* 
2  * This file is part of the UCB release of Plan 9. It is subject to the license
3  * terms in the LICENSE file found in the top-level directory of this
4  * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
5  * part of the UCB release of Plan 9, including this file, may be copied,
6  * modified, propagated, or distributed except according to the terms contained
7  * in the LICENSE file.
8  */
9 #include <stdlib.h>
10
11 #include <stdio.h>
12 #include <parlib.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <unistd.h>
16 #include <signal.h>
17 #include <fcntl.h>
18 #include <iplib.h>
19 #include <dir.h>
20 #include <ndb.h>
21 #include "ndbhf.h"
22
23 static struct ndb*      doopen(char*);
24 static void     hffree(struct ndb*);
25
26 static char *deffile = "/lib/ndb/local";
27
28 /*
29  *  the database entry in 'file' indicates the list of files
30  *  that makeup the database.  Open each one and search in
31  *  the same order.
32  */
33 struct ndb*
34 ndbopen(char *file)
35 {
36
37         struct ndb *db, *first, *last;
38         struct ndbs s;
39         struct ndbtuple *t, *nt;
40
41         if(file == 0)
42                 file = deffile;
43         db = doopen(file);
44         if(db == 0) {
45                 return 0;
46         }
47         first = last = db;
48         t = ndbsearch(db, &s, "database", "");
49         fseek(db->b, 0, 0);
50         if(t == 0) {
51                 return db;
52         }
53         for(nt = t; nt; nt = nt->entry){
54                 if(strcmp(nt->attr, "file") != 0)
55                         continue;
56                 if(strcmp(nt->val, file) == 0){
57                         /* default file can be reordered in the list */
58                         if(first->next == 0)
59                                 continue;
60                         if(strcmp(first->file, file) == 0){
61                                 db = first;
62                                 first = first->next;
63                                 last->next = db;
64                                 db->next = 0;
65                                 last = db;
66                         }
67                         continue;
68                 }
69                 db = doopen(nt->val);
70                 if(db == 0)
71                         continue;
72                 last->next = db;
73                 last = db;
74         }
75         ndbfree(t);
76         return first;
77 }
78
79 /*
80  *  open a single file
81  */
82 static struct ndb*
83 doopen(char *file)
84 {
85
86         struct ndb *db;
87
88         db = (struct ndb*)calloc(sizeof(struct ndb), 1);
89         if(db == 0) {
90                 return 0;
91         }
92         memset(db, 0, sizeof(struct ndb));
93         strncpy(db->file, file, sizeof(db->file)-1);
94
95         if(ndbreopen(db) < 0){
96                 free(db);
97                 return 0;
98         }
99
100         return db;
101 }
102
103 /*
104  *  dump any cached information, forget the hash tables, and reopen a single file
105  */
106 int
107 ndbreopen(struct ndb *db)
108 {
109
110         int fd;
111         struct dir *d;
112
113         /* forget what we know about the open files */
114         if(db->isopen){
115                 _ndbcacheflush(db);
116                 hffree(db);
117                 fclose(db->b);
118                 db->mtime = 0;
119                 db->isopen = 0;
120         }
121
122         /* try the open again */
123         db->b = fopen(db->file, "r");
124         if(! db->b) {
125                 return -1;
126         }
127 #if 0
128         d = dirfstat(fd);
129         if(d == NULL){
130                 close(fd);
131                 return -1;
132         }
133
134         db->qid.path = d->qid.path;
135         db->mtime = d->mtime;
136         db->length = d->length;
137         free(d);
138 #else
139         struct stat s;
140         /* we opened it, this WILL work */
141         stat(db->file, &s);
142         db->qid.path = s.st_ino;
143         db->mtime = s.st_mtime + 1;
144         db->length = s.st_size;
145 #endif
146         db->isopen = 1;
147         return 0;
148 }
149
150 /*
151  *  close the database files
152  */
153 void
154 ndbclose(struct ndb *db)
155 {
156
157         struct ndb *nextdb;
158
159         for(; db; db = nextdb){
160                 nextdb = db->next;
161                 _ndbcacheflush(db);
162                 hffree(db);
163                 fclose(db->b);
164                 free(db);
165         }
166 }
167
168 /*
169  *  free the hash files belonging to a db
170  */
171 static void
172 hffree(struct ndb *db)
173 {
174
175         struct ndbhf *hf, *next;
176
177         for(hf = db->hf; hf; hf = next){
178                 next = hf->next;
179                 close(hf->fd);
180                 free(hf);
181         }
182         db->hf = 0;
183 }
184
185 /*
186  *  return true if any part of the database has changed
187  */
188 int
189 ndbchanged(struct ndb *db)
190 {
191 #warning "ndbchanged always returns 0"
192         return 0;
193 #if 0
194         struct ndb *ndb;
195         struct dir *d;
196
197 /* FIX ME */
198         for(ndb = db; ndb != NULL; ndb = ndb->next){
199                 d = dirfstat(Bfildes(&ndb->b));
200                 if(d == NULL)
201                         continue;
202                 if(ndb->qid.path != d->qid.path
203                 || ndb->qid.vers != d->qid.vers){
204                         free(d);
205                         return 1;
206                 }
207                 free(d);
208         }
209         return 0;
210 #endif
211 }