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 * mkyaffs2image hacks by NCB
2340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project *
2440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project */
2540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
2640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <stdlib.h>
2740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <stdio.h>
2840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <fcntl.h>
2940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <sys/types.h>
3040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <sys/stat.h>
3140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <dirent.h>
3240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <string.h>
3340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <unistd.h>
3440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
3584f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley#define XATTR_NAME_SELINUX "security.selinux"
3684f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley#include <selinux/selinux.h>
3784f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley#include <selinux/label.h>
3884f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley
3984f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalleystatic struct selabel_handle *sehnd;
4084f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalleystatic unsigned int seprefixlen;
4184f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalleystatic char *mntpoint;
4284f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley
4340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include <private/android_filesystem_config.h>
4440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
4540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "yaffs_ecc.h"
4640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "yaffs_guts.h"
4740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
4840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "yaffs_tagsvalidity.h"
4940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#include "yaffs_packedtags2.h"
5040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
5140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectunsigned source_path_len = 0;
5240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectunsigned yaffs_traceMask=0;
5340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
5440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#define MAX_OBJECTS 50000
5540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
56193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavinunsigned chunkSize = 2048;
57193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavinunsigned spareSize = 64;
5840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
5940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectconst char * mkyaffsimage_c_version = "$Id: mkyaffs2image.c,v 1.2 2005/12/13 00:34:58 tpoynor Exp $";
6040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
6140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
6240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projecttypedef struct
6340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
6440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	dev_t dev;
6540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	ino_t ino;
6640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	int   obj;
6740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project} objItem;
6840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
6940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
7040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic objItem obj_list[MAX_OBJECTS];
7140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int n_obj = 0;
7240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int obj_id = YAFFS_NOBJECT_BUCKETS + 1;
7340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
7440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int nObjects, nDirectories, nPages;
7540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
7640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int outFile;
7740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
7840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int error;
7940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
8040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#ifdef HAVE_BIG_ENDIAN
8140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int convert_endian = 1;
8240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#elif defined(HAVE_LITTLE_ENDIAN)
8340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int convert_endian = 0;
8440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#endif
8540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
8640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int obj_compare(const void *a, const void * b)
8740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
8840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  objItem *oa, *ob;
8940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
9040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  oa = (objItem *)a;
9140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  ob = (objItem *)b;
9240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
9340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  if(oa->dev < ob->dev) return -1;
9440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  if(oa->dev > ob->dev) return 1;
9540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  if(oa->ino < ob->ino) return -1;
9640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  if(oa->ino > ob->ino) return 1;
9740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
9840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project  return 0;
9940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
10040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
10140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
10240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic void add_obj_to_list(dev_t dev, ino_t ino, int obj)
10340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
10440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(n_obj < MAX_OBJECTS)
10540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
10640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		obj_list[n_obj].dev = dev;
10740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		obj_list[n_obj].ino = ino;
10840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		obj_list[n_obj].obj = obj;
10940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		n_obj++;
11040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		qsort(obj_list,n_obj,sizeof(objItem),obj_compare);
11140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
11240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
11340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
11440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
11540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		// oops! not enough space in the object array
11640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		fprintf(stderr,"Not enough space in object array\n");
11740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		exit(2);
11840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
11940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
12040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
12140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
12240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int find_obj_in_list(dev_t dev, ino_t ino)
12340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
12440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	objItem *i = NULL;
12540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	objItem test;
12640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
12740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	test.dev = dev;
12840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	test.ino = ino;
12940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
13040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(n_obj > 0)
13140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
13240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		i = bsearch(&test,obj_list,n_obj,sizeof(objItem),obj_compare);
13340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
13440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
13540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(i)
13640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
13740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		return i->obj;
13840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
13940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return -1;
14040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
14140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
14240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#define SWAP32(x)   ((((x) & 0x000000FF) << 24) | \
14340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project                     (((x) & 0x0000FF00) << 8 ) | \
14440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project                     (((x) & 0x00FF0000) >> 8 ) | \
14540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project                     (((x) & 0xFF000000) >> 24))
14640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
14740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#define SWAP16(x)   ((((x) & 0x00FF) << 8) | \
14840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project                     (((x) & 0xFF00) >> 8))
14940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
15040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// This one is easier, since the types are more standard. No funky shifts here.
15140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic void object_header_little_to_big_endian(yaffs_ObjectHeader* oh)
15240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
15340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->type = SWAP32(oh->type); // GCC makes enums 32 bits.
15440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->parentObjectId = SWAP32(oh->parentObjectId); // int
15540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->sum__NoLongerUsed = SWAP16(oh->sum__NoLongerUsed); // __u16 - Not used, but done for completeness.
15640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    // name = skip. Char array. Not swapped.
15740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->yst_mode = SWAP32(oh->yst_mode);
15840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#ifdef CONFIG_YAFFS_WINCE // WinCE doesn't implement this, but we need to just in case.
15940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    // In fact, WinCE would be *THE* place where this would be an issue!
16040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->notForWinCE[0] = SWAP32(oh->notForWinCE[0]);
16140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->notForWinCE[1] = SWAP32(oh->notForWinCE[1]);
16240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->notForWinCE[2] = SWAP32(oh->notForWinCE[2]);
16340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->notForWinCE[3] = SWAP32(oh->notForWinCE[3]);
16440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->notForWinCE[4] = SWAP32(oh->notForWinCE[4]);
16540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#else
16640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    // Regular POSIX.
16740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->yst_uid = SWAP32(oh->yst_uid);
16840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->yst_gid = SWAP32(oh->yst_gid);
16940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->yst_atime = SWAP32(oh->yst_atime);
17040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->yst_mtime = SWAP32(oh->yst_mtime);
17140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->yst_ctime = SWAP32(oh->yst_ctime);
17240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#endif
17340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
17440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->fileSize = SWAP32(oh->fileSize); // Aiee. An int... signed, at that!
17540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->equivalentObjectId = SWAP32(oh->equivalentObjectId);
17640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    // alias  - char array.
17740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->yst_rdev = SWAP32(oh->yst_rdev);
17840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
17940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#ifdef CONFIG_YAFFS_WINCE
18040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->win_ctime[0] = SWAP32(oh->win_ctime[0]);
18140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->win_ctime[1] = SWAP32(oh->win_ctime[1]);
18240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->win_atime[0] = SWAP32(oh->win_atime[0]);
18340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->win_atime[1] = SWAP32(oh->win_atime[1]);
18440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->win_mtime[0] = SWAP32(oh->win_mtime[0]);
18540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->win_mtime[1] = SWAP32(oh->win_mtime[1]);
18640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[0] = SWAP32(oh->roomToGrow[0]);
18740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[1] = SWAP32(oh->roomToGrow[1]);
18840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[2] = SWAP32(oh->roomToGrow[2]);
18940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[3] = SWAP32(oh->roomToGrow[3]);
19040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[4] = SWAP32(oh->roomToGrow[4]);
19140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[5] = SWAP32(oh->roomToGrow[5]);
19240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#else
19340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[0] = SWAP32(oh->roomToGrow[0]);
19440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[1] = SWAP32(oh->roomToGrow[1]);
19540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[2] = SWAP32(oh->roomToGrow[2]);
19640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[3] = SWAP32(oh->roomToGrow[3]);
19740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[4] = SWAP32(oh->roomToGrow[4]);
19840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[5] = SWAP32(oh->roomToGrow[5]);
19940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[6] = SWAP32(oh->roomToGrow[6]);
20040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[7] = SWAP32(oh->roomToGrow[7]);
20140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[8] = SWAP32(oh->roomToGrow[8]);
20240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[9] = SWAP32(oh->roomToGrow[9]);
20340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[10] = SWAP32(oh->roomToGrow[10]);
20440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    oh->roomToGrow[11] = SWAP32(oh->roomToGrow[11]);
20540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project#endif
20640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
20740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
20840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project/* This little function converts a little endian tag to a big endian tag.
20940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * NOTE: The tag is not usable after this other than calculating the CRC
21040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project * with.
21140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project */
21240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic void little_to_big_endian(yaffs_PackedTags2 *pt)
21340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
21440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	pt->t.sequenceNumber = SWAP32(pt->t.sequenceNumber);
21540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	pt->t.objectId = SWAP32(pt->t.objectId);
21640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	pt->t.chunkId = SWAP32(pt->t.chunkId);
21740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	pt->t.byteCount = SWAP32(pt->t.byteCount);
21840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
21940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
22040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int write_chunk(__u8 *data, __u32 objId, __u32 chunkId, __u32 nBytes)
22140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
22260d7a5d90e475ba32005300994300bc8bec296bcrjn	char spare[spareSize];
22340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_ExtendedTags t;
22460d7a5d90e475ba32005300994300bc8bec296bcrjn	yaffs_PackedTags2 *pt = (yaffs_PackedTags2 *)spare;
22560d7a5d90e475ba32005300994300bc8bec296bcrjn
22660d7a5d90e475ba32005300994300bc8bec296bcrjn	memset(spare, 0xff, spareSize);
22740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
22840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	error = write(outFile,data,chunkSize);
22940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(error < 0) return error;
23040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
23140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_InitialiseTags(&t);
23240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
23340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	t.chunkId = chunkId;
23440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project//	t.serialNumber = 0;
23540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	t.serialNumber = 1;	// **CHECK**
23640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	t.byteCount = nBytes;
23740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	t.objectId = objId;
23840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
23940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	t.sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER;
24040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
24140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// added NCB **CHECK**
24240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	t.chunkUsed = 1;
24340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
24440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	nPages++;
24540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
24660d7a5d90e475ba32005300994300bc8bec296bcrjn	yaffs_PackTags2(pt,&t);
24740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
24840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if (convert_endian)
24940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
25060d7a5d90e475ba32005300994300bc8bec296bcrjn		little_to_big_endian(pt);
25140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
25240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
25340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project//	return write(outFile,&pt,sizeof(yaffs_PackedTags2));
25460d7a5d90e475ba32005300994300bc8bec296bcrjn	return write(outFile,spare, spareSize);
25540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
25640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
25740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
25884f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalleystatic int write_object_header(int objId, yaffs_ObjectType t, struct stat *s, int parent, const char *name, int equivalentObj, const char * alias, const char *secontext)
25940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
26040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	__u8 bytes[chunkSize];
26140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
26240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
26340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	yaffs_ObjectHeader *oh = (yaffs_ObjectHeader *)bytes;
26484f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley	char *xb = (char *)bytes + sizeof(*oh);
26584f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley	int xnamelen = strlen(XATTR_NAME_SELINUX) + 1;
26684f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley	int xvalsize = 0;
26784f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley	int xreclen = 0;
26884f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley
26984f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley	if (secontext) {
27084f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley		xvalsize = strlen(secontext) + 1;
27184f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley		xreclen = sizeof(int) + xnamelen + xvalsize;
27284f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley	}
27340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
27440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	memset(bytes,0xff,sizeof(bytes));
27540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
27640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	oh->type = t;
27740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
27840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	oh->parentObjectId = parent;
27940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
28040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	strncpy(oh->name,name,YAFFS_MAX_NAME_LENGTH);
28184f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley
28284f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley	if (xreclen) {
28384f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley		memcpy(xb, &xreclen, sizeof(int));
28484f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley		xb += sizeof(int);
28584f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley		strcpy(xb, XATTR_NAME_SELINUX);
28684f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley		xb += xnamelen;
28784f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley		memcpy(xb, secontext, xvalsize);
28884f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley	}
28940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
29040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(t != YAFFS_OBJECT_TYPE_HARDLINK)
29140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
29240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->yst_mode = s->st_mode;
29340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->yst_uid = s->st_uid;
29440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// NCB 12/9/02		oh->yst_gid = s->yst_uid;
29540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->yst_gid = s->st_gid;
29640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->yst_atime = s->st_atime;
29740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->yst_mtime = s->st_mtime;
29840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->yst_ctime = s->st_ctime;
29940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->yst_rdev  = s->st_rdev;
30040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
30140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
30240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(t == YAFFS_OBJECT_TYPE_FILE)
30340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
30440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->fileSize = s->st_size;
30540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
30640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
30740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(t == YAFFS_OBJECT_TYPE_HARDLINK)
30840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
30940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		oh->equivalentObjectId = equivalentObj;
31040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
31140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
31240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(t == YAFFS_OBJECT_TYPE_SYMLINK)
31340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
31440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		strncpy(oh->alias,alias,YAFFS_MAX_ALIAS_LENGTH);
31540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
31640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
31740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if (convert_endian)
31840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
31940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    		object_header_little_to_big_endian(oh);
32040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
32140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
32240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return write_chunk(bytes,objId,0,0xffff);
32340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
32440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
32540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
32640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic void fix_stat(const char *path, struct stat *s)
32740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
32849cc2ffe1feae14951a7174625ba7269685a5357Nick Kralevich    uint64_t capabilities;
32940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    path += source_path_len;
33049cc2ffe1feae14951a7174625ba7269685a5357Nick Kralevich    fs_config(path, S_ISDIR(s->st_mode), &s->st_uid, &s->st_gid, &s->st_mode, &capabilities);
33140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
33240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
33340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectstatic int process_directory(int parent, const char *path, int fixstats)
33440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
33540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
33640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	DIR *dir;
33740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	struct dirent *entry;
33884f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley	char *secontext = NULL;
33940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
34040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	nDirectories++;
34140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
34240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	dir = opendir(path);
34340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
34440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(dir)
34540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
34640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		while((entry = readdir(dir)) != NULL)
34740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		{
34840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
34940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			/* Ignore . and .. */
35040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			if(strcmp(entry->d_name,".") &&
35140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			   strcmp(entry->d_name,".."))
35240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project 			{
35340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project 				char full_name[500];
35484f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley				char *suffix, dest_name[500];
35584f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley				int ret;
35640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				struct stat stats;
35740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				int equivalentObj;
35840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				int newObj;
35940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
36040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				sprintf(full_name,"%s/%s",path,entry->d_name);
36140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
36240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				lstat(full_name,&stats);
36384f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley
36484f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley				if (sehnd) {
36584f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley					suffix = full_name + seprefixlen;
36684f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley					ret = snprintf(dest_name,
36784f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley						       sizeof dest_name,
36884f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley						       "%s%s", mntpoint,
36984f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley						       suffix);
37084f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley					if (ret < 0 ||
37184f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley					    (size_t) ret >= sizeof dest_name) {
37284f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley						fprintf(stderr,
37384f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley							"snprintf failed on %s%s\n",
37484f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley							mntpoint, suffix);
37584f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley						exit(1);
37684f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley					}
377bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig
378bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig					char *sepath = NULL;
379bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig					if (dest_name[0] == '/')
380bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig					        sepath = strdup(dest_name);
381bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig					else if (asprintf(&sepath, "/%s", dest_name) < 0)
382bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig                                                sepath = NULL;
383bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig
384bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig					if (!sepath) {
385bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig					        perror("malloc");
386bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig					        exit(1);
387bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig					}
388bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig
38984f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley					if (selabel_lookup(sehnd, &secontext,
390bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig							   sepath,
39184f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley							   stats.st_mode) < 0) {
392bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig					        perror("selabel_lookup");
393bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig					        free(sepath);
394bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig					        exit(1);
39584f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley					}
396bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig					free(sepath);
39784f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley				}
39884f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley
39940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				if(S_ISLNK(stats.st_mode) ||
40040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				    S_ISREG(stats.st_mode) ||
40140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				    S_ISDIR(stats.st_mode) ||
40240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				    S_ISFIFO(stats.st_mode) ||
40340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				    S_ISBLK(stats.st_mode) ||
40440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				    S_ISCHR(stats.st_mode) ||
40540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				    S_ISSOCK(stats.st_mode))
40640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				{
40740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
40840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					newObj = obj_id++;
40940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					nObjects++;
41040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
41140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project                    if (fixstats) {
41240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project                        fix_stat(full_name, &stats);
41340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project                    }
41440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
41540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					//printf("Object %d, %s is a ",newObj,full_name);
41640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
41740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					/* We're going to create an object for it */
41840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					if((equivalentObj = find_obj_in_list(stats.st_dev, stats.st_ino)) > 0)
41940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					{
42040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					 	/* we need to make a hard link */
42140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					 	//printf("hard link to object %d\n",equivalentObj);
42284f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley						error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_HARDLINK, &stats, parent, entry->d_name, equivalentObj, NULL, secontext);
42340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					}
42440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					else
42540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					{
42640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
42740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						add_obj_to_list(stats.st_dev,stats.st_ino,newObj);
42840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
42940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						if(S_ISLNK(stats.st_mode))
43040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						{
43140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
43240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							char symname[500];
43340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
43440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							memset(symname,0, sizeof(symname));
43540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
43640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							readlink(full_name,symname,sizeof(symname) -1);
43740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
43840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							//printf("symlink to \"%s\"\n",symname);
43984f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SYMLINK, &stats, parent, entry->d_name, -1, symname, secontext);
44040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
44140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						}
44240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						else if(S_ISREG(stats.st_mode))
44340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						{
44440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							//printf("file, ");
44584f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_FILE, &stats, parent, entry->d_name, -1, NULL, secontext);
44640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
44740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							if(error >= 0)
44840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							{
44940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								int h;
45040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								__u8 bytes[chunkSize];
45140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								int nBytes;
45240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								int chunk = 0;
45340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
45440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								h = open(full_name,O_RDONLY);
45540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								if(h >= 0)
45640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								{
45740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									memset(bytes,0xff,sizeof(bytes));
45840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									while((nBytes = read(h,bytes,sizeof(bytes))) > 0)
45940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									{
46040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project										chunk++;
46140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project										write_chunk(bytes,newObj,chunk,nBytes);
46240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project										memset(bytes,0xff,sizeof(bytes));
46340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									}
46440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									if(nBytes < 0)
46540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									   error = nBytes;
46640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
46740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									//printf("%d data chunks written\n",chunk);
46840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								}
46940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								else
47040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								{
47140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project									perror("Error opening file");
47240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								}
47340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project								close(h);
47440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
47540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							}
47640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
47740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						}
47840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						else if(S_ISSOCK(stats.st_mode))
47940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						{
48040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							//printf("socket\n");
48184f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL, secontext);
48240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						}
48340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						else if(S_ISFIFO(stats.st_mode))
48440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						{
48540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							//printf("fifo\n");
48684f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL, secontext);
48740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						}
48840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						else if(S_ISCHR(stats.st_mode))
48940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						{
49040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							//printf("character device\n");
49184f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL, secontext);
49240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						}
49340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						else if(S_ISBLK(stats.st_mode))
49440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						{
49540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							//printf("block device\n");
49684f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL, secontext);
49740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						}
49840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						else if(S_ISDIR(stats.st_mode))
49940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						{
50040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							//printf("directory\n");
50184f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, parent, entry->d_name, -1, NULL, secontext);
50240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project// NCB modified 10/9/2001				process_directory(1,full_name);
50340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project							process_directory(newObj,full_name,fixstats);
50440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project						}
50540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					}
50640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				}
50740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				else
50840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				{
50940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project					//printf(" we don't handle this type\n");
51040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project				}
51140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project			}
51240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		}
51340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		closedir(dir);
51440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
51540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
51640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	return 0;
51740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
51840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
51940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
520eadd925d248de16fe7f19ac85c542a18f09149acDima Zavinstatic void usage(void)
521eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin{
522eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	fprintf(stderr,"mkyaffs2image: image building tool for YAFFS2 built "__DATE__"\n");
52384f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley	fprintf(stderr,"usage: mkyaffs2image [-f] [-c <size>] [-s <size>] dir image_file [file_contexts mountpoint] [convert]\n");
524eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	fprintf(stderr,"           -f         fix file stat (mods, user, group) for device\n");
525193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavin	fprintf(stderr,"           -c <size>  set the chunk (NAND page) size. default: 2048\n");
526193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavin	fprintf(stderr,"           -s <size>  set the spare (NAND OOB) size. default: 64\n");
527eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	fprintf(stderr,"           dir        the directory tree to be converted\n");
528eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	fprintf(stderr,"           image_file the output file to hold the image\n");
52984f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley	fprintf(stderr,"           file_contexts the file contexts configuration used to assign SELinux file context attributes\n");
53084f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley	fprintf(stderr,"           mountpoint the directory where this image be mounted on the device\n");
531eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	fprintf(stderr,"           'convert'  produce a big-endian image from a little-endian machine\n");
532eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin}
53340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
53440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Projectint main(int argc, char *argv[])
53540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project{
536eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	int fixstats = 0;
53740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	struct stat stats;
538eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	int opt;
539eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	char *image;
540eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	char *dir;
54184f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley	char *secontext = NULL;
542eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin
543193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavin	while ((opt = getopt(argc, argv, "fc:s:")) != -1) {
544eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin		switch (opt) {
545eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin		case 'f':
546eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin			fixstats = 1;
547eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin			break;
548193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavin		case 'c':
549193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavin			chunkSize = (unsigned)strtoul(optarg, NULL, 0);
550193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavin			break;
551193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavin		case 's':
552193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavin			spareSize = (unsigned)strtoul(optarg, NULL, 0);
553193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavin			break;
554eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin		default:
555eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin			usage();
556eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin			exit(1);
557eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin		}
558eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	}
55940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
560193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavin	if (!chunkSize || !spareSize) {
561193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavin		usage();
562193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavin		exit(1);
563193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavin	}
564193ce3d45a984427f9db7c81ff958c0ad62d6c54Dima Zavin
56584f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley	if ((argc - optind < 2) || (argc - optind > 4)) {
566eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin		usage();
56740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		exit(1);
56840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
56940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
570eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	dir = argv[optind];
57184f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley	seprefixlen = strlen(dir);
572eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	image = argv[optind + 1];
573eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin
574eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	if (optind + 2 < argc) {
575eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin		if (!strncmp(argv[optind + 2], "convert", strlen("convert")))
576eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin			convert_endian = 1;
577eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin		else {
57884f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley			struct selinux_opt seopts[] = {
57984f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley				{ SELABEL_OPT_PATH, argv[optind + 2] }
58084f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley			};
58184f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley			sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1);
58284f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley			if (!sehnd) {
58384f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley				perror(argv[optind + 2]);
58484f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley				usage();
58584f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley				exit(1);
58684f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley			}
58784f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley			if (optind + 3 >= argc) {
58884f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley				usage();
58984f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley				exit(1);
59084f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley			}
59184f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley			mntpoint = argv[optind + 3];
59284f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley			if (optind + 4 < argc) {
59384f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley				if (!strncmp(argv[optind + 4], "convert", strlen("convert")))
59484f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley					convert_endian = 1;
59584f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley			}
596eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin		}
597eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	}
598eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin
599eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	if(stat(dir,&stats) < 0)
60040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
601eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin		fprintf(stderr,"Could not stat %s\n",dir);
60240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		exit(1);
60340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
60440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
60540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(!S_ISDIR(stats.st_mode))
60640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
607eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin		fprintf(stderr," %s is not a directory\n",dir);
60840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		exit(1);
60940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
61040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
611eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	outFile = open(image,O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | S_IWRITE);
61240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
61340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
61440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(outFile < 0)
61540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
616eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin		fprintf(stderr,"Could not open output file %s\n",image);
61740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		exit(1);
61840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
61940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
62040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    if (fixstats) {
621eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin        int len = strlen(dir);
62240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
623eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin        if((len >= 4) && (!strcmp(dir + len - 4, "data"))) {
62440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project            source_path_len = len - 4;
625f9485fe8567fc50f2eecf35055ee5c5c31d61362The Android Open Source Project        } else if((len >= 6) && (!strcmp(dir + len - 6, "system"))) {
62640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project            source_path_len = len - 6;
62740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project        } else {
62840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project            fprintf(stderr,"Fixstats (-f) option requested but filesystem is not data or android!\n");
62940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project            exit(1);
63040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project        }
631eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin        fix_stat(dir, &stats);
63240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project    }
63340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
634eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	//printf("Processing directory %s into image file %s\n",dir,image);
63584f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley    if (sehnd) {
636bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig
637bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig        char *sepath = NULL;
638bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig        if (mntpoint[0] == '/')
639bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig	    sepath = strdup(mntpoint);
640bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig        else if (asprintf(&sepath, "/%s", mntpoint) < 0)
641bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig            sepath = NULL;
642bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig
643bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig        if (!sepath) {
644bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig	    perror("malloc");
645bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig	    exit(1);
646bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig	}
647bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig
648bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig	if (selabel_lookup(sehnd, &secontext, sepath, stats.st_mode) < 0) {
649bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig	    perror("selabel_lookup");
650bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig	    free(sepath);
651bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig	    exit(1);
652bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig	}
653bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig
654bd009e4d493deaf90c38da1cdbaa1db69db073barpcraig	free(sepath);
65584f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley    }
65684f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley
65784f79e8e767a95ea761f430a12adb13ce687ae7eStephen Smalley    error =  write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 1,"", -1, NULL, secontext);
65840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(error)
659eadd925d248de16fe7f19ac85c542a18f09149acDima Zavin	error = process_directory(YAFFS_OBJECTID_ROOT,dir,fixstats);
66040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
66140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	close(outFile);
66240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
66340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	if(error < 0)
66440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
66540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		perror("operation incomplete");
66640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		exit(1);
66740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
66840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	else
66940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	{
67040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project        /*
67140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		printf("Operation complete.\n"
67240c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		       "%d objects in %d directories\n"
67340c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project		       "%d NAND pages\n",nObjects, nDirectories, nPages);
67440c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project        */
67540c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	}
67640c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
67740c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	close(outFile);
67840c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
67940c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project	exit(0);
68040c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project}
68140c4004d07a37a9b140067f893930ce4436b9346The Android Open Source Project
682