cmd_find.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <getopt.h>
  5. #include <string.h>
  6. #include "cgpt.h"
  7. #include "vboot_host.h"
  8. extern const char* progname;
  9. static void Usage(void)
  10. {
  11. printf("\nUsage: %s find [OPTIONS] [DRIVE]\n\n"
  12. "Find a partition by its UUID or label. With no specified DRIVE\n"
  13. "it scans all physical drives.\n\n"
  14. "Options:\n"
  15. " -D NUM Size (in bytes) of the disk where partitions reside\n"
  16. " default 0, meaning partitions and GPT structs are\n"
  17. " both on DRIVE\n"
  18. " -t GUID Search for Partition Type GUID\n"
  19. " -u GUID Search for Partition Unique ID\n"
  20. " -l LABEL Search for Label\n"
  21. " -v Be verbose in displaying matches (repeatable)\n"
  22. " -n Numeric output only\n"
  23. " -1 Fail if more than one match is found\n"
  24. " -M FILE"
  25. " Matching partition data must also contain FILE content\n"
  26. " -O NUM"
  27. " Byte offset into partition to match content (default 0)\n"
  28. "\n", progname);
  29. PrintTypes();
  30. }
  31. // read a file into a buffer, return buffer and update size
  32. static uint8_t *ReadFile(const char *filename, uint64_t *size) {
  33. FILE *f;
  34. uint8_t *buf;
  35. long pos;
  36. f = fopen(filename, "rb");
  37. if (!f) {
  38. return NULL;
  39. }
  40. fseek(f, 0, SEEK_END);
  41. pos = ftell(f);
  42. if (pos < 0) {
  43. fclose(f);
  44. return NULL;
  45. }
  46. *size = pos;
  47. rewind(f);
  48. buf = malloc(*size);
  49. if (!buf) {
  50. fclose(f);
  51. return NULL;
  52. }
  53. if(1 != fread(buf, *size, 1, f)) {
  54. fclose(f);
  55. free(buf);
  56. return NULL;
  57. }
  58. fclose(f);
  59. return buf;
  60. }
  61. int cmd_find(int argc, char *argv[]) {
  62. CgptFindParams params;
  63. memset(&params, 0, sizeof(params));
  64. int i;
  65. int errorcnt = 0;
  66. char *e = 0;
  67. int c;
  68. opterr = 0; // quiet, you
  69. while ((c=getopt(argc, argv, ":hv1nt:u:l:M:O:D:")) != -1)
  70. {
  71. switch (c)
  72. {
  73. case 'D':
  74. params.drive_size = strtoull(optarg, &e, 0);
  75. errorcnt += check_int_parse(c, e);
  76. break;
  77. case 'v':
  78. params.verbose++;
  79. break;
  80. case 'n':
  81. params.numeric = 1;
  82. break;
  83. case '1':
  84. params.oneonly = 1;
  85. break;
  86. case 'l':
  87. params.set_label = 1;
  88. params.label = optarg;
  89. break;
  90. case 't':
  91. params.set_type = 1;
  92. if (CGPT_OK != SupportedType(optarg, &params.type_guid) &&
  93. CGPT_OK != StrToGuid(optarg, &params.type_guid)) {
  94. Error("invalid argument to -%c: %s\n", c, optarg);
  95. errorcnt++;
  96. }
  97. break;
  98. case 'u':
  99. params.set_unique = 1;
  100. if (CGPT_OK != StrToGuid(optarg, &params.unique_guid)) {
  101. Error("invalid argument to -%c: %s\n", c, optarg);
  102. errorcnt++;
  103. }
  104. break;
  105. case 'M':
  106. params.matchbuf = ReadFile(optarg, &params.matchlen);
  107. if (!params.matchbuf || !params.matchlen) {
  108. Error("Unable to read from %s\n", optarg);
  109. errorcnt++;
  110. }
  111. // Go ahead and allocate space for the comparison too
  112. params.comparebuf = (uint8_t *)malloc(params.matchlen);
  113. if (!params.comparebuf) {
  114. Error("Unable to allocate %" PRIu64 "bytes for comparison buffer\n",
  115. params.matchlen);
  116. errorcnt++;
  117. }
  118. break;
  119. case 'O':
  120. params.matchoffset = strtoull(optarg, &e, 0);
  121. errorcnt += check_int_parse(c, e);
  122. break;
  123. case 'h':
  124. Usage();
  125. return CGPT_OK;
  126. case '?':
  127. Error("unrecognized option: -%c\n", optopt);
  128. errorcnt++;
  129. break;
  130. case ':':
  131. Error("missing argument to -%c\n", optopt);
  132. errorcnt++;
  133. break;
  134. default:
  135. errorcnt++;
  136. break;
  137. }
  138. }
  139. if (!params.set_unique && !params.set_type && !params.set_label) {
  140. Error("You must specify at least one of -t, -u, or -l\n");
  141. errorcnt++;
  142. }
  143. if (errorcnt)
  144. {
  145. Usage();
  146. return CGPT_FAILED;
  147. }
  148. if (optind < argc) {
  149. for (i=optind; i<argc; i++) {
  150. params.drive_name = argv[i];
  151. CgptFind(&params);
  152. }
  153. } else {
  154. CgptFind(&params);
  155. }
  156. if (params.oneonly && params.hits != 1) {
  157. return CGPT_FAILED;
  158. }
  159. if (params.match_partnum) {
  160. return CGPT_OK;
  161. }
  162. return CGPT_FAILED;
  163. }