view ffstools/tiffs-rd/object.c @ 421:ab8fb95a28da
rvinterf/rvtat converted to use libinterf
author |
Mychaela Falconia <falcon@freecalypso.org> |
date |
Sat, 27 Oct 2018 23:48:20 +0000 (2018-10-27) |
parents |
e7502631a0f9 |
children |
1f27fc13eab7 |
line source
/*
* This C module implements object-level analysis.
*/
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "types.h"
#include "struct.h"
#include "globals.h"
#include "pathname.h"
validate_obj_name(ino, root_special)
{
struct inode_info *inf = inode_info[ino];
u8 *p, *endp;
int c;
if (!inf->len)
return(0);
p = inf->dataptr;
endp = p + inf->len;
for (; ; p++) {
if (p >= endp)
return(0);
c = *p;
if (!c)
break;
if (c < ' ' || c > '~')
return(0);
if (root_special || isalnum(c))
continue;
switch (c) {
case '.':
case ',':
case '_':
case '-':
case '+':
case '%':
case '$':
case '#':
continue;
default:
return(0);
}
}
if (!root_special) {
c = p - inf->dataptr;
if (c < 1 || c > MAX_FN_COMPONENT)
return(0);
if (!strcmp(inf->dataptr, ".") || !strcmp(inf->dataptr, ".."))
return(0);
}
inf->byte_after_name = p + 1;
return(1);
}
u8 *
find_end_of_chunk(inf)
struct inode_info *inf;
{
u8 *p;
int i;
p = inf->dataptr + inf->len;
for (i = 1; i <= 16; i++) {
if (!p[-i])
return(p - i);
if (p[-i] != 0xFF)
break;
}
fprintf(stderr,
"error: chunk @%x (inode #%x): no valid termination found\n",
inf->offset, inf->ino);
return(p); /* bogon, allows the rest to continue */
}
size_head_chunk(inf, chi)
struct inode_info *inf;
struct chunkinfo *chi;
{
chi->start = inf->byte_after_name;
chi->end = find_end_of_chunk(inf);
if (chi->start >= chi->end) {
chi->len = 0;
return(0);
} else {
chi->len = chi->end - chi->start;
return(1);
}
}
size_extra_chunk(inf, chi)
struct inode_info *inf;
struct chunkinfo *chi;
{
chi->start = inf->dataptr;
chi->end = find_end_of_chunk(inf);
chi->len = chi->end - chi->start;
}
void
iterate_seg_file(seghead, callback, callback_data, deleted, verbose)
void (*callback)();
u_long callback_data;
{
int ino;
struct inode_info *inf;
for (ino = inode_info[seghead]->descend; ino; ino = inf->descend) {
loop: if (!validate_inode(ino)) {
fprintf(stderr,
"error: following seg file hit invalid inode #%x\n",
ino);
return;
}
inf = inode_info[ino];
switch (inf->type) {
case 0xF4:
callback(inf, callback_data);
continue;
case 0x00:
if (deleted) {
if (inf->len)
callback(inf, callback_data);
else
fprintf(stderr,
"error: presumed deleted segment inode #%x has been reclaimed\n",
ino);
continue;
}
if (!inf->sibling) {
fprintf(stderr,
"error: segment object at inode #%x: marked deleted, but no sibling\n",
ino);
return;
}
if (verbose)
printf("seg inode #%x deleted, moved to #%x\n",
ino, inf->sibling);
ino = inf->sibling;
goto loop;
default:
fprintf(stderr,
"error: inode #%x: unexpected type %02X when expecting segment (F4)\n",
ino, inf->type);
return;
}
}
}