aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>1999-11-09 01:47:36 +0000
committerEric Andersen <andersen@codepoet.org>1999-11-09 01:47:36 +0000
commit50d6360771be509737bb55b2cc5bc5e25f2a4fea (patch)
tree81d4cfe9ec9b5281924f678c28f61542616a3db7
parentfbb39c83b69d6c4de943c0b7374000339635d13d (diff)
downloadbusybox-w32-50d6360771be509737bb55b2cc5bc5e25f2a4fea.tar.gz
busybox-w32-50d6360771be509737bb55b2cc5bc5e25f2a4fea.tar.bz2
busybox-w32-50d6360771be509737bb55b2cc5bc5e25f2a4fea.zip
Stuff
-rw-r--r--Changelog11
-rw-r--r--Makefile2
-rw-r--r--archival/tar.c15
-rw-r--r--busybox.def.h2
-rw-r--r--coreutils/ls.c61
-rw-r--r--coreutils/rm.c2
-rw-r--r--editors/sed.c68
-rw-r--r--findutils/grep.c79
-rw-r--r--grep.c79
-rw-r--r--ls.c61
-rw-r--r--more.c73
-rw-r--r--procps/ps.c2
-rw-r--r--ps.c2
-rw-r--r--regexp.c1
-rw-r--r--rm.c2
-rw-r--r--sed.c68
-rw-r--r--tar.c15
-rw-r--r--util-linux/more.c73
-rw-r--r--utility.c8
19 files changed, 325 insertions, 299 deletions
diff --git a/Changelog b/Changelog
index 1dd93c3c7..750768b61 100644
--- a/Changelog
+++ b/Changelog
@@ -5,6 +5,17 @@
5 better job of finding the real consol device rather than using 5 better job of finding the real consol device rather than using
6 /dev/console which doesn't support job control. Patch also 6 /dev/console which doesn't support job control. Patch also
7 thanks to Eric Delaunay. 7 thanks to Eric Delaunay.
8 * more started to read from stdin after the last file was finished, and
9 options were not parsed correctly (fix thanks to Eric Delaunay).
10 * rm wouldn't remove a symlink unless the symlink was valid. This was
11 a side effect of the busybox 0.32 recursiveAction() fix. Things
12 should now work correctly.
13 * grep wouldn't grep stdin. Now it does.
14 * sed wouldn't sed stdin. Now it does.
15 * sed was appending a \n to the end of lines with replacements.
16 Now it doesn't do that.
17 * ls -l now bypasses libc6 nss when displaying user/group names.
18 Now uses my_getpwuid and my_getgrgid.
8 19
90.33 200.33
10 * Fixed a bug where init could hang instead of rebooting. 21 * Fixed a bug where init could hang instead of rebooting.
diff --git a/Makefile b/Makefile
index 13d349dc3..14c2f413f 100644
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,7 @@ BUILDTIME=$(shell date "+%Y%m%d-%H%M")
22 22
23# Comment out the following to make a debuggable build 23# Comment out the following to make a debuggable build
24# Leave this off for production use. 24# Leave this off for production use.
25DODEBUG=false 25DODEBUG=true
26# If you want a static binary, turn this on. I can't think 26# If you want a static binary, turn this on. I can't think
27# of many situations where anybody would ever want it static, 27# of many situations where anybody would ever want it static,
28# but... 28# but...
diff --git a/archival/tar.c b/archival/tar.c
index cd255f85c..9ad41bea8 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -35,6 +35,16 @@
35#include <signal.h> 35#include <signal.h>
36#include <time.h> 36#include <time.h>
37 37
38/* Note that tar.c expects TRUE and FALSE to be defined
39 * exactly the opposite of how they are used everywhere else.
40 * Some time this should be integrated a bit better, but this
41 * does the job for now.
42 */
43#undef FALSE
44#undef TRUE
45#define FALSE ((int) 0)
46#define TRUE ((int) 1)
47
38 48
39static const char tar_usage[] = 49static const char tar_usage[] =
40 "tar -[cxtvOf] [tarFileName] [FILE] ...\n" 50 "tar -[cxtvOf] [tarFileName] [FILE] ...\n"
@@ -169,10 +179,9 @@ extern int tar_main (int argc, char **argv)
169 /* 179 /*
170 * Parse the options. 180 * Parse the options.
171 */ 181 */
172 options = *argv++;
173 argc--;
174
175 if (**argv == '-') { 182 if (**argv == '-') {
183 options = (*argv++) + 1;
184 argc--;
176 for (; *options; options++) { 185 for (; *options; options++) {
177 switch (*options) { 186 switch (*options) {
178 case 'f': 187 case 'f':
diff --git a/busybox.def.h b/busybox.def.h
index 59c1df188..26fd8f822 100644
--- a/busybox.def.h
+++ b/busybox.def.h
@@ -54,7 +54,7 @@
54#define BB_SYNC 54#define BB_SYNC
55#define BB_TAR 55#define BB_TAR
56#define BB_TOUCH 56#define BB_TOUCH
57//#define BB_TRUE_FALSE // Supplied by ash 57//#define BB_TRUE_FALSE
58#define BB_UMOUNT 58#define BB_UMOUNT
59#define BB_UPDATE 59#define BB_UPDATE
60#define BB_UNAME 60#define BB_UNAME
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 4eb486f87..f09cbbc22 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -40,7 +40,7 @@
40 * 1. requires lstat (BSD) - how do you do it without? 40 * 1. requires lstat (BSD) - how do you do it without?
41 */ 41 */
42 42
43//#define FEATURE_USERNAME /* show username/groupnames (libc6 uses NSS) */ 43#define FEATURE_USERNAME /* show username/groupnames (bypasses libc6 NSS) */
44#define FEATURE_TIMESTAMPS /* show file timestamps */ 44#define FEATURE_TIMESTAMPS /* show file timestamps */
45#define FEATURE_AUTOWIDTH /* calculate terminal & column widths */ 45#define FEATURE_AUTOWIDTH /* calculate terminal & column widths */
46#define FEATURE_FILETYPECHAR /* enable -p and -F */ 46#define FEATURE_FILETYPECHAR /* enable -p and -F */
@@ -64,10 +64,6 @@
64#include <dirent.h> 64#include <dirent.h>
65#include <errno.h> 65#include <errno.h>
66#include <stdio.h> 66#include <stdio.h>
67#ifdef FEATURE_USERNAME
68#include <pwd.h>
69#include <grp.h>
70#endif
71#ifdef FEATURE_TIMESTAMPS 67#ifdef FEATURE_TIMESTAMPS
72#include <time.h> 68#include <time.h>
73#endif 69#endif
@@ -83,27 +79,6 @@
83#define MINOR(dev) ((dev)&0xff) 79#define MINOR(dev) ((dev)&0xff)
84#endif 80#endif
85 81
86#define MODE1 "rwxrwxrwx"
87#define MODE0 "---------"
88#define SMODE1 "..s..s..t"
89#define SMODE0 "..S..S..T"
90
91/* The 9 mode bits to test */
92
93static const mode_t MBIT[] = {
94 S_IRUSR, S_IWUSR, S_IXUSR,
95 S_IRGRP, S_IWGRP, S_IXGRP,
96 S_IROTH, S_IWOTH, S_IXOTH
97};
98
99/* The special bits. If set, display SMODE0/1 instead of MODE0/1 */
100
101static const mode_t SBIT[] = {
102 0, 0, S_ISUID,
103 0, 0, S_ISGID,
104 0, 0, S_ISVTX
105};
106
107#define FMT_AUTO 0 82#define FMT_AUTO 0
108#define FMT_LONG 1 /* one record per line, extended info */ 83#define FMT_LONG 1 /* one record per line, extended info */
109#define FMT_SINGLE 2 /* one record per line */ 84#define FMT_SINGLE 2 /* one record per line */
@@ -216,45 +191,35 @@ static void list_single(const char *name, struct stat *info, const char *fullnam
216 191
217 if (display_fmt == FMT_LONG) { 192 if (display_fmt == FMT_LONG) {
218 mode_t mode = info->st_mode; 193 mode_t mode = info->st_mode;
219 int i;
220
221 scratch[0] = TYPECHAR(mode);
222 for (i=0; i<9; i++)
223 if (mode & SBIT[i])
224 scratch[i+1] = (mode & MBIT[i])
225 ? SMODE1[i]
226 : SMODE0[i];
227 else
228 scratch[i+1] = (mode & MBIT[i])
229 ? MODE1[i]
230 : MODE0[i];
231 newline(); 194 newline();
232 wr(scratch, 10); 195 wr(modeString(mode), 10);
233 column=10; 196 column=10;
234 writenum((long)info->st_nlink,(short)4); 197 writenum((long)info->st_nlink,(short)5);
235 fputs(" ", stdout); 198 fputs(" ", stdout);
236#ifdef FEATURE_USERNAME 199#ifdef FEATURE_USERNAME
237 if (!(opts & DISP_NUMERIC)) { 200 if (!(opts & DISP_NUMERIC)) {
238 struct passwd *pw = getpwuid(info->st_uid); 201 scratch[8]='\0';
239 if (pw) 202 my_getpwuid( scratch, info->st_uid);
240 fputs(pw->pw_name, stdout); 203 if (*scratch)
204 fputs(scratch, stdout);
241 else 205 else
242 writenum((long)info->st_uid,(short)0); 206 writenum((long)info->st_uid,(short)0);
243 } else 207 } else
244#endif 208#endif
245 writenum((long)info->st_uid,(short)0); 209 writenum((long)info->st_uid,(short)0);
246 tab(24); 210 tab(16);
247#ifdef FEATURE_USERNAME 211#ifdef FEATURE_USERNAME
248 if (!(opts & DISP_NUMERIC)) { 212 if (!(opts & DISP_NUMERIC)) {
249 struct group *gr = getgrgid(info->st_gid); 213 scratch[8]='\0';
250 if (gr) 214 my_getgrgid( scratch, info->st_gid);
251 fputs(gr->gr_name, stdout); 215 if (*scratch)
216 fputs(scratch, stdout);
252 else 217 else
253 writenum((long)info->st_gid,(short)0); 218 writenum((long)info->st_gid,(short)0);
254 } else 219 } else
255#endif 220#endif
256 writenum((long)info->st_gid,(short)0); 221 writenum((long)info->st_gid,(short)0);
257 tab(33); 222 tab(17);
258 if (S_ISBLK(mode) || S_ISCHR(mode)) { 223 if (S_ISBLK(mode) || S_ISCHR(mode)) {
259 writenum((long)MAJOR(info->st_rdev),(short)3); 224 writenum((long)MAJOR(info->st_rdev),(short)3);
260 fputs(", ", stdout); 225 fputs(", ", stdout);
diff --git a/coreutils/rm.c b/coreutils/rm.c
index f49ada5e1..077e792f9 100644
--- a/coreutils/rm.c
+++ b/coreutils/rm.c
@@ -84,7 +84,7 @@ extern int rm_main(int argc, char **argv)
84 84
85 while (argc-- > 0) { 85 while (argc-- > 0) {
86 srcName = *(argv++); 86 srcName = *(argv++);
87 if (recursiveAction( srcName, recursiveFlag, TRUE, TRUE, 87 if (recursiveAction( srcName, recursiveFlag, FALSE, TRUE,
88 fileAction, dirAction) == FALSE) { 88 fileAction, dirAction) == FALSE) {
89 exit( FALSE); 89 exit( FALSE);
90 } 90 }
diff --git a/editors/sed.c b/editors/sed.c
index f0a6a3b48..34756e09a 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -45,9 +45,23 @@ static const char sed_usage[] =
45#else 45#else
46"This version of sed matches strings (not full regexps).\n"; 46"This version of sed matches strings (not full regexps).\n";
47#endif 47#endif
48
48 49
50static void do_sed(FILE *fp, char *needle, char *newNeedle, int ignoreCase, int printFlag, int quietFlag)
51{
52 int foundOne=FALSE;
53 char haystack[1024];
49 54
50 55 while (fgets (haystack, 1023, fp)) {
56 foundOne = replace_match(haystack, needle, newNeedle, ignoreCase);
57 if (foundOne==TRUE && printFlag==TRUE) {
58 fprintf(stdout, haystack);
59 }
60 if (quietFlag==FALSE) {
61 fprintf(stdout, haystack);
62 }
63 }
64}
51 65
52extern int sed_main (int argc, char **argv) 66extern int sed_main (int argc, char **argv)
53{ 67{
@@ -56,11 +70,9 @@ extern int sed_main (int argc, char **argv)
56 char *name; 70 char *name;
57 char *cp; 71 char *cp;
58 int ignoreCase=FALSE; 72 int ignoreCase=FALSE;
59 int foundOne=FALSE;
60 int printFlag=FALSE; 73 int printFlag=FALSE;
61 int quietFlag=FALSE; 74 int quietFlag=FALSE;
62 int stopNow; 75 int stopNow;
63 char *haystack;
64 76
65 argc--; 77 argc--;
66 argv++; 78 argv++;
@@ -73,24 +85,23 @@ extern int sed_main (int argc, char **argv)
73 cp = *argv++; 85 cp = *argv++;
74 stopNow=FALSE; 86 stopNow=FALSE;
75 87
76 while (*++cp && stopNow==FALSE) 88 while (*++cp && stopNow==FALSE) {
77 switch (*cp) { 89 switch (*cp) {
78 case 'n': 90 case 'n':
79 quietFlag = TRUE; 91 quietFlag = TRUE;
80 break; 92 break;
81 case 'e': 93 case 'e':
82 if (*(cp+1)==0 && --argc < 0) { 94 if (*(cp+1)==0 && --argc < 0) {
83 fprintf(stderr, "A\n");
84 usage( sed_usage); 95 usage( sed_usage);
85 } 96 }
86 cp = *argv++; 97 if ( *++cp != 's')
98 cp = *argv++;
87 while( *cp ) { 99 while( *cp ) {
88 if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') { 100 if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') {
89 char* pos=needle=cp+2; 101 char* pos=needle=cp+2;
90 for(;;) { 102 for(;;) {
91 pos = strchr(pos, '/'); 103 pos = strchr(pos, '/');
92 if (pos==NULL) { 104 if (pos==NULL) {
93 fprintf(stderr, "B\n");
94 usage( sed_usage); 105 usage( sed_usage);
95 } 106 }
96 if (*(pos-1) == '\\') { 107 if (*(pos-1) == '\\') {
@@ -104,7 +115,6 @@ extern int sed_main (int argc, char **argv)
104 for(;;) { 115 for(;;) {
105 pos = strchr(pos, '/'); 116 pos = strchr(pos, '/');
106 if (pos==NULL) { 117 if (pos==NULL) {
107 fprintf(stderr, "C\n");
108 usage( sed_usage); 118 usage( sed_usage);
109 } 119 }
110 if (*(pos-1) == '\\') { 120 if (*(pos-1) == '\\') {
@@ -116,7 +126,6 @@ extern int sed_main (int argc, char **argv)
116 *pos=0; 126 *pos=0;
117 if (pos+2 != 0) { 127 if (pos+2 != 0) {
118 while (*++pos) { 128 while (*++pos) {
119 fprintf(stderr, "pos='%s'\n", pos);
120 switch (*pos) { 129 switch (*pos) {
121 case 'i': 130 case 'i':
122 ignoreCase=TRUE; 131 ignoreCase=TRUE;
@@ -134,42 +143,35 @@ extern int sed_main (int argc, char **argv)
134 } 143 }
135 cp++; 144 cp++;
136 } 145 }
137 fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); 146 //fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle);
138 stopNow=TRUE; 147 stopNow=TRUE;
139 break; 148 break;
140 149
141 default: 150 default:
142 fprintf(stderr, "D\n");
143 usage(sed_usage); 151 usage(sed_usage);
144 } 152 }
153 }
145 } 154 }
146 155
147 while (argc-- > 0) { 156 if (argc==0) {
148 name = *argv++; 157 do_sed( stdin, needle, newNeedle, ignoreCase, printFlag, quietFlag);
158 } else {
159 while (argc-- > 0) {
160 name = *argv++;
149 161
150 fp = fopen (name, "r"); 162 fp = fopen (name, "r");
151 if (fp == NULL) { 163 if (fp == NULL) {
152 perror (name); 164 perror (name);
153 continue; 165 continue;
154 } 166 }
155 167
156 haystack = (char*)malloc( 1024); 168 do_sed( fp, needle, newNeedle, ignoreCase, printFlag, quietFlag);
157 while (fgets (haystack, 1023, fp)) {
158
159 foundOne = replace_match(haystack, needle, newNeedle, ignoreCase);
160 if (foundOne==TRUE && printFlag==TRUE)
161 fputs (haystack, stdout);
162 if (quietFlag==FALSE)
163 fputs (haystack, stdout);
164 /* Avoid any mem leaks */
165 free(haystack);
166 haystack = (char*)malloc( BUF_SIZE);
167 }
168 169
169 if (ferror (fp)) 170 if (ferror (fp))
170 perror (name); 171 perror (name);
171 172
172 fclose (fp); 173 fclose (fp);
174 }
173 } 175 }
174 exit( TRUE); 176 exit( TRUE);
175} 177}
diff --git a/findutils/grep.c b/findutils/grep.c
index 50a296178..8dcff0586 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -40,45 +40,46 @@ static const char grep_usage[] =
40#if defined BB_REGEXP 40#if defined BB_REGEXP
41"This version of grep matches full regexps.\n"; 41"This version of grep matches full regexps.\n";
42#else 42#else
43"This version of grep matches strings (not full regexps).\n"; 43"This version of grep matches strings (not regexps).\n";
44#endif 44#endif
45 45
46int tellName=TRUE;
47int ignoreCase=FALSE;
48int tellLine=FALSE;
49 46
50static do_grep(char* needle, char* haystack ) 47static void do_grep(FILE *fp, char* needle, char *fileName, int tellName, int ignoreCase, int tellLine)
51{ 48{
52 line = 0; 49 char *cp;
50 long line = 0;
51 char haystack[BUF_SIZE];
53 52
54 while (fgets (haystack, sizeof (haystack), fp)) { 53 while (fgets (haystack, sizeof (haystack), fp)) {
55 line++; 54 line++;
56 cp = &haystack[strlen (haystack) - 1]; 55 cp = &haystack[strlen (haystack) - 1];
57 56
58 if (*cp != '\n') 57 if (*cp != '\n')
59 fprintf (stderr, "%s: Line too long\n", name); 58 fprintf (stderr, "%s: Line too long\n", fileName);
60 59
61 if (find_match(haystack, needle, ignoreCase) == TRUE) { 60 if (find_match(haystack, needle, ignoreCase) == TRUE) {
62 if (tellName==TRUE) 61 if (tellName==TRUE)
63 printf ("%s: ", name); 62 printf ("%s:", fileName);
64 63
65 if (tellLine==TRUE) 64 if (tellLine==TRUE)
66 printf ("%ld: ", line); 65 printf ("%ld:", line);
67 66
68 fputs (haystack, stdout); 67 fputs (haystack, stdout);
69 }
70 } 68 }
69 }
71} 70}
72 71
73 72
74extern int grep_main (int argc, char **argv) 73extern int grep_main (int argc, char **argv)
75{ 74{
76 FILE *fp; 75 FILE *fp;
77 char *needle;
78 char *name;
79 char *cp; 76 char *cp;
80 long line; 77 char *needle;
81 char haystack[BUF_SIZE]; 78 char *fileName;
79 int tellName=FALSE;
80 int ignoreCase=FALSE;
81 int tellLine=FALSE;
82
82 83
83 ignoreCase = FALSE; 84 ignoreCase = FALSE;
84 tellLine = FALSE; 85 tellLine = FALSE;
@@ -100,7 +101,7 @@ extern int grep_main (int argc, char **argv)
100 break; 101 break;
101 102
102 case 'h': 103 case 'h':
103 tellName = FALSE; 104 tellName = TRUE;
104 break; 105 break;
105 106
106 case 'n': 107 case 'n':
@@ -115,28 +116,24 @@ extern int grep_main (int argc, char **argv)
115 needle = *argv++; 116 needle = *argv++;
116 argc--; 117 argc--;
117 118
119 if (argc==0) {
120 do_grep( stdin, needle, "stdin", FALSE, ignoreCase, tellLine);
121 } else {
122 while (argc-- > 0) {
123 fileName = *argv++;
118 124
119 while (argc-- > 0) { 125 fp = fopen (fileName, "r");
120 126 if (fp == NULL) {
121 if (argc==0) { 127 perror (fileName);
122 file = stdin; 128 continue;
123 } 129 }
124 else
125 file = fopen(*argv, "r");
126
127 130
128 name = *argv++; 131 do_grep( fp, needle, fileName, tellName, ignoreCase, tellLine);
129 132
130 fp = fopen (name, "r"); 133 if (ferror (fp))
131 if (fp == NULL) { 134 perror (fileName);
132 perror (name); 135 fclose (fp);
133 continue;
134 } 136 }
135
136 if (ferror (fp))
137 perror (name);
138
139 fclose (fp);
140 } 137 }
141 exit( TRUE); 138 exit( TRUE);
142} 139}
diff --git a/grep.c b/grep.c
index 50a296178..8dcff0586 100644
--- a/grep.c
+++ b/grep.c
@@ -40,45 +40,46 @@ static const char grep_usage[] =
40#if defined BB_REGEXP 40#if defined BB_REGEXP
41"This version of grep matches full regexps.\n"; 41"This version of grep matches full regexps.\n";
42#else 42#else
43"This version of grep matches strings (not full regexps).\n"; 43"This version of grep matches strings (not regexps).\n";
44#endif 44#endif
45 45
46int tellName=TRUE;
47int ignoreCase=FALSE;
48int tellLine=FALSE;
49 46
50static do_grep(char* needle, char* haystack ) 47static void do_grep(FILE *fp, char* needle, char *fileName, int tellName, int ignoreCase, int tellLine)
51{ 48{
52 line = 0; 49 char *cp;
50 long line = 0;
51 char haystack[BUF_SIZE];
53 52
54 while (fgets (haystack, sizeof (haystack), fp)) { 53 while (fgets (haystack, sizeof (haystack), fp)) {
55 line++; 54 line++;
56 cp = &haystack[strlen (haystack) - 1]; 55 cp = &haystack[strlen (haystack) - 1];
57 56
58 if (*cp != '\n') 57 if (*cp != '\n')
59 fprintf (stderr, "%s: Line too long\n", name); 58 fprintf (stderr, "%s: Line too long\n", fileName);
60 59
61 if (find_match(haystack, needle, ignoreCase) == TRUE) { 60 if (find_match(haystack, needle, ignoreCase) == TRUE) {
62 if (tellName==TRUE) 61 if (tellName==TRUE)
63 printf ("%s: ", name); 62 printf ("%s:", fileName);
64 63
65 if (tellLine==TRUE) 64 if (tellLine==TRUE)
66 printf ("%ld: ", line); 65 printf ("%ld:", line);
67 66
68 fputs (haystack, stdout); 67 fputs (haystack, stdout);
69 }
70 } 68 }
69 }
71} 70}
72 71
73 72
74extern int grep_main (int argc, char **argv) 73extern int grep_main (int argc, char **argv)
75{ 74{
76 FILE *fp; 75 FILE *fp;
77 char *needle;
78 char *name;
79 char *cp; 76 char *cp;
80 long line; 77 char *needle;
81 char haystack[BUF_SIZE]; 78 char *fileName;
79 int tellName=FALSE;
80 int ignoreCase=FALSE;
81 int tellLine=FALSE;
82
82 83
83 ignoreCase = FALSE; 84 ignoreCase = FALSE;
84 tellLine = FALSE; 85 tellLine = FALSE;
@@ -100,7 +101,7 @@ extern int grep_main (int argc, char **argv)
100 break; 101 break;
101 102
102 case 'h': 103 case 'h':
103 tellName = FALSE; 104 tellName = TRUE;
104 break; 105 break;
105 106
106 case 'n': 107 case 'n':
@@ -115,28 +116,24 @@ extern int grep_main (int argc, char **argv)
115 needle = *argv++; 116 needle = *argv++;
116 argc--; 117 argc--;
117 118
119 if (argc==0) {
120 do_grep( stdin, needle, "stdin", FALSE, ignoreCase, tellLine);
121 } else {
122 while (argc-- > 0) {
123 fileName = *argv++;
118 124
119 while (argc-- > 0) { 125 fp = fopen (fileName, "r");
120 126 if (fp == NULL) {
121 if (argc==0) { 127 perror (fileName);
122 file = stdin; 128 continue;
123 } 129 }
124 else
125 file = fopen(*argv, "r");
126
127 130
128 name = *argv++; 131 do_grep( fp, needle, fileName, tellName, ignoreCase, tellLine);
129 132
130 fp = fopen (name, "r"); 133 if (ferror (fp))
131 if (fp == NULL) { 134 perror (fileName);
132 perror (name); 135 fclose (fp);
133 continue;
134 } 136 }
135
136 if (ferror (fp))
137 perror (name);
138
139 fclose (fp);
140 } 137 }
141 exit( TRUE); 138 exit( TRUE);
142} 139}
diff --git a/ls.c b/ls.c
index 4eb486f87..f09cbbc22 100644
--- a/ls.c
+++ b/ls.c
@@ -40,7 +40,7 @@
40 * 1. requires lstat (BSD) - how do you do it without? 40 * 1. requires lstat (BSD) - how do you do it without?
41 */ 41 */
42 42
43//#define FEATURE_USERNAME /* show username/groupnames (libc6 uses NSS) */ 43#define FEATURE_USERNAME /* show username/groupnames (bypasses libc6 NSS) */
44#define FEATURE_TIMESTAMPS /* show file timestamps */ 44#define FEATURE_TIMESTAMPS /* show file timestamps */
45#define FEATURE_AUTOWIDTH /* calculate terminal & column widths */ 45#define FEATURE_AUTOWIDTH /* calculate terminal & column widths */
46#define FEATURE_FILETYPECHAR /* enable -p and -F */ 46#define FEATURE_FILETYPECHAR /* enable -p and -F */
@@ -64,10 +64,6 @@
64#include <dirent.h> 64#include <dirent.h>
65#include <errno.h> 65#include <errno.h>
66#include <stdio.h> 66#include <stdio.h>
67#ifdef FEATURE_USERNAME
68#include <pwd.h>
69#include <grp.h>
70#endif
71#ifdef FEATURE_TIMESTAMPS 67#ifdef FEATURE_TIMESTAMPS
72#include <time.h> 68#include <time.h>
73#endif 69#endif
@@ -83,27 +79,6 @@
83#define MINOR(dev) ((dev)&0xff) 79#define MINOR(dev) ((dev)&0xff)
84#endif 80#endif
85 81
86#define MODE1 "rwxrwxrwx"
87#define MODE0 "---------"
88#define SMODE1 "..s..s..t"
89#define SMODE0 "..S..S..T"
90
91/* The 9 mode bits to test */
92
93static const mode_t MBIT[] = {
94 S_IRUSR, S_IWUSR, S_IXUSR,
95 S_IRGRP, S_IWGRP, S_IXGRP,
96 S_IROTH, S_IWOTH, S_IXOTH
97};
98
99/* The special bits. If set, display SMODE0/1 instead of MODE0/1 */
100
101static const mode_t SBIT[] = {
102 0, 0, S_ISUID,
103 0, 0, S_ISGID,
104 0, 0, S_ISVTX
105};
106
107#define FMT_AUTO 0 82#define FMT_AUTO 0
108#define FMT_LONG 1 /* one record per line, extended info */ 83#define FMT_LONG 1 /* one record per line, extended info */
109#define FMT_SINGLE 2 /* one record per line */ 84#define FMT_SINGLE 2 /* one record per line */
@@ -216,45 +191,35 @@ static void list_single(const char *name, struct stat *info, const char *fullnam
216 191
217 if (display_fmt == FMT_LONG) { 192 if (display_fmt == FMT_LONG) {
218 mode_t mode = info->st_mode; 193 mode_t mode = info->st_mode;
219 int i;
220
221 scratch[0] = TYPECHAR(mode);
222 for (i=0; i<9; i++)
223 if (mode & SBIT[i])
224 scratch[i+1] = (mode & MBIT[i])
225 ? SMODE1[i]
226 : SMODE0[i];
227 else
228 scratch[i+1] = (mode & MBIT[i])
229 ? MODE1[i]
230 : MODE0[i];
231 newline(); 194 newline();
232 wr(scratch, 10); 195 wr(modeString(mode), 10);
233 column=10; 196 column=10;
234 writenum((long)info->st_nlink,(short)4); 197 writenum((long)info->st_nlink,(short)5);
235 fputs(" ", stdout); 198 fputs(" ", stdout);
236#ifdef FEATURE_USERNAME 199#ifdef FEATURE_USERNAME
237 if (!(opts & DISP_NUMERIC)) { 200 if (!(opts & DISP_NUMERIC)) {
238 struct passwd *pw = getpwuid(info->st_uid); 201 scratch[8]='\0';
239 if (pw) 202 my_getpwuid( scratch, info->st_uid);
240 fputs(pw->pw_name, stdout); 203 if (*scratch)
204 fputs(scratch, stdout);
241 else 205 else
242 writenum((long)info->st_uid,(short)0); 206 writenum((long)info->st_uid,(short)0);
243 } else 207 } else
244#endif 208#endif
245 writenum((long)info->st_uid,(short)0); 209 writenum((long)info->st_uid,(short)0);
246 tab(24); 210 tab(16);
247#ifdef FEATURE_USERNAME 211#ifdef FEATURE_USERNAME
248 if (!(opts & DISP_NUMERIC)) { 212 if (!(opts & DISP_NUMERIC)) {
249 struct group *gr = getgrgid(info->st_gid); 213 scratch[8]='\0';
250 if (gr) 214 my_getgrgid( scratch, info->st_gid);
251 fputs(gr->gr_name, stdout); 215 if (*scratch)
216 fputs(scratch, stdout);
252 else 217 else
253 writenum((long)info->st_gid,(short)0); 218 writenum((long)info->st_gid,(short)0);
254 } else 219 } else
255#endif 220#endif
256 writenum((long)info->st_gid,(short)0); 221 writenum((long)info->st_gid,(short)0);
257 tab(33); 222 tab(17);
258 if (S_ISBLK(mode) || S_ISCHR(mode)) { 223 if (S_ISBLK(mode) || S_ISCHR(mode)) {
259 writenum((long)MAJOR(info->st_rdev),(short)3); 224 writenum((long)MAJOR(info->st_rdev),(short)3);
260 fputs(", ", stdout); 225 fputs(", ", stdout);
diff --git a/more.c b/more.c
index ea5e22562..469316128 100644
--- a/more.c
+++ b/more.c
@@ -25,7 +25,9 @@
25 25
26 26
27/* Turning this off makes things a bit smaller (and less pretty) */ 27/* Turning this off makes things a bit smaller (and less pretty) */
28#define BB_MORE_TERM 28#define BB_FEATURE_USE_TERMIOS
29/* Turning this off makes things a bit smaller (and less pretty) */
30#define BB_FEATURE_AUTOWIDTH
29 31
30 32
31 33
@@ -33,18 +35,16 @@
33#include <stdio.h> 35#include <stdio.h>
34#include <fcntl.h> 36#include <fcntl.h>
35#include <signal.h> 37#include <signal.h>
36 38#include <sys/ioctl.h>
37 39
38static const char more_usage[] = "[file ...]"; 40static const char more_usage[] = "[file ...]";
39 41
40
41/* ED: sparc termios is broken: revert back to old termio handling. */ 42/* ED: sparc termios is broken: revert back to old termio handling. */
42#ifdef BB_MORE_TERM 43#ifdef BB_FEATURE_USE_TERMIOS
43 44
44#if #cpu(sparc) 45#if #cpu(sparc)
45# define USE_OLD_TERMIO 46# define USE_OLD_TERMIO
46# include <termio.h> 47# include <termio.h>
47# include <sys/ioctl.h>
48# define termios termio 48# define termios termio
49# define stty(fd,argp) ioctl(fd,TCSETAF,argp) 49# define stty(fd,argp) ioctl(fd,TCSETAF,argp)
50#else 50#else
@@ -57,16 +57,35 @@ static const char more_usage[] = "[file ...]";
57 57
58 void gotsig(int sig) { 58 void gotsig(int sig) {
59 stty(fileno(cin), &initial_settings); 59 stty(fileno(cin), &initial_settings);
60 fprintf(stdout, "\n");
60 exit( TRUE); 61 exit( TRUE);
61 } 62 }
62#endif 63#endif
63 64
65
66
67#define TERMINAL_WIDTH 79 /* not 80 in case terminal has linefold bug */
68#define TERMINAL_HEIGHT 24
69
70
71#if defined BB_FEATURE_AUTOWIDTH && ! defined USE_OLD_TERMIO
72static int terminal_width = 0, terminal_height = 0;
73#else
74#define terminal_width TERMINAL_WIDTH
75#define terminal_height TERMINAL_HEIGHT
76#endif
77
78
79
64extern int more_main(int argc, char **argv) 80extern int more_main(int argc, char **argv)
65{ 81{
66 int c, lines=0, input=0; 82 int c, lines=0, input=0;
67 int next_page=0; 83 int next_page=0;
68 struct stat st; 84 struct stat st;
69 FILE *file; 85 FILE *file;
86#ifdef BB_FEATURE_AUTOWIDTH
87 struct winsize win;
88#endif
70 89
71 argc--; 90 argc--;
72 argv++; 91 argv++;
@@ -87,7 +106,7 @@ extern int more_main(int argc, char **argv)
87 } 106 }
88 fstat(fileno(file), &st); 107 fstat(fileno(file), &st);
89 108
90#ifdef BB_MORE_TERM 109#ifdef BB_FEATURE_USE_TERMIOS
91 cin = fopen("/dev/tty", "r"); 110 cin = fopen("/dev/tty", "r");
92 if (!cin) 111 if (!cin)
93 cin = fopen("/dev/console", "r"); 112 cin = fopen("/dev/console", "r");
@@ -100,12 +119,19 @@ extern int more_main(int argc, char **argv)
100 new_settings.c_lflag &= ~ICANON; 119 new_settings.c_lflag &= ~ICANON;
101 new_settings.c_lflag &= ~ECHO; 120 new_settings.c_lflag &= ~ECHO;
102 stty(fileno(cin), &new_settings); 121 stty(fileno(cin), &new_settings);
103 122
123#ifdef BB_FEATURE_AUTOWIDTH
124 ioctl(STDOUT_FILENO, TIOCGWINSZ, &win);
125 if (win.ws_row > 4)
126 terminal_height = win.ws_row - 2;
127 if (win.ws_col > 0)
128 terminal_width = win.ws_col - 1;
129#endif
130
104 (void) signal(SIGINT, gotsig); 131 (void) signal(SIGINT, gotsig);
105 (void) signal(SIGQUIT, gotsig); 132 (void) signal(SIGQUIT, gotsig);
106 (void) signal(SIGTERM, gotsig); 133 (void) signal(SIGTERM, gotsig);
107 134
108
109#endif 135#endif
110 while ((c = getc(file)) != EOF) { 136 while ((c = getc(file)) != EOF) {
111 if ( next_page ) { 137 if ( next_page ) {
@@ -119,7 +145,7 @@ extern int more_main(int argc, char **argv)
119 st.st_size); 145 st.st_size);
120 } 146 }
121 len += fprintf(stdout, "%s", 147 len += fprintf(stdout, "%s",
122#ifdef BB_MORE_TERM 148#ifdef BB_FEATURE_USE_TERMIOS
123 "" 149 ""
124#else 150#else
125 "\n" 151 "\n"
@@ -129,24 +155,31 @@ extern int more_main(int argc, char **argv)
129 fflush(stdout); 155 fflush(stdout);
130 input = getc( cin); 156 input = getc( cin);
131 157
132#ifdef BB_MORE_TERM 158#ifdef BB_FEATURE_USE_TERMIOS
133 /* Erase the "More" message */ 159 /* Erase the "More" message */
134 while(len-- > 0) 160 while(--len >= 0)
135 putc('\b', stdout); 161 putc('\b', stdout);
136 while(len++ < 79) 162 while(++len <= terminal_width)
137 putc(' ', stdout); 163 putc(' ', stdout);
138 while(len-- > 0) 164 while(--len >= 0)
139 putc('\b', stdout); 165 putc('\b', stdout);
140 fflush(stdout); 166 fflush(stdout);
141#endif 167#endif
142 168
143 } 169 }
144 if (input=='q') 170 if (c == '\n' ) {
145 goto end; 171 switch(input) {
146 if (input=='\n' && c == '\n' ) 172 case 'q':
147 next_page = 1; 173 goto end;
148 if ( c == ' ' && ++lines == 24 ) 174 case '\n':
149 next_page = 1; 175 /* increment by just one line if we are at
176 * the end of this line*/
177 next_page = 1;
178 break;
179 }
180 if ( ++lines == terminal_height )
181 next_page = 1;
182 }
150 putc(c, stdout); 183 putc(c, stdout);
151 } 184 }
152 fclose(file); 185 fclose(file);
@@ -155,7 +188,7 @@ extern int more_main(int argc, char **argv)
155 argv++; 188 argv++;
156 } while (--argc > 0); 189 } while (--argc > 0);
157end: 190end:
158#ifdef BB_MORE_TERM 191#ifdef BB_FEATURE_USE_TERMIOS
159 gotsig(0); 192 gotsig(0);
160#endif 193#endif
161 exit(TRUE); 194 exit(TRUE);
diff --git a/procps/ps.c b/procps/ps.c
index d8a4233da..55439dada 100644
--- a/procps/ps.c
+++ b/procps/ps.c
@@ -74,7 +74,7 @@ static void parse_proc_status(char* S, proc_t* P)
74 ); 74 );
75 else fprintf(stderr, "Internal error!\n"); 75 else fprintf(stderr, "Internal error!\n");
76 76
77 /* For busybox, ignoring effecting, saved, etc */ 77 /* For busybox, ignoring effective, saved, etc */
78 tmp = strstr (S,"Uid:"); 78 tmp = strstr (S,"Uid:");
79 if(tmp) sscanf (tmp, 79 if(tmp) sscanf (tmp,
80 "Uid:\t%d", &P->ruid); 80 "Uid:\t%d", &P->ruid);
diff --git a/ps.c b/ps.c
index d8a4233da..55439dada 100644
--- a/ps.c
+++ b/ps.c
@@ -74,7 +74,7 @@ static void parse_proc_status(char* S, proc_t* P)
74 ); 74 );
75 else fprintf(stderr, "Internal error!\n"); 75 else fprintf(stderr, "Internal error!\n");
76 76
77 /* For busybox, ignoring effecting, saved, etc */ 77 /* For busybox, ignoring effective, saved, etc */
78 tmp = strstr (S,"Uid:"); 78 tmp = strstr (S,"Uid:");
79 if(tmp) sscanf (tmp, 79 if(tmp) sscanf (tmp,
80 "Uid:\t%d", &P->ruid); 80 "Uid:\t%d", &P->ruid);
diff --git a/regexp.c b/regexp.c
index 164f88037..5500b1da7 100644
--- a/regexp.c
+++ b/regexp.c
@@ -50,7 +50,6 @@ extern int replace_match(char *haystack, char *needle, char *newNeedle, int igno
50 } while (regexec(re, s, FALSE, ignoreCase) == TRUE); 50 } while (regexec(re, s, FALSE, ignoreCase) == TRUE);
51 /* copy stuff from after the match */ 51 /* copy stuff from after the match */
52 while ( (*d++ = *s++) ) {} 52 while ( (*d++ = *s++) ) {}
53 d[-1] = '\n';
54 d[0] = '\0'; 53 d[0] = '\0';
55 strcpy(haystack, buf); 54 strcpy(haystack, buf);
56 } 55 }
diff --git a/rm.c b/rm.c
index f49ada5e1..077e792f9 100644
--- a/rm.c
+++ b/rm.c
@@ -84,7 +84,7 @@ extern int rm_main(int argc, char **argv)
84 84
85 while (argc-- > 0) { 85 while (argc-- > 0) {
86 srcName = *(argv++); 86 srcName = *(argv++);
87 if (recursiveAction( srcName, recursiveFlag, TRUE, TRUE, 87 if (recursiveAction( srcName, recursiveFlag, FALSE, TRUE,
88 fileAction, dirAction) == FALSE) { 88 fileAction, dirAction) == FALSE) {
89 exit( FALSE); 89 exit( FALSE);
90 } 90 }
diff --git a/sed.c b/sed.c
index f0a6a3b48..34756e09a 100644
--- a/sed.c
+++ b/sed.c
@@ -45,9 +45,23 @@ static const char sed_usage[] =
45#else 45#else
46"This version of sed matches strings (not full regexps).\n"; 46"This version of sed matches strings (not full regexps).\n";
47#endif 47#endif
48
48 49
50static void do_sed(FILE *fp, char *needle, char *newNeedle, int ignoreCase, int printFlag, int quietFlag)
51{
52 int foundOne=FALSE;
53 char haystack[1024];
49 54
50 55 while (fgets (haystack, 1023, fp)) {
56 foundOne = replace_match(haystack, needle, newNeedle, ignoreCase);
57 if (foundOne==TRUE && printFlag==TRUE) {
58 fprintf(stdout, haystack);
59 }
60 if (quietFlag==FALSE) {
61 fprintf(stdout, haystack);
62 }
63 }
64}
51 65
52extern int sed_main (int argc, char **argv) 66extern int sed_main (int argc, char **argv)
53{ 67{
@@ -56,11 +70,9 @@ extern int sed_main (int argc, char **argv)
56 char *name; 70 char *name;
57 char *cp; 71 char *cp;
58 int ignoreCase=FALSE; 72 int ignoreCase=FALSE;
59 int foundOne=FALSE;
60 int printFlag=FALSE; 73 int printFlag=FALSE;
61 int quietFlag=FALSE; 74 int quietFlag=FALSE;
62 int stopNow; 75 int stopNow;
63 char *haystack;
64 76
65 argc--; 77 argc--;
66 argv++; 78 argv++;
@@ -73,24 +85,23 @@ extern int sed_main (int argc, char **argv)
73 cp = *argv++; 85 cp = *argv++;
74 stopNow=FALSE; 86 stopNow=FALSE;
75 87
76 while (*++cp && stopNow==FALSE) 88 while (*++cp && stopNow==FALSE) {
77 switch (*cp) { 89 switch (*cp) {
78 case 'n': 90 case 'n':
79 quietFlag = TRUE; 91 quietFlag = TRUE;
80 break; 92 break;
81 case 'e': 93 case 'e':
82 if (*(cp+1)==0 && --argc < 0) { 94 if (*(cp+1)==0 && --argc < 0) {
83 fprintf(stderr, "A\n");
84 usage( sed_usage); 95 usage( sed_usage);
85 } 96 }
86 cp = *argv++; 97 if ( *++cp != 's')
98 cp = *argv++;
87 while( *cp ) { 99 while( *cp ) {
88 if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') { 100 if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') {
89 char* pos=needle=cp+2; 101 char* pos=needle=cp+2;
90 for(;;) { 102 for(;;) {
91 pos = strchr(pos, '/'); 103 pos = strchr(pos, '/');
92 if (pos==NULL) { 104 if (pos==NULL) {
93 fprintf(stderr, "B\n");
94 usage( sed_usage); 105 usage( sed_usage);
95 } 106 }
96 if (*(pos-1) == '\\') { 107 if (*(pos-1) == '\\') {
@@ -104,7 +115,6 @@ extern int sed_main (int argc, char **argv)
104 for(;;) { 115 for(;;) {
105 pos = strchr(pos, '/'); 116 pos = strchr(pos, '/');
106 if (pos==NULL) { 117 if (pos==NULL) {
107 fprintf(stderr, "C\n");
108 usage( sed_usage); 118 usage( sed_usage);
109 } 119 }
110 if (*(pos-1) == '\\') { 120 if (*(pos-1) == '\\') {
@@ -116,7 +126,6 @@ extern int sed_main (int argc, char **argv)
116 *pos=0; 126 *pos=0;
117 if (pos+2 != 0) { 127 if (pos+2 != 0) {
118 while (*++pos) { 128 while (*++pos) {
119 fprintf(stderr, "pos='%s'\n", pos);
120 switch (*pos) { 129 switch (*pos) {
121 case 'i': 130 case 'i':
122 ignoreCase=TRUE; 131 ignoreCase=TRUE;
@@ -134,42 +143,35 @@ extern int sed_main (int argc, char **argv)
134 } 143 }
135 cp++; 144 cp++;
136 } 145 }
137 fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); 146 //fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle);
138 stopNow=TRUE; 147 stopNow=TRUE;
139 break; 148 break;
140 149
141 default: 150 default:
142 fprintf(stderr, "D\n");
143 usage(sed_usage); 151 usage(sed_usage);
144 } 152 }
153 }
145 } 154 }
146 155
147 while (argc-- > 0) { 156 if (argc==0) {
148 name = *argv++; 157 do_sed( stdin, needle, newNeedle, ignoreCase, printFlag, quietFlag);
158 } else {
159 while (argc-- > 0) {
160 name = *argv++;
149 161
150 fp = fopen (name, "r"); 162 fp = fopen (name, "r");
151 if (fp == NULL) { 163 if (fp == NULL) {
152 perror (name); 164 perror (name);
153 continue; 165 continue;
154 } 166 }
155 167
156 haystack = (char*)malloc( 1024); 168 do_sed( fp, needle, newNeedle, ignoreCase, printFlag, quietFlag);
157 while (fgets (haystack, 1023, fp)) {
158
159 foundOne = replace_match(haystack, needle, newNeedle, ignoreCase);
160 if (foundOne==TRUE && printFlag==TRUE)
161 fputs (haystack, stdout);
162 if (quietFlag==FALSE)
163 fputs (haystack, stdout);
164 /* Avoid any mem leaks */
165 free(haystack);
166 haystack = (char*)malloc( BUF_SIZE);
167 }
168 169
169 if (ferror (fp)) 170 if (ferror (fp))
170 perror (name); 171 perror (name);
171 172
172 fclose (fp); 173 fclose (fp);
174 }
173 } 175 }
174 exit( TRUE); 176 exit( TRUE);
175} 177}
diff --git a/tar.c b/tar.c
index cd255f85c..9ad41bea8 100644
--- a/tar.c
+++ b/tar.c
@@ -35,6 +35,16 @@
35#include <signal.h> 35#include <signal.h>
36#include <time.h> 36#include <time.h>
37 37
38/* Note that tar.c expects TRUE and FALSE to be defined
39 * exactly the opposite of how they are used everywhere else.
40 * Some time this should be integrated a bit better, but this
41 * does the job for now.
42 */
43#undef FALSE
44#undef TRUE
45#define FALSE ((int) 0)
46#define TRUE ((int) 1)
47
38 48
39static const char tar_usage[] = 49static const char tar_usage[] =
40 "tar -[cxtvOf] [tarFileName] [FILE] ...\n" 50 "tar -[cxtvOf] [tarFileName] [FILE] ...\n"
@@ -169,10 +179,9 @@ extern int tar_main (int argc, char **argv)
169 /* 179 /*
170 * Parse the options. 180 * Parse the options.
171 */ 181 */
172 options = *argv++;
173 argc--;
174
175 if (**argv == '-') { 182 if (**argv == '-') {
183 options = (*argv++) + 1;
184 argc--;
176 for (; *options; options++) { 185 for (; *options; options++) {
177 switch (*options) { 186 switch (*options) {
178 case 'f': 187 case 'f':
diff --git a/util-linux/more.c b/util-linux/more.c
index ea5e22562..469316128 100644
--- a/util-linux/more.c
+++ b/util-linux/more.c
@@ -25,7 +25,9 @@
25 25
26 26
27/* Turning this off makes things a bit smaller (and less pretty) */ 27/* Turning this off makes things a bit smaller (and less pretty) */
28#define BB_MORE_TERM 28#define BB_FEATURE_USE_TERMIOS
29/* Turning this off makes things a bit smaller (and less pretty) */
30#define BB_FEATURE_AUTOWIDTH
29 31
30 32
31 33
@@ -33,18 +35,16 @@
33#include <stdio.h> 35#include <stdio.h>
34#include <fcntl.h> 36#include <fcntl.h>
35#include <signal.h> 37#include <signal.h>
36 38#include <sys/ioctl.h>
37 39
38static const char more_usage[] = "[file ...]"; 40static const char more_usage[] = "[file ...]";
39 41
40
41/* ED: sparc termios is broken: revert back to old termio handling. */ 42/* ED: sparc termios is broken: revert back to old termio handling. */
42#ifdef BB_MORE_TERM 43#ifdef BB_FEATURE_USE_TERMIOS
43 44
44#if #cpu(sparc) 45#if #cpu(sparc)
45# define USE_OLD_TERMIO 46# define USE_OLD_TERMIO
46# include <termio.h> 47# include <termio.h>
47# include <sys/ioctl.h>
48# define termios termio 48# define termios termio
49# define stty(fd,argp) ioctl(fd,TCSETAF,argp) 49# define stty(fd,argp) ioctl(fd,TCSETAF,argp)
50#else 50#else
@@ -57,16 +57,35 @@ static const char more_usage[] = "[file ...]";
57 57
58 void gotsig(int sig) { 58 void gotsig(int sig) {
59 stty(fileno(cin), &initial_settings); 59 stty(fileno(cin), &initial_settings);
60 fprintf(stdout, "\n");
60 exit( TRUE); 61 exit( TRUE);
61 } 62 }
62#endif 63#endif
63 64
65
66
67#define TERMINAL_WIDTH 79 /* not 80 in case terminal has linefold bug */
68#define TERMINAL_HEIGHT 24
69
70
71#if defined BB_FEATURE_AUTOWIDTH && ! defined USE_OLD_TERMIO
72static int terminal_width = 0, terminal_height = 0;
73#else
74#define terminal_width TERMINAL_WIDTH
75#define terminal_height TERMINAL_HEIGHT
76#endif
77
78
79
64extern int more_main(int argc, char **argv) 80extern int more_main(int argc, char **argv)
65{ 81{
66 int c, lines=0, input=0; 82 int c, lines=0, input=0;
67 int next_page=0; 83 int next_page=0;
68 struct stat st; 84 struct stat st;
69 FILE *file; 85 FILE *file;
86#ifdef BB_FEATURE_AUTOWIDTH
87 struct winsize win;
88#endif
70 89
71 argc--; 90 argc--;
72 argv++; 91 argv++;
@@ -87,7 +106,7 @@ extern int more_main(int argc, char **argv)
87 } 106 }
88 fstat(fileno(file), &st); 107 fstat(fileno(file), &st);
89 108
90#ifdef BB_MORE_TERM 109#ifdef BB_FEATURE_USE_TERMIOS
91 cin = fopen("/dev/tty", "r"); 110 cin = fopen("/dev/tty", "r");
92 if (!cin) 111 if (!cin)
93 cin = fopen("/dev/console", "r"); 112 cin = fopen("/dev/console", "r");
@@ -100,12 +119,19 @@ extern int more_main(int argc, char **argv)
100 new_settings.c_lflag &= ~ICANON; 119 new_settings.c_lflag &= ~ICANON;
101 new_settings.c_lflag &= ~ECHO; 120 new_settings.c_lflag &= ~ECHO;
102 stty(fileno(cin), &new_settings); 121 stty(fileno(cin), &new_settings);
103 122
123#ifdef BB_FEATURE_AUTOWIDTH
124 ioctl(STDOUT_FILENO, TIOCGWINSZ, &win);
125 if (win.ws_row > 4)
126 terminal_height = win.ws_row - 2;
127 if (win.ws_col > 0)
128 terminal_width = win.ws_col - 1;
129#endif
130
104 (void) signal(SIGINT, gotsig); 131 (void) signal(SIGINT, gotsig);
105 (void) signal(SIGQUIT, gotsig); 132 (void) signal(SIGQUIT, gotsig);
106 (void) signal(SIGTERM, gotsig); 133 (void) signal(SIGTERM, gotsig);
107 134
108
109#endif 135#endif
110 while ((c = getc(file)) != EOF) { 136 while ((c = getc(file)) != EOF) {
111 if ( next_page ) { 137 if ( next_page ) {
@@ -119,7 +145,7 @@ extern int more_main(int argc, char **argv)
119 st.st_size); 145 st.st_size);
120 } 146 }
121 len += fprintf(stdout, "%s", 147 len += fprintf(stdout, "%s",
122#ifdef BB_MORE_TERM 148#ifdef BB_FEATURE_USE_TERMIOS
123 "" 149 ""
124#else 150#else
125 "\n" 151 "\n"
@@ -129,24 +155,31 @@ extern int more_main(int argc, char **argv)
129 fflush(stdout); 155 fflush(stdout);
130 input = getc( cin); 156 input = getc( cin);
131 157
132#ifdef BB_MORE_TERM 158#ifdef BB_FEATURE_USE_TERMIOS
133 /* Erase the "More" message */ 159 /* Erase the "More" message */
134 while(len-- > 0) 160 while(--len >= 0)
135 putc('\b', stdout); 161 putc('\b', stdout);
136 while(len++ < 79) 162 while(++len <= terminal_width)
137 putc(' ', stdout); 163 putc(' ', stdout);
138 while(len-- > 0) 164 while(--len >= 0)
139 putc('\b', stdout); 165 putc('\b', stdout);
140 fflush(stdout); 166 fflush(stdout);
141#endif 167#endif
142 168
143 } 169 }
144 if (input=='q') 170 if (c == '\n' ) {
145 goto end; 171 switch(input) {
146 if (input=='\n' && c == '\n' ) 172 case 'q':
147 next_page = 1; 173 goto end;
148 if ( c == ' ' && ++lines == 24 ) 174 case '\n':
149 next_page = 1; 175 /* increment by just one line if we are at
176 * the end of this line*/
177 next_page = 1;
178 break;
179 }
180 if ( ++lines == terminal_height )
181 next_page = 1;
182 }
150 putc(c, stdout); 183 putc(c, stdout);
151 } 184 }
152 fclose(file); 185 fclose(file);
@@ -155,7 +188,7 @@ extern int more_main(int argc, char **argv)
155 argv++; 188 argv++;
156 } while (--argc > 0); 189 } while (--argc > 0);
157end: 190end:
158#ifdef BB_MORE_TERM 191#ifdef BB_FEATURE_USE_TERMIOS
159 gotsig(0); 192 gotsig(0);
160#endif 193#endif
161 exit(TRUE); 194 exit(TRUE);
diff --git a/utility.c b/utility.c
index 97c597ee6..59ac36197 100644
--- a/utility.c
+++ b/utility.c
@@ -415,8 +415,12 @@ recursiveAction(const char *fileName, int recurse, int followLinks, int depthFir
415 return (FALSE); 415 return (FALSE);
416 } 416 }
417 417
418 if ( (followLinks == FALSE) && (S_ISLNK(statbuf.st_mode)) ) 418 if ( (followLinks == FALSE) && (S_ISLNK(statbuf.st_mode)) ) {
419 return (TRUE); 419 if (fileAction == NULL)
420 return (TRUE);
421 else
422 return (fileAction(fileName, &statbuf));
423 }
420 424
421 if (recurse == FALSE) { 425 if (recurse == FALSE) {
422 if (S_ISDIR(statbuf.st_mode)) { 426 if (S_ISDIR(statbuf.st_mode)) {