partiter.c: add stepall modifier; bugfixes + comment changes
authorMichal Soltys <soltys@ziu.info>
Sun, 22 Aug 2010 13:36:23 +0000 (15:36 +0200)
committerMichal Soltys <soltys@ziu.info>
Tue, 28 Sep 2010 07:32:52 +0000 (09:32 +0200)
In certain situations (new features to be added later), it's useful
to be able to step through all partitions in a partition list. This
patch adds necessary functionality.

Adjust chain.c to use new version of partiter.

Also small bugfixes and comment changes.

Signed-off-by: Michal Soltys <soltys@ziu.info>
com32/chain/chain.c
com32/chain/partiter.c
com32/chain/partiter.h

index d1939ec..88424db 100644 (file)
@@ -60,7 +60,10 @@ static int is_phys(uint8_t sdifs)
        sdifs == SYSLINUX_FS_ISOLINUX;
 }
 
-/* Search for a specific drive, based on the MBR signature; bytes 440-443 */
+/*
+ * Search for a specific drive, based on the MBR signature.
+ * Return drive and iterator at 0th position.
+ */
 static int find_by_sig(uint32_t mbr_sig,
                        struct part_iter **_boot_part)
 {
@@ -71,7 +74,7 @@ static int find_by_sig(uint32_t mbr_sig,
     for (drive = 0x80; drive < 0x80 + fixed_cnt; drive++) {
        if (disk_get_params(drive, &diskinfo))
            continue;           /* Drive doesn't exist */
-       if (!(boot_part = pi_begin(&diskinfo)))
+       if (!(boot_part = pi_begin(&diskinfo, 0)))
            continue;
        /* Check for a MBR disk */
        if (boot_part->type != typedos) {
@@ -90,11 +93,7 @@ ok:
 
 /*
  * Search for a specific drive/partition, based on the GPT GUID.
- * We return the disk drive number if found, as well as populating the
- * boot_part pointer with the matching partition, if applicable.
- * If no matching partition is found or the GUID is a disk GUID,
- * boot_part will be populated with NULL.  If not matching disk is
- * found, we return -1.
+ * Return drive and iterator at proper position.
  */
 static int find_by_guid(const struct guid *gpt_guid,
                        struct part_iter **_boot_part)
@@ -106,7 +105,7 @@ static int find_by_guid(const struct guid *gpt_guid,
     for (drive = 0x80; drive < 0x80 + fixed_cnt; drive++) {
        if (disk_get_params(drive, &diskinfo))
            continue;           /* Drive doesn't exist */
-       if (!(boot_part = pi_begin(&diskinfo)))
+       if (!(boot_part = pi_begin(&diskinfo, 0)))
            continue;
        /* Check for a GPT disk */
        if (boot_part->type != typegpt) {
@@ -130,11 +129,8 @@ ok:
 }
 
 /*
- * Search for a specific partition, based on the GPT label.
- * We return the disk drive number if found, as well as populating the
- * boot_part pointer with the matching partition, if applicable.
- * If no matching partition is found, boot_part will be populated with
- * NULL and we return -1.
+ * Search for a specific drive/partition, based on the GPT label.
+ * Return drive and iterator at proper position.
  */
 static int find_by_label(const char *label, struct part_iter **_boot_part)
 {
@@ -145,10 +141,9 @@ static int find_by_label(const char *label, struct part_iter **_boot_part)
     for (drive = 0x80; drive < 0x80 + fixed_cnt; drive++) {
        if (disk_get_params(drive, &diskinfo))
            continue;           /* Drive doesn't exist */
-       if (!(boot_part = pi_begin(&diskinfo)))
+       if (!(boot_part = pi_begin(&diskinfo, 0)))
            continue;
        /* Check for a GPT disk */
-       boot_part = pi_begin(&diskinfo);
        if (!(boot_part->type == typegpt)) {
            pi_del(&boot_part);
            continue;
@@ -383,7 +378,7 @@ int find_dp(struct part_iter **_iter)
        if (disk_get_params(drive, &diskinfo))
            goto bail;
        /* this will start iteration over FDD, possibly raw */
-       if (!(iter = pi_begin(&diskinfo)))
+       if (!(iter = pi_begin(&diskinfo, 0)))
            goto bail;
 
     } else if (!strcmp(opt.drivename, "boot") || !strcmp(opt.drivename, "fs")) {
@@ -408,7 +403,7 @@ int find_dp(struct part_iter **_iter)
        if (disk_get_params(drive, &diskinfo))
            goto bail;
        /* this will start iteration over disk emulation, possibly raw */
-       if (!(iter = pi_begin(&diskinfo)))
+       if (!(iter = pi_begin(&diskinfo, 0)))
            goto bail;
 
        /* 'fs' => we should lookup the syslinux partition number and use it */
index 2859694..0d1ea5e 100644 (file)
@@ -95,12 +95,14 @@ static int inv_type(const void *type)
  * iter_ctor() - common iterator initialization
  * @iter:      iterator pointer
  * @args(0):   disk_info structure used for disk functions
+ * @args(1):   stepall modifier
  *
  * Second and further arguments are passed as a pointer to va_list
  **/
 static int iter_ctor(struct part_iter *iter, va_list *args)
 {
     const struct disk_info *di = va_arg(*args, const struct disk_info *);
+    int stepall = va_arg(*args, int);
 
 #ifdef DEBUG
     if (!di)
@@ -108,6 +110,7 @@ static int iter_ctor(struct part_iter *iter, va_list *args)
 #endif
 
     memcpy(&iter->di, di, sizeof(struct disk_info));
+    iter->stepall = stepall;
 
     return 0;
 }
@@ -340,16 +343,13 @@ static int pi_dos_next_mbr(struct part_iter *iter, uint32_t *lba,
            /* record base EBR index */
            iter->sub.dos.bebr_index0 = iter->sub.dos.index0;
        }
-       if (ost_is_nondata(dp->ostype))
-           continue;
-
-       break;
+       if (!ost_is_nondata(dp->ostype) || iter->stepall) {
+           *lba = dp->start_lba;
+           *_dp = dp;
+           break;
+       }
     }
 
-    /* safe */
-    *lba = dp->start_lba;
-    *_dp = dp;
-
     return 0;
 bail:
     return -1;
@@ -402,6 +402,7 @@ static int pi_dos_next_ebr(struct part_iter *iter, uint32_t *lba,
        if (notsane_logical(iter) || notsane_extended(iter))
            goto bail;
 
+       iter->sub.dos.mbr_lba = abs_ebr;
        dp = ((struct disk_dos_mbr *)iter->data)->table;
        abs_ebr += dp[0].start_lba;
 
@@ -413,7 +414,7 @@ static int pi_dos_next_ebr(struct part_iter *iter, uint32_t *lba,
            iter->sub.dos.ebr_size = 0;
        }
 
-       if (dp[0].ostype) {
+       if (dp[0].ostype || iter->stepall) {
            *lba = abs_ebr;
            *_dp = dp;
            break;
@@ -422,7 +423,8 @@ static int pi_dos_next_ebr(struct part_iter *iter, uint32_t *lba,
         * This way it's possible to continue, if some crazy soft left a "hole"
         * - EBR with a valid extended partition without a logical one. In
         * such case, linux will not reserve a number for such hole - so we
-        * don't increase index0.
+        * don't increase index0. If stepall flag is set, we will never reach
+        * this place.
         */
     }
     return 0;
@@ -447,7 +449,17 @@ static struct part_iter *pi_dos_next(struct part_iter *iter)
 
     /* dos_part and start_lba are guaranteed to be valid here */
 
-    iter->index = iter->sub.dos.index0 + 1;
+    /*
+     * note special index handling, if we have stepall set -
+     * this is made to keep index consistent with non-stepall
+     * iterators
+     */
+
+    if (iter->sub.dos.index0 >= 4 && !dos_part->ostype) {
+       iter->index = -1;
+       iter->sub.dos.index0--;
+    } else
+       iter->index = iter->sub.dos.index0 + 1;
     iter->start_lba = start_lba;
     iter->record = (char *)dos_part;
 
@@ -487,9 +499,8 @@ static struct part_iter *pi_gpt_next(struct part_iter *iter)
        if (notsane_gpt(gpt_part))
            goto bail;
 
-       if (guid_is0(&gpt_part->type))
-           continue;
-       break;
+       if (!guid_is0(&gpt_part->type) || iter->stepall)
+           break;
     }
     /* no more partitions ? */
     if (iter->sub.gpt.index0 == iter->sub.gpt.pe_count) {
@@ -658,7 +669,7 @@ void *pi_del(struct part_iter **_iter)
  * This function checks the disk for GPT or legacy partition table and allocates
  * an appropriate iterator.
  **/
-struct part_iter *pi_begin(const struct disk_info *di)
+struct part_iter *pi_begin(const struct disk_info *di, int stepall)
 {
     int setraw = 0;
     struct part_iter *iter = NULL;
@@ -723,17 +734,17 @@ struct part_iter *pi_begin(const struct disk_info *di)
            goto bail;
        }
        /* allocate iterator and exit */
-       iter = pi_new(typegpt, di, gpth, gptl);
+       iter = pi_new(typegpt, di, stepall, gpth, gptl);
     } else {
        /* looks like MBR */
-       iter = pi_new(typedos, di, mbr);
+       iter = pi_new(typedos, di, stepall, mbr);
     }
 
     setraw = 0;
 bail:
     if (setraw) {
        error("WARNING: treating disk as raw.\n");
-       iter = pi_new(typeraw, di);
+       iter = pi_new(typeraw, di, stepall);
     }
     free(mbr);
     free(gpth);
index d00d609..718f603 100644 (file)
@@ -52,15 +52,17 @@ struct itertype {
 
 struct part_iter {
     const struct itertype *type;
+    char *data;
     char *record;
     uint64_t start_lba;
     int index;
     struct disk_info di;
     /* internal */
-    char *data;
+    int stepall;
     union _sub {
        struct _dos {
            uint32_t disk_sig;
+           uint32_t mbr_lba;
            /* internal */
            uint32_t ebr_start;
            uint32_t ebr_size;
@@ -85,7 +87,7 @@ extern const struct itertype * const typedos;
 extern const struct itertype * const typegpt;
 extern const struct itertype * const typeraw;
 
-struct part_iter *pi_begin(const struct disk_info *);
+struct part_iter *pi_begin(const struct disk_info *, int stepall);
 struct part_iter *pi_new(const struct itertype *, ...);
 void *pi_del(struct part_iter **);
 struct part_iter *pi_next(struct part_iter **);