view target-utils/libtiffs/findfile.c @ 652:d42534e5ac02

loadtools: discontig.h split out of flash.h
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 02 Mar 2020 03:49:31 +0000
parents 87cb03b35f77
children
line wrap: on
line source

#include <sys/types.h>
#include "types.h"
#include "struct.h"
#include "globals.h"
#include "macros.h"

static u8 *
find_endofchunk(ino)
{
	struct inode *irec = tiffs_active_index + ino;
	u8 *p;
	int i;

	p = inode_to_dataptr(irec) + irec->len;
	for (i = 0; i < 16; i++) {
		p--;
		if (!*p)
			return(p);
		if (*p != 0xFF)
			break;
	}
	printf("Error: inode #%x has no valid termination\n", ino);
	return(p);	/* XXX */
}

tiffs_find_file(pathname, startret, sizeret, continue_ret)
	char *pathname;
	u8 **startret;
	size_t *sizeret;
	int *continue_ret;
{
	int ino, cont;
	struct inode *irec;
	u8 *start, *end;
	int size;

	ino = tiffs_pathname_to_inode(pathname);
	if (ino <= 0)
		return(-1);
	irec = tiffs_active_index + ino;
	if (irec->type != OBJTYPE_FILE) {
		printf("Error: %s is not a regular file\n", pathname);
		return(-1);
	}
	start = inode_to_dataptr(irec);
	start += strlen(start) + 1;
	end = find_endofchunk(ino);
	size = end - start;
	if (size < 0)
		size = 0;
	cont = irec->descend;
	if (cont == 0xFFFF)
		cont = 0;
	if (startret)
		*startret = start;
	if (sizeret)
		*sizeret = size;
	if (continue_ret)
		*continue_ret = cont;
	return(0);
}

tiffs_get_segment(ino, startret, sizeret, continue_ret)
	int ino;
	u8 **startret;
	size_t *sizeret;
	int *continue_ret;
{
	int cont;
	struct inode *irec;
	u8 *start, *end;
	int size;

	for (;;) {
		irec = tiffs_active_index + ino;
		if (irec->type)
			break;
		if (irec->sibling == 0xFFFF) {
		    printf("Error: segment inode #%d: deleted and no sibling\n",
				ino);
			return(-1);
		}
		ino = irec->sibling;
	}
	if (irec->type != OBJTYPE_SEGMENT) {
		printf("Error: inode #%x is not a segment\n", ino);
		return(-1);
	}
	start = inode_to_dataptr(irec);
	end = find_endofchunk(ino);
	size = end - start;
	if (size <= 0) {
		printf("Error: segment inode #%x: bad length\n", ino);
		return(-1);
	}
	cont = irec->descend;
	if (cont == 0xFFFF)
		cont = 0;
	if (startret)
		*startret = start;
	if (sizeret)
		*sizeret = size;
	if (continue_ret)
		*continue_ret = cont;
	return(0);
}