|
|
1.1 root 1: #include <stdio.h>
2: #include <sys/fcntl.h>
3: #include "quipu/config.h"
4: #include "quipu/entry.h"
5: #include "psap.h"
6: #include "quipu/malloc.h"
7: #include "logger.h"
8:
9: #ifdef TURBO_DISK
10: #include <gdbm.h>
11: extern RDN parse_rdn;
12: extern LLog *log_dsap;
13: extern int gdbm_errno;
14: extern datum turbo_header_key;
15:
16: static turbo_write_entry(db, e)
17: GDBM_FILE db;
18: Entry e;
19: {
20: static char kbuf[512];
21: static char buf[10000];
22: int rc;
23: PS ps;
24: datum rdn;
25: datum ent;
26:
27: LLOG (log_dsap, LLOG_TRACE,("turbo: write_entry"));
28:
29: /* allocate the string presentation stream to print to */
30: if ( (ps = ps_alloc(str_open)) == NULLPS )
31: return(NOTOK);
32: if ( str_setup(ps, buf, sizeof(buf), 0) == NOTOK ) {
33: ps_free(ps);
34: return(NOTOK);
35: }
36: *ps->ps_ptr = 0;
37:
38: rdn_print(ps, e->e_name, EDBOUT);
39: *ps->ps_ptr = '\0';
40: strcpy(kbuf, ps->ps_base);
41:
42: rdn.dptr = kbuf;
43: rdn.dsize = strlen(rdn.dptr) + 1;
44:
45: ps_print(ps, "\n");
46: as_print(ps, e->e_attributes, EDBOUT);
47: ps_print(ps, "\n");
48: *ps->ps_ptr = '\0';
49:
50: ent.dptr = ps->ps_base;
51: ent.dsize = strlen(ent.dptr) + 1;
52:
53: if ( (rc = gdbm_store(db, rdn, ent, GDBM_REPLACE)) != 0 ) {
54: LLOG (log_dsap, LLOG_EXCEPTIONS,("turbo: gdbm_store %d, gdbm_errno %d", rc, gdbm_errno));
55: ps_free(ps);
56: return(NOTOK);
57: }
58:
59: ps_free(ps);
60: return(OK);
61: }
62:
63: /*
64: * turbo_writeall -- write the entries in list p to the proper edb
65: * dbm file the file is opened by turbo_open, then the list is traversed,
66: * calling turbo_write_entry to write each entry
67: */
68:
69: turbo_writeall(e)
70: Entry e;
71: {
72: GDBM_FILE db, turbo_open();
73: DN dn;
74: char *filename;
75: int save_heap;
76:
77: LLOG (log_dsap, LLOG_TRACE,("turbo: write_all"));
78:
79: save_heap = mem_heap;
80: GENERAL_HEAP;
81:
82: if ( (db = turbo_open(e, 1)) == NULL ) {
83: mem_heap = save_heap;
84: return(NOTOK);
85: }
86:
87: if ( turbo_write_header(db, e) != OK ) {
88: (void) gdbm_close(db);
89: mem_heap = save_heap;
90: return(NOTOK);
91: }
92:
93: while (e) {
94: if ( turbo_write_entry(db, e) != OK ) {
95: (void) gdbm_close(db);
96: mem_heap = save_heap;
97: return(NOTOK);
98: }
99: e = e->e_sibling;
100: }
101:
102: (void) gdbm_close(db);
103: mem_heap = save_heap;
104: return(OK);
105: }
106:
107: /*
108: * turbo_write -- write the single entry pointed to by e to the proper
109: * edb dbm file. The edb dbm file is opened by turbo_open, then a new
110: * header is written by turbo_write_header, and finally the entry is
111: * written with a call to turbo_write_entry.
112: */
113:
114: turbo_write(e)
115: Entry e;
116: {
117: GDBM_FILE db, turbo_open();
118: int save_heap;
119:
120: LLOG (log_dsap, LLOG_TRACE, ("turbo: write"));
121:
122: save_heap = mem_heap;
123: GENERAL_HEAP;
124:
125: if ( (db = turbo_open(e, 0)) == NULL ) {
126: mem_heap = save_heap;
127: return(NOTOK);
128: }
129:
130: if ( turbo_write_header(db, e) != OK ) {
131: (void) gdbm_close(db);
132: mem_heap = save_heap;
133: return(NOTOK);
134: }
135:
136: if ( turbo_write_entry(db, e) != OK ) {
137: (void) gdbm_close(db);
138: mem_heap = save_heap;
139: return(NOTOK);
140: }
141:
142: (void) gdbm_close(db);
143: mem_heap = save_heap;
144: return(OK);
145: }
146:
147: /*
148: * turbo_delete -- delete the entry pointed to by p from the proper
149: * edb dbm file.
150: */
151:
152: turbo_delete(e)
153: Entry e;
154: {
155: static char deletekey[256];
156: int rc;
157: GDBM_FILE db, turbo_open();
158: PS ps;
159: datum key;
160: int save_heap;
161:
162: LLOG (log_dsap, LLOG_TRACE,("turbo: delete"));
163:
164: save_heap = mem_heap;
165: GENERAL_HEAP;
166:
167: if ( (db = turbo_open(e, 0)) == NULL ) {
168: mem_heap = save_heap;
169: return(NOTOK);
170: }
171:
172: if ( turbo_write_header(db, e) != OK ) {
173: (void) gdbm_close(db);
174: mem_heap = save_heap;
175: return(NOTOK);
176: }
177:
178: /* allocate the string presentation stream to print the key to */
179: if ( (ps = ps_alloc(str_open)) == NULLPS ) {
180: mem_heap = save_heap;
181: return(NOTOK);
182: }
183: if ( str_setup(ps, deletekey, sizeof(deletekey), 0) == NOTOK ) {
184: ps_free(ps);
185: mem_heap = save_heap;
186: return(NOTOK);
187: }
188: *ps->ps_ptr = 0;
189:
190: rdn_print(ps, e->e_name, EDBOUT);
191: *ps->ps_ptr = '\0';
192: key.dptr = ps->ps_base;
193: key.dsize = strlen(key.dptr) + 1;
194:
195: printf("deleting (%s)\n", key.dptr);
196: if ( (rc = gdbm_delete(db, key)) != 0 ) {
197: LLOG (log_dsap, LLOG_EXCEPTIONS,("turbo: gdbm_delete %d gdbm_errno %d", rc, gdbm_errno));
198: ps_free(ps);
199: (void) gdbm_close(db);
200: mem_heap = save_heap;
201: return(NOTOK);
202: }
203:
204: ps_free(ps);
205: (void) gdbm_close(db);
206: mem_heap = save_heap;
207: return(OK);
208: }
209:
210: /*
211: * turbo_open -- open a dbm edb file for writing. e is a pointer to the
212: * entry to be written. It's parent is used to construct the name of
213: * the file to write. If create is 0 a new database will not be created,
214: * otherwise it will and a backup of the old one will be made.
215: */
216:
217: static GDBM_FILE turbo_open(e, create)
218: Entry e;
219: char create;
220: {
221: GDBM_FILE db;
222: DN dn, get_copy_dn();
223: char *filename, *dn2edbfile();
224: char bakname[1024], turbo_gfname[1024];
225:
226: LLOG (log_dsap, LLOG_TRACE,("turbo: open"));
227:
228: /* get the name of the edb file to write to */
229: dn = get_copy_dn (e->e_parent);
230: if ((filename = dn2edbfile (dn)) == NULLCP) {
231: dn_free (dn);
232: LLOG (log_dsap, LLOG_EXCEPTIONS,("turbo: dn2edbfile failed"));
233: return (NULL);
234: }
235: dn_free(dn);
236: strcpy(turbo_gfname, filename);
237: strcat(turbo_gfname, ".gdbm");
238: strcpy(bakname, turbo_gfname);
239: strcat(bakname, ".bak");
240:
241: /* try to open it */
242: if ( create ) {
243: /* first make a backup of the old one */
244: (void) unlink(bakname);
245: if ( link(turbo_gfname, bakname) != 0 ) {
246: LLOG (log_dsap, LLOG_EXCEPTIONS, ("turbo: could not make backup"));
247: return(NULL);
248: }
249: (void) unlink(turbo_gfname);
250:
251: /* then open the new one */
252: db = gdbm_open(turbo_gfname, 0, GDBM_WRCREAT, 0600, 0);
253: } else
254: db = gdbm_open(turbo_gfname, 0, GDBM_WRITER, 0, 0);
255:
256: if ( db == NULL ) {
257: LLOG (log_dsap, LLOG_EXCEPTIONS, ("turbo: gdbm_open failed gdbm_errno %d", gdbm_errno));
258: return (NULL);
259: }
260:
261: return(db);
262: }
263:
264: /*
265: * turbo_write_header -- write a new header for the edb dbm file db.
266: * The version is taken from e's parent version
267: */
268:
269: turbo_write_header(db, e)
270: GDBM_FILE db;
271: Entry e;
272: {
273: static char hbuf[256];
274: PS ps;
275: int rc;
276: char *type;
277: datum newheader;
278: int save_heap;
279:
280: LLOG (log_dsap, LLOG_TRACE,("turbo: write_header"));
281:
282: save_heap = mem_heap;
283: GENERAL_HEAP;
284:
285: switch (e->e_data) {
286: case E_DATA_MASTER:
287: type = "MASTER";
288: break;
289: case E_TYPE_SLAVE :
290: type = "SLAVE";
291: break;
292: default:
293: type = "CACHE";
294: break;
295: }
296:
297: /* allocate the string presentation stream to print to */
298: if ( (ps = ps_alloc(str_open)) == NULLPS ) {
299: mem_heap = save_heap;
300: return(NOTOK);
301: }
302: if ( str_setup(ps, hbuf, sizeof(hbuf), 0) == NOTOK ) {
303: ps_free(ps);
304: mem_heap = save_heap;
305: return(NOTOK);
306: }
307:
308: ps_print(ps, type);
309: ps_print(ps, "\n");
310: if (e->e_parent != NULLENTRY)
311: ps_print(ps, e->e_parent->e_edbversion);
312: else
313: ps_print(ps, new_version());
314: ps_print(ps, "\n");
315: *ps->ps_ptr = '\0';
316:
317: newheader.dptr = ps->ps_base;
318: newheader.dsize = strlen(newheader.dptr) + 1;
319:
320: if ( (rc = gdbm_store(db, turbo_header_key, newheader, GDBM_REPLACE)) != 0 ) {
321: LLOG (log_dsap, LLOG_EXCEPTIONS,("turbo: gdbm_store %d gdbm_errno %d", rc, gdbm_errno));
322: mem_heap = save_heap;
323: return(NOTOK);
324: }
325: mem_heap = save_heap;
326: return(OK);
327: }
328: #else
329: /* ARGSUSED */
330: turbo_writeall(e)
331: Entry e;
332: {}
333: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.