Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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