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