diff options
| author | Ron Yorston <rmy@pobox.com> | 2022-10-12 10:43:26 +0100 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2022-10-12 10:43:26 +0100 |
| commit | 49c6f079acb4edae84b4496bd941cdbb5048ba01 (patch) | |
| tree | ac54ecaad45050f7bfe274a11db29882aa32a9a8 /miscutils | |
| parent | a55cf07365ec2ff51749a77e09ae9edac79a99fe (diff) | |
| parent | c8c1fcdba163f264a503380bc63485aacd09214c (diff) | |
| download | busybox-w32-49c6f079acb4edae84b4496bd941cdbb5048ba01.tar.gz busybox-w32-49c6f079acb4edae84b4496bd941cdbb5048ba01.tar.bz2 busybox-w32-49c6f079acb4edae84b4496bd941cdbb5048ba01.zip | |
Merge branch 'busybox' into merge
Diffstat (limited to 'miscutils')
| -rw-r--r-- | miscutils/bc.c | 4 | ||||
| -rw-r--r-- | miscutils/devfsd.c | 6 | ||||
| -rw-r--r-- | miscutils/devmem.c | 68 | ||||
| -rw-r--r-- | miscutils/hdparm.c | 24 | ||||
| -rw-r--r-- | miscutils/tree.c | 131 |
5 files changed, 193 insertions, 40 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index fe555d018..01402b311 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
| @@ -2892,6 +2892,8 @@ static char peek_inbuf(void) | |||
| 2892 | ) { | 2892 | ) { |
| 2893 | xc_read_line(&G.input_buffer, G.prs.lex_input_fp); | 2893 | xc_read_line(&G.input_buffer, G.prs.lex_input_fp); |
| 2894 | G.prs.lex_inbuf = G.input_buffer.v; | 2894 | G.prs.lex_inbuf = G.input_buffer.v; |
| 2895 | // lex_next_at may point to now-freed data, update it: | ||
| 2896 | G.prs.lex_next_at = G.prs.lex_inbuf; | ||
| 2895 | if (G.input_buffer.len <= 1) // on EOF, len is 1 (NUL byte) | 2897 | if (G.input_buffer.len <= 1) // on EOF, len is 1 (NUL byte) |
| 2896 | G.prs.lex_input_fp = NULL; | 2898 | G.prs.lex_input_fp = NULL; |
| 2897 | } | 2899 | } |
| @@ -3103,7 +3105,7 @@ static BC_STATUS zbc_lex_identifier(void) | |||
| 3103 | continue; | 3105 | continue; |
| 3104 | match: | 3106 | match: |
| 3105 | // buf starts with keyword bc_lex_kws[i] | 3107 | // buf starts with keyword bc_lex_kws[i] |
| 3106 | if (isalnum(buf[j]) || buf[j]=='_') | 3108 | if (isalnum(buf[j]) || buf[j] == '_') |
| 3107 | continue; // "ifz" does not match "if" keyword, "if." does | 3109 | continue; // "ifz" does not match "if" keyword, "if." does |
| 3108 | p->lex = BC_LEX_KEY_1st_keyword + i; | 3110 | p->lex = BC_LEX_KEY_1st_keyword + i; |
| 3109 | if (!keyword_is_POSIX(i)) { | 3111 | if (!keyword_is_POSIX(i)) { |
diff --git a/miscutils/devfsd.c b/miscutils/devfsd.c index fb9ebcf60..297693f8c 100644 --- a/miscutils/devfsd.c +++ b/miscutils/devfsd.c | |||
| @@ -976,7 +976,7 @@ static void action_compat(const struct devfsd_notify_struct *info, unsigned int | |||
| 976 | rewind_ = info->devname[info->namelen - 1]; | 976 | rewind_ = info->devname[info->namelen - 1]; |
| 977 | if (rewind_ != 'n') | 977 | if (rewind_ != 'n') |
| 978 | rewind_ = '\0'; | 978 | rewind_ = '\0'; |
| 979 | mode=0; | 979 | mode = 0; |
| 980 | if (ptr[2] == 'l' /*108*/ || ptr[2] == 'm'/*109*/) | 980 | if (ptr[2] == 'l' /*108*/ || ptr[2] == 'm'/*109*/) |
| 981 | mode = ptr[2] - 107; /* 1 or 2 */ | 981 | mode = ptr[2] - 107; /* 1 or 2 */ |
| 982 | if (ptr[2] == 'a') | 982 | if (ptr[2] == 'a') |
| @@ -1595,11 +1595,11 @@ static char *write_old_sd_name(char *buffer, | |||
| 1595 | return buffer; | 1595 | return buffer; |
| 1596 | } | 1596 | } |
| 1597 | if ((major > 64) && (major < 72)) { | 1597 | if ((major > 64) && (major < 72)) { |
| 1598 | disc_index = ((major - 64) << 4) +(minor >> 4); | 1598 | disc_index = ((major - 64) << 4) + (minor >> 4); |
| 1599 | if (disc_index < 26) | 1599 | if (disc_index < 26) |
| 1600 | sprintf(buffer, "sd%c%s", 'a' + disc_index, part); | 1600 | sprintf(buffer, "sd%c%s", 'a' + disc_index, part); |
| 1601 | else | 1601 | else |
| 1602 | sprintf(buffer, "sd%c%c%s", 'a' +(disc_index / 26) - 1, 'a' + disc_index % 26, part); | 1602 | sprintf(buffer, "sd%c%c%s", 'a' + (disc_index / 26) - 1, 'a' + disc_index % 26, part); |
| 1603 | return buffer; | 1603 | return buffer; |
| 1604 | } | 1604 | } |
| 1605 | return NULL; | 1605 | return NULL; |
diff --git a/miscutils/devmem.c b/miscutils/devmem.c index f9f0276bc..f21621bd6 100644 --- a/miscutils/devmem.c +++ b/miscutils/devmem.c | |||
| @@ -29,7 +29,6 @@ int devmem_main(int argc UNUSED_PARAM, char **argv) | |||
| 29 | { | 29 | { |
| 30 | void *map_base, *virt_addr; | 30 | void *map_base, *virt_addr; |
| 31 | uint64_t read_result; | 31 | uint64_t read_result; |
| 32 | uint64_t writeval = writeval; /* for compiler */ | ||
| 33 | off_t target; | 32 | off_t target; |
| 34 | unsigned page_size, mapped_size, offset_in_page; | 33 | unsigned page_size, mapped_size, offset_in_page; |
| 35 | int fd; | 34 | int fd; |
| @@ -64,9 +63,6 @@ int devmem_main(int argc UNUSED_PARAM, char **argv) | |||
| 64 | width = strchrnul(bhwl, (argv[2][0] | 0x20)) - bhwl; | 63 | width = strchrnul(bhwl, (argv[2][0] | 0x20)) - bhwl; |
| 65 | width = sizes[width]; | 64 | width = sizes[width]; |
| 66 | } | 65 | } |
| 67 | /* VALUE */ | ||
| 68 | if (argv[3]) | ||
| 69 | writeval = bb_strtoull(argv[3], NULL, 0); | ||
| 70 | } else { /* argv[2] == NULL */ | 66 | } else { /* argv[2] == NULL */ |
| 71 | /* make argv[3] to be a valid thing to fetch */ | 67 | /* make argv[3] to be a valid thing to fetch */ |
| 72 | argv--; | 68 | argv--; |
| @@ -96,28 +92,46 @@ int devmem_main(int argc UNUSED_PARAM, char **argv) | |||
| 96 | virt_addr = (char*)map_base + offset_in_page; | 92 | virt_addr = (char*)map_base + offset_in_page; |
| 97 | 93 | ||
| 98 | if (!argv[3]) { | 94 | if (!argv[3]) { |
| 99 | switch (width) { | 95 | #ifdef __SIZEOF_INT128__ |
| 100 | case 8: | 96 | if (width == 128) { |
| 101 | read_result = *(volatile uint8_t*)virt_addr; | 97 | unsigned __int128 rd = |
| 102 | break; | 98 | *(volatile unsigned __int128 *)virt_addr; |
| 103 | case 16: | 99 | printf("0x%016llX%016llX\n", |
| 104 | read_result = *(volatile uint16_t*)virt_addr; | 100 | (unsigned long long)(uint64_t)(rd >> 64), |
| 105 | break; | 101 | (unsigned long long)(uint64_t)rd |
| 106 | case 32: | 102 | ); |
| 107 | read_result = *(volatile uint32_t*)virt_addr; | 103 | } else |
| 108 | break; | 104 | #endif |
| 109 | case 64: | 105 | { |
| 110 | read_result = *(volatile uint64_t*)virt_addr; | 106 | switch (width) { |
| 111 | break; | 107 | case 8: |
| 112 | default: | 108 | read_result = *(volatile uint8_t*)virt_addr; |
| 113 | bb_simple_error_msg_and_die("bad width"); | 109 | break; |
| 110 | case 16: | ||
| 111 | read_result = *(volatile uint16_t*)virt_addr; | ||
| 112 | break; | ||
| 113 | case 32: | ||
| 114 | read_result = *(volatile uint32_t*)virt_addr; | ||
| 115 | break; | ||
| 116 | case 64: | ||
| 117 | read_result = *(volatile uint64_t*)virt_addr; | ||
| 118 | break; | ||
| 119 | default: | ||
| 120 | bb_simple_error_msg_and_die("bad width"); | ||
| 121 | } | ||
| 122 | // printf("Value at address 0x%"OFF_FMT"X (%p): 0x%llX\n", | ||
| 123 | // target, virt_addr, | ||
| 124 | // (unsigned long long)read_result); | ||
| 125 | /* Zero-padded output shows the width of access just done */ | ||
| 126 | printf("0x%0*llX\n", (width >> 2), (unsigned long long)read_result); | ||
| 114 | } | 127 | } |
| 115 | // printf("Value at address 0x%"OFF_FMT"X (%p): 0x%llX\n", | ||
| 116 | // target, virt_addr, | ||
| 117 | // (unsigned long long)read_result); | ||
| 118 | /* Zero-padded output shows the width of access just done */ | ||
| 119 | printf("0x%0*llX\n", (width >> 2), (unsigned long long)read_result); | ||
| 120 | } else { | 128 | } else { |
| 129 | /* parse VALUE */ | ||
| 130 | #ifdef __SIZEOF_INT128__ | ||
| 131 | unsigned __int128 writeval = strtoumax(argv[3], NULL, 0); | ||
| 132 | #else | ||
| 133 | uint64_t writeval = bb_strtoull(argv[3], NULL, 0); | ||
| 134 | #endif | ||
| 121 | switch (width) { | 135 | switch (width) { |
| 122 | case 8: | 136 | case 8: |
| 123 | *(volatile uint8_t*)virt_addr = writeval; | 137 | *(volatile uint8_t*)virt_addr = writeval; |
| @@ -135,6 +149,12 @@ int devmem_main(int argc UNUSED_PARAM, char **argv) | |||
| 135 | *(volatile uint64_t*)virt_addr = writeval; | 149 | *(volatile uint64_t*)virt_addr = writeval; |
| 136 | // read_result = *(volatile uint64_t*)virt_addr; | 150 | // read_result = *(volatile uint64_t*)virt_addr; |
| 137 | break; | 151 | break; |
| 152 | #ifdef __SIZEOF_INT128__ | ||
| 153 | case 128: | ||
| 154 | *(volatile unsigned __int128 *)virt_addr = writeval; | ||
| 155 | // read_result = *(volatile uint64_t*)virt_addr; | ||
| 156 | break; | ||
| 157 | #endif | ||
| 138 | default: | 158 | default: |
| 139 | bb_simple_error_msg_and_die("bad width"); | 159 | bb_simple_error_msg_and_die("bad width"); |
| 140 | } | 160 | } |
diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index d8d8f6166..83e2f8d53 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c | |||
| @@ -798,7 +798,7 @@ static void identify(uint16_t *val) | |||
| 798 | if (!(val[GEN_CONFIG] & NOT_ATA)) { | 798 | if (!(val[GEN_CONFIG] & NOT_ATA)) { |
| 799 | dev = ATA_DEV; | 799 | dev = ATA_DEV; |
| 800 | printf("ATA device, with "); | 800 | printf("ATA device, with "); |
| 801 | } else if (val[GEN_CONFIG]==CFA_SUPPORT_VAL) { | 801 | } else if (val[GEN_CONFIG] == CFA_SUPPORT_VAL) { |
| 802 | dev = ATA_DEV; | 802 | dev = ATA_DEV; |
| 803 | like_std = 4; | 803 | like_std = 4; |
| 804 | printf("CompactFlash ATA device, with "); | 804 | printf("CompactFlash ATA device, with "); |
| @@ -819,13 +819,13 @@ static void identify(uint16_t *val) | |||
| 819 | * specific, it should be safe to check it now, even though we don't | 819 | * specific, it should be safe to check it now, even though we don't |
| 820 | * know yet what standard this device is using. | 820 | * know yet what standard this device is using. |
| 821 | */ | 821 | */ |
| 822 | if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL) | 822 | if ((val[CONFIG] == STBY_NID_VAL) || (val[CONFIG] == STBY_ID_VAL) |
| 823 | || (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL) | 823 | || (val[CONFIG] == PWRD_NID_VAL) || (val[CONFIG] == PWRD_ID_VAL) |
| 824 | ) { | 824 | ) { |
| 825 | like_std = 5; | 825 | like_std = 5; |
| 826 | if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)) | 826 | if ((val[CONFIG] == STBY_NID_VAL) || (val[CONFIG] == STBY_ID_VAL)) |
| 827 | puts("powers-up in standby; SET FEATURES subcmd spins-up."); | 827 | puts("powers-up in standby; SET FEATURES subcmd spins-up."); |
| 828 | if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE)) | 828 | if (((val[CONFIG] == STBY_NID_VAL) || (val[CONFIG] == PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE)) |
| 829 | puts("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n"); | 829 | puts("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n"); |
| 830 | } | 830 | } |
| 831 | 831 | ||
| @@ -853,7 +853,7 @@ static void identify(uint16_t *val) | |||
| 853 | printf("\n\tSupported: "); | 853 | printf("\n\tSupported: "); |
| 854 | jj = val[MAJOR] << 1; | 854 | jj = val[MAJOR] << 1; |
| 855 | kk = like_std >4 ? like_std-4: 0; | 855 | kk = like_std >4 ? like_std-4: 0; |
| 856 | for (ii = 14; (ii >0)&&(ii>kk); ii--) { | 856 | for (ii = 14; (ii > 0) && (ii > kk); ii--) { |
| 857 | if (jj & 0x8000) { | 857 | if (jj & 0x8000) { |
| 858 | printf("%u ", ii); | 858 | printf("%u ", ii); |
| 859 | if (like_std < ii) { | 859 | if (like_std < ii) { |
| @@ -943,7 +943,7 @@ static void identify(uint16_t *val) | |||
| 943 | for (ii = 1; ii < 15; ii++) { | 943 | for (ii = 1; ii < 15; ii++) { |
| 944 | if (jj & 0x0001) | 944 | if (jj & 0x0001) |
| 945 | printf("\t%s\n", nth_string(ata1_cfg_str, ii)); | 945 | printf("\t%s\n", nth_string(ata1_cfg_str, ii)); |
| 946 | jj >>=1; | 946 | jj >>= 1; |
| 947 | } | 947 | } |
| 948 | } | 948 | } |
| 949 | if (dev == ATAPI_DEV) { | 949 | if (dev == ATAPI_DEV) { |
| @@ -952,7 +952,7 @@ static void identify(uint16_t *val) | |||
| 952 | else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL) | 952 | else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL) |
| 953 | strng = "<=10ms with INTRQ"; | 953 | strng = "<=10ms with INTRQ"; |
| 954 | else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL) | 954 | else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL) |
| 955 | strng ="50us"; | 955 | strng = "50us"; |
| 956 | else | 956 | else |
| 957 | strng = "unknown"; | 957 | strng = "unknown"; |
| 958 | printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */ | 958 | printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */ |
| @@ -1014,7 +1014,7 @@ static void identify(uint16_t *val) | |||
| 1014 | } | 1014 | } |
| 1015 | 1015 | ||
| 1016 | if (!bbbig) | 1016 | if (!bbbig) |
| 1017 | bbbig = (uint64_t)(ll>mm ? ll : mm); /* # 512 byte blocks */ | 1017 | bbbig = (uint64_t)(ll > mm ? ll : mm); /* # 512 byte blocks */ |
| 1018 | printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11); | 1018 | printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11); |
| 1019 | bbbig = (bbbig << 9) / 1000000; | 1019 | bbbig = (bbbig << 9) / 1000000; |
| 1020 | printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig); | 1020 | printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig); |
| @@ -1160,7 +1160,7 @@ static void identify(uint16_t *val) | |||
| 1160 | jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007; | 1160 | jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007; |
| 1161 | for (ii = 0; ii <= PIO_MODE_MAX; ii++) { | 1161 | for (ii = 0; ii <= PIO_MODE_MAX; ii++) { |
| 1162 | if (jj & 0x0001) printf("pio%d ", ii); | 1162 | if (jj & 0x0001) printf("pio%d ", ii); |
| 1163 | jj >>=1; | 1163 | jj >>= 1; |
| 1164 | } | 1164 | } |
| 1165 | bb_putchar('\n'); | 1165 | bb_putchar('\n'); |
| 1166 | } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) { | 1166 | } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) { |
| @@ -1199,7 +1199,7 @@ static void identify(uint16_t *val) | |||
| 1199 | } | 1199 | } |
| 1200 | if (ii == 31) { | 1200 | if (ii == 31) { |
| 1201 | if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL) | 1201 | if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL) |
| 1202 | ii +=16; | 1202 | ii += 16; |
| 1203 | } | 1203 | } |
| 1204 | } | 1204 | } |
| 1205 | } | 1205 | } |
| @@ -1220,7 +1220,7 @@ static void identify(uint16_t *val) | |||
| 1220 | printf("\t%s\t%s\n", | 1220 | printf("\t%s\t%s\n", |
| 1221 | (!(jj & 0x0001)) ? "not" : "", | 1221 | (!(jj & 0x0001)) ? "not" : "", |
| 1222 | nth_string(secu_str, ii)); | 1222 | nth_string(secu_str, ii)); |
| 1223 | jj >>=1; | 1223 | jj >>= 1; |
| 1224 | } | 1224 | } |
| 1225 | if (val[SECU_STATUS] & SECU_ENABLED) { | 1225 | if (val[SECU_STATUS] & SECU_ENABLED) { |
| 1226 | printf("\tSecurity level %s\n", | 1226 | printf("\tSecurity level %s\n", |
diff --git a/miscutils/tree.c b/miscutils/tree.c new file mode 100644 index 000000000..fa55696c6 --- /dev/null +++ b/miscutils/tree.c | |||
| @@ -0,0 +1,131 @@ | |||
| 1 | /* vi: set sw=4 ts=4: */ | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2022 Roger Knecht <rknecht@pm.me> | ||
| 4 | * | ||
| 5 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
| 6 | */ | ||
| 7 | //config:config TREE | ||
| 8 | //config: bool "tree (0.6 kb)" | ||
| 9 | //config: default y | ||
| 10 | //config: help | ||
| 11 | //config: List files and directories in a tree structure. | ||
| 12 | |||
| 13 | //applet:IF_TREE(APPLET(tree, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
| 14 | |||
| 15 | //kbuild:lib-$(CONFIG_TREE) += tree.o | ||
| 16 | |||
| 17 | //usage:#define tree_trivial_usage NOUSAGE_STR | ||
| 18 | //usage:#define tree_full_usage "" | ||
| 19 | |||
| 20 | #include "libbb.h" | ||
| 21 | #include "common_bufsiz.h" | ||
| 22 | #include "unicode.h" | ||
| 23 | |||
| 24 | #define prefix_buf bb_common_bufsiz1 | ||
| 25 | |||
| 26 | static void tree_print(unsigned count[2], const char* directory_name, char* prefix_pos) | ||
| 27 | { | ||
| 28 | struct dirent **entries; | ||
| 29 | int index, size; | ||
| 30 | const char *bar = "| "; | ||
| 31 | const char *mid = "|-- "; | ||
| 32 | const char *end = "`-- "; | ||
| 33 | |||
| 34 | #if ENABLE_UNICODE_SUPPORT | ||
| 35 | if (unicode_status == UNICODE_ON) { | ||
| 36 | bar = "│ "; | ||
| 37 | mid = "├── "; | ||
| 38 | end = "└── "; | ||
| 39 | } | ||
| 40 | #endif | ||
| 41 | |||
| 42 | // read directory entries | ||
| 43 | size = scandir(directory_name, &entries, NULL, alphasort); | ||
| 44 | |||
| 45 | if (size < 0) { | ||
| 46 | fputs_stdout(directory_name); | ||
| 47 | puts(" [error opening dir]"); | ||
| 48 | return; | ||
| 49 | } | ||
| 50 | |||
| 51 | // print directory name | ||
| 52 | puts(directory_name); | ||
| 53 | |||
| 54 | // switch to sub directory | ||
| 55 | xchdir(directory_name); | ||
| 56 | |||
| 57 | // print all directory entries | ||
| 58 | for (index = 0; index < size;) { | ||
| 59 | struct dirent *dirent = entries[index++]; | ||
| 60 | |||
| 61 | // filter hidden files and directories | ||
| 62 | if (dirent->d_name[0] != '.') { | ||
| 63 | int status; | ||
| 64 | struct stat statBuf; | ||
| 65 | |||
| 66 | //TODO: when -l is implemented, use stat, not lstat, if -l | ||
| 67 | status = lstat(dirent->d_name, &statBuf); | ||
| 68 | |||
| 69 | if (index == size) { | ||
| 70 | strcpy(prefix_pos, end); | ||
| 71 | } else { | ||
| 72 | strcpy(prefix_pos, mid); | ||
| 73 | } | ||
| 74 | fputs_stdout(prefix_buf); | ||
| 75 | |||
| 76 | if (status == 0 && S_ISLNK(statBuf.st_mode)) { | ||
| 77 | // handle symlink | ||
| 78 | char* symlink_path = xmalloc_readlink(dirent->d_name); | ||
| 79 | printf("%s -> %s\n", dirent->d_name, symlink_path); | ||
| 80 | free(symlink_path); | ||
| 81 | count[1]++; | ||
| 82 | } else if (status == 0 && S_ISDIR(statBuf.st_mode) | ||
| 83 | && (prefix_pos - prefix_buf) < (COMMON_BUFSIZE - 16) | ||
| 84 | ) { | ||
| 85 | // handle directory | ||
| 86 | char* pos; | ||
| 87 | if (index == size) { | ||
| 88 | pos = stpcpy(prefix_pos, " "); | ||
| 89 | } else { | ||
| 90 | pos = stpcpy(prefix_pos, bar); | ||
| 91 | } | ||
| 92 | tree_print(count, dirent->d_name, pos); | ||
| 93 | count[0]++; | ||
| 94 | } else { | ||
| 95 | // handle file | ||
| 96 | puts(dirent->d_name); | ||
| 97 | count[1]++; | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | // release directory entry | ||
| 102 | free(dirent); | ||
| 103 | } | ||
| 104 | |||
| 105 | // release directory array | ||
| 106 | free(entries); | ||
| 107 | |||
| 108 | // switch to parent directory | ||
| 109 | xchdir(".."); | ||
| 110 | } | ||
| 111 | |||
| 112 | int tree_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
| 113 | int tree_main(int argc UNUSED_PARAM, char **argv) | ||
| 114 | { | ||
| 115 | unsigned count[2] = { 0, 0 }; | ||
| 116 | |||
| 117 | setup_common_bufsiz(); | ||
| 118 | init_unicode(); | ||
| 119 | |||
| 120 | if (!argv[1]) | ||
| 121 | *argv-- = (char*)"."; | ||
| 122 | |||
| 123 | // list directories given as command line arguments | ||
| 124 | while (*(++argv)) | ||
| 125 | tree_print(count, *argv, prefix_buf); | ||
| 126 | |||
| 127 | // print statistic | ||
| 128 | printf("\n%u directories, %u files\n", count[0], count[1]); | ||
| 129 | |||
| 130 | return EXIT_SUCCESS; | ||
| 131 | } | ||
