diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-03 14:09:04 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-03-03 14:09:04 +0000 |
| commit | 248ce91017cdc5ea8bdc496ebbbc8f3e97ab298d (patch) | |
| tree | 35ceaf16b4b76d97d5b1f7412113ab086648687e /coreutils | |
| parent | 11a6f9b44f4a425b03e3a7a984e7b3e253e5f884 (diff) | |
| download | busybox-w32-248ce91017cdc5ea8bdc496ebbbc8f3e97ab298d.tar.gz busybox-w32-248ce91017cdc5ea8bdc496ebbbc8f3e97ab298d.tar.bz2 busybox-w32-248ce91017cdc5ea8bdc496ebbbc8f3e97ab298d.zip | |
ls: implement -Q and -g (-g was accepted but ignored)
function old new delta
print_name - 198 +198
showfiles 1489 1508 +19
ls_options 30 31 +1
opt_flags 112 108 -4
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/1 up/down: 218/-4) Total: 214 bytes
Diffstat (limited to 'coreutils')
| -rw-r--r-- | coreutils/ls.c | 238 |
1 files changed, 138 insertions, 100 deletions
diff --git a/coreutils/ls.c b/coreutils/ls.c index 8aa05507d..edb6300ba 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
| @@ -118,6 +118,103 @@ SPLIT_SUBDIR = 2, | |||
| 118 | #define ATTR(mode) ("\00\00\01\00\01\00\01\00"\ | 118 | #define ATTR(mode) ("\00\00\01\00\01\00\01\00"\ |
| 119 | "\00\00\01\00\01\00\00\01" [TYPEINDEX(mode)]) | 119 | "\00\00\01\00\01\00\00\01" [TYPEINDEX(mode)]) |
| 120 | 120 | ||
| 121 | /* "[-]Cadil1", POSIX mandated options, busybox always supports */ | ||
| 122 | /* "[-]gnsx", POSIX non-mandated options, busybox always supports */ | ||
| 123 | /* "[-]Q" GNU option? busybox always supports */ | ||
| 124 | /* "[-]Ak" GNU options, busybox always supports */ | ||
| 125 | /* "[-]FLRctur", POSIX mandated options, busybox optionally supports */ | ||
| 126 | /* "[-]p", POSIX non-mandated options, busybox optionally supports */ | ||
| 127 | /* "[-]SXvThw", GNU options, busybox optionally supports */ | ||
| 128 | /* "[-]K", SELinux mandated options, busybox optionally supports */ | ||
| 129 | /* "[-]e", I think we made this one up */ | ||
| 130 | static const char ls_options[] ALIGN1 = | ||
| 131 | "Cadil1gnsxQAk" /* 13 opts, total 13 */ | ||
| 132 | USE_FEATURE_LS_TIMESTAMPS("cetu") /* 4, 17 */ | ||
| 133 | USE_FEATURE_LS_SORTFILES("SXrv") /* 4, 21 */ | ||
| 134 | USE_FEATURE_LS_FILETYPES("Fp") /* 2, 23 */ | ||
| 135 | USE_FEATURE_LS_FOLLOWLINKS("L") /* 1, 24 */ | ||
| 136 | USE_FEATURE_LS_RECURSIVE("R") /* 1, 25 */ | ||
| 137 | USE_FEATURE_HUMAN_READABLE("h") /* 1, 26 */ | ||
| 138 | USE_SELINUX("K") /* 1, 27 */ | ||
| 139 | USE_SELINUX("Z") /* 1, 28 */ | ||
| 140 | USE_FEATURE_AUTOWIDTH("T:w:") /* 2, 30 */ | ||
| 141 | ; | ||
| 142 | enum { | ||
| 143 | //OPT_C = (1 << 0), | ||
| 144 | //OPT_a = (1 << 1), | ||
| 145 | //OPT_d = (1 << 2), | ||
| 146 | //OPT_i = (1 << 3), | ||
| 147 | //OPT_l = (1 << 4), | ||
| 148 | //OPT_1 = (1 << 5), | ||
| 149 | OPT_g = (1 << 6), | ||
| 150 | //OPT_n = (1 << 7), | ||
| 151 | //OPT_s = (1 << 8), | ||
| 152 | //OPT_x = (1 << 9), | ||
| 153 | OPT_Q = (1 << 10), | ||
| 154 | //OPT_A = (1 << 11), | ||
| 155 | //OPT_k = (1 << 12), | ||
| 156 | }; | ||
| 157 | |||
| 158 | enum { | ||
| 159 | LIST_MASK_TRIGGER = 0, | ||
| 160 | STYLE_MASK_TRIGGER = STYLE_MASK, | ||
| 161 | DISP_MASK_TRIGGER = DISP_ROWS, | ||
| 162 | SORT_MASK_TRIGGER = SORT_MASK, | ||
| 163 | }; | ||
| 164 | |||
| 165 | /* TODO: simple toggles may be stored as OPT_xxx bits instead */ | ||
| 166 | static const unsigned opt_flags[] = { | ||
| 167 | LIST_SHORT | STYLE_COLUMNS, /* C */ | ||
| 168 | DISP_HIDDEN | DISP_DOT, /* a */ | ||
| 169 | DISP_NOLIST, /* d */ | ||
| 170 | LIST_INO, /* i */ | ||
| 171 | LIST_LONG | STYLE_LONG, /* l - remember LS_DISP_HR in mask! */ | ||
| 172 | LIST_SHORT | STYLE_SINGLE, /* 1 */ | ||
| 173 | 0, /* g (don't show group) - handled via OPT_g */ | ||
| 174 | LIST_ID_NUMERIC, /* n */ | ||
| 175 | LIST_BLOCKS, /* s */ | ||
| 176 | DISP_ROWS, /* x */ | ||
| 177 | 0, /* Q (quote filename) - handled via OPT_Q */ | ||
| 178 | DISP_HIDDEN, /* A */ | ||
| 179 | ENABLE_SELINUX * LIST_CONTEXT, /* k (ignored if !SELINUX) */ | ||
| 180 | #if ENABLE_FEATURE_LS_TIMESTAMPS | ||
| 181 | TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */ | ||
| 182 | LIST_FULLTIME, /* e */ | ||
| 183 | ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */ | ||
| 184 | TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */ | ||
| 185 | #endif | ||
| 186 | #if ENABLE_FEATURE_LS_SORTFILES | ||
| 187 | SORT_SIZE, /* S */ | ||
| 188 | SORT_EXT, /* X */ | ||
| 189 | SORT_REVERSE, /* r */ | ||
| 190 | SORT_VERSION, /* v */ | ||
| 191 | #endif | ||
| 192 | #if ENABLE_FEATURE_LS_FILETYPES | ||
| 193 | LIST_FILETYPE | LIST_EXEC, /* F */ | ||
| 194 | LIST_FILETYPE, /* p */ | ||
| 195 | #endif | ||
| 196 | #if ENABLE_FEATURE_LS_FOLLOWLINKS | ||
| 197 | FOLLOW_LINKS, /* L */ | ||
| 198 | #endif | ||
| 199 | #if ENABLE_FEATURE_LS_RECURSIVE | ||
| 200 | DISP_RECURSIVE, /* R */ | ||
| 201 | #endif | ||
| 202 | #if ENABLE_FEATURE_HUMAN_READABLE | ||
| 203 | LS_DISP_HR, /* h */ | ||
| 204 | #endif | ||
| 205 | #if ENABLE_SELINUX | ||
| 206 | LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME, /* K */ | ||
| 207 | #endif | ||
| 208 | #if ENABLE_SELINUX | ||
| 209 | LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT, /* Z */ | ||
| 210 | #endif | ||
| 211 | (1U<<31) | ||
| 212 | /* options after Z are not processed through opt_flags: | ||
| 213 | * T, w - ignored | ||
| 214 | */ | ||
| 215 | }; | ||
| 216 | |||
| 217 | |||
| 121 | /* | 218 | /* |
| 122 | * a directory entry and its stat info are stored here | 219 | * a directory entry and its stat info are stored here |
| 123 | */ | 220 | */ |
| @@ -573,6 +670,37 @@ static struct dnode **list_dir(const char *path) | |||
| 573 | } | 670 | } |
| 574 | 671 | ||
| 575 | 672 | ||
| 673 | static int print_name(const char *name) | ||
| 674 | { | ||
| 675 | if (option_mask32 & OPT_Q) { | ||
| 676 | #if ENABLE_FEATURE_ASSUME_UNICODE | ||
| 677 | int len = 2 + mbstrlen(name); | ||
| 678 | #else | ||
| 679 | int len = 2; | ||
| 680 | #endif | ||
| 681 | putchar('"'); | ||
| 682 | while (*name) { | ||
| 683 | if (*name == '"') { | ||
| 684 | putchar('\\'); | ||
| 685 | len++; | ||
| 686 | } | ||
| 687 | putchar(*name++); | ||
| 688 | if (!ENABLE_FEATURE_ASSUME_UNICODE) | ||
| 689 | len++; | ||
| 690 | } | ||
| 691 | putchar('"'); | ||
| 692 | return len; | ||
| 693 | } | ||
| 694 | /* No -Q: */ | ||
| 695 | #if ENABLE_FEATURE_ASSUME_UNICODE | ||
| 696 | fputs(name, stdout); | ||
| 697 | return mbstrlen(name); | ||
| 698 | #else | ||
| 699 | return printf("%s", name); | ||
| 700 | #endif | ||
| 701 | } | ||
| 702 | |||
| 703 | |||
| 576 | static int list_single(const struct dnode *dn) | 704 | static int list_single(const struct dnode *dn) |
| 577 | { | 705 | { |
| 578 | int i, column = 0; | 706 | int i, column = 0; |
| @@ -617,6 +745,12 @@ static int list_single(const struct dnode *dn) | |||
| 617 | break; | 745 | break; |
| 618 | case LIST_ID_NAME: | 746 | case LIST_ID_NAME: |
| 619 | #if ENABLE_FEATURE_LS_USERNAME | 747 | #if ENABLE_FEATURE_LS_USERNAME |
| 748 | if (option_mask32 & OPT_g) { | ||
| 749 | printf("%-8.8s", | ||
| 750 | get_cached_username(dn->dstat.st_uid)); | ||
| 751 | column += 9; | ||
| 752 | break; | ||
| 753 | } | ||
| 620 | printf("%-8.8s %-8.8s", | 754 | printf("%-8.8s %-8.8s", |
| 621 | get_cached_username(dn->dstat.st_uid), | 755 | get_cached_username(dn->dstat.st_uid), |
| 622 | get_cached_groupname(dn->dstat.st_gid)); | 756 | get_cached_groupname(dn->dstat.st_gid)); |
| @@ -662,21 +796,8 @@ static int list_single(const struct dnode *dn) | |||
| 662 | #endif | 796 | #endif |
| 663 | #if ENABLE_SELINUX | 797 | #if ENABLE_SELINUX |
| 664 | case LIST_CONTEXT: | 798 | case LIST_CONTEXT: |
| 665 | { | 799 | column += printf("%-32s ", dn->sid ? dn->sid : "unknown"); |
| 666 | char context[80]; | 800 | freecon(dn->sid); |
| 667 | int len = 0; | ||
| 668 | |||
| 669 | if (dn->sid) { | ||
| 670 | /* I assume sid initilized with NULL */ | ||
| 671 | len = strlen(dn->sid) + 1; | ||
| 672 | safe_strncpy(context, dn->sid, len); | ||
| 673 | freecon(dn->sid); | ||
| 674 | } else { | ||
| 675 | safe_strncpy(context, "unknown", 8); | ||
| 676 | } | ||
| 677 | printf("%-32s ", context); | ||
| 678 | column += MAX(33, len); | ||
| 679 | } | ||
| 680 | break; | 801 | break; |
| 681 | #endif | 802 | #endif |
| 682 | case LIST_FILENAME: | 803 | case LIST_FILENAME: |
| @@ -687,12 +808,7 @@ static int list_single(const struct dnode *dn) | |||
| 687 | fgcolor(info.st_mode)); | 808 | fgcolor(info.st_mode)); |
| 688 | } | 809 | } |
| 689 | #endif | 810 | #endif |
| 690 | #if ENABLE_FEATURE_ASSUME_UNICODE | 811 | column += print_name(dn->name); |
| 691 | printf("%s", dn->name); | ||
| 692 | column += mbstrlen(dn->name); | ||
| 693 | #else | ||
| 694 | column += printf("%s", dn->name); | ||
| 695 | #endif | ||
| 696 | if (show_color) { | 812 | if (show_color) { |
| 697 | printf("\033[0m"); | 813 | printf("\033[0m"); |
| 698 | } | 814 | } |
| @@ -714,7 +830,7 @@ static int list_single(const struct dnode *dn) | |||
| 714 | fgcolor(info.st_mode)); | 830 | fgcolor(info.st_mode)); |
| 715 | } | 831 | } |
| 716 | #endif | 832 | #endif |
| 717 | column += printf("%s", lpath) + 4; | 833 | column += print_name(lpath) + 4; |
| 718 | if (show_color) { | 834 | if (show_color) { |
| 719 | printf("\033[0m"); | 835 | printf("\033[0m"); |
| 720 | } | 836 | } |
| @@ -736,84 +852,6 @@ static int list_single(const struct dnode *dn) | |||
| 736 | } | 852 | } |
| 737 | 853 | ||
| 738 | 854 | ||
| 739 | /* "[-]Cadil1", POSIX mandated options, busybox always supports */ | ||
| 740 | /* "[-]gnsx", POSIX non-mandated options, busybox always supports */ | ||
| 741 | /* "[-]Ak" GNU options, busybox always supports */ | ||
| 742 | /* "[-]FLRctur", POSIX mandated options, busybox optionally supports */ | ||
| 743 | /* "[-]p", POSIX non-mandated options, busybox optionally supports */ | ||
| 744 | /* "[-]SXvThw", GNU options, busybox optionally supports */ | ||
| 745 | /* "[-]K", SELinux mandated options, busybox optionally supports */ | ||
| 746 | /* "[-]e", I think we made this one up */ | ||
| 747 | static const char ls_options[] ALIGN1 = | ||
| 748 | "Cadil1gnsxAk" | ||
| 749 | USE_FEATURE_LS_TIMESTAMPS("cetu") | ||
| 750 | USE_FEATURE_LS_SORTFILES("SXrv") | ||
| 751 | USE_FEATURE_LS_FILETYPES("Fp") | ||
| 752 | USE_FEATURE_LS_FOLLOWLINKS("L") | ||
| 753 | USE_FEATURE_LS_RECURSIVE("R") | ||
| 754 | USE_FEATURE_HUMAN_READABLE("h") | ||
| 755 | USE_SELINUX("K") | ||
| 756 | USE_FEATURE_AUTOWIDTH("T:w:") | ||
| 757 | USE_SELINUX("Z"); | ||
| 758 | |||
| 759 | enum { | ||
| 760 | LIST_MASK_TRIGGER = 0, | ||
| 761 | STYLE_MASK_TRIGGER = STYLE_MASK, | ||
| 762 | DISP_MASK_TRIGGER = DISP_ROWS, | ||
| 763 | SORT_MASK_TRIGGER = SORT_MASK, | ||
| 764 | }; | ||
| 765 | |||
| 766 | static const unsigned opt_flags[] = { | ||
| 767 | LIST_SHORT | STYLE_COLUMNS, /* C */ | ||
| 768 | DISP_HIDDEN | DISP_DOT, /* a */ | ||
| 769 | DISP_NOLIST, /* d */ | ||
| 770 | LIST_INO, /* i */ | ||
| 771 | LIST_LONG | STYLE_LONG, /* l - remember LS_DISP_HR in mask! */ | ||
| 772 | LIST_SHORT | STYLE_SINGLE, /* 1 */ | ||
| 773 | 0, /* g - ingored */ | ||
| 774 | LIST_ID_NUMERIC, /* n */ | ||
| 775 | LIST_BLOCKS, /* s */ | ||
| 776 | DISP_ROWS, /* x */ | ||
| 777 | DISP_HIDDEN, /* A */ | ||
| 778 | ENABLE_SELINUX * LIST_CONTEXT, /* k (ignored if !SELINUX) */ | ||
| 779 | #if ENABLE_FEATURE_LS_TIMESTAMPS | ||
| 780 | TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */ | ||
| 781 | LIST_FULLTIME, /* e */ | ||
| 782 | ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */ | ||
| 783 | TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */ | ||
| 784 | #endif | ||
| 785 | #if ENABLE_FEATURE_LS_SORTFILES | ||
| 786 | SORT_SIZE, /* S */ | ||
| 787 | SORT_EXT, /* X */ | ||
| 788 | SORT_REVERSE, /* r */ | ||
| 789 | SORT_VERSION, /* v */ | ||
| 790 | #endif | ||
| 791 | #if ENABLE_FEATURE_LS_FILETYPES | ||
| 792 | LIST_FILETYPE | LIST_EXEC, /* F */ | ||
| 793 | LIST_FILETYPE, /* p */ | ||
| 794 | #endif | ||
| 795 | #if ENABLE_FEATURE_LS_FOLLOWLINKS | ||
| 796 | FOLLOW_LINKS, /* L */ | ||
| 797 | #endif | ||
| 798 | #if ENABLE_FEATURE_LS_RECURSIVE | ||
| 799 | DISP_RECURSIVE, /* R */ | ||
| 800 | #endif | ||
| 801 | #if ENABLE_FEATURE_HUMAN_READABLE | ||
| 802 | LS_DISP_HR, /* h */ | ||
| 803 | #endif | ||
| 804 | #if ENABLE_SELINUX | ||
| 805 | LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME, /* K */ | ||
| 806 | #endif | ||
| 807 | #if ENABLE_FEATURE_AUTOWIDTH | ||
| 808 | 0, 0, /* T, w - ignored */ | ||
| 809 | #endif | ||
| 810 | #if ENABLE_SELINUX | ||
| 811 | LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT, /* Z */ | ||
| 812 | #endif | ||
| 813 | (1U<<31) | ||
| 814 | }; | ||
| 815 | |||
| 816 | |||
| 817 | /* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */ | 855 | /* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */ |
| 818 | #if ENABLE_FEATURE_LS_COLOR | 856 | #if ENABLE_FEATURE_LS_COLOR |
| 819 | /* long option entry used only for --color, which has no short option | 857 | /* long option entry used only for --color, which has no short option |
