Blame


1 d957951b 2005-02-11 devnull #include <u.h>
2 d957951b 2005-02-11 devnull #include <libc.h>
3 d957951b 2005-02-11 devnull #include <bio.h>
4 d957951b 2005-02-11 devnull #include <ctype.h>
5 d957951b 2005-02-11 devnull #include <ndb.h>
6 d957951b 2005-02-11 devnull #include "ndbhf.h"
7 d957951b 2005-02-11 devnull
8 34d1b690 2005-12-26 devnull static Ndb* doopen(char*, char*);
9 d957951b 2005-02-11 devnull static void hffree(Ndb*);
10 d957951b 2005-02-11 devnull
11 34d1b690 2005-12-26 devnull static char *deffile = "#9/ndb/local";
12 d957951b 2005-02-11 devnull
13 d957951b 2005-02-11 devnull /*
14 d957951b 2005-02-11 devnull * the database entry in 'file' indicates the list of files
15 d957951b 2005-02-11 devnull * that makeup the database. Open each one and search in
16 d957951b 2005-02-11 devnull * the same order.
17 d957951b 2005-02-11 devnull */
18 d957951b 2005-02-11 devnull Ndb*
19 d957951b 2005-02-11 devnull ndbopen(char *file)
20 d957951b 2005-02-11 devnull {
21 d957951b 2005-02-11 devnull Ndb *db, *first, *last;
22 d957951b 2005-02-11 devnull Ndbs s;
23 d957951b 2005-02-11 devnull Ndbtuple *t, *nt;
24 d957951b 2005-02-11 devnull
25 d957951b 2005-02-11 devnull if(file == 0)
26 34d1b690 2005-12-26 devnull file = unsharp(deffile);
27 34d1b690 2005-12-26 devnull db = doopen(file, nil);
28 d957951b 2005-02-11 devnull if(db == 0)
29 d957951b 2005-02-11 devnull return 0;
30 d957951b 2005-02-11 devnull first = last = db;
31 d957951b 2005-02-11 devnull t = ndbsearch(db, &s, "database", "");
32 d957951b 2005-02-11 devnull Bseek(&db->b, 0, 0);
33 d957951b 2005-02-11 devnull if(t == 0)
34 d957951b 2005-02-11 devnull return db;
35 d957951b 2005-02-11 devnull for(nt = t; nt; nt = nt->entry){
36 d957951b 2005-02-11 devnull if(strcmp(nt->attr, "file") != 0)
37 d957951b 2005-02-11 devnull continue;
38 d957951b 2005-02-11 devnull if(strcmp(nt->val, file) == 0){
39 d957951b 2005-02-11 devnull /* default file can be reordered in the list */
40 d957951b 2005-02-11 devnull if(first->next == 0)
41 d957951b 2005-02-11 devnull continue;
42 d957951b 2005-02-11 devnull if(strcmp(first->file, file) == 0){
43 d957951b 2005-02-11 devnull db = first;
44 d957951b 2005-02-11 devnull first = first->next;
45 d957951b 2005-02-11 devnull last->next = db;
46 d957951b 2005-02-11 devnull db->next = 0;
47 d957951b 2005-02-11 devnull last = db;
48 d957951b 2005-02-11 devnull }
49 d957951b 2005-02-11 devnull continue;
50 d957951b 2005-02-11 devnull }
51 34d1b690 2005-12-26 devnull db = doopen(nt->val, file);
52 d957951b 2005-02-11 devnull if(db == 0)
53 d957951b 2005-02-11 devnull continue;
54 d957951b 2005-02-11 devnull last->next = db;
55 d957951b 2005-02-11 devnull last = db;
56 d957951b 2005-02-11 devnull }
57 d957951b 2005-02-11 devnull ndbfree(t);
58 d957951b 2005-02-11 devnull return first;
59 d957951b 2005-02-11 devnull }
60 d957951b 2005-02-11 devnull
61 d957951b 2005-02-11 devnull /*
62 d957951b 2005-02-11 devnull * open a single file
63 d957951b 2005-02-11 devnull */
64 d957951b 2005-02-11 devnull static Ndb*
65 34d1b690 2005-12-26 devnull doopen(char *file, char *rel)
66 d957951b 2005-02-11 devnull {
67 34d1b690 2005-12-26 devnull char *p;
68 d957951b 2005-02-11 devnull Ndb *db;
69 d957951b 2005-02-11 devnull
70 d957951b 2005-02-11 devnull db = (Ndb*)malloc(sizeof(Ndb));
71 d957951b 2005-02-11 devnull if(db == 0)
72 d957951b 2005-02-11 devnull return 0;
73 34d1b690 2005-12-26 devnull
74 d957951b 2005-02-11 devnull memset(db, 0, sizeof(Ndb));
75 34d1b690 2005-12-26 devnull /*
76 34d1b690 2005-12-26 devnull * Rooted paths are taken as is.
77 34d1b690 2005-12-26 devnull * Unrooted paths are taken relative to db we opened.
78 34d1b690 2005-12-26 devnull */
79 34d1b690 2005-12-26 devnull if(file[0]!='/' && rel && (p=strrchr(rel, '/'))!=nil)
80 fa325e9b 2020-01-10 cross snprint(db->file, sizeof(db->file), "%.*s/%s",
81 34d1b690 2005-12-26 devnull utfnlen(rel, p-rel), rel, file);
82 34d1b690 2005-12-26 devnull else
83 34d1b690 2005-12-26 devnull strncpy(db->file, file, sizeof(db->file)-1);
84 d957951b 2005-02-11 devnull
85 d957951b 2005-02-11 devnull if(ndbreopen(db) < 0){
86 d957951b 2005-02-11 devnull free(db);
87 d957951b 2005-02-11 devnull return 0;
88 d957951b 2005-02-11 devnull }
89 d957951b 2005-02-11 devnull
90 d957951b 2005-02-11 devnull return db;
91 d957951b 2005-02-11 devnull }
92 d957951b 2005-02-11 devnull
93 d957951b 2005-02-11 devnull /*
94 d957951b 2005-02-11 devnull * dump any cached information, forget the hash tables, and reopen a single file
95 d957951b 2005-02-11 devnull */
96 d957951b 2005-02-11 devnull int
97 d957951b 2005-02-11 devnull ndbreopen(Ndb *db)
98 d957951b 2005-02-11 devnull {
99 d957951b 2005-02-11 devnull int fd;
100 d957951b 2005-02-11 devnull Dir *d;
101 d957951b 2005-02-11 devnull
102 d957951b 2005-02-11 devnull /* forget what we know about the open files */
103 d957951b 2005-02-11 devnull if(db->mtime){
104 d957951b 2005-02-11 devnull _ndbcacheflush(db);
105 d957951b 2005-02-11 devnull hffree(db);
106 d957951b 2005-02-11 devnull close(Bfildes(&db->b));
107 d957951b 2005-02-11 devnull Bterm(&db->b);
108 d957951b 2005-02-11 devnull db->mtime = 0;
109 d957951b 2005-02-11 devnull }
110 d957951b 2005-02-11 devnull
111 d957951b 2005-02-11 devnull /* try the open again */
112 d957951b 2005-02-11 devnull fd = open(db->file, OREAD);
113 d957951b 2005-02-11 devnull if(fd < 0)
114 d957951b 2005-02-11 devnull return -1;
115 d957951b 2005-02-11 devnull d = dirfstat(fd);
116 d957951b 2005-02-11 devnull if(d == nil){
117 d957951b 2005-02-11 devnull close(fd);
118 d957951b 2005-02-11 devnull return -1;
119 d957951b 2005-02-11 devnull }
120 d957951b 2005-02-11 devnull
121 d957951b 2005-02-11 devnull db->qid = d->qid;
122 d957951b 2005-02-11 devnull db->mtime = d->mtime;
123 d957951b 2005-02-11 devnull db->length = d->length;
124 d957951b 2005-02-11 devnull Binit(&db->b, fd, OREAD);
125 d957951b 2005-02-11 devnull free(d);
126 d957951b 2005-02-11 devnull return 0;
127 d957951b 2005-02-11 devnull }
128 d957951b 2005-02-11 devnull
129 d957951b 2005-02-11 devnull /*
130 d957951b 2005-02-11 devnull * close the database files
131 d957951b 2005-02-11 devnull */
132 d957951b 2005-02-11 devnull void
133 d957951b 2005-02-11 devnull ndbclose(Ndb *db)
134 d957951b 2005-02-11 devnull {
135 d957951b 2005-02-11 devnull Ndb *nextdb;
136 d957951b 2005-02-11 devnull
137 d957951b 2005-02-11 devnull for(; db; db = nextdb){
138 d957951b 2005-02-11 devnull nextdb = db->next;
139 d957951b 2005-02-11 devnull _ndbcacheflush(db);
140 d957951b 2005-02-11 devnull hffree(db);
141 d957951b 2005-02-11 devnull close(Bfildes(&db->b));
142 d957951b 2005-02-11 devnull Bterm(&db->b);
143 d957951b 2005-02-11 devnull free(db);
144 d957951b 2005-02-11 devnull }
145 d957951b 2005-02-11 devnull }
146 d957951b 2005-02-11 devnull
147 d957951b 2005-02-11 devnull /*
148 d957951b 2005-02-11 devnull * free the hash files belonging to a db
149 d957951b 2005-02-11 devnull */
150 d957951b 2005-02-11 devnull static void
151 d957951b 2005-02-11 devnull hffree(Ndb *db)
152 d957951b 2005-02-11 devnull {
153 d957951b 2005-02-11 devnull Ndbhf *hf, *next;
154 d957951b 2005-02-11 devnull
155 d957951b 2005-02-11 devnull for(hf = db->hf; hf; hf = next){
156 d957951b 2005-02-11 devnull next = hf->next;
157 d957951b 2005-02-11 devnull close(hf->fd);
158 d957951b 2005-02-11 devnull free(hf);
159 d957951b 2005-02-11 devnull }
160 d957951b 2005-02-11 devnull db->hf = 0;
161 d957951b 2005-02-11 devnull }
162 d957951b 2005-02-11 devnull
163 d957951b 2005-02-11 devnull /*
164 d957951b 2005-02-11 devnull * return true if any part of the database has changed
165 d957951b 2005-02-11 devnull */
166 d957951b 2005-02-11 devnull int
167 d957951b 2005-02-11 devnull ndbchanged(Ndb *db)
168 d957951b 2005-02-11 devnull {
169 d957951b 2005-02-11 devnull Ndb *ndb;
170 d957951b 2005-02-11 devnull Dir *d;
171 d957951b 2005-02-11 devnull
172 d957951b 2005-02-11 devnull for(ndb = db; ndb != nil; ndb = ndb->next){
173 d957951b 2005-02-11 devnull d = dirfstat(Bfildes(&db->b));
174 d957951b 2005-02-11 devnull if(d == nil)
175 d957951b 2005-02-11 devnull continue;
176 d957951b 2005-02-11 devnull if(ndb->qid.path != d->qid.path
177 d957951b 2005-02-11 devnull || ndb->qid.vers != d->qid.vers){
178 d957951b 2005-02-11 devnull free(d);
179 d957951b 2005-02-11 devnull return 1;
180 d957951b 2005-02-11 devnull }
181 d957951b 2005-02-11 devnull free(d);
182 d957951b 2005-02-11 devnull }
183 d957951b 2005-02-11 devnull return 0;
184 d957951b 2005-02-11 devnull }