char * do_part_get_name (const char *device, int partnum) { CLEANUP_FREE char *parttype; parttype = do_part_get_parttype (device); if (parttype == NULL) return NULL; if (STREQ (parttype, "gpt")) { CLEANUP_FREE char *out = print_partition_table (device, true); if (!out) return NULL; CLEANUP_FREE_STRING_LIST char **lines = split_lines (out); if (!lines) return NULL; if (lines[0] == NULL || STRNEQ (lines[0], "BYT;")) { reply_with_error ("unknown signature, expected \"BYT;\" as first line of the output: %s", lines[0] ? lines[0] : "(signature was null)"); return NULL; } if (lines[1] == NULL) { reply_with_error ("parted didn't return a line describing the device"); return NULL; } size_t row; int pnum; for (row = 2; lines[row] != NULL; ++row) { if (sscanf (lines[row], "%d:", &pnum) != 1) { reply_with_error ("could not parse row from output of parted print command: %s", lines[row]); return NULL; } if (pnum == partnum) break; } if (lines[row] == NULL) { reply_with_error ("partition number %d not found", partnum); return NULL; } char *name = get_table_field (lines[row], 5); if (name == NULL) reply_with_error ("cannot get the name field from '%s'", lines[row]); return name; } else { reply_with_error ("part-get-name can only be used on GUID Partition Tables"); return NULL; } }
int do_part_get_bootable (const char *device, int partnum) { if (partnum <= 0) { reply_with_error ("partition number must be >= 1"); return -1; } CLEANUP_FREE char *out = print_partition_table (device, true); if (!out) return -1; CLEANUP_FREE_STRING_LIST char **lines = split_lines (out); if (!lines) return -1; /* Partitions may not be in any order, so we have to look for * the matching partition number (RHBZ#602997). */ if (lines[0] == NULL || STRNEQ (lines[0], "BYT;")) { reply_with_error ("unknown signature, expected \"BYT;\" as first line of the output: %s", lines[0] ? lines[0] : "(signature was null)"); return -1; } if (lines[1] == NULL) { reply_with_error ("parted didn't return a line describing the device"); return -1; } size_t row; int pnum; for (row = 2; lines[row] != NULL; ++row) { if (sscanf (lines[row], "%d:", &pnum) != 1) { reply_with_error ("could not parse row from output of parted print command: %s", lines[row]); return -1; } if (pnum == partnum) break; } if (lines[row] == NULL) { reply_with_error ("partition number %d not found", partnum); return -1; } CLEANUP_FREE char *boot = get_table_field (lines[row], 6); if (boot == NULL) return -1; return strstr (boot, "boot") != NULL; }
int do_part_get_bootable (const char *device, int partnum) { if (partnum <= 0) { reply_with_error ("partition number must be >= 1"); return -1; } int parted_has_m_opt = test_parted_m_opt (); if (parted_has_m_opt == -1) return -1; char *out = print_partition_table (device, parted_has_m_opt); if (!out) return -1; char **lines = split_lines (out); free (out); if (!lines) return -1; if (parted_has_m_opt) { /* New-style parsing using the "machine-readable" format from * 'parted -m'. * * Partitions may not be in any order, so we have to look for * the matching partition number (RHBZ#602997). */ if (lines[0] == NULL || STRNEQ (lines[0], "BYT;")) { reply_with_error ("unknown signature, expected \"BYT;\" as first line of the output: %s", lines[0] ? lines[0] : "(signature was null)"); free_strings (lines); return -1; } if (lines[1] == NULL) { reply_with_error ("parted didn't return a line describing the device"); free_strings (lines); return -1; } size_t row; int pnum; for (row = 2; lines[row] != NULL; ++row) { if (sscanf (lines[row], "%d:", &pnum) != 1) { reply_with_error ("could not parse row from output of parted print command: %s", lines[row]); free_strings (lines); return -1; } if (pnum == partnum) break; } if (lines[row] == NULL) { reply_with_error ("partition number %d not found", partnum); free_strings (lines); return -1; } char *boot = get_table_field (lines[row], 6); if (boot == NULL) { free_strings (lines); return -1; } int r = STREQ (boot, "boot"); free (boot); free_strings (lines); return r; } else { /* Old-style: First look for the line matching "^Number". */ size_t start = 0, header, row; for (row = 0; lines[row] != NULL; ++row) if (STRPREFIX (lines[row], "Number")) { start = row+1; header = row; break; } if (start == 0) { reply_with_error ("parted output has no \"Number\" line"); free_strings (lines); return -1; } /* Now we have to look at the column number of the "Flags" field. * This is because parted's output has no way to represent a * missing field except as whitespace, so we cannot just count * fields from the left. eg. The "File system" field is often * missing in the output. */ char *p = strstr (lines[header], "Flags"); if (!p) { reply_with_error ("parted output has no \"Flags\" field"); free_strings (lines); return -1; } size_t col = p - lines[header]; /* Look for the line corresponding to this partition number. */ row = start + partnum - 1; if (row >= count_strings (lines) || !STRPREFIX (lines[row], " ")) { reply_with_error ("partition number out of range: %d", partnum); free_strings (lines); return -1; } int r = STRPREFIX (&lines[row][col], "boot"); free_strings (lines); return r; } }
char * do_part_get_parttype (const char *device) { int parted_has_m_opt = test_parted_m_opt (); if (parted_has_m_opt == -1) return NULL; char *out = print_partition_table (device, parted_has_m_opt); if (!out) return NULL; if (parted_has_m_opt) { /* New-style parsing using the "machine-readable" format from * 'parted -m'. */ char **lines = split_lines (out); free (out); if (!lines) return NULL; if (lines[0] == NULL || STRNEQ (lines[0], "BYT;")) { reply_with_error ("unknown signature, expected \"BYT;\" as first line of the output: %s", lines[0] ? lines[0] : "(signature was null)"); free_strings (lines); return NULL; } if (lines[1] == NULL) { reply_with_error ("parted didn't return a line describing the device"); free_strings (lines); return NULL; } /* lines[1] is something like: * "/dev/sda:1953525168s:scsi:512:512:msdos:ATA Hitachi HDT72101;" */ char *r = get_table_field (lines[1], 5); if (r == NULL) { free_strings (lines); return NULL; } free_strings (lines); /* If "loop" return an error (RHBZ#634246). */ if (STREQ (r, "loop")) { free (r); reply_with_error ("not a partitioned device"); return NULL; } return r; } else { /* Old-style. Look for "\nPartition Table: <str>\n". */ char *p = strstr (out, "\nPartition Table: "); if (!p) { reply_with_error ("parted didn't return Partition Table line"); free (out); return NULL; } p += 18; char *q = strchr (p, '\n'); if (!q) { reply_with_error ("parted Partition Table has no end of line char"); free (out); return NULL; } *q = '\0'; p = strdup (p); free (out); if (!p) { reply_with_perror ("strdup"); return NULL; } /* If "loop" return an error (RHBZ#634246). */ if (STREQ (p, "loop")) { free (p); reply_with_error ("not a partitioned device"); return NULL; } return p; /* caller frees */ } }