140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project/*
240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * YAFFS: Yet another FFS. A NAND-flash specific file system.
340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * makeyaffsimage.c
540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * Makes a YAFFS file system image that can be used to load up a file system.
740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * Copyright (C) 2002 Aleph One Ltd.
940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *   for Toby Churchill Ltd and Brightstar Engineering
1040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
1140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * Created by Charles Manning <charles@aleph1.co.uk>
1240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
1340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * This program is free software; you can redistribute it and/or modify
1440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * it under the terms of the GNU General Public License version 2 as
1540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * published by the Free Software Foundation.
1640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
1740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
1840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * Nick Bane modifications flagged NCB
1940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
2040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * Endian handling patches by James Ng.
2140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
2240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
2340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project */
2440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
2540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <stdlib.h>
2640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <stdio.h>
2740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <fcntl.h>
2840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <sys/types.h>
2940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <sys/stat.h>
3040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <dirent.h>
3140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <string.h>
3240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <unistd.h>
3340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "yaffs_ecc.h"
3440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "yaffs_guts.h"
3540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
3640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
3740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#define MAX_OBJECTS 10000
3840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
3940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectconst char * mkyaffsimage_c_version = "$Id: mkyaffsimage.c,v 1.7 2003/07/16 03:00:48 charles Exp $";
4040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
4140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
4240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projecttypedef struct
4340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
4440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	dev_t dev;
4540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	ino_t ino;
4640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int   obj;
4740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project} objItem;
4840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
4940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
5040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic objItem obj_list[MAX_OBJECTS];
5140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int n_obj = 0;
5240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int obj_id = YAFFS_NOBJECT_BUCKETS + 1;
5340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
5440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int nObjects, nDirectories, nPages;
5540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
5640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int outFile;
5740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
5840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int error;
5940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
6040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int convert_endian = 0;
6140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
6240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int obj_compare(const void *a, const void * b)
6340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
6440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  objItem *oa, *ob;
6540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
6640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  oa = (objItem *)a;
6740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  ob = (objItem *)b;
6840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
6940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  if(oa->dev < ob->dev) return -1;
7040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  if(oa->dev > ob->dev) return 1;
7140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  if(oa->ino < ob->ino) return -1;
7240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  if(oa->ino > ob->ino) return 1;
7340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
7440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  return 0;
7540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
7640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
7740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
7840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic void add_obj_to_list(dev_t dev, ino_t ino, int obj)
7940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
8040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(n_obj < MAX_OBJECTS)
8140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
8240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		obj_list[n_obj].dev = dev;
8340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		obj_list[n_obj].ino = ino;
8440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		obj_list[n_obj].obj = obj;
8540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		n_obj++;
8640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		qsort(obj_list,n_obj,sizeof(objItem),obj_compare);
8740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
8840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
8940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
9040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
9140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// oops! not enough space in the object array
9240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		fprintf(stderr,"Not enough space in object array\n");
9340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		exit(2);
9440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
9540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
9640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
9740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
9840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int find_obj_in_list(dev_t dev, ino_t ino)
9940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
10040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	objItem *i = NULL;
10140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	objItem test;
10240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
10340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	test.dev = dev;
10440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	test.ino = ino;
10540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
10640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(n_obj > 0)
10740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
10840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		i = bsearch(&test,obj_list,n_obj,sizeof(objItem),obj_compare);
10940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
11040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
11140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(i)
11240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
11340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		return i->obj;
11440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
11540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return -1;
11640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
11740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
11840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// NCB added 10/9/2002
11940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic __u16 yaffs_CalcNameSum(const char *name)
12040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
12140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	__u16 sum = 0;
12240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	__u16 i = 1;
12340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
12440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	__u8 *bname = (__u8 *)name;
12540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
12640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	while (*bname)
12740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
12840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		sum += (*bname) * i;
12940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		i++;
13040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		bname++;
13140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
13240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return sum;
13340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
13440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
13540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
13640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic void yaffs_CalcECC(const __u8 *data, yaffs_Spare *spare)
13740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
13840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_ECCCalculate(data , spare->ecc1);
13940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_ECCCalculate(&data[256] , spare->ecc2);
14040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
14140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
14240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic void yaffs_CalcTagsECC(yaffs_Tags *tags)
14340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
14440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	// Todo don't do anything yet. Need to calculate ecc
14540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	unsigned char *b = ((yaffs_TagsUnion *)tags)->asBytes;
14640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	unsigned  i,j;
14740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	unsigned  ecc = 0;
14840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	unsigned bit = 0;
14940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
15040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    // Clear ECC fields
15140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    if (!convert_endian)
15240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    {
15340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	    tags->ecc = 0;
15440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    }
15540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    else
15640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    {
15740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project        // Because we're in "munged tag" mode, we have to clear it manually
15840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project        b[6] &= 0xC0;
15940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project        b[7] &= 0x03;
16040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    }
16140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
16240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	for(i = 0; i < 8; i++)
16340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
16440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// NCB modified 20-9-02		for(j = 1; j &0x7f; j<<=1)
16540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		for(j = 1; j &0xff; j<<=1)
16640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
16740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			bit++;
16840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(b[i] & j)
16940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			{
17040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				ecc ^= bit;
17140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
17240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
17340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
17440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
17540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	// Write out ECC
17640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    if (!convert_endian)
17740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    {
17840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project        tags->ecc = ecc;
17940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    }
18040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    else
18140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    {
18240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	    // We have to munge the ECC again.
18340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	    b[6] |= ((ecc >> 6) & 0x3F);
18440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project        b[7] |= ((ecc & 0x3F) << 2);
18540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    }
18640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
18740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic void yaffs_LoadTagsIntoSpare(yaffs_Spare *sparePtr, yaffs_Tags *tagsPtr)
18840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
18940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_TagsUnion *tu = (yaffs_TagsUnion *)tagsPtr;
19040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
19140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	//yaffs_CalcTagsECC(tagsPtr);
19240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
19340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	sparePtr->tagByte0 = tu->asBytes[0];
19440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	sparePtr->tagByte1 = tu->asBytes[1];
19540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	sparePtr->tagByte2 = tu->asBytes[2];
19640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	sparePtr->tagByte3 = tu->asBytes[3];
19740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	sparePtr->tagByte4 = tu->asBytes[4];
19840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	sparePtr->tagByte5 = tu->asBytes[5];
19940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	sparePtr->tagByte6 = tu->asBytes[6];
20040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	sparePtr->tagByte7 = tu->asBytes[7];
20140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
20240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
20340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project/* This little function converts a little endian tag to a big endian tag.
20440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * NOTE: The tag is not usable after this other than calculating the CRC
20540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * with.
20640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project */
20740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic void little_to_big_endian(yaffs_Tags *tagsPtr)
20840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
20940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    yaffs_TagsUnion * tags = (yaffs_TagsUnion* )tagsPtr; // Work in bytes.
21040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    yaffs_TagsUnion   temp;
21140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
21240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    memset(&temp, 0, sizeof(temp));
21340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    // Ick, I hate magic numbers.
21440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    temp.asBytes[0] = ((tags->asBytes[2] & 0x0F) << 4) | ((tags->asBytes[1] & 0xF0) >> 4);
21540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    temp.asBytes[1] = ((tags->asBytes[1] & 0x0F) << 4) | ((tags->asBytes[0] & 0xF0) >> 4);
21640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    temp.asBytes[2] = ((tags->asBytes[0] & 0x0F) << 4) | ((tags->asBytes[2] & 0x30) >> 2) | ((tags->asBytes[3] & 0xC0) >> 6);
21740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    temp.asBytes[3] = ((tags->asBytes[3] & 0x3F) << 2) | ((tags->asBytes[2] & 0xC0) >> 6);
21840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    temp.asBytes[4] = ((tags->asBytes[6] & 0x03) << 6) | ((tags->asBytes[5] & 0xFC) >> 2);
21940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    temp.asBytes[5] = ((tags->asBytes[5] & 0x03) << 6) | ((tags->asBytes[4] & 0xFC) >> 2);
22040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    temp.asBytes[6] = ((tags->asBytes[4] & 0x03) << 6) | (tags->asBytes[7] & 0x3F);
22140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    temp.asBytes[7] = (tags->asBytes[6] & 0xFC) | ((tags->asBytes[7] & 0xC0) >> 6);
22240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
22340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    // Now copy it back.
22440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    tags->asBytes[0] = temp.asBytes[0];
22540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    tags->asBytes[1] = temp.asBytes[1];
22640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    tags->asBytes[2] = temp.asBytes[2];
22740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    tags->asBytes[3] = temp.asBytes[3];
22840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    tags->asBytes[4] = temp.asBytes[4];
22940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    tags->asBytes[5] = temp.asBytes[5];
23040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    tags->asBytes[6] = temp.asBytes[6];
23140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    tags->asBytes[7] = temp.asBytes[7];
23240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
23340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
23440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int write_chunk(__u8 *data, __u32 objId, __u32 chunkId, __u32 nBytes)
23540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
23640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Tags t;
23740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_Spare s;
23840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
23940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	error = write(outFile,data,512);
24040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(error < 0) return error;
24140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
24240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	memset(&t,0xff,sizeof (yaffs_Tags));
24340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	memset(&s,0xff,sizeof (yaffs_Spare));
24440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
24540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	t.chunkId = chunkId;
24640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	t.serialNumber = 0;
24740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	t.byteCount = nBytes;
24840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	t.objectId = objId;
24940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
25040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    if (convert_endian)
25140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    {
25240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project        little_to_big_endian(&t);
25340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    }
25440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
25540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_CalcTagsECC(&t);
25640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_LoadTagsIntoSpare(&s,&t);
25740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_CalcECC(data,&s);
25840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
25940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	nPages++;
26040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
26140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return write(outFile,&s,sizeof(yaffs_Spare));
26240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
26340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
26440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
26540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#define SWAP32(x)   ((((x) & 0x000000FF) << 24) | \
26640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project                     (((x) & 0x0000FF00) << 8 ) | \
26740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project                     (((x) & 0x00FF0000) >> 8 ) | \
26840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project                     (((x) & 0xFF000000) >> 24))
26940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
27040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#define SWAP16(x)   ((((x) & 0x00FF) << 8) | \
27140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project                     (((x) & 0xFF00) >> 8))
27240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
27340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// This one is easier, since the types are more standard. No funky shifts here.
27440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic void object_header_little_to_big_endian(yaffs_ObjectHeader* oh)
27540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
27640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->type = SWAP32(oh->type); // GCC makes enums 32 bits.
27740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->parentObjectId = SWAP32(oh->parentObjectId); // int
27840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->sum__NoLongerUsed = SWAP16(oh->sum__NoLongerUsed); // __u16 - Not used, but done for completeness.
27940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    // name = skip. Char array. Not swapped.
28040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->yst_mode = SWAP32(oh->yst_mode);
28140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#ifdef CONFIG_YAFFS_WINCE // WinCE doesn't implement this, but we need to just in case.
28240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    // In fact, WinCE would be *THE* place where this would be an issue!
28340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->notForWinCE[0] = SWAP32(oh->notForWinCE[0]);
28440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->notForWinCE[1] = SWAP32(oh->notForWinCE[1]);
28540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->notForWinCE[2] = SWAP32(oh->notForWinCE[2]);
28640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->notForWinCE[3] = SWAP32(oh->notForWinCE[3]);
28740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->notForWinCE[4] = SWAP32(oh->notForWinCE[4]);
28840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#else
28940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    // Regular POSIX.
29040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->yst_uid = SWAP32(oh->yst_uid);
29140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->yst_gid = SWAP32(oh->yst_gid);
29240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->yst_atime = SWAP32(oh->yst_atime);
29340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->yst_mtime = SWAP32(oh->yst_mtime);
29440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->yst_ctime = SWAP32(oh->yst_ctime);
29540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#endif
29640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
29740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->fileSize = SWAP32(oh->fileSize); // Aiee. An int... signed, at that!
29840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->equivalentObjectId = SWAP32(oh->equivalentObjectId);
29940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    // alias  - char array.
30040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->yst_rdev = SWAP32(oh->yst_rdev);
30140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
30240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#ifdef CONFIG_YAFFS_WINCE
30340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->win_ctime[0] = SWAP32(oh->win_ctime[0]);
30440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->win_ctime[1] = SWAP32(oh->win_ctime[1]);
30540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->win_atime[0] = SWAP32(oh->win_atime[0]);
30640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->win_atime[1] = SWAP32(oh->win_atime[1]);
30740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->win_mtime[0] = SWAP32(oh->win_mtime[0]);
30840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->win_mtime[1] = SWAP32(oh->win_mtime[1]);
30940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[0] = SWAP32(oh->roomToGrow[0]);
31040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[1] = SWAP32(oh->roomToGrow[1]);
31140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[2] = SWAP32(oh->roomToGrow[2]);
31240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[3] = SWAP32(oh->roomToGrow[3]);
31340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[4] = SWAP32(oh->roomToGrow[4]);
31440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[5] = SWAP32(oh->roomToGrow[5]);
31540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#else
31640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[0] = SWAP32(oh->roomToGrow[0]);
31740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[1] = SWAP32(oh->roomToGrow[1]);
31840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[2] = SWAP32(oh->roomToGrow[2]);
31940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[3] = SWAP32(oh->roomToGrow[3]);
32040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[4] = SWAP32(oh->roomToGrow[4]);
32140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[5] = SWAP32(oh->roomToGrow[5]);
32240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[6] = SWAP32(oh->roomToGrow[6]);
32340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[7] = SWAP32(oh->roomToGrow[7]);
32440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[8] = SWAP32(oh->roomToGrow[8]);
32540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[9] = SWAP32(oh->roomToGrow[9]);
32640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[10] = SWAP32(oh->roomToGrow[10]);
32740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[11] = SWAP32(oh->roomToGrow[11]);
32840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#endif
32940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
33040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
33140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int write_object_header(int objId, yaffs_ObjectType t, struct stat *s, int parent, const char *name, int equivalentObj, const char * alias)
33240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
33340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	__u8 bytes[512];
33440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
33540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
33640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_ObjectHeader *oh = (yaffs_ObjectHeader *)bytes;
33740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
33840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	memset(bytes,0xff,512);
33940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
34040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	oh->type = t;
34140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
34240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	oh->parentObjectId = parent;
34340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
34440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	strncpy(oh->name,name,YAFFS_MAX_NAME_LENGTH);
34540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
34640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
34740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(t != YAFFS_OBJECT_TYPE_HARDLINK)
34840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
34940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->yst_mode = s->st_mode;
35040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->yst_uid = s->st_uid;
35140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// NCB 12/9/02		oh->yst_gid = s->yst_uid;
35240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->yst_gid = s->st_gid;
35340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->yst_atime = s->st_atime;
35440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->yst_mtime = s->st_mtime;
35540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->yst_ctime = s->st_ctime;
35640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->yst_rdev  = s->st_rdev;
35740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
35840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
35940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(t == YAFFS_OBJECT_TYPE_FILE)
36040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
36140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->fileSize = s->st_size;
36240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
36340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
36440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(t == YAFFS_OBJECT_TYPE_HARDLINK)
36540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
36640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->equivalentObjectId = equivalentObj;
36740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
36840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
36940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(t == YAFFS_OBJECT_TYPE_SYMLINK)
37040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
37140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		strncpy(oh->alias,alias,YAFFS_MAX_ALIAS_LENGTH);
37240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
37340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
37440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    if (convert_endian)
37540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    {
37640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project        object_header_little_to_big_endian(oh);
37740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    }
37840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
37940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return write_chunk(bytes,objId,0,0xffff);
38040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
38140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
38240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
38340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
38440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int process_directory(int parent, const char *path)
38540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
38640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
38740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	DIR *dir;
38840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	struct dirent *entry;
38940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
39040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	nDirectories++;
39140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
39240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	dir = opendir(path);
39340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
39440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(dir)
39540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
39640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		while((entry = readdir(dir)) != NULL)
39740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
39840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
39940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			/* Ignore . and .. */
40040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(strcmp(entry->d_name,".") &&
40140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			   strcmp(entry->d_name,".."))
40240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project 			{
40340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project 				char full_name[500];
40440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				struct stat stats;
40540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				int equivalentObj;
40640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				int newObj;
40740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
40840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				sprintf(full_name,"%s/%s",path,entry->d_name);
40940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
41040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				lstat(full_name,&stats);
41140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
41240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				if(S_ISLNK(stats.st_mode) ||
41340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				    S_ISREG(stats.st_mode) ||
41440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				    S_ISDIR(stats.st_mode) ||
41540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				    S_ISFIFO(stats.st_mode) ||
41640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				    S_ISBLK(stats.st_mode) ||
41740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				    S_ISCHR(stats.st_mode) ||
41840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				    S_ISSOCK(stats.st_mode))
41940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				{
42040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
42140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					newObj = obj_id++;
42240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					nObjects++;
42340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
42440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					printf("Object %d, %s is a ",newObj,full_name);
42540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
42640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					/* We're going to create an object for it */
42740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					if((equivalentObj = find_obj_in_list(stats.st_dev, stats.st_ino)) > 0)
42840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					{
42940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					 	/* we need to make a hard link */
43040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					 	printf("hard link to object %d\n",equivalentObj);
43140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_HARDLINK, &stats, parent, entry->d_name, equivalentObj, NULL);
43240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					}
43340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					else
43440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					{
43540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
43640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						add_obj_to_list(stats.st_dev,stats.st_ino,newObj);
43740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
43840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						if(S_ISLNK(stats.st_mode))
43940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						{
44040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
44140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							char symname[500];
44240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
44340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							memset(symname,0, sizeof(symname));
44440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
44540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							readlink(full_name,symname,sizeof(symname) -1);
44640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
44740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							printf("symlink to \"%s\"\n",symname);
44840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SYMLINK, &stats, parent, entry->d_name, -1, symname);
44940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
45040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						}
45140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						else if(S_ISREG(stats.st_mode))
45240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						{
45340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							printf("file, ");
45440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_FILE, &stats, parent, entry->d_name, -1, NULL);
45540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
45640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							if(error >= 0)
45740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							{
45840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								int h;
45940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								__u8 bytes[512];
46040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								int nBytes;
46140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								int chunk = 0;
46240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
46340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								h = open(full_name,O_RDONLY);
46440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								if(h >= 0)
46540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								{
46640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									memset(bytes,0xff,512);
46740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									while((nBytes = read(h,bytes,512)) > 0)
46840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									{
46940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project										chunk++;
47040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project										write_chunk(bytes,newObj,chunk,nBytes);
47140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project										memset(bytes,0xff,512);
47240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									}
47340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									if(nBytes < 0)
47440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									   error = nBytes;
47540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
47640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									printf("%d data chunks written\n",chunk);
47740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								}
47840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								else
47940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								{
48040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									perror("Error opening file");
48140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								}
48240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								close(h);
48340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
48440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							}
48540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
48640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						}
48740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						else if(S_ISSOCK(stats.st_mode))
48840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						{
48940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							printf("socket\n");
49040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
49140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						}
49240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						else if(S_ISFIFO(stats.st_mode))
49340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						{
49440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							printf("fifo\n");
49540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
49640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						}
49740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						else if(S_ISCHR(stats.st_mode))
49840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						{
49940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							printf("character device\n");
50040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
50140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						}
50240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						else if(S_ISBLK(stats.st_mode))
50340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						{
50440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							printf("block device\n");
50540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL);
50640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						}
50740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						else if(S_ISDIR(stats.st_mode))
50840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						{
50940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							printf("directory\n");
51040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, parent, entry->d_name, -1, NULL);
51140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// NCB modified 10/9/2001				process_directory(1,full_name);
51240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							process_directory(newObj,full_name);
51340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						}
51440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					}
51540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				}
51640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				else
51740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				{
51840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					printf(" we don't handle this type\n");
51940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				}
52040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
52140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
52240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
52340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
52440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return 0;
52540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
52640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
52740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
52840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
52940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint main(int argc, char *argv[])
53040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
53140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	struct stat stats;
53240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
53340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	printf("mkyaffsimage: image building tool for YAFFS built "__DATE__"\n");
53440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
53540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(argc < 3)
53640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
53740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		printf("usage: mkyaffsimage dir image_file [convert]\n");
53840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		printf("           dir        the directory tree to be converted\n");
53940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		printf("           image_file the output file to hold the image\n");
54040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project        printf("           'convert'  produce a big-endian image from a little-endian machine\n");
54140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		exit(1);
54240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
54340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
54440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    if ((argc == 4) && (!strncmp(argv[3], "convert", strlen("convert"))))
54540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    {
54640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project        convert_endian = 1;
54740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    }
54840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
54940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(stat(argv[1],&stats) < 0)
55040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
55140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		printf("Could not stat %s\n",argv[1]);
55240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		exit(1);
55340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
55440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
55540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(!S_ISDIR(stats.st_mode))
55640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
55740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		printf(" %s is not a directory\n",argv[1]);
55840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		exit(1);
55940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
56040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
56140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	outFile = open(argv[2],O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | S_IWRITE);
56240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
56340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
56440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(outFile < 0)
56540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
56640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		printf("Could not open output file %s\n",argv[2]);
56740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		exit(1);
56840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
56940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
57040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	printf("Processing directory %s into image file %s\n",argv[1],argv[2]);
57140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	error =  write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 1,"", -1, NULL);
57240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(error)
57340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	error = process_directory(YAFFS_OBJECTID_ROOT,argv[1]);
57440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
57540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	close(outFile);
57640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
57740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(error < 0)
57840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
57940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		perror("operation incomplete");
58040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		exit(1);
58140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
58240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
58340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
58440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		printf("Operation complete.\n"
58540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		       "%d objects in %d directories\n"
58640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		       "%d NAND pages\n",nObjects, nDirectories, nPages);
58740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
58840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
58940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	close(outFile);
59040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
59140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	exit(0);
59240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
59340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
594