]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libfdisk: fix script parser to support resize operations
authorKarel Zak <kzak@redhat.com>
Tue, 21 Apr 2015 12:32:31 +0000 (14:32 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 22 Apr 2015 10:21:19 +0000 (12:21 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
libfdisk/src/fdiskP.h
libfdisk/src/script.c

index 0ca498d54f992263e50e08a05e3a3651e05c620c..5e8ed9c3552f26af4daaf2b666ceef66d57835ee 100644 (file)
@@ -121,6 +121,9 @@ struct fdisk_partition {
        fdisk_sector_t  start;                  /* first sectors */
        fdisk_sector_t  size;                   /* size in sectors */
 
+       int             movestart;              /* FDISK_MOVE_* (scripts only) */
+       int             resize;                 /* FDISK_RESIZE_* (scripts only) */
+
        char            *name;                  /* partition name */
        char            *uuid;                  /* partition UUID */
        char            *attrs;                 /* partition flags/attributes converted to string */
@@ -152,6 +155,18 @@ struct fdisk_partition {
                        wholedisk : 1;                  /* special system partition */
 };
 
+enum {
+       FDISK_MOVE_NONE = 0,
+       FDISK_MOVE_DOWN = -1,
+       FDISK_MOVE_UP = 1
+};
+
+enum {
+       FDISK_RESIZE_NONE = 0,
+       FDISK_RESIZE_REDUCE = -1,
+       FDISK_RESIZE_ENLARGE = 1
+};
+
 #define FDISK_INIT_UNDEF(_x)   ((_x) = (__typeof__(_x)) -1)
 #define FDISK_IS_UNDEF(_x)     ((_x) == (__typeof__(_x)) -1)
 
index a7e0d21d8bf725ad0589e730b2e2f667ec58ece7..469c1d4c1af0f4c9ada0a94e19d7b4f80a0c8b04 100644 (file)
@@ -815,6 +815,9 @@ static struct fdisk_parttype *translate_type_shortcuts(struct fdisk_script *dp,
        return type ? fdisk_label_parse_parttype(lb, type) : NULL;
 }
 
+#define TK_PLUS                1
+#define TK_MINUS       -1
+
 /* simple format:
  * <start>, <size>, <type>, <bootable>, ...
  */
@@ -840,6 +843,7 @@ static int parse_commas_line(struct fdisk_script *dp, char *s)
        while (rc == 0 && p && *p) {
                uint64_t num;
                char *begin;
+               int sign = 0;
 
                p = (char *) skip_blank(p);
                item++;
@@ -847,25 +851,38 @@ static int parse_commas_line(struct fdisk_script *dp, char *s)
                DBG(SCRIPT, ul_debugobj(dp, " parsing item %d ('%s')", item, p));
                begin = p;
 
+               if (item != ITEM_BOOTABLE) {
+                       sign = *p == '-' ? TK_MINUS : *p == '+' ? TK_PLUS : 0;
+                       if (sign)
+                               p++;
+               }
+
                switch (item) {
                case ITEM_START:
-                       if (*p == ',' || *p == ';')
+                       if (*p == ',' || *p == ';' || (sign && *p == '\0'))
                                fdisk_partition_start_follow_default(pa, 1);
                        else {
                                int pow = 0;
+
                                rc = next_number(&p, &num, &pow);
                                if (!rc) {
                                        if (pow)        /* specified as <num><suffix> */
                                                num /= dp->cxt->sector_size;
                                        fdisk_partition_set_start(pa, num);
+                                       pa->movestart = sign == TK_MINUS ? FDISK_MOVE_DOWN :
+                                                       sign == TK_PLUS  ? FDISK_MOVE_UP :
+                                                       FDISK_MOVE_NONE;
                                }
                                fdisk_partition_start_follow_default(pa, 0);
                        }
                        break;
                case ITEM_SIZE:
-                       if (*p == ',' || *p == ';' || *p == '+')
+                       if (*p == ',' || *p == ';' || (sign && *p == '\0')) {
                                fdisk_partition_end_follow_default(pa, 1);
-                       else {
+                               if (sign == TK_PLUS)
+                                       /* alone '+' means use all possible space, elone '-' means nothing */
+                                       pa->resize = FDISK_RESIZE_ENLARGE;
+                       } else {
                                int pow = 0;
                                rc = next_number(&p, &num, &pow);
                                if (!rc) {
@@ -874,12 +891,15 @@ static int parse_commas_line(struct fdisk_script *dp, char *s)
                                        else     /* specified as number of sectors */
                                                fdisk_partition_size_explicit(pa, 1);
                                        fdisk_partition_set_size(pa, num);
+                                       pa->resize = sign == TK_MINUS ? FDISK_RESIZE_REDUCE :
+                                                    sign == TK_PLUS  ? FDISK_RESIZE_ENLARGE :
+                                                       FDISK_RESIZE_NONE;
                                }
                                fdisk_partition_end_follow_default(pa, 0);
                        }
                        break;
                case ITEM_TYPE:
-                       if (*p == ',' || *p == ';')
+                       if (*p == ',' || *p == ';' || (sign && *p == '\0'))
                                break;  /* use default type */
 
                        rc = next_string(&p, &str);
@@ -908,6 +928,8 @@ static int parse_commas_line(struct fdisk_script *dp, char *s)
                                        pa->boot = 1;
                                else if (tk && *tk == '-' && *(tk + 1) == '\0')
                                        pa->boot = 0;
+                               else if (tk && *tk == '+' && *(tk + 1) == '\0')
+                                       pa->boot = 1;
                                else
                                        rc = -EINVAL;
                        }