aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-02-14 07:15:30 +0000
committerEric Andersen <andersen@codepoet.org>2001-02-14 07:15:30 +0000
commitfc83c4c3535cb5bce344821d382122262a8450f5 (patch)
treec61695c497186a7e201315b93541846c3a72f201
parent6fd8c664c1bcb44429b81444be640ff08cac3702 (diff)
downloadbusybox-w32-fc83c4c3535cb5bce344821d382122262a8450f5.tar.gz
busybox-w32-fc83c4c3535cb5bce344821d382122262a8450f5.tar.bz2
busybox-w32-fc83c4c3535cb5bce344821d382122262a8450f5.zip
Several cleanups from Manuel Novoa III.
get_kernel_revision -- size reduction NOTE: may want to combine with get_kernel_version in insmod??? parse_mode -- size reduction, multiple settings with "," now work correctly, sticky-bit setting now implemented process_escape_sequence -- size reduction, octal code to big for char bug fixed format -- size reduction, val > LONG_MAX and hr = 1 printing bug fixed (was %ld),
-rw-r--r--busybox.h2
-rw-r--r--include/busybox.h2
-rw-r--r--utility.c285
3 files changed, 155 insertions, 134 deletions
diff --git a/busybox.h b/busybox.h
index 2fc0cc7e0..101e65989 100644
--- a/busybox.h
+++ b/busybox.h
@@ -232,7 +232,7 @@ extern int sysinfo (struct sysinfo* info);
232#endif 232#endif
233 233
234#ifdef BB_FEATURE_HUMAN_READABLE 234#ifdef BB_FEATURE_HUMAN_READABLE
235char *format(unsigned long val, unsigned long hr); 235const char *format(unsigned long val, unsigned long hr);
236#define KILOBYTE 1024 236#define KILOBYTE 1024
237#define MEGABYTE (KILOBYTE*1024) 237#define MEGABYTE (KILOBYTE*1024)
238#define GIGABYTE (MEGABYTE*1024) 238#define GIGABYTE (MEGABYTE*1024)
diff --git a/include/busybox.h b/include/busybox.h
index 2fc0cc7e0..101e65989 100644
--- a/include/busybox.h
+++ b/include/busybox.h
@@ -232,7 +232,7 @@ extern int sysinfo (struct sysinfo* info);
232#endif 232#endif
233 233
234#ifdef BB_FEATURE_HUMAN_READABLE 234#ifdef BB_FEATURE_HUMAN_READABLE
235char *format(unsigned long val, unsigned long hr); 235const char *format(unsigned long val, unsigned long hr);
236#define KILOBYTE 1024 236#define KILOBYTE 1024
237#define MEGABYTE (KILOBYTE*1024) 237#define MEGABYTE (KILOBYTE*1024)
238#define GIGABYTE (MEGABYTE*1024) 238#define GIGABYTE (MEGABYTE*1024)
diff --git a/utility.c b/utility.c
index 9f0bca971..f3c184e73 100644
--- a/utility.c
+++ b/utility.c
@@ -51,6 +51,7 @@
51#include <unistd.h> 51#include <unistd.h>
52#include <ctype.h> 52#include <ctype.h>
53#include <stdlib.h> 53#include <stdlib.h>
54#include <limits.h>
54#include <sys/ioctl.h> 55#include <sys/ioctl.h>
55#include <sys/utsname.h> /* for uname(2) */ 56#include <sys/utsname.h> /* for uname(2) */
56 57
@@ -77,7 +78,7 @@ const char mtab_file[] = "/proc/mounts";
77 78
78extern void usage(const char *usage) 79extern void usage(const char *usage)
79{ 80{
80 fprintf(stderr, "%s\n\nUsage: %s\n", full_version, usage); 81 fprintf(stderr, "%s\n\nUsage: %s\n\n", full_version, usage);
81 exit(EXIT_FAILURE); 82 exit(EXIT_FAILURE);
82} 83}
83 84
@@ -145,16 +146,21 @@ extern void perror_msg_and_die(const char *s, ...)
145extern int get_kernel_revision(void) 146extern int get_kernel_revision(void)
146{ 147{
147 struct utsname name; 148 struct utsname name;
148 int major = 0, minor = 0, patch = 0; 149 char *s;
150 int i, r;
149 151
150 if (uname(&name) == -1) { 152 if (uname(&name) == -1) {
151 perror_msg("cannot get system information"); 153 perror_msg("cannot get system information");
152 return (0); 154 return (0);
153 } 155 }
154 major = atoi(strtok(name.release, ".")); 156
155 minor = atoi(strtok(NULL, ".")); 157 s = name.release;
156 patch = atoi(strtok(NULL, ".")); 158 r = 0;
157 return major * 65536 + minor * 256 + patch; 159 for (i=0 ; i<3 ; i++) {
160 r = r * 256 + atoi(strtok(s, "."));
161 s = NULL;
162 }
163 return r;
158} 164}
159#endif /* BB_INIT */ 165#endif /* BB_INIT */
160 166
@@ -749,102 +755,100 @@ extern int create_path(const char *name, int mode)
749 || defined (BB_MKFIFO) || defined (BB_MKNOD) || defined (BB_AR) 755 || defined (BB_MKFIFO) || defined (BB_MKNOD) || defined (BB_AR)
750/* [ugoa]{+|-|=}[rwxst] */ 756/* [ugoa]{+|-|=}[rwxst] */
751 757
752
753
754extern int parse_mode(const char *s, mode_t * theMode) 758extern int parse_mode(const char *s, mode_t * theMode)
755{ 759{
756 mode_t andMode = 760 static const mode_t group_set[] = {
761 S_ISUID | S_IRWXU, /* u */
762 S_ISGID | S_IRWXG, /* g */
763 S_IRWXO, /* o */
764 S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO /* a */
765 };
766
767 static const mode_t mode_set[] = {
768 S_IRUSR | S_IRGRP | S_IROTH, /* r */
769 S_IWUSR | S_IWGRP | S_IWOTH, /* w */
770 S_IXUSR | S_IXGRP | S_IXOTH, /* x */
771 S_ISUID | S_ISGID, /* s */
772 S_ISVTX /* t */
773 };
774
775 static const char group_string[] = "ugoa";
776 static const char mode_string[] = "rwxst";
777
778 const char *p;
757 779
780 mode_t andMode =
758 S_ISVTX | S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO; 781 S_ISVTX | S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;
759 mode_t orMode = 0; 782 mode_t orMode = 0;
760 mode_t mode = 0; 783 mode_t mode;
761 mode_t groups = 0; 784 mode_t groups;
762 char type; 785 char type;
763 char c; 786 char c;
764 787
765 if (s==NULL) 788 if (s==NULL) {
766 return (FALSE); 789 return (FALSE);
790 }
767 791
768 do { 792 do {
769 for (;;) { 793 mode = 0;
770 switch (c = *s++) { 794 groups = 0;
771 case '\0': 795 NEXT_GROUP:
772 return -1; 796 if ((c = *s++) == '\0') {
773 case 'u': 797 return -1;
774 groups |= S_ISUID | S_IRWXU; 798 }
775 continue; 799 for (p=group_string ; *p ; p++) {
776 case 'g': 800 if (*p == c) {
777 groups |= S_ISGID | S_IRWXG; 801 groups |= group_set[(int)(p-group_string)];
778 continue; 802 goto NEXT_GROUP;
779 case 'o': 803 }
780 groups |= S_IRWXO; 804 }
781 continue; 805 switch (c) {
782 case 'a':
783 groups |= S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;
784 continue;
785 case '+':
786 case '=': 806 case '=':
807 case '+':
787 case '-': 808 case '-':
788 type = c; 809 type = c;
789 if (groups == 0) /* The default is "all" */ 810 if (groups == 0) { /* The default is "all" */
790 groups |= 811 groups |= S_ISUID | S_ISGID | S_ISVTX
791 S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO; 812 | S_IRWXU | S_IRWXG | S_IRWXO;
813 }
792 break; 814 break;
793 default: 815 default:
794 if (isdigit(c) && c >= '0' && c <= '7' && 816 if ((c < '0') || (c > '7') || (mode | groups)) {
795 mode == 0 && groups == 0) { 817 return (FALSE);
818 } else {
796 *theMode = strtol(--s, NULL, 8); 819 *theMode = strtol(--s, NULL, 8);
797 return (TRUE); 820 return (TRUE);
798 } else 821 }
799 return (FALSE);
800 }
801 break;
802 } 822 }
803 823
804 while ((c = *s++) != '\0') { 824 NEXT_MODE:
805 switch (c) { 825 if (((c = *s++) != '\0') && (c != ',')) {
806 case ',': 826 for (p=mode_string ; *p ; p++) {
807 break; 827 if (*p == c) {
808 case 'r': 828 mode |= mode_set[(int)(p-mode_string)];
809 mode |= S_IRUSR | S_IRGRP | S_IROTH; 829 goto NEXT_MODE;
810 continue; 830 }
811 case 'w':
812 mode |= S_IWUSR | S_IWGRP | S_IWOTH;
813 continue;
814 case 'x':
815 mode |= S_IXUSR | S_IXGRP | S_IXOTH;
816 continue;
817 case 's':
818 mode |= S_IXGRP | S_ISUID | S_ISGID;
819 continue;
820 case 't':
821 mode |= 0;
822 continue;
823 default:
824 *theMode &= andMode;
825 *theMode |= orMode;
826 return (TRUE);
827 } 831 }
828 break; 832 break; /* We're done so break out of loop.*/
829 } 833 }
830 switch (type) { 834 switch (type) {
831 case '=': 835 case '=':
832 andMode &= ~(groups); 836 andMode &= ~(groups); /* Now fall through. */
833 /* fall through */ 837 case '+':
834 case '+': 838 orMode |= mode & groups;
835 orMode |= mode & groups; 839 break;
836 break; 840 case '-':
837 case '-': 841 andMode &= ~(mode & groups);
838 andMode &= ~(mode & groups); 842 orMode &= ~(mode & groups);
839 orMode &= andMode; 843 break;
840 break;
841 } 844 }
842 } while (c == ','); 845 } while (c == ',');
846
843 *theMode &= andMode; 847 *theMode &= andMode;
844 *theMode |= orMode; 848 *theMode |= orMode;
845 return (TRUE);
846}
847 849
850 return TRUE;
851}
848 852
849#endif 853#endif
850/* BB_CHMOD_CHOWN_CHGRP || BB_MKDIR || BB_MKFIFO || BB_MKNOD */ 854/* BB_CHMOD_CHOWN_CHGRP || BB_MKDIR || BB_MKFIFO || BB_MKNOD */
@@ -1575,48 +1579,43 @@ extern int print_file_by_name(char *filename)
1575#if defined BB_ECHO || defined BB_SH || defined BB_TR 1579#if defined BB_ECHO || defined BB_SH || defined BB_TR
1576char process_escape_sequence(char **ptr) 1580char process_escape_sequence(char **ptr)
1577{ 1581{
1578 char c; 1582 static const char charmap[] = {
1579 1583 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', 0,
1580 switch (c = *(*ptr)++) { 1584 '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '\\' };
1581 case 'a': 1585
1582 c = '\a'; 1586 const char *p;
1583 break; 1587 char *q;
1584 case 'b': 1588 int num_digits;
1585 c = '\b'; 1589 unsigned int n;
1586 break; 1590
1587 case 'f': 1591 n = 0;
1588 c = '\f'; 1592 q = *ptr;
1589 break; 1593
1590 case 'n': 1594 for ( num_digits = 0 ; num_digits < 3 ; ++num_digits) {
1591 c = '\n'; 1595 if ((*q < '0') || (*q > '7')) { /* not a digit? */
1592 break; 1596 break;
1593 case 'r': 1597 }
1594 c = '\r'; 1598 n = n * 8 + (*q++ - '0');
1595 break; 1599 }
1596 case 't': 1600
1597 c = '\t'; 1601 if (num_digits == 0) { /* mnemonic escape sequence? */
1598 break; 1602 for (p=charmap ; *p ; p++) {
1599 case 'v': 1603 if (*p == *q) {
1600 c = '\v'; 1604 q++;
1601 break; 1605 break;
1602 case '\\': 1606 }
1603 c = '\\'; 1607 }
1604 break; 1608 n = *(p+(sizeof(charmap)/2));
1605 case '0': case '1': case '2': case '3': 1609 }
1606 case '4': case '5': case '6': case '7': 1610
1607 c -= '0'; 1611 /* doesn't hurt to fall through to here from mnemonic case */
1608 if ('0' <= **ptr && **ptr <= '7') { 1612 if (n > UCHAR_MAX) { /* is octal code too big for a char? */
1609 c = c * 8 + (*(*ptr)++ - '0'); 1613 n /= 8; /* adjust value and */
1610 if ('0' <= **ptr && **ptr <= '7') 1614 --q; /* back up one char */
1611 c = c * 8 + (*(*ptr)++ - '0'); 1615 }
1612 } 1616
1613 break; 1617 *ptr = q;
1614 default: 1618 return (char) n;
1615 (*ptr)--;
1616 c = '\\';
1617 break;
1618 }
1619 return c;
1620} 1619}
1621#endif 1620#endif
1622 1621
@@ -1737,23 +1736,45 @@ ssize_t safe_read(int fd, void *buf, size_t count)
1737#endif 1736#endif
1738 1737
1739#ifdef BB_FEATURE_HUMAN_READABLE 1738#ifdef BB_FEATURE_HUMAN_READABLE
1740char *format(unsigned long val, unsigned long hr) 1739const char *format(unsigned long val, unsigned long hr)
1741{ 1740{
1742 static char str[10] = "\0"; 1741 static const char strings[] = { '0', 0, 'k', 0, 'M', 0, 'G', 0 };
1743 1742 static const char fmt[] = "%lu";
1744 if(val == 0) 1743 static const char fmt_u[] = "%lu.%lu%s";
1745 return("0"); 1744
1746 if(hr) 1745 static char str[10];
1747 snprintf(str, 9, "%ld", val/hr); 1746
1748 else if(val >= GIGABYTE) 1747 unsigned long frac __attribute__ ((unused)); /* 'may be uninitialized' warning is ok */
1749 snprintf(str, 9, "%.1LfG", ((long double)(val)/GIGABYTE)); 1748 const char *u;
1750 else if(val >= MEGABYTE) 1749 const char *f;
1751 snprintf(str, 9, "%.1LfM", ((long double)(val)/MEGABYTE)); 1750
1752 else if(val >= KILOBYTE) 1751#if 1
1753 snprintf(str, 9, "%.1Lfk", ((long double)(val)/KILOBYTE)); 1752 if(val == 0) { /* This may be omitted to reduce size */
1754 else 1753 return strings; /* at the cost of speed. */
1755 snprintf(str, 9, "%ld", (val)); 1754 }
1756 return(str); 1755#endif
1756
1757 u = strings;
1758 f = fmt;
1759 if (hr) {
1760 val /= hr;
1761 } else {
1762 while ((val >= KILOBYTE) && (*u != 'G')) {
1763 f = fmt_u;
1764 u += 2;
1765 frac = (((val % KILOBYTE) * 10) + (KILOBYTE/2)) / KILOBYTE;
1766 val /= KILOBYTE;
1767 if (frac >= 10) { /* We need to round up here. */
1768 ++val;
1769 frac = 0;
1770 }
1771 }
1772 }
1773
1774 /* If f==fmt then 'frac' and 'u' are ignored and need not be set. */
1775 snprintf(str, sizeof(str), f, val, frac, u);
1776
1777 return str;
1757} 1778}
1758#endif 1779#endif
1759 1780