1a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// Use of this source code is governed by a BSD-style license that can be 3a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// found in the LICENSE file. 4a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 5a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#include <string.h> 6a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#include <sys/stat.h> 7a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#include <sys/types.h> 8f47291926afce3235421f73811a04324195f3e13Bill Richardson#include <unistd.h> 9a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 10f47291926afce3235421f73811a04324195f3e13Bill Richardson#include "cgpt.h" 11d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen#include "cgpt_nor.h" 12f47291926afce3235421f73811a04324195f3e13Bill Richardson#include "cgptlib_internal.h" 130c3ba249abb1dc60f5ebabccf84ff13206440b83Bill Richardson#include "vboot_host.h" 14a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 15a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#define BUFSIZE 1024 16a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// FIXME: currently we only support 512-byte sectors. 17a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#define LBA_SIZE 512 18a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 19a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 20a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// fill comparebuf with the data to be examined, returning true on success. 21250549d3e742cddaf72b4f53d5739e54faf5db96Jay Srinivasanstatic int FillBuffer(CgptFindParams *params, int fd, uint64_t pos, 22a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan uint64_t count) { 23a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan uint8_t *bufptr = params->comparebuf; 24a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 25a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (-1 == lseek(fd, pos, SEEK_SET)) 26a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return 0; 27a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 28a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan // keep reading until done or error 29a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan while (count) { 30a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan ssize_t bytes_read = read(fd, bufptr, count); 31a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan // negative means error, 0 means (unexpected) EOF 32a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (bytes_read <= 0) 33a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return 0; 34a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan count -= bytes_read; 35a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan bufptr += bytes_read; 36a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 37a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 38a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return 1; 39a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan} 40a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 41a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// check partition data content. return true for match, 0 for no match or error 42250549d3e742cddaf72b4f53d5739e54faf5db96Jay Srinivasanstatic int match_content(CgptFindParams *params, struct drive *drive, 43a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan GptEntry *entry) { 44a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan uint64_t part_size; 45a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 46a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (!params->matchlen) 47a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return 1; 48a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 49a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan // Ensure that the region we want to match against is inside the partition. 50a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan part_size = LBA_SIZE * (entry->ending_lba - entry->starting_lba + 1); 51a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (params->matchoffset + params->matchlen > part_size) { 52a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return 0; 53a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 54a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 55a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan // Read the partition data. 56a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (!FillBuffer(params, 57a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan drive->fd, 58a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan (LBA_SIZE * entry->starting_lba) + params->matchoffset, 59a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan params->matchlen)) { 60a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan Error("unable to read partition data\n"); 61a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return 0; 62a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 63a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 64a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan // Compare it 65a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (0 == memcmp(params->matchbuf, params->comparebuf, params->matchlen)) { 66a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return 1; 67a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 68a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 69a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan // Nope. 70a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return 0; 71a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan} 72a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 73a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// This needs to handle /dev/mmcblk0 -> /dev/mmcblk0p3, /dev/sda -> /dev/sda3 74250549d3e742cddaf72b4f53d5739e54faf5db96Jay Srinivasanstatic void showmatch(CgptFindParams *params, char *filename, 75549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen int partnum, GptEntry *entry) { 76a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan char * format = "%s%d\n"; 77a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (strncmp("/dev/mmcblk", filename, 11) == 0) 78a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan format = "%sp%d\n"; 79549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen 80549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen if (params->numeric) { 81a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan printf("%d\n", partnum); 82549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen } else { 83549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen if (params->show_fn) { 84549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen params->show_fn(params, filename, partnum, entry); 85549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen } else { 86549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen printf(format, filename, partnum); 87549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen } 88549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen } 89a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (params->verbose > 0) 90a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan EntryDetails(entry, partnum - 1, params->numeric); 91a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan} 92a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 93549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen// This handles the MTD devices. ChromeOS uses /dev/mtdX for kernel partitions, 94549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen// /dev/ubiblockX_0 for root partitions, and /dev/ubiX for stateful partition. 95549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyenstatic void chromeos_mtd_show(CgptFindParams *params, char *filename, 96549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen int partnum, GptEntry *entry) { 97549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen if (GuidEqual(&guid_chromeos_kernel, &entry->type)) { 98549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen printf("/dev/mtd%d\n", partnum); 99549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen } else if (GuidEqual(&guid_chromeos_rootfs, &entry->type)) { 100549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen printf("/dev/ubiblock%d_0\n", partnum); 101549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen } else { 102549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen printf("/dev/ubi%d_0\n", partnum); 103549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen } 104549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen} 105549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen 106a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// This returns true if a GPT partition matches the search criteria. If a match 107a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// isn't found (or if the file doesn't contain a GPT), it returns false. The 108a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// filename and partition number that matched is left in a global, since we 109a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// could have multiple hits. 1101c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulkstatic int gpt_search(CgptFindParams *params, struct drive *drive, 1111c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk char *filename) { 112a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan int i; 113a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan GptEntry *entry; 1141c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk int retval = 0; 115a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan char partlabel[GPT_PARTNAME_LEN]; 116a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 1171c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk if (GPT_SUCCESS != GptSanityCheck(&drive->gpt)) { 118a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return 0; 119a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 120a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 1211c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk for (i = 0; i < GetNumberOfEntries(drive); ++i) { 1221c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk entry = GetEntry(&drive->gpt, ANY_VALID, i); 123a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 1243f806a2abf07d7b801852a4a6f3a9080a4b5c427Bill Richardson if (GuidIsZero(&entry->type)) 125a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan continue; 126a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 127a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan int found = 0; 128a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if ((params->set_unique && GuidEqual(¶ms->unique_guid, &entry->unique)) 129a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan || (params->set_type && GuidEqual(¶ms->type_guid, &entry->type))) { 130a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan found = 1; 131a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } else if (params->set_label) { 132a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (CGPT_OK != UTF16ToUTF8(entry->name, 133a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan sizeof(entry->name) / sizeof(entry->name[0]), 134a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan (uint8_t *)partlabel, sizeof(partlabel))) { 135a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan Error("The label cannot be converted from UTF16, so abort.\n"); 136a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return 0; 137a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 138a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (!strncmp(params->label, partlabel, sizeof(partlabel))) 139a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan found = 1; 140a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 1411c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk if (found && match_content(params, drive, entry)) { 142a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan params->hits++; 143a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan retval++; 1441c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk showmatch(params, filename, i+1, entry); 145a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (!params->match_partnum) 146a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan params->match_partnum = i+1; 147a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 148a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 149a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 1501c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk return retval; 1511c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk} 1521c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk 1531c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulkstatic int do_search(CgptFindParams *params, char *fileName) { 1541c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk int retval; 1551c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk struct drive drive; 1561c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk 157ab899591808dd3e5f955ab7693b54a83389cd35fNam T. Nguyen if (CGPT_OK != DriveOpen(fileName, &drive, O_RDONLY, params->drive_size)) 1581c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk return 0; 1591c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk 1608577b5360ca4c9514d9091ed9aded2bb3193f1f0Nam T. Nguyen retval = gpt_search(params, &drive, fileName); 1611c568bccc442afd91ea7ee5367668ba9ebc06a40Albert Chaulk 162a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan (void) DriveClose(&drive, 0); 163a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 164a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return retval; 165a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan} 166a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 167a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 168d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen#define PROC_MTD "/proc/mtd" 169a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#define PROC_PARTITIONS "/proc/partitions" 170a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#define DEV_DIR "/dev" 171a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan#define SYS_BLOCK_DIR "/sys/block" 172a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 173a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasanstatic const char *devdirs[] = { "/dev", "/devices", "/devfs", 0 }; 174a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 175a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// Given basename "foo", see if we can find a whole, real device by that name. 176a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// This is copied from the logic in the linux utility 'findfs', although that 177a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// does more exhaustive searching. 178a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasanstatic char *is_wholedev(const char *basename) { 179a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan int i; 180a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan struct stat statbuf; 181a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan static char pathname[BUFSIZE]; // we'll return this. 182a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan char tmpname[BUFSIZE]; 183a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 184a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan // It should be a block device under /dev/, 185a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan for (i = 0; devdirs[i]; i++) { 186a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan sprintf(pathname, "%s/%s", devdirs[i], basename); 187a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 188a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (0 != stat(pathname, &statbuf)) 189a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan continue; 190a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 191a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (!S_ISBLK(statbuf.st_mode)) 192a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan continue; 193a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 194a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan // It should have a symlink called /sys/block/*/device 195a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan sprintf(tmpname, "%s/%s/device", SYS_BLOCK_DIR, basename); 196a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 197a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (0 != lstat(tmpname, &statbuf)) 198a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan continue; 199a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 200a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (!S_ISLNK(statbuf.st_mode)) 201a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan continue; 202a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 203a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan // found it 204a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return pathname; 205a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 206a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 207a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return 0; 208a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan} 209a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 210a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// This scans all the physical devices it can find, looking for a match. It 211a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan// returns true if any matches were found, false otherwise. 212a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasanstatic int scan_real_devs(CgptFindParams *params) { 213a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan int found = 0; 214a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan char partname[128]; // max size for /proc/partition lines? 215a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan FILE *fp; 216a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan char *pathname; 217a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 218d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen fp = fopen(PROC_PARTITIONS, "re"); 219a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (!fp) { 220a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan perror("can't read " PROC_PARTITIONS); 221a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return found; 222a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 223a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 224d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen size_t line_length = 0; 225d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen char *line = NULL; 226d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen while (getline(&line, &line_length, fp) != -1) { 227a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan int ma, mi; 228a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan long long unsigned int sz; 229a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 230a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (sscanf(line, " %d %d %llu %127[^\n ]", &ma, &mi, &sz, partname) != 4) 231a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan continue; 232a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 233a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if ((pathname = is_wholedev(partname))) { 234a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (do_search(params, pathname)) { 235a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan found++; 236a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 237a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 238a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan } 239a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 240a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan fclose(fp); 241d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen 242d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen fp = fopen(PROC_MTD, "re"); 243d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen if (!fp) { 244d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen free(line); 245d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen return found; 246d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen } 247d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen 248d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen while (getline(&line, &line_length, fp) != -1) { 249d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen uint64_t sz; 250d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen uint32_t erasesz; 251d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen char name[128]; 252d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen // dev: size erasesize name 253d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen if (sscanf(line, "%64[^:]: %" PRIx64 " %x \"%127[^\"]\"", 254d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen partname, &sz, &erasesz, name) != 4) 255d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen continue; 256d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen if (strcmp(partname, "mtd0") == 0) { 257d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen char temp_dir[] = "/tmp/cgpt_find.XXXXXX"; 258d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen if (params->drive_size == 0) { 259d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen if (GetMtdSize("/dev/mtd0", ¶ms->drive_size) != 0) { 260d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen perror("GetMtdSize"); 261d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen goto cleanup; 262d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen } 263d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen } 264d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen if (ReadNorFlash(temp_dir) != 0) { 265d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen perror("ReadNorFlash"); 266d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen goto cleanup; 267d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen } 268d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen char nor_file[64]; 269d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen if (snprintf(nor_file, sizeof(nor_file), "%s/rw_gpt", temp_dir) > 0) { 270549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen params->show_fn = chromeos_mtd_show; 271d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen if (do_search(params, nor_file)) { 272d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen found++; 273d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen } 274549205787527d85dead8968af7a1e1064cafa00eNam T. Nguyen params->show_fn = NULL; 275d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen } 276d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen RemoveDir(temp_dir); 277d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen break; 278d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen } 279d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen } 280d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyencleanup: 281d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen fclose(fp); 282d1236e4be6a7fe1c2b132ca8f63a513949d59775Nam T. Nguyen free(line); 283a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return found; 284a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan} 285a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 286a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 2873f806a2abf07d7b801852a4a6f3a9080a4b5c427Bill Richardsonvoid CgptFind(CgptFindParams *params) { 288a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan if (params == NULL) 289a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan return; 290a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan 291250549d3e742cddaf72b4f53d5739e54faf5db96Jay Srinivasan if (params->drive_name != NULL) 292250549d3e742cddaf72b4f53d5739e54faf5db96Jay Srinivasan do_search(params, params->drive_name); 293a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan else 294a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan scan_real_devs(params); 295a05814398202c4147a5e3f28474830ec0a9a0a90Jay Srinivasan} 296