1 /*
2 * Copyright (c) 2001,2002
3 * Traakan, Inc., Los Altos, CA
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
11 * disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 /*
30 * Project: NDMJOB
31 * Ident: $Id: $
32 *
33 * Description:
34 *
35 */
36
37
38 #include "ndmlib.h"
39
ndmfhdb_register_callbacks(struct ndmlog * ixlog,struct ndm_fhdb_callbacks * callbacks)40 void ndmfhdb_register_callbacks(struct ndmlog* ixlog,
41 struct ndm_fhdb_callbacks* callbacks)
42 {
43 /*
44 * Only allow one register.
45 */
46 if (!ixlog->nfc) {
47 ixlog->nfc = NDMOS_API_MALLOC(sizeof(struct ndm_fhdb_callbacks));
48 if (ixlog->nfc) {
49 memcpy(ixlog->nfc, callbacks, sizeof(struct ndm_fhdb_callbacks));
50 }
51 }
52 }
53
ndmfhdb_unregister_callbacks(struct ndmlog * ixlog)54 void ndmfhdb_unregister_callbacks(struct ndmlog* ixlog)
55 {
56 if (ixlog->nfc) {
57 NDMOS_API_FREE(ixlog->nfc);
58 ixlog->nfc = NULL;
59 }
60 }
61
ndmfhdb_add_file(struct ndmlog * ixlog,int tagc,char * raw_name,ndmp9_file_stat * fstat)62 int ndmfhdb_add_file(struct ndmlog* ixlog,
63 int tagc,
64 char* raw_name,
65 ndmp9_file_stat* fstat)
66 {
67 if (ixlog->nfc && ixlog->nfc->add_file) {
68 return ixlog->nfc->add_file(ixlog, tagc, raw_name, fstat);
69 } else {
70 return 0;
71 }
72 }
73
ndmfhdb_add_dir(struct ndmlog * ixlog,int tagc,char * raw_name,ndmp9_u_quad dir_node,ndmp9_u_quad node)74 int ndmfhdb_add_dir(struct ndmlog* ixlog,
75 int tagc,
76 char* raw_name,
77 ndmp9_u_quad dir_node,
78 ndmp9_u_quad node)
79 {
80 if (ixlog->nfc && ixlog->nfc->add_dir) {
81 return ixlog->nfc->add_dir(ixlog, tagc, raw_name, dir_node, node);
82 } else {
83 return 0;
84 }
85 }
86
ndmfhdb_add_node(struct ndmlog * ixlog,int tagc,ndmp9_u_quad node,ndmp9_file_stat * fstat)87 int ndmfhdb_add_node(struct ndmlog* ixlog,
88 int tagc,
89 ndmp9_u_quad node,
90 ndmp9_file_stat* fstat)
91 {
92 if (ixlog->nfc && ixlog->nfc->add_node) {
93 return ixlog->nfc->add_node(ixlog, tagc, node, fstat);
94 } else {
95 return 0;
96 }
97 }
98
ndmfhdb_add_dirnode_root(struct ndmlog * ixlog,int tagc,ndmp9_u_quad root_node)99 int ndmfhdb_add_dirnode_root(struct ndmlog* ixlog,
100 int tagc,
101 ndmp9_u_quad root_node)
102 {
103 if (ixlog->nfc && ixlog->nfc->add_dirnode_root) {
104 return ixlog->nfc->add_dirnode_root(ixlog, tagc, root_node);
105 } else {
106 return 0;
107 }
108 }
109
ndmfhdb_add_fh_info_to_nlist(FILE * fp,ndmp9_name * nlist,int n_nlist)110 int ndmfhdb_add_fh_info_to_nlist(FILE* fp, ndmp9_name* nlist, int n_nlist)
111 {
112 struct ndmfhdb _fhcb, *fhcb = &_fhcb;
113 int i, rc, n_found;
114 ndmp9_file_stat fstat;
115
116 rc = ndmfhdb_open(fp, fhcb);
117 if (rc != 0) { return -31; }
118
119 n_found = 0;
120
121 for (i = 0; i < n_nlist; i++) {
122 char* name = nlist[i].original_path;
123
124 rc = ndmfhdb_lookup(fhcb, name, &fstat);
125 if (rc > 0) {
126 nlist[i].fh_info = fstat.fh_info;
127 if (fstat.fh_info.valid) { n_found++; }
128 }
129 }
130
131 return n_found;
132 }
133
ndmfhdb_open(FILE * fp,struct ndmfhdb * fhcb)134 int ndmfhdb_open(FILE* fp, struct ndmfhdb* fhcb)
135 {
136 int rc;
137
138 NDMOS_MACRO_ZEROFILL(fhcb);
139
140 fhcb->fp = fp;
141
142 rc = ndmfhdb_dirnode_root(fhcb);
143 if (rc > 0) {
144 fhcb->use_dir_node = 1;
145 return 0;
146 }
147
148 rc = ndmfhdb_file_root(fhcb);
149 if (rc > 0) {
150 fhcb->use_dir_node = 0;
151 return 0;
152 }
153
154 return -1;
155 }
156
ndmfhdb_lookup(struct ndmfhdb * fhcb,char * path,ndmp9_file_stat * fstat)157 int ndmfhdb_lookup(struct ndmfhdb* fhcb, char* path, ndmp9_file_stat* fstat)
158 {
159 if (fhcb->use_dir_node) {
160 return ndmfhdb_dirnode_lookup(fhcb, path, fstat);
161 } else {
162 return ndmfhdb_file_lookup(fhcb, path, fstat);
163 }
164 }
165
ndmfhdb_dirnode_root(struct ndmfhdb * fhcb)166 int ndmfhdb_dirnode_root(struct ndmfhdb* fhcb)
167 {
168 int rc, off;
169 char* p;
170 char key[256];
171 char linebuf[2048];
172
173 snprintf(key, sizeof(key), "DHr ");
174
175 p = NDMOS_API_STREND(key);
176 off = p - key;
177
178 rc = ndmbstf_first(fhcb->fp, key, linebuf, sizeof linebuf);
179
180 if (rc <= 0) { return rc; /* error or not found */ }
181
182 fhcb->root_node = NDMOS_API_STRTOLL(linebuf + off, &p, 0);
183
184 if (*p != 0) { return -10; }
185
186 return 1;
187 }
188
ndmfhdb_dirnode_lookup(struct ndmfhdb * fhcb,char * path,ndmp9_file_stat * fstat)189 int ndmfhdb_dirnode_lookup(struct ndmfhdb* fhcb,
190 char* path,
191 ndmp9_file_stat* fstat)
192 {
193 int rc;
194 char* p;
195 char* q;
196 char component[256 + 128];
197 uint64_t dir_node;
198 uint64_t node;
199
200 /* classic path name reduction */
201 node = dir_node = fhcb->root_node;
202 p = path;
203 for (;;) {
204 if (*p == '/') {
205 p++;
206 continue;
207 }
208 if (*p == 0) { break; }
209 q = component;
210 while (*p != 0 && *p != '/') { *q++ = *p++; }
211 *q = 0;
212
213 dir_node = node;
214 rc = ndmfhdb_dir_lookup(fhcb, dir_node, component, &node);
215 if (rc <= 0) return rc; /* error or not found */
216 }
217
218 rc = ndmfhdb_node_lookup(fhcb, node, fstat);
219
220 return rc;
221 }
222
ndmfhdb_dir_lookup(struct ndmfhdb * fhcb,uint64_t dir_node,char * name,uint64_t * node_p)223 int ndmfhdb_dir_lookup(struct ndmfhdb* fhcb,
224 uint64_t dir_node,
225 char* name,
226 uint64_t* node_p)
227 {
228 int rc, off;
229 char* p;
230 char key[256 + 128];
231 char linebuf[2048];
232
233 snprintf(key, sizeof(key), "DHd %llu ", dir_node);
234 p = NDMOS_API_STREND(key);
235
236 ndmcstr_from_str(name, p, sizeof key - (p - key) - 10);
237
238 strcat(p, " UNIX ");
239
240 p = NDMOS_API_STREND(key);
241 off = p - key;
242
243 rc = ndmbstf_first(fhcb->fp, key, linebuf, sizeof linebuf);
244
245 if (rc <= 0) { return rc; /* error or not found */ }
246
247 *node_p = NDMOS_API_STRTOLL(linebuf + off, &p, 0);
248
249 if (*p != 0) { return -10; }
250
251 return 1;
252 }
253
ndmfhdb_node_lookup(struct ndmfhdb * fhcb,uint64_t node,ndmp9_file_stat * fstat)254 int ndmfhdb_node_lookup(struct ndmfhdb* fhcb,
255 uint64_t node,
256 ndmp9_file_stat* fstat)
257 {
258 int rc, off;
259 char* p;
260 char key[128];
261 char linebuf[2048];
262
263 snprintf(key, sizeof(key), "DHn %llu UNIX ", node);
264
265 p = NDMOS_API_STREND(key);
266 off = p - key;
267
268
269 rc = ndmbstf_first(fhcb->fp, key, linebuf, sizeof linebuf);
270
271 if (rc <= 0) { return rc; /* error or not found */ }
272
273
274 rc = ndm_fstat_from_str(fstat, linebuf + off);
275 if (rc < 0) { return rc; }
276
277 return 1;
278 }
279
ndmfhdb_file_root(struct ndmfhdb * fhcb)280 int ndmfhdb_file_root(struct ndmfhdb* fhcb)
281 {
282 int rc;
283 ndmp9_file_stat fstat;
284
285 rc = ndmfhdb_file_lookup(fhcb, "/", &fstat);
286 if (rc > 0) {
287 if (fstat.node.valid) fhcb->root_node = fstat.node.value;
288 }
289
290 return rc;
291 }
292
ndmfhdb_file_lookup(struct ndmfhdb * fhcb,char * path,ndmp9_file_stat * fstat)293 int ndmfhdb_file_lookup(struct ndmfhdb* fhcb,
294 char* path,
295 ndmp9_file_stat* fstat)
296 {
297 int rc, off;
298 char* p;
299 char key[2048];
300 char linebuf[2048];
301
302 snprintf(key, sizeof(key), "DHf ");
303 p = NDMOS_API_STREND(key);
304
305 ndmcstr_from_str(path, p, sizeof key - (p - key) - 10);
306
307 strcat(p, " UNIX ");
308
309 p = NDMOS_API_STREND(key);
310 off = p - key;
311
312 rc = ndmbstf_first(fhcb->fp, key, linebuf, sizeof linebuf);
313
314 if (rc <= 0) { return rc; /* error or not found */ }
315
316 rc = ndm_fstat_from_str(fstat, linebuf + off);
317 if (rc < 0) { return rc; }
318
319 return 1;
320 }
321
322 /*
323 * Same codes as wraplib.[ch] wrap_parse_fstat_subr()
324 * and wrap_send_fstat_subr().
325 */
ndm_fstat_to_str(ndmp9_file_stat * fstat,char * buf)326 char* ndm_fstat_to_str(ndmp9_file_stat* fstat, char* buf)
327 {
328 char* p = buf;
329
330 *p++ = 'f';
331 switch (fstat->ftype) {
332 case NDMP9_FILE_DIR:
333 *p++ = 'd';
334 break;
335 case NDMP9_FILE_FIFO:
336 *p++ = 'p';
337 break;
338 case NDMP9_FILE_CSPEC:
339 *p++ = 'c';
340 break;
341 case NDMP9_FILE_BSPEC:
342 *p++ = 'b';
343 break;
344 case NDMP9_FILE_REG:
345 *p++ = '-';
346 break;
347 case NDMP9_FILE_SLINK:
348 *p++ = 'l';
349 break;
350 case NDMP9_FILE_SOCK:
351 *p++ = 's';
352 break;
353 case NDMP9_FILE_REGISTRY:
354 *p++ = 'R';
355 break;
356 case NDMP9_FILE_OTHER:
357 *p++ = 'o';
358 break;
359 default:
360 *p++ = '?';
361 break;
362 }
363
364 if (fstat->mode.valid) { sprintf(p, " m%04lo", fstat->mode.value & 07777); }
365 while (*p) p++;
366
367 if (fstat->uid.valid) { sprintf(p, " u%ld", fstat->uid.value); }
368 while (*p) p++;
369
370 if (fstat->gid.valid) { sprintf(p, " g%ld", fstat->gid.value); }
371 while (*p) p++;
372
373 if (fstat->ftype == NDMP9_FILE_REG || fstat->ftype == NDMP9_FILE_SLINK) {
374 if (fstat->size.valid) { sprintf(p, " s%llu", fstat->size.value); }
375 } else {
376 /* ignore size on other file types */
377 }
378 while (*p) p++;
379
380 /* tar -t can not recover atime/ctime */
381 /* they are also not particularly interesting in the index */
382
383 if (fstat->mtime.valid) { sprintf(p, " tm%lu", fstat->mtime.value); }
384 while (*p) p++;
385
386 if (fstat->fh_info.valid) { sprintf(p, " @%lld", fstat->fh_info.value); }
387 while (*p) p++;
388
389 return buf;
390 }
391
ndm_fstat_from_str(ndmp9_file_stat * fstat,char * buf)392 int ndm_fstat_from_str(ndmp9_file_stat* fstat, char* buf)
393 {
394 char* scan = buf;
395 ndmp9_validity* valid_p;
396
397 NDMOS_MACRO_ZEROFILL(fstat);
398
399 while (*scan) {
400 char* p = scan + 1;
401
402 switch (*scan) {
403 case ' ':
404 scan++;
405 continue;
406
407 case '@': /* fh_info */
408 fstat->fh_info.value = NDMOS_API_STRTOLL(p, &scan, 0);
409 valid_p = &fstat->fh_info.valid;
410 break;
411
412 case 's': /* size */
413 fstat->size.value = NDMOS_API_STRTOLL(p, &scan, 0);
414 valid_p = &fstat->size.valid;
415 break;
416
417 case 'i': /* fileno (inum) */
418 fstat->node.value = NDMOS_API_STRTOLL(p, &scan, 0);
419 valid_p = &fstat->node.valid;
420 break;
421
422 case 'm': /* mode low twelve bits */
423 fstat->mode.value = strtol(p, &scan, 8);
424 valid_p = &fstat->mode.valid;
425 break;
426
427 case 'l': /* link count */
428 fstat->links.value = strtol(p, &scan, 0);
429 valid_p = &fstat->links.valid;
430 break;
431
432 case 'u': /* uid */
433 fstat->uid.value = strtol(p, &scan, 0);
434 valid_p = &fstat->uid.valid;
435 break;
436
437 case 'g': /* gid */
438 fstat->gid.value = strtol(p, &scan, 0);
439 valid_p = &fstat->gid.valid;
440 break;
441
442 case 't': /* one of the times */
443 p = scan + 2;
444 switch (scan[1]) {
445 case 'm': /* mtime */
446 fstat->mtime.value = strtol(p, &scan, 0);
447 valid_p = &fstat->mtime.valid;
448 break;
449
450 case 'a': /* atime */
451 fstat->atime.value = strtol(p, &scan, 0);
452 valid_p = &fstat->atime.valid;
453 break;
454
455 case 'c': /* ctime */
456 fstat->ctime.value = strtol(p, &scan, 0);
457 valid_p = &fstat->ctime.valid;
458 break;
459
460 default:
461 return -13;
462 }
463 break;
464
465 case 'f': /* ftype (file type) */
466 switch (scan[1]) {
467 case 'd':
468 fstat->ftype = NDMP9_FILE_DIR;
469 break;
470 case 'p':
471 fstat->ftype = NDMP9_FILE_FIFO;
472 break;
473 case 'c':
474 fstat->ftype = NDMP9_FILE_CSPEC;
475 break;
476 case 'b':
477 fstat->ftype = NDMP9_FILE_BSPEC;
478 break;
479 case '-':
480 fstat->ftype = NDMP9_FILE_REG;
481 break;
482 case 'l':
483 fstat->ftype = NDMP9_FILE_SLINK;
484 break;
485 case 's':
486 fstat->ftype = NDMP9_FILE_SOCK;
487 break;
488 case 'R':
489 fstat->ftype = NDMP9_FILE_REGISTRY;
490 break;
491 case 'o':
492 fstat->ftype = NDMP9_FILE_OTHER;
493 break;
494 default:
495 fstat->ftype = NDMP9_FILE_OTHER;
496 return -15;
497 }
498 scan += 2;
499 valid_p = 0;
500 break;
501
502 default:
503 return -13;
504 }
505
506 if (*scan != ' ' && *scan != 0) return -11;
507
508 if (valid_p) *valid_p = NDMP9_VALIDITY_VALID;
509 }
510
511 return 0;
512 }
513