hexedit: new applet
[oweals/busybox.git] / miscutils / setserial.c
index 501beaacc0bb1368f527373d8c90f166e1667712..f217c3beb866c48da214a9ba6b69480df397bbed 100644 (file)
@@ -9,13 +9,13 @@
  */
 
 //config:config SETSERIAL
-//config:      bool "setserial"
+//config:      bool "setserial (6.6 kb)"
 //config:      default y
-//config:      depends on PLATFORM_LINUX
+//config:      select PLATFORM_LINUX
 //config:      help
-//config:        Retrieve or set Linux serial port.
+//config:      Retrieve or set Linux serial port.
 
-//applet:IF_SETSERIAL(APPLET(setserial, BB_DIR_BIN, BB_SUID_DROP))
+//applet:IF_SETSERIAL(APPLET_NOEXEC(setserial, setserial, BB_DIR_BIN, BB_SUID_DROP, setserial))
 
 //kbuild:lib-$(CONFIG_SETSERIAL) += setserial.o
 
@@ -210,35 +210,35 @@ struct serial_struct {
 #endif
 
 //usage:#define setserial_trivial_usage
-//usage:       "[-gabGvzV] DEVICE [PARAMETER [ARG]]..."
+//usage:       "[-abGvz] { DEVICE [PARAMETER [ARG]]... | -g DEVICE... }"
 //usage:#define setserial_full_usage "\n\n"
-//usage:       "Request or set Linux serial port information\n\n"
-//usage:       "Options:\n"
-//usage:       "       -g      Interpret parameters as list of devices for reporting"
-//usage:       "       -a      Print all available information\n"
-//usage:       "       -b      Print summary information\n"
-//usage:       "       -G      Print in form which can be fed back\n"
-//usage:       "               to setserial as command line parameters\n"
-//usage:       "       -z      Zero out serial flags before setting\n"
-//usage:       "       -v      Verbose\n"
-//usage:       "\n"
-//usage:       "Parameters: (* = takes an argument, ^ = can be turned off by preceding ^)\n"
-//usage:       "       *port, *irq, *divisor, *uart, *baund_base, *close_delay, *closing_wait,\n"
-//usage:       "       ^fourport, ^auto_irq, ^skip_test, ^sak, ^session_lockout, ^pgrp_lockout,\n"
-//usage:       "       ^callout_nohup, ^split_termios, ^hup_notify, ^low_latency, autoconfig,\n"
-//usage:       "       spd_normal, spd_hi, spd_vhi, spd_shi, spd_warp, spd_cust\n"
-//usage:       "\n"
-//usage:       "UART types:\n"
-//usage:       "       unknown, 8250, 16450, 16550, 16550A, Cirrus, 16650, 16650V2, 16750,\n"
-//usage:       "       16950, 16954, 16654, 16850, RSA, NS16550A, XSCALE, RM9000, OCTEON, AR7,\n"
-//usage:       "       U6_16550A"
-
+//usage:       "Print or set serial port parameters"
+//usage:   "\n"
+//usage:   "\n""       -a      Print all"
+//usage:   "\n""       -b      Print summary"
+//usage:   "\n""       -G      Print as setserial PARAMETERs"
+//usage:   "\n""       -v      Verbose"
+//usage:   "\n""       -z      Zero out serial flags before setting"
+//usage:   "\n""       -g      All args are device names"
+//usage:   "\n"
+//usage:   "\n""PARAMETERs: (* = takes ARG, ^ = can be turned off by preceding ^)"
+//usage:   "\n""       *port, *irq, *divisor, *uart, *baud_base, *close_delay, *closing_wait,"
+//usage:   "\n""       ^fourport, ^auto_irq, ^skip_test, ^sak, ^session_lockout, ^pgrp_lockout,"
+//usage:   "\n""       ^callout_nohup, ^split_termios, ^hup_notify, ^low_latency, autoconfig,"
+//usage:   "\n""       spd_normal, spd_hi, spd_vhi, spd_shi, spd_warp, spd_cust"
+//usage:   "\n""ARG for uart:"
+//usage:   "\n""       unknown, 8250, 16450, 16550, 16550A, Cirrus, 16650, 16650V2, 16750,"
+//usage:   "\n""       16950, 16954, 16654, 16850, RSA, NS16550A, XSCALE, RM9000, OCTEON, AR7,"
+//usage:   "\n""       U6_16550A"
+
+// option string is "bGavzgq". "q" is accepted but ignored.
 #define OPT_PRINT_SUMMARY       (1 << 0)
 #define OPT_PRINT_FEDBACK       (1 << 1)
 #define OPT_PRINT_ALL           (1 << 2)
 #define OPT_VERBOSE             (1 << 3)
 #define OPT_ZERO                (1 << 4)
-#define OPT_GET                 (1 << 5)
+#define OPT_LIST_OF_DEVS        (1 << 5)
+/*#define OPT_QUIET             (1 << 6)*/
 
 #define OPT_MODE_MASK \
        (OPT_PRINT_ALL | OPT_PRINT_SUMMARY | OPT_PRINT_FEDBACK)
@@ -257,7 +257,7 @@ enum print_mode
 #define CTL_CLOSE               (1 << 3)
 #define CTL_NODIE               (1 << 4)
 
-static const char serial_types[] =
+static const char serial_types[] ALIGN1 =
        "unknown\0"             /* 0 */
        "8250\0"                /* 1 */
        "16450\0"               /* 2 */
@@ -288,7 +288,7 @@ static const char serial_types[] =
 # define MAX_SERIAL_TYPE       13
 #endif
 
-static const char commands[] =
+static const char commands[] ALIGN1 =
        "spd_normal\0"
        "spd_hi\0"
        "spd_vhi\0"
@@ -311,7 +311,7 @@ static const char commands[] =
        "irq\0"
        "divisor\0"
        "uart\0"
-       "baund_base\0"
+       "baud_base\0"
        "close_delay\0"
        "closing_wait\0"
 
@@ -362,7 +362,7 @@ static bool cmd_is_flag(int cmd)
        return (cmd >= CMD_FLAG_FIRST && cmd <= CMD_FLAG_LAST);
 }
 
-static bool cmd_need_arg(int cmd)
+static bool cmd_needs_arg(int cmd)
 {
        return (cmd >= CMD_PORT && cmd <= CMD_WAIT);
 }
@@ -404,8 +404,8 @@ static const uint16_t setbits[CMD_FLAG_LAST + 1] =
        ASYNC_LOW_LATENCY
 };
 
-static const char STR_INFINITE[] = "infinite";
-static const char STR_NONE[] = "none";
+#define STR_INFINITE "infinite"
+#define STR_NONE     "none"
 
 static const char *uart_type(int type)
 {
@@ -652,11 +652,9 @@ static int find_cmd(const char *cmd)
 static void serial_set(char **arg, int opts)
 {
        struct serial_struct serinfo;
-       int cmd;
-       const char *word;
        int fd;
 
-       fd = serial_open(*arg++, /*quiet:*/ false);
+       fd = serial_open(*arg, /*quiet:*/ false);
        if (fd < 0)
                exit(201);
 
@@ -665,17 +663,20 @@ static void serial_set(char **arg, int opts)
        if (opts & OPT_ZERO)
                serinfo.flags = 0;
 
-       while (*arg) {
+       while (*++arg) {
+               const char *word;
                int invert;
+               int cmd;
 
-               word = *arg++;
-               invert = (*word == '^');
+               word = *arg;
+               invert = (word[0] == '^');
                word += invert;
 
                cmd = find_cmd(word);
 
-               if (*arg == NULL && cmd_need_arg(cmd))
-                       bb_error_msg_and_die(bb_msg_requires_arg, word);
+               if (cmd_needs_arg(cmd))
+                       if (*++arg == NULL)
+                               bb_error_msg_and_die(bb_msg_requires_arg, word);
 
                if (invert && !cmd_is_flag(cmd))
                        bb_error_msg_and_die("can't invert %s", word);
@@ -687,7 +688,7 @@ static void serial_set(char **arg, int opts)
                case CMD_SPD_SHI:
                case CMD_SPD_WARP:
                case CMD_SPD_CUST:
-                       serinfo.flags &= ASYNC_SPD_MASK;
+                       serinfo.flags &= ~ASYNC_SPD_MASK;
                        /* fallthrough */
                case CMD_FLAG_SAK:
                case CMD_FLAG_FOURPORT:
@@ -705,25 +706,25 @@ static void serial_set(char **arg, int opts)
                                serinfo.flags |= setbits[cmd];
                        break;
                case CMD_PORT:
-                       serinfo.port = get_numeric(*arg++);
+                       serinfo.port = get_numeric(*arg);
                        break;
                case CMD_IRQ:
-                       serinfo.irq = get_numeric(*arg++);
+                       serinfo.irq = get_numeric(*arg);
                        break;
                case CMD_DIVISOR:
-                       serinfo.custom_divisor = get_numeric(*arg++);
+                       serinfo.custom_divisor = get_numeric(*arg);
                        break;
                case CMD_UART:
-                       serinfo.type = get_uart(*arg++);
+                       serinfo.type = get_uart(*arg);
                        break;
                case CMD_BASE:
-                       serinfo.baud_base = get_numeric(*arg++);
+                       serinfo.baud_base = get_numeric(*arg);
                        break;
                case CMD_DELAY:
-                       serinfo.close_delay = get_numeric(*arg++);
+                       serinfo.close_delay = get_numeric(*arg);
                        break;
                case CMD_WAIT:
-                       serinfo.closing_wait = get_wait(*arg++);
+                       serinfo.closing_wait = get_wait(*arg);
                        break;
                case CMD_AUTOCONFIG:
                        serial_ctl(fd, CTL_SET | CTL_CONFIG | CTL_GET, &serinfo);
@@ -741,22 +742,22 @@ int setserial_main(int argc UNUSED_PARAM, char **argv)
 {
        int opts;
 
-       opt_complementary = "-1:b-aG:G-ab:a-bG";
-       opts = getopt32(argv, "bGavzg");
+       opts = getopt32(argv, "^" "bGavzgq" "\0" "-1:b-aG:G-ab:a-bG");
        argv += optind;
 
-       if (!argv[1]) /* one arg only? */
-               opts |= OPT_GET;
+       if (!argv[1]) /* one arg only? (nothing to change?) */
+               opts |= OPT_LIST_OF_DEVS; /* force display */
 
-       if (!(opts & OPT_GET)) {
+       if (!(opts & OPT_LIST_OF_DEVS)) {
                serial_set(argv, opts);
                argv[1] = NULL;
        }
 
-       if (opts & (OPT_VERBOSE | OPT_GET)) {
+       /* -v effect: "after setting params, do not be silent, show them" */
+       if (opts & (OPT_VERBOSE | OPT_LIST_OF_DEVS)) {
                do {
-                       serial_get(*argv++, opts & OPT_MODE_MASK);
-               } while (*argv);
+                       serial_get(*argv, opts & OPT_MODE_MASK);
+               } while (*++argv);
        }
 
        return EXIT_SUCCESS;