diff options
-rw-r--r-- | archival/tar.c | 19 | ||||
-rw-r--r-- | examples/mdev.conf | 10 | ||||
-rw-r--r-- | examples/mdev_fat.conf | 9 | ||||
-rw-r--r-- | util-linux/mdev.c | 51 |
4 files changed, 40 insertions, 49 deletions
diff --git a/archival/tar.c b/archival/tar.c index cf972c24c..a64d6510f 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -60,8 +60,8 @@ | |||
60 | 60 | ||
61 | #if !ENABLE_FEATURE_SEAMLESS_GZ && !ENABLE_FEATURE_SEAMLESS_BZ2 | 61 | #if !ENABLE_FEATURE_SEAMLESS_GZ && !ENABLE_FEATURE_SEAMLESS_BZ2 |
62 | /* Do not pass gzip flag to writeTarFile() */ | 62 | /* Do not pass gzip flag to writeTarFile() */ |
63 | #define writeTarFile(tar_fd, verboseFlag, dereferenceFlag, include, exclude, gzip) \ | 63 | #define writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude, gzip) \ |
64 | writeTarFile(tar_fd, verboseFlag, dereferenceFlag, include, exclude) | 64 | writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude) |
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | 67 | ||
@@ -598,7 +598,7 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip) | |||
598 | 598 | ||
599 | /* gcc 4.2.1 inlines it, making code bigger */ | 599 | /* gcc 4.2.1 inlines it, making code bigger */ |
600 | static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, | 600 | static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, |
601 | int dereferenceFlag, const llist_t *include, | 601 | int recurseFlags, const llist_t *include, |
602 | const llist_t *exclude, int gzip) | 602 | const llist_t *exclude, int gzip) |
603 | { | 603 | { |
604 | int errorFlag = FALSE; | 604 | int errorFlag = FALSE; |
@@ -621,8 +621,7 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, | |||
621 | 621 | ||
622 | /* Read the directory/files and iterate over them one at a time */ | 622 | /* Read the directory/files and iterate over them one at a time */ |
623 | while (include) { | 623 | while (include) { |
624 | if (!recursive_action(include->data, ACTION_RECURSE | | 624 | if (!recursive_action(include->data, recurseFlags, |
625 | (dereferenceFlag ? ACTION_FOLLOWLINKS : 0), | ||
626 | writeFileToTarball, writeFileToTarball, &tbInfo, 0) | 625 | writeFileToTarball, writeFileToTarball, &tbInfo, 0) |
627 | ) { | 626 | ) { |
628 | errorFlag = TRUE; | 627 | errorFlag = TRUE; |
@@ -662,7 +661,7 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, | |||
662 | } | 661 | } |
663 | #else | 662 | #else |
664 | int writeTarFile(int tar_fd, int verboseFlag, | 663 | int writeTarFile(int tar_fd, int verboseFlag, |
665 | int dereferenceFlag, const llist_t *include, | 664 | int recurseFlags, const llist_t *include, |
666 | const llist_t *exclude, int gzip); | 665 | const llist_t *exclude, int gzip); |
667 | #endif /* FEATURE_TAR_CREATE */ | 666 | #endif /* FEATURE_TAR_CREATE */ |
668 | 667 | ||
@@ -749,6 +748,7 @@ static llist_t *append_file_list_to_list(llist_t *list) | |||
749 | // o no-same-owner | 748 | // o no-same-owner |
750 | // p same-permissions | 749 | // p same-permissions |
751 | // k keep-old | 750 | // k keep-old |
751 | // no-recursion | ||
752 | // numeric-owner | 752 | // numeric-owner |
753 | // no-same-permissions | 753 | // no-same-permissions |
754 | // overwrite | 754 | // overwrite |
@@ -768,6 +768,7 @@ enum { | |||
768 | IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) // 16th bit | 768 | IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) // 16th bit |
769 | IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) | 769 | IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) |
770 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS | 770 | #if ENABLE_FEATURE_TAR_LONG_OPTIONS |
771 | OPTBIT_NORECURSION, | ||
771 | IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) | 772 | IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) |
772 | OPTBIT_NUMERIC_OWNER, | 773 | OPTBIT_NUMERIC_OWNER, |
773 | OPTBIT_NOPRESERVE_PERM, | 774 | OPTBIT_NOPRESERVE_PERM, |
@@ -791,6 +792,7 @@ enum { | |||
791 | OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z | 792 | OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z |
792 | OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z | 793 | OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z |
793 | OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m | 794 | OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m |
795 | OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion | ||
794 | OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command | 796 | OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command |
795 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner | 797 | OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner |
796 | OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions | 798 | OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions |
@@ -835,6 +837,7 @@ static const char tar_longopts[] ALIGN1 = | |||
835 | # if ENABLE_FEATURE_TAR_NOPRESERVE_TIME | 837 | # if ENABLE_FEATURE_TAR_NOPRESERVE_TIME |
836 | "touch\0" No_argument "m" | 838 | "touch\0" No_argument "m" |
837 | # endif | 839 | # endif |
840 | "no-recursion\0" No_argument "\xfa" | ||
838 | # if ENABLE_FEATURE_TAR_TO_COMMAND | 841 | # if ENABLE_FEATURE_TAR_TO_COMMAND |
839 | "to-command\0" Required_argument "\xfb" | 842 | "to-command\0" Required_argument "\xfb" |
840 | # endif | 843 | # endif |
@@ -1050,7 +1053,9 @@ int tar_main(int argc UNUSED_PARAM, char **argv) | |||
1050 | zipMode = 2; | 1053 | zipMode = 2; |
1051 | #endif | 1054 | #endif |
1052 | /* NB: writeTarFile() closes tar_handle->src_fd */ | 1055 | /* NB: writeTarFile() closes tar_handle->src_fd */ |
1053 | return writeTarFile(tar_handle->src_fd, verboseFlag, opt & OPT_DEREFERENCE, | 1056 | return writeTarFile(tar_handle->src_fd, verboseFlag, |
1057 | (opt & OPT_DEREFERENCE ? ACTION_FOLLOWLINKS : 0) | ||
1058 | | (opt & OPT_NORECURSION ? 0 : ACTION_RECURSE), | ||
1054 | tar_handle->accept, | 1059 | tar_handle->accept, |
1055 | tar_handle->reject, zipMode); | 1060 | tar_handle->reject, zipMode); |
1056 | } | 1061 | } |
diff --git a/examples/mdev.conf b/examples/mdev.conf index cdbb4fcfe..51795694d 100644 --- a/examples/mdev.conf +++ b/examples/mdev.conf | |||
@@ -7,8 +7,14 @@ | |||
7 | # instead of the default 0:0 660. | 7 | # instead of the default 0:0 660. |
8 | # | 8 | # |
9 | # Syntax: | 9 | # Syntax: |
10 | # %s %d:%d %s | 10 | # [-]devicename_regex user:group mode [=path]|[>path]|[!] [@|$|*cmd args...] |
11 | # devicename_regex user:group mode | 11 | # [-]$ENVVAR=regex user:group mode [=path]|[>path]|[!] [@|$|*cmd args...] |
12 | # [-]@maj,min[-min2] user:group mode [=path]|[>path]|[!] [@|$|*cmd args...] | ||
13 | # | ||
14 | # [-]: do not stop on this match, continue reading mdev.conf | ||
15 | # =: move, >: move and create a symlink | ||
16 | # !: do not create device node | ||
17 | # @|$|*: run@cmd if $ACTION=add, $cmd if $ACTION=remove, *cmd in all cases | ||
12 | 18 | ||
13 | null 0:0 666 | 19 | null 0:0 666 |
14 | zero 0:0 666 | 20 | zero 0:0 666 |
diff --git a/examples/mdev_fat.conf b/examples/mdev_fat.conf index df329b4b5..ceba3a797 100644 --- a/examples/mdev_fat.conf +++ b/examples/mdev_fat.conf | |||
@@ -7,10 +7,14 @@ | |||
7 | # instead of the default 0:0 660. | 7 | # instead of the default 0:0 660. |
8 | # | 8 | # |
9 | # Syntax: | 9 | # Syntax: |
10 | # [-]devicename_regex user:group mode [>|=path] [@|$|*cmd args...] | 10 | # [-]devicename_regex user:group mode [=path]|[>path]|[!] [@|$|*cmd args...] |
11 | # [-]$ENVVAR=regex user:group mode [=path]|[>path]|[!] [@|$|*cmd args...] | ||
12 | # [-]@maj,min[-min2] user:group mode [=path]|[>path]|[!] [@|$|*cmd args...] | ||
11 | # | 13 | # |
14 | # [-]: do not stop on this match, continue reading mdev.conf | ||
12 | # =: move, >: move and create a symlink | 15 | # =: move, >: move and create a symlink |
13 | # @|$|*: run $cmd on delete, @cmd on create, *cmd on both | 16 | # !: do not create device node |
17 | # @|$|*: run cmd if $ACTION=remove, @cmd if $ACTION=add, *cmd in all cases | ||
14 | 18 | ||
15 | # support module loading on hotplug | 19 | # support module loading on hotplug |
16 | $MODALIAS=.* root:root 660 @modprobe "$MODALIAS" | 20 | $MODALIAS=.* root:root 660 @modprobe "$MODALIAS" |
@@ -49,7 +53,6 @@ sr[0-9]* root:cdrom 660 @ln -sf $MDEV cdrom | |||
49 | fd[0-9]* root:floppy 660 | 53 | fd[0-9]* root:floppy 660 |
50 | 54 | ||
51 | # net devices | 55 | # net devices |
52 | -net/.* root:root 600 @nameif | ||
53 | tun[0-9]* root:root 600 =net/ | 56 | tun[0-9]* root:root 600 =net/ |
54 | tap[0-9]* root:root 600 =net/ | 57 | tap[0-9]* root:root 600 =net/ |
55 | 58 | ||
diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 17355bf62..84e72e2e6 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c | |||
@@ -236,7 +236,6 @@ enum { OP_add, OP_remove }; | |||
236 | struct rule { | 236 | struct rule { |
237 | bool keep_matching; | 237 | bool keep_matching; |
238 | bool regex_compiled; | 238 | bool regex_compiled; |
239 | bool regex_has_slash; | ||
240 | mode_t mode; | 239 | mode_t mode; |
241 | int maj, min0, min1; | 240 | int maj, min0, min1; |
242 | struct bb_uidgid_t ugid; | 241 | struct bb_uidgid_t ugid; |
@@ -340,7 +339,6 @@ static void parse_next_rule(void) | |||
340 | } | 339 | } |
341 | xregcomp(&G.cur_rule.match, val, REG_EXTENDED); | 340 | xregcomp(&G.cur_rule.match, val, REG_EXTENDED); |
342 | G.cur_rule.regex_compiled = 1; | 341 | G.cur_rule.regex_compiled = 1; |
343 | G.cur_rule.regex_has_slash = (strchr(val, '/') != NULL); | ||
344 | } | 342 | } |
345 | 343 | ||
346 | /* 2nd field: uid:gid - device ownership */ | 344 | /* 2nd field: uid:gid - device ownership */ |
@@ -467,11 +465,10 @@ static char *build_alias(char *alias, const char *device_name) | |||
467 | */ | 465 | */ |
468 | static void make_device(char *device_name, char *path, int operation) | 466 | static void make_device(char *device_name, char *path, int operation) |
469 | { | 467 | { |
470 | char *subsystem_slash_devname; | ||
471 | int major, minor, type, len; | 468 | int major, minor, type, len; |
472 | 469 | ||
473 | if (G.verbose) | 470 | if (G.verbose) |
474 | bb_error_msg("make_device: %s, %s, op:%d", device_name, path, operation); | 471 | bb_error_msg("device: %s, %s", device_name, path); |
475 | 472 | ||
476 | /* Try to read major/minor string. Note that the kernel puts \n after | 473 | /* Try to read major/minor string. Note that the kernel puts \n after |
477 | * the data, so we don't need to worry about null terminating the string | 474 | * the data, so we don't need to worry about null terminating the string |
@@ -479,7 +476,7 @@ static void make_device(char *device_name, char *path, int operation) | |||
479 | * We also depend on path having writeable space after it. | 476 | * We also depend on path having writeable space after it. |
480 | */ | 477 | */ |
481 | major = -1; | 478 | major = -1; |
482 | if (operation != OP_remove) { | 479 | if (operation == OP_add) { |
483 | char *dev_maj_min = path + strlen(path); | 480 | char *dev_maj_min = path + strlen(path); |
484 | 481 | ||
485 | strcpy(dev_maj_min, "/dev"); | 482 | strcpy(dev_maj_min, "/dev"); |
@@ -490,7 +487,10 @@ static void make_device(char *device_name, char *path, int operation) | |||
490 | return; | 487 | return; |
491 | /* no "dev" file, but we can still run scripts | 488 | /* no "dev" file, but we can still run scripts |
492 | * based on device name */ | 489 | * based on device name */ |
493 | } else if (sscanf(++dev_maj_min, "%u:%u", &major, &minor) != 2) { | 490 | } else if (sscanf(++dev_maj_min, "%u:%u", &major, &minor) == 2) { |
491 | if (G.verbose) | ||
492 | bb_error_msg("maj,min: %u,%u", major, minor); | ||
493 | } else { | ||
494 | major = -1; | 494 | major = -1; |
495 | } | 495 | } |
496 | } | 496 | } |
@@ -502,29 +502,12 @@ static void make_device(char *device_name, char *path, int operation) | |||
502 | /* http://kernel.org/doc/pending/hotplug.txt says that only | 502 | /* http://kernel.org/doc/pending/hotplug.txt says that only |
503 | * "/sys/block/..." is for block devices. "/sys/bus" etc is not. | 503 | * "/sys/block/..." is for block devices. "/sys/bus" etc is not. |
504 | * But since 2.6.25 block devices are also in /sys/class/block. | 504 | * But since 2.6.25 block devices are also in /sys/class/block. |
505 | * We use strstr("/block/") to forestall future surprises. */ | 505 | * We use strstr("/block/") to forestall future surprises. |
506 | */ | ||
506 | type = S_IFCHR; | 507 | type = S_IFCHR; |
507 | if (strstr(path, "/block/") || (G.subsystem && strncmp(G.subsystem, "block", 5) == 0)) | 508 | if (strstr(path, "/block/") || (G.subsystem && strncmp(G.subsystem, "block", 5) == 0)) |
508 | type = S_IFBLK; | 509 | type = S_IFBLK; |
509 | 510 | ||
510 | /* Make path point to "subsystem/device_name" */ | ||
511 | subsystem_slash_devname = NULL; | ||
512 | /* Check for coldplug invocations first */ | ||
513 | if (strncmp(path, "/sys/block/", 11) == 0) /* legacy case */ | ||
514 | path += sizeof("/sys/") - 1; | ||
515 | else if (strncmp(path, "/sys/class/", 11) == 0) | ||
516 | path += sizeof("/sys/class/") - 1; | ||
517 | else { | ||
518 | /* Example of a hotplug invocation: | ||
519 | * SUBSYSTEM="block" | ||
520 | * DEVPATH="/sys" + "/devices/virtual/mtd/mtd3/mtdblock3" | ||
521 | * ("/sys" is added by mdev_main) | ||
522 | * - path does not contain subsystem | ||
523 | */ | ||
524 | subsystem_slash_devname = concat_path_file(G.subsystem, device_name); | ||
525 | path = subsystem_slash_devname; | ||
526 | } | ||
527 | |||
528 | #if ENABLE_FEATURE_MDEV_CONF | 511 | #if ENABLE_FEATURE_MDEV_CONF |
529 | G.rule_idx = 0; /* restart from the beginning (think mdev -s) */ | 512 | G.rule_idx = 0; /* restart from the beginning (think mdev -s) */ |
530 | #endif | 513 | #endif |
@@ -537,7 +520,7 @@ static void make_device(char *device_name, char *path, int operation) | |||
537 | char *node_name; | 520 | char *node_name; |
538 | const struct rule *rule; | 521 | const struct rule *rule; |
539 | 522 | ||
540 | str_to_match = ""; | 523 | str_to_match = device_name; |
541 | 524 | ||
542 | rule = next_rule(); | 525 | rule = next_rule(); |
543 | 526 | ||
@@ -555,12 +538,8 @@ static void make_device(char *device_name, char *path, int operation) | |||
555 | dbg("getenv('%s'):'%s'", rule->envvar, str_to_match); | 538 | dbg("getenv('%s'):'%s'", rule->envvar, str_to_match); |
556 | if (!str_to_match) | 539 | if (!str_to_match) |
557 | continue; | 540 | continue; |
558 | } else { | ||
559 | //TODO: $DEVNAME can have slashes too, | ||
560 | // we should stop abusing '/' as a special syntax in our regex'es | ||
561 | /* regex to match [subsystem/]device_name */ | ||
562 | str_to_match = (rule->regex_has_slash ? path : device_name); | ||
563 | } | 541 | } |
542 | /* else: str_to_match = device_name */ | ||
564 | 543 | ||
565 | if (rule->regex_compiled) { | 544 | if (rule->regex_compiled) { |
566 | int regex_match = regexec(&rule->match, str_to_match, ARRAY_SIZE(off), off, 0); | 545 | int regex_match = regexec(&rule->match, str_to_match, ARRAY_SIZE(off), off, 0); |
@@ -669,12 +648,12 @@ static void make_device(char *device_name, char *path, int operation) | |||
669 | bb_error_msg("mknod: %s (%d,%d) %o", node_name, major, minor, rule->mode | type); | 648 | bb_error_msg("mknod: %s (%d,%d) %o", node_name, major, minor, rule->mode | type); |
670 | if (mknod(node_name, rule->mode | type, makedev(major, minor)) && errno != EEXIST) | 649 | if (mknod(node_name, rule->mode | type, makedev(major, minor)) && errno != EEXIST) |
671 | bb_perror_msg("can't create '%s'", node_name); | 650 | bb_perror_msg("can't create '%s'", node_name); |
672 | if (major == G.root_major && minor == G.root_minor) | ||
673 | symlink(node_name, "root"); | ||
674 | if (ENABLE_FEATURE_MDEV_CONF) { | 651 | if (ENABLE_FEATURE_MDEV_CONF) { |
675 | chmod(node_name, rule->mode); | 652 | chmod(node_name, rule->mode); |
676 | chown(node_name, rule->ugid.uid, rule->ugid.gid); | 653 | chown(node_name, rule->ugid.uid, rule->ugid.gid); |
677 | } | 654 | } |
655 | if (major == G.root_major && minor == G.root_minor) | ||
656 | symlink(node_name, "root"); | ||
678 | if (ENABLE_FEATURE_MDEV_RENAME && alias) { | 657 | if (ENABLE_FEATURE_MDEV_RENAME && alias) { |
679 | if (aliaslink == '>') { | 658 | if (aliaslink == '>') { |
680 | //TODO: on devtmpfs, device_name already exists and symlink() fails. | 659 | //TODO: on devtmpfs, device_name already exists and symlink() fails. |
@@ -723,8 +702,6 @@ static void make_device(char *device_name, char *path, int operation) | |||
723 | if (!ENABLE_FEATURE_MDEV_CONF || !rule->keep_matching) | 702 | if (!ENABLE_FEATURE_MDEV_CONF || !rule->keep_matching) |
724 | break; | 703 | break; |
725 | } /* for (;;) */ | 704 | } /* for (;;) */ |
726 | |||
727 | free(subsystem_slash_devname); | ||
728 | } | 705 | } |
729 | 706 | ||
730 | /* File callback for /sys/ traversal */ | 707 | /* File callback for /sys/ traversal */ |
@@ -890,13 +867,13 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) | |||
890 | * DEVPATH is like "/block/sda" or "/class/input/mice" | 867 | * DEVPATH is like "/block/sda" or "/class/input/mice" |
891 | */ | 868 | */ |
892 | action = getenv("ACTION"); | 869 | action = getenv("ACTION"); |
870 | op = index_in_strings(keywords, action); | ||
893 | env_devname = getenv("DEVNAME"); /* can be NULL */ | 871 | env_devname = getenv("DEVNAME"); /* can be NULL */ |
894 | env_devpath = getenv("DEVPATH"); | 872 | env_devpath = getenv("DEVPATH"); |
895 | G.subsystem = getenv("SUBSYSTEM"); | 873 | G.subsystem = getenv("SUBSYSTEM"); |
896 | if (!action || !env_devpath /*|| !G.subsystem*/) | 874 | if (!action || !env_devpath /*|| !G.subsystem*/) |
897 | bb_show_usage(); | 875 | bb_show_usage(); |
898 | fw = getenv("FIRMWARE"); | 876 | fw = getenv("FIRMWARE"); |
899 | op = index_in_strings(keywords, action); | ||
900 | /* If it exists, does /dev/mdev.seq match $SEQNUM? | 877 | /* If it exists, does /dev/mdev.seq match $SEQNUM? |
901 | * If it does not match, earlier mdev is running | 878 | * If it does not match, earlier mdev is running |
902 | * in parallel, and we need to wait */ | 879 | * in parallel, and we need to wait */ |
@@ -927,7 +904,7 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) | |||
927 | if (logfd >= 0) { | 904 | if (logfd >= 0) { |
928 | xmove_fd(logfd, STDERR_FILENO); | 905 | xmove_fd(logfd, STDERR_FILENO); |
929 | G.verbose = 1; | 906 | G.verbose = 1; |
930 | bb_error_msg("pid: %u seq: %s action: %s", getpid(), seq, action); | 907 | bb_error_msg("seq: %s action: %s", seq, action); |
931 | } | 908 | } |
932 | } | 909 | } |
933 | 910 | ||