2 * Copyright (c) 2001,2002
3 * Traakan, Inc., Los Altos, CA
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
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.
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
43 ndmfhdb_add_file (struct ndmlog *ixlog, int tagc,
44 char *raw_name, ndmp9_file_stat *fstat)
48 char namebuf[NDMOS_CONST_PATH_MAX];
50 strcpy (prefix, "DHf");
53 ndm_fstat_to_str (fstat, statbuf);
55 ndmcstr_from_str (raw_name, namebuf, sizeof namebuf);
57 ndmlogf (ixlog, prefix, 0, "%s UNIX %s", namebuf, statbuf);
63 ndmfhdb_add_dir (struct ndmlog *ixlog, int tagc,
64 char *raw_name, ndmp9_u_quad dir_node, ndmp9_u_quad node)
67 char namebuf[NDMOS_CONST_PATH_MAX];
69 strcpy (prefix, "DHd");
72 ndmcstr_from_str (raw_name, namebuf, sizeof namebuf);
74 ndmlogf (ixlog, prefix, 0, "%llu %s UNIX %llu",
75 dir_node, namebuf, node);
81 ndmfhdb_add_node (struct ndmlog *ixlog, int tagc,
82 ndmp9_u_quad node, ndmp9_file_stat *fstat)
87 strcpy (prefix, "DHn");
90 ndm_fstat_to_str (fstat, statbuf);
92 ndmlogf (ixlog, prefix, 0, "%llu UNIX %s", node, statbuf);
98 ndmfhdb_add_dirnode_root (struct ndmlog *ixlog, int tagc,
99 ndmp9_u_quad root_node)
103 strcpy (prefix, "DHr");
106 ndmlogf (ixlog, prefix, 0, "%llu", root_node);
113 ndmfhdb_add_fh_info_to_nlist (FILE *fp, ndmp9_name *nlist, int n_nlist)
115 struct ndmfhdb _fhcb, *fhcb = &_fhcb;
117 ndmp9_file_stat fstat;
119 rc = ndmfhdb_open (fp, fhcb);
126 for (i = 0; i < n_nlist; i++) {
127 char * name = nlist[i].original_path;
129 rc = ndmfhdb_lookup (fhcb, name, &fstat);
131 nlist[i].fh_info = fstat.fh_info;
132 if (fstat.fh_info.valid) {
142 ndmfhdb_open (FILE *fp, struct ndmfhdb *fhcb)
146 NDMOS_MACRO_ZEROFILL (fhcb);
150 rc = ndmfhdb_dirnode_root (fhcb);
152 fhcb->use_dir_node = 1;
156 rc = ndmfhdb_file_root (fhcb);
158 fhcb->use_dir_node = 0;
166 ndmfhdb_lookup (struct ndmfhdb *fhcb, char *path, ndmp9_file_stat *fstat)
168 if (fhcb->use_dir_node) {
169 return ndmfhdb_dirnode_lookup (fhcb, path, fstat);
171 return ndmfhdb_file_lookup (fhcb, path, fstat);
176 ndmfhdb_dirnode_root (struct ndmfhdb *fhcb)
183 sprintf (key, "DHr ");
185 p = NDMOS_API_STREND(key);
188 rc = ndmbstf_first (fhcb->fp, key, linebuf, sizeof linebuf);
191 return rc; /* error or not found */
194 fhcb->root_node = NDMOS_API_STRTOLL (linebuf+off, &p, 0);
204 ndmfhdb_dirnode_lookup (struct ndmfhdb *fhcb, char *path,
205 ndmp9_file_stat *fstat)
210 char component[256+128];
211 unsigned long long dir_node;
212 unsigned long long node;
214 /* classic path name reduction */
215 node = dir_node = fhcb->root_node;
226 while (*p != 0 && *p != '/') {
232 rc = ndmfhdb_dir_lookup (fhcb, dir_node, component, &node);
234 return rc; /* error or not found */
237 rc = ndmfhdb_node_lookup (fhcb, node, fstat);
243 ndmfhdb_dir_lookup (struct ndmfhdb *fhcb, unsigned long long dir_node,
244 char *name, unsigned long long *node_p)
251 sprintf (key, "DHd %llu ", dir_node);
252 p = NDMOS_API_STREND(key);
254 ndmcstr_from_str (name, p, sizeof key - (p-key) - 10);
256 strcat (p, " UNIX ");
258 p = NDMOS_API_STREND(key);
261 rc = ndmbstf_first (fhcb->fp, key, linebuf, sizeof linebuf);
264 return rc; /* error or not found */
267 *node_p = NDMOS_API_STRTOLL (linebuf+off, &p, 0);
277 ndmfhdb_node_lookup (struct ndmfhdb *fhcb, unsigned long long node,
278 ndmp9_file_stat *fstat)
285 sprintf (key, "DHn %llu UNIX ", node);
287 p = NDMOS_API_STREND(key);
291 rc = ndmbstf_first (fhcb->fp, key, linebuf, sizeof linebuf);
294 return rc; /* error or not found */
298 rc = ndm_fstat_from_str (fstat, linebuf + off);
307 ndmfhdb_file_root (struct ndmfhdb *fhcb)
310 ndmp9_file_stat fstat;
312 rc = ndmfhdb_file_lookup (fhcb, "/", &fstat);
314 if (fstat.node.valid)
315 fhcb->root_node = fstat.node.value;
322 ndmfhdb_file_lookup (struct ndmfhdb *fhcb, char *path,
323 ndmp9_file_stat *fstat)
330 sprintf (key, "DHf ");
331 p = NDMOS_API_STREND(key);
333 ndmcstr_from_str (path, p, sizeof key - (p-key) - 10);
335 strcat (p, " UNIX ");
337 p = NDMOS_API_STREND(key);
340 rc = ndmbstf_first (fhcb->fp, key, linebuf, sizeof linebuf);
343 return rc; /* error or not found */
346 rc = ndm_fstat_from_str (fstat, linebuf + off);
358 * Same codes as wraplib.[ch] wrap_parse_fstat_subr()
359 * and wrap_send_fstat_subr().
363 ndm_fstat_to_str (ndmp9_file_stat *fstat, char *buf)
368 switch (fstat->ftype) {
369 case NDMP9_FILE_DIR: *p++ = 'd'; break;
370 case NDMP9_FILE_FIFO: *p++ = 'p'; break;
371 case NDMP9_FILE_CSPEC: *p++ = 'c'; break;
372 case NDMP9_FILE_BSPEC: *p++ = 'b'; break;
373 case NDMP9_FILE_REG: *p++ = '-'; break;
374 case NDMP9_FILE_SLINK: *p++ = 'l'; break;
375 case NDMP9_FILE_SOCK: *p++ = 's'; break;
376 case NDMP9_FILE_REGISTRY: *p++ = 'R'; break;
377 case NDMP9_FILE_OTHER: *p++ = 'o'; break;
378 default: *p++ = '?'; break;
381 if (fstat->mode.valid) {
382 sprintf (p, " m%04lo", fstat->mode.value & 07777);
386 if (fstat->uid.valid) {
387 sprintf (p, " u%ld", fstat->uid.value);
391 if (fstat->gid.valid) {
392 sprintf (p, " g%ld", fstat->gid.value);
396 if (fstat->ftype == NDMP9_FILE_REG
397 || fstat->ftype == NDMP9_FILE_SLINK) {
398 if (fstat->size.valid) {
399 sprintf (p, " s%llu", fstat->size.value);
402 /* ignore size on other file types */
406 /* tar -t can not recover atime/ctime */
407 /* they are also not particularly interesting in the index */
409 if (fstat->mtime.valid) {
410 sprintf (p, " tm%lu", fstat->mtime.value);
414 if (fstat->fh_info.valid) {
415 sprintf (p, " @%lld", fstat->fh_info.value);
423 ndm_fstat_from_str (ndmp9_file_stat *fstat, char *buf)
426 ndmp9_validity * valid_p;
428 NDMOS_MACRO_ZEROFILL (fstat);
438 case '@': /* fh_info */
439 fstat->fh_info.value = NDMOS_API_STRTOLL (p, &scan, 0);
440 valid_p = &fstat->fh_info.valid;
444 fstat->size.value = NDMOS_API_STRTOLL (p, &scan, 0);
445 valid_p = &fstat->size.valid;
448 case 'i': /* fileno (inum) */
449 fstat->node.value = NDMOS_API_STRTOLL (p, &scan, 0);
450 valid_p = &fstat->node.valid;
453 case 'm': /* mode low twelve bits */
454 fstat->mode.value = strtol (p, &scan, 8);
455 valid_p = &fstat->mode.valid;
458 case 'l': /* link count */
459 fstat->links.value = strtol (p, &scan, 0);
460 valid_p = &fstat->links.valid;
464 fstat->uid.value = strtol (p, &scan, 0);
465 valid_p = &fstat->uid.valid;
469 fstat->gid.value = strtol (p, &scan, 0);
470 valid_p = &fstat->gid.valid;
473 case 't': /* one of the times */
476 case 'm': /* mtime */
477 fstat->mtime.value = strtol (p, &scan, 0);
478 valid_p = &fstat->mtime.valid;
481 case 'a': /* atime */
482 fstat->atime.value = strtol (p, &scan, 0);
483 valid_p = &fstat->atime.valid;
486 case 'c': /* ctime */
487 fstat->ctime.value = strtol (p, &scan, 0);
488 valid_p = &fstat->ctime.valid;
496 case 'f': /* ftype (file type) */
498 case 'd': fstat->ftype = NDMP9_FILE_DIR; break;
499 case 'p': fstat->ftype = NDMP9_FILE_FIFO; break;
500 case 'c': fstat->ftype = NDMP9_FILE_CSPEC; break;
501 case 'b': fstat->ftype = NDMP9_FILE_BSPEC; break;
502 case '-': fstat->ftype = NDMP9_FILE_REG; break;
503 case 'l': fstat->ftype = NDMP9_FILE_SLINK; break;
504 case 's': fstat->ftype = NDMP9_FILE_SOCK; break;
505 case 'R': fstat->ftype = NDMP9_FILE_REGISTRY; break;
506 case 'o': fstat->ftype = NDMP9_FILE_OTHER; break;
508 fstat->ftype = NDMP9_FILE_OTHER;
519 if (*scan != ' ' && *scan != 0)
523 *valid_p = NDMP9_VALIDITY_VALID;