]> www.infradead.org Git - mtd-utils.git/commitdiff
mtd-utils: new prompt() helper for talking to the user
authorMike Frysinger <vapier@gentoo.org>
Wed, 8 May 2013 16:27:25 +0000 (12:27 -0400)
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
Mon, 1 Jul 2013 05:55:55 +0000 (08:55 +0300)
We've got a few tools that prompt the user for "yes/no" questions.
Add a common helper to simplify the various implementations.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
flash_otp_lock.c
ftl_format.c
include/common.h
ubi-utils/ubiformat.c

index cc8759ed3d6d3824f5554f98c3d5ffd7fa4a231d..3c39a2d0563640964f2627d0c063284951b67dd9 100644 (file)
 #include <sys/ioctl.h>
 
 #include <mtd/mtd-user.h>
+#include "common.h"
 
 int main(int argc,char *argv[])
 {
        int fd, val, ret, offset, size;
-       char *p, buf[8];
+       char *p;
 
        if (argc != 5 || strcmp(argv[1], "-u")) {
                fprintf(stderr, "Usage: %s -u <device> <offset> <size>\n", PROGRAM_NAME);
@@ -53,8 +54,7 @@ int main(int argc,char *argv[])
 
        printf("About to lock OTP user data on %s from 0x%x to 0x%x\n",
                        argv[2], offset, offset + size);
-       printf("Are you sure (yes|no)? ");
-       if (fgets(buf, sizeof(buf), stdin) && strcmp(buf, "yes\n") == 0) {
+       if (prompt("Are you sure?", false)) {
                struct otp_info info;
                info.start = offset;
                info.length = size;
index 0f69b8f0fc183bafb425f0623401c625e2c1527a..b58677f891c652cb6e02d99774ee8a5e4e2b5c31 100644 (file)
@@ -51,6 +51,7 @@
 #include <mtd/mtd-user.h>
 #include <mtd/ftl-user.h>
 #include <mtd_swab.h>
+#include "common.h"
 
 /*====================================================================*/
 
@@ -164,15 +165,9 @@ static int format_partition(int fd, int quiet, int interrogate,
                fflush(stdout);
        }
 
-       if (interrogate) {
-               char str[3];
-               printf("This will destroy all data on the target device.  "
-                               "Confirm (y/n): ");
-               if (fgets(str, 3, stdin) == NULL)
+       if (interrogate)
+               if (!prompt("This will destroy all data on the target device. Confirm?", false))
                        return -1;
-               if ((strcmp(str, "y\n") != 0) && (strcmp(str, "Y\n") != 0))
-                       return -1;
-       }
 
        /* Create basic block allocation table for control blocks */
        nbam = ((mtd.erasesize >> hdr.BlockSize) * sizeof(u_int)
index d0c4146ec263b05ce22460bea122375de0f9a8da..4ffccea1721336e59123623e4abbf2a98a88dac9 100644 (file)
@@ -19,6 +19,7 @@
 #ifndef __MTD_UTILS_COMMON_H__
 #define __MTD_UTILS_COMMON_H__
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
@@ -101,9 +102,45 @@ extern "C" {
        fprintf(stderr, "%s: warning!: " fmt "\n", PROGRAM_NAME, ##__VA_ARGS__); \
 } while(0)
 
+/**
+ * prompt the user for confirmation
+ */
+static inline bool prompt(const char *msg, bool def)
+{
+       char *line = NULL;
+       size_t len;
+       bool ret = def;
+
+       do {
+               normsg_cont("%s (%c/%c) ", msg, def ? 'Y' : 'y', def ? 'n' : 'N');
+               fflush(stdout);
+
+               while (getline(&line, &len, stdin) == -1) {
+                       printf("failed to read prompt; assuming '%s'\n",
+                               def ? "yes" : "no");
+                       break;
+               }
+
+               if (strcmp("\n", line) != 0) {
+                       switch (rpmatch(line)) {
+                       case 0: ret = false; break;
+                       case 1: ret = true; break;
+                       case -1:
+                               puts("unknown response; please try again");
+                               continue;
+                       }
+               }
+               break;
+       } while (1);
+
+       free(line);
+
+       return ret;
+}
+
 static inline int is_power_of_2(unsigned long long n)
 {
-               return (n != 0 && ((n & (n - 1)) == 0));
+       return (n != 0 && ((n & (n - 1)) == 0));
 }
 
 /**
index 899f9fc62fea0f2e941db36dbb666636fc09cf32..97a4eaba2591d5cc288654a2c6c0c68502878292 100644 (file)
@@ -243,35 +243,12 @@ static int parse_opt(int argc, char * const argv[])
 
 static int want_exit(void)
 {
-       char buf[4];
-
-       while (1) {
-               normsg_cont("continue? (yes/no)  ");
-               if (scanf("%3s", buf) == EOF) {
-                       sys_errmsg("scanf returned unexpected EOF, assume \"yes\"");
-                       return 1;
-               }
-               if (!strncmp(buf, "yes", 3) || !strncmp(buf, "y", 1))
-                       return 0;
-               if (!strncmp(buf, "no", 2) || !strncmp(buf, "n", 1))
-                       return 1;
-       }
+       return prompt("continue?", false) == true ? 0 : 1;
 }
 
-static int answer_is_yes(void)
+static int answer_is_yes(const char *msg)
 {
-       char buf[4];
-
-       while (1) {
-               if (scanf("%3s", buf) == EOF) {
-                       sys_errmsg("scanf returned unexpected EOF, assume \"no\"");
-                       return 0;
-               }
-               if (!strncmp(buf, "yes", 3) || !strncmp(buf, "y", 1))
-                       return 1;
-               if (!strncmp(buf, "no", 2) || !strncmp(buf, "n", 1))
-                       return 0;
-       }
+       return prompt(msg ? : "continue?", false);
 }
 
 static void print_bad_eraseblocks(const struct mtd_dev_info *mtd,
@@ -412,11 +389,9 @@ static int mark_bad(const struct mtd_dev_info *mtd, struct ubi_scan_info *si, in
 {
        int err;
 
-       if (!args.yes) {
-               normsg_cont("mark it as bad? Continue (yes/no) ");
-               if (!answer_is_yes())
+       if (!args.yes)
+               if (!answer_is_yes("mark it as bad?"))
                        return -1;
-       }
 
        if (!args.quiet)
                normsg_cont("marking block %d bad", eb);
@@ -922,10 +897,10 @@ int main(int argc, char * const argv[])
                                "which is different to requested offsets %d and %d",
                                si->vid_hdr_offs, si->data_offs, ui.vid_hdr_offs,
                                ui.data_offs);
-                       normsg_cont("use new offsets %d and %d? (yes/no)  ",
+                       normsg_cont("use new offsets %d and %d? ",
                                    ui.vid_hdr_offs, ui.data_offs);
                }
-               if (args.yes || answer_is_yes()) {
+               if (args.yes || answer_is_yes(NULL)) {
                        if (args.yes && !args.quiet)
                                printf("yes\n");
                } else