Stuff
No binary (build failed)
—
(log yok)
| @@ -5,6 +5,17 @@ | |
| better job of finding the real consol device rather than using | |
| /dev/console which doesn't support job control. Patch also | |
| thanks to Eric Delaunay. | |
| + | * more started to read from stdin after the last file was finished, and |
| + | options were not parsed correctly (fix thanks to Eric Delaunay). |
| + | * rm wouldn't remove a symlink unless the symlink was valid. This was |
| + | a side effect of the busybox 0.32 recursiveAction() fix. Things |
| + | should now work correctly. |
| + | * grep wouldn't grep stdin. Now it does. |
| + | * sed wouldn't sed stdin. Now it does. |
| + | * sed was appending a \n to the end of lines with replacements. |
| + | Now it doesn't do that. |
| + | * ls -l now bypasses libc6 nss when displaying user/group names. |
| + | Now uses my_getpwuid and my_getgrgid. |
| 0.33 | |
| * Fixed a bug where init could hang instead of rebooting. | |
| @@ -22,7 +22,7 @@ BUILDTIME=$(shell date "+%Y%m%d-%H%M") | |
| # Comment out the following to make a debuggable build | |
| # Leave this off for production use. | |
| - | DODEBUG=false |
| + | DODEBUG=true |
| # If you want a static binary, turn this on. I can't think | |
| # of many situations where anybody would ever want it static, | |
| # but... | |
| @@ -35,6 +35,16 @@ | |
| #include <signal.h> | |
| #include <time.h> | |
| + | /* Note that tar.c expects TRUE and FALSE to be defined |
| + | * exactly the opposite of how they are used everywhere else. |
| + | * Some time this should be integrated a bit better, but this |
| + | * does the job for now. |
| + | */ |
| + | #undef FALSE |
| + | #undef TRUE |
| + | #define FALSE ((int) 0) |
| + | #define TRUE ((int) 1) |
| + | |
| static const char tar_usage[] = | |
| "tar -[cxtvOf] [tarFileName] [FILE] ...\n" | |
| @@ -169,10 +179,9 @@ extern int tar_main (int argc, char **argv) | |
| /* | |
| * Parse the options. | |
| */ | |
| - | options = *argv++; |
| - | argc--; |
| - | |
| if (**argv == '-') { | |
| + | options = (*argv++) + 1; |
| + | argc--; |
| for (; *options; options++) { | |
| switch (*options) { | |
| case 'f': | |
| @@ -54,7 +54,7 @@ | |
| #define BB_SYNC | |
| #define BB_TAR | |
| #define BB_TOUCH | |
| - | //#define BB_TRUE_FALSE // Supplied by ash |
| + | //#define BB_TRUE_FALSE |
| #define BB_UMOUNT | |
| #define BB_UPDATE | |
| #define BB_UNAME | |
| @@ -40,7 +40,7 @@ | |
| * 1. requires lstat (BSD) - how do you do it without? | |
| */ | |
| - | //#define FEATURE_USERNAME /* show username/groupnames (libc6 uses NSS) */ |
| + | #define FEATURE_USERNAME /* show username/groupnames (bypasses libc6 NSS) */ |
| #define FEATURE_TIMESTAMPS /* show file timestamps */ | |
| #define FEATURE_AUTOWIDTH /* calculate terminal & column widths */ | |
| #define FEATURE_FILETYPECHAR /* enable -p and -F */ | |
| @@ -64,10 +64,6 @@ | |
| #include <dirent.h> | |
| #include <errno.h> | |
| #include <stdio.h> | |
| - | #ifdef FEATURE_USERNAME |
| - | #include <pwd.h> |
| - | #include <grp.h> |
| - | #endif |
| #ifdef FEATURE_TIMESTAMPS | |
| #include <time.h> | |
| #endif | |
| @@ -83,27 +79,6 @@ | |
| #define MINOR(dev) ((dev)&0xff) | |
| #endif | |
| - | #define MODE1 "rwxrwxrwx" |
| - | #define MODE0 "---------" |
| - | #define SMODE1 "..s..s..t" |
| - | #define SMODE0 "..S..S..T" |
| - | |
| - | /* The 9 mode bits to test */ |
| - | |
| - | static const mode_t MBIT[] = { |
| - | S_IRUSR, S_IWUSR, S_IXUSR, |
| - | S_IRGRP, S_IWGRP, S_IXGRP, |
| - | S_IROTH, S_IWOTH, S_IXOTH |
| - | }; |
| - | |
| - | /* The special bits. If set, display SMODE0/1 instead of MODE0/1 */ |
| - | |
| - | static const mode_t SBIT[] = { |
| - | 0, 0, S_ISUID, |
| - | 0, 0, S_ISGID, |
| - | 0, 0, S_ISVTX |
| - | }; |
| - | |
| #define FMT_AUTO 0 | |
| #define FMT_LONG 1 /* one record per line, extended info */ | |
| #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 | |
| if (display_fmt == FMT_LONG) { | |
| mode_t mode = info->st_mode; | |
| - | int i; |
| - | |
| - | scratch[0] = TYPECHAR(mode); |
| - | for (i=0; i<9; i++) |
| - | if (mode & SBIT[i]) |
| - | scratch[i+1] = (mode & MBIT[i]) |
| - | ? SMODE1[i] |
| - | : SMODE0[i]; |
| - | else |
| - | scratch[i+1] = (mode & MBIT[i]) |
| - | ? MODE1[i] |
| - | : MODE0[i]; |
| newline(); | |
| - | wr(scratch, 10); |
| + | wr(modeString(mode), 10); |
| column=10; | |
| - | writenum((long)info->st_nlink,(short)4); |
| + | writenum((long)info->st_nlink,(short)5); |
| fputs(" ", stdout); | |
| #ifdef FEATURE_USERNAME | |
| if (!(opts & DISP_NUMERIC)) { | |
| - | struct passwd *pw = getpwuid(info->st_uid); |
| - | if (pw) |
| - | fputs(pw->pw_name, stdout); |
| + | scratch[8]='\0'; |
| + | my_getpwuid( scratch, info->st_uid); |
| + | if (*scratch) |
| + | fputs(scratch, stdout); |
| else | |
| writenum((long)info->st_uid,(short)0); | |
| } else | |
| #endif | |
| writenum((long)info->st_uid,(short)0); | |
| - | tab(24); |
| + | tab(16); |
| #ifdef FEATURE_USERNAME | |
| if (!(opts & DISP_NUMERIC)) { | |
| - | struct group *gr = getgrgid(info->st_gid); |
| - | if (gr) |
| - | fputs(gr->gr_name, stdout); |
| + | scratch[8]='\0'; |
| + | my_getgrgid( scratch, info->st_gid); |
| + | if (*scratch) |
| + | fputs(scratch, stdout); |
| else | |
| writenum((long)info->st_gid,(short)0); | |
| } else | |
| #endif | |
| writenum((long)info->st_gid,(short)0); | |
| - | tab(33); |
| + | tab(17); |
| if (S_ISBLK(mode) || S_ISCHR(mode)) { | |
| writenum((long)MAJOR(info->st_rdev),(short)3); | |
| fputs(", ", stdout); | |
| @@ -84,7 +84,7 @@ extern int rm_main(int argc, char **argv) | |
| while (argc-- > 0) { | |
| srcName = *(argv++); | |
| - | if (recursiveAction( srcName, recursiveFlag, TRUE, TRUE, |
| + | if (recursiveAction( srcName, recursiveFlag, FALSE, TRUE, |
| fileAction, dirAction) == FALSE) { | |
| exit( FALSE); | |
| } | |
| @@ -45,9 +45,23 @@ static const char sed_usage[] = | |
| #else | |
| "This version of sed matches strings (not full regexps).\n"; | |
| #endif | |
| + | |
| + | static void do_sed(FILE *fp, char *needle, char *newNeedle, int ignoreCase, int printFlag, int quietFlag) |
| + | { |
| + | int foundOne=FALSE; |
| + | char haystack[1024]; |
| - | |
| + | while (fgets (haystack, 1023, fp)) { |
| + | foundOne = replace_match(haystack, needle, newNeedle, ignoreCase); |
| + | if (foundOne==TRUE && printFlag==TRUE) { |
| + | fprintf(stdout, haystack); |
| + | } |
| + | if (quietFlag==FALSE) { |
| + | fprintf(stdout, haystack); |
| + | } |
| + | } |
| + | } |
| extern int sed_main (int argc, char **argv) | |
| { | |
| @@ -56,11 +70,9 @@ extern int sed_main (int argc, char **argv) | |
| char *name; | |
| char *cp; | |
| int ignoreCase=FALSE; | |
| - | int foundOne=FALSE; |
| int printFlag=FALSE; | |
| int quietFlag=FALSE; | |
| int stopNow; | |
| - | char *haystack; |
| argc--; | |
| argv++; | |
| @@ -73,24 +85,23 @@ extern int sed_main (int argc, char **argv) | |
| cp = *argv++; | |
| stopNow=FALSE; | |
| - | while (*++cp && stopNow==FALSE) |
| + | while (*++cp && stopNow==FALSE) { |
| switch (*cp) { | |
| case 'n': | |
| quietFlag = TRUE; | |
| break; | |
| case 'e': | |
| if (*(cp+1)==0 && --argc < 0) { | |
| - | fprintf(stderr, "A\n"); |
| usage( sed_usage); | |
| } | |
| - | cp = *argv++; |
| + | if ( *++cp != 's') |
| + | cp = *argv++; |
| while( *cp ) { | |
| if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') { | |
| char* pos=needle=cp+2; | |
| for(;;) { | |
| pos = strchr(pos, '/'); | |
| if (pos==NULL) { | |
| - | fprintf(stderr, "B\n"); |
| usage( sed_usage); | |
| } | |
| if (*(pos-1) == '\\') { | |
| @@ -104,7 +115,6 @@ extern int sed_main (int argc, char **argv) | |
| for(;;) { | |
| pos = strchr(pos, '/'); | |
| if (pos==NULL) { | |
| - | fprintf(stderr, "C\n"); |
| usage( sed_usage); | |
| } | |
| if (*(pos-1) == '\\') { | |
| @@ -116,7 +126,6 @@ extern int sed_main (int argc, char **argv) | |
| *pos=0; | |
| if (pos+2 != 0) { | |
| while (*++pos) { | |
| - | fprintf(stderr, "pos='%s'\n", pos); |
| switch (*pos) { | |
| case 'i': | |
| ignoreCase=TRUE; | |
| @@ -134,42 +143,35 @@ extern int sed_main (int argc, char **argv) | |
| } | |
| cp++; | |
| } | |
| - | fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); |
| + | //fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); |
| stopNow=TRUE; | |
| break; | |
| default: | |
| - | fprintf(stderr, "D\n"); |
| usage(sed_usage); | |
| } | |
| + | } |
| } | |
| - | while (argc-- > 0) { |
| - | name = *argv++; |
| + | if (argc==0) { |
| + | do_sed( stdin, needle, newNeedle, ignoreCase, printFlag, quietFlag); |
| + | } else { |
| + | while (argc-- > 0) { |
| + | name = *argv++; |
| - | fp = fopen (name, "r"); |
| - | if (fp == NULL) { |
| - | perror (name); |
| - | continue; |
| - | } |
| + | fp = fopen (name, "r"); |
| + | if (fp == NULL) { |
| + | perror (name); |
| + | continue; |
| + | } |
| - | haystack = (char*)malloc( 1024); |
| - | while (fgets (haystack, 1023, fp)) { |
| - | |
| - | foundOne = replace_match(haystack, needle, newNeedle, ignoreCase); |
| - | if (foundOne==TRUE && printFlag==TRUE) |
| - | fputs (haystack, stdout); |
| - | if (quietFlag==FALSE) |
| - | fputs (haystack, stdout); |
| - | /* Avoid any mem leaks */ |
| - | free(haystack); |
| - | haystack = (char*)malloc( BUF_SIZE); |
| - | } |
| + | do_sed( fp, needle, newNeedle, ignoreCase, printFlag, quietFlag); |
| - | if (ferror (fp)) |
| - | perror (name); |
| + | if (ferror (fp)) |
| + | perror (name); |
| - | fclose (fp); |
| + | fclose (fp); |
| + | } |
| } | |
| exit( TRUE); | |
| } | |
| @@ -40,45 +40,46 @@ static const char grep_usage[] = | |
| #if defined BB_REGEXP | |
| "This version of grep matches full regexps.\n"; | |
| #else | |
| - | "This version of grep matches strings (not full regexps).\n"; |
| + | "This version of grep matches strings (not regexps).\n"; |
| #endif | |
| - | int tellName=TRUE; |
| - | int ignoreCase=FALSE; |
| - | int tellLine=FALSE; |
| - | static do_grep(char* needle, char* haystack ) |
| + | static void do_grep(FILE *fp, char* needle, char *fileName, int tellName, int ignoreCase, int tellLine) |
| { | |
| - | line = 0; |
| + | char *cp; |
| + | long line = 0; |
| + | char haystack[BUF_SIZE]; |
| - | while (fgets (haystack, sizeof (haystack), fp)) { |
| - | line++; |
| - | cp = &haystack[strlen (haystack) - 1]; |
| + | while (fgets (haystack, sizeof (haystack), fp)) { |
| + | line++; |
| + | cp = &haystack[strlen (haystack) - 1]; |
| - | if (*cp != '\n') |
| - | fprintf (stderr, "%s: Line too long\n", name); |
| + | if (*cp != '\n') |
| + | fprintf (stderr, "%s: Line too long\n", fileName); |
| - | if (find_match(haystack, needle, ignoreCase) == TRUE) { |
| - | if (tellName==TRUE) |
| - | printf ("%s: ", name); |
| + | if (find_match(haystack, needle, ignoreCase) == TRUE) { |
| + | if (tellName==TRUE) |
| + | printf ("%s:", fileName); |
| - | if (tellLine==TRUE) |
| - | printf ("%ld: ", line); |
| + | if (tellLine==TRUE) |
| + | printf ("%ld:", line); |
| - | fputs (haystack, stdout); |
| - | } |
| + | fputs (haystack, stdout); |
| } | |
| + | } |
| } | |
| extern int grep_main (int argc, char **argv) | |
| { | |
| FILE *fp; | |
| - | char *needle; |
| - | char *name; |
| char *cp; | |
| - | long line; |
| - | char haystack[BUF_SIZE]; |
| + | char *needle; |
| + | char *fileName; |
| + | int tellName=FALSE; |
| + | int ignoreCase=FALSE; |
| + | int tellLine=FALSE; |
| + | |
| ignoreCase = FALSE; | |
| tellLine = FALSE; | |
| @@ -100,7 +101,7 @@ extern int grep_main (int argc, char **argv) | |
| break; | |
| case 'h': | |
| - | tellName = FALSE; |
| + | tellName = TRUE; |
| break; | |
| case 'n': | |
| @@ -115,28 +116,24 @@ extern int grep_main (int argc, char **argv) | |
| needle = *argv++; | |
| argc--; | |
| + | if (argc==0) { |
| + | do_grep( stdin, needle, "stdin", FALSE, ignoreCase, tellLine); |
| + | } else { |
| + | while (argc-- > 0) { |
| + | fileName = *argv++; |
| - | while (argc-- > 0) { |
| - | |
| - | if (argc==0) { |
| - | file = stdin; |
| - | } |
| - | else |
| - | file = fopen(*argv, "r"); |
| - | |
| + | fp = fopen (fileName, "r"); |
| + | if (fp == NULL) { |
| + | perror (fileName); |
| + | continue; |
| + | } |
| - | name = *argv++; |
| + | do_grep( fp, needle, fileName, tellName, ignoreCase, tellLine); |
| - | fp = fopen (name, "r"); |
| - | if (fp == NULL) { |
| - | perror (name); |
| - | continue; |
| + | if (ferror (fp)) |
| + | perror (fileName); |
| + | fclose (fp); |
| } | |
| - | |
| - | if (ferror (fp)) |
| - | perror (name); |
| - | |
| - | fclose (fp); |
| } | |
| exit( TRUE); | |
| } | |
| @@ -40,45 +40,46 @@ static const char grep_usage[] = | |
| #if defined BB_REGEXP | |
| "This version of grep matches full regexps.\n"; | |
| #else | |
| - | "This version of grep matches strings (not full regexps).\n"; |
| + | "This version of grep matches strings (not regexps).\n"; |
| #endif | |
| - | int tellName=TRUE; |
| - | int ignoreCase=FALSE; |
| - | int tellLine=FALSE; |
| - | static do_grep(char* needle, char* haystack ) |
| + | static void do_grep(FILE *fp, char* needle, char *fileName, int tellName, int ignoreCase, int tellLine) |
| { | |
| - | line = 0; |
| + | char *cp; |
| + | long line = 0; |
| + | char haystack[BUF_SIZE]; |
| - | while (fgets (haystack, sizeof (haystack), fp)) { |
| - | line++; |
| - | cp = &haystack[strlen (haystack) - 1]; |
| + | while (fgets (haystack, sizeof (haystack), fp)) { |
| + | line++; |
| + | cp = &haystack[strlen (haystack) - 1]; |
| - | if (*cp != '\n') |
| - | fprintf (stderr, "%s: Line too long\n", name); |
| + | if (*cp != '\n') |
| + | fprintf (stderr, "%s: Line too long\n", fileName); |
| - | if (find_match(haystack, needle, ignoreCase) == TRUE) { |
| - | if (tellName==TRUE) |
| - | printf ("%s: ", name); |
| + | if (find_match(haystack, needle, ignoreCase) == TRUE) { |
| + | if (tellName==TRUE) |
| + | printf ("%s:", fileName); |
| - | if (tellLine==TRUE) |
| - | printf ("%ld: ", line); |
| + | if (tellLine==TRUE) |
| + | printf ("%ld:", line); |
| - | fputs (haystack, stdout); |
| - | } |
| + | fputs (haystack, stdout); |
| } | |
| + | } |
| } | |
| extern int grep_main (int argc, char **argv) | |
| { | |
| FILE *fp; | |
| - | char *needle; |
| - | char *name; |
| char *cp; | |
| - | long line; |
| - | char haystack[BUF_SIZE]; |
| + | char *needle; |
| + | char *fileName; |
| + | int tellName=FALSE; |
| + | int ignoreCase=FALSE; |
| + | int tellLine=FALSE; |
| + | |
| ignoreCase = FALSE; | |
| tellLine = FALSE; | |
| @@ -100,7 +101,7 @@ extern int grep_main (int argc, char **argv) | |
| break; | |
| case 'h': | |
| - | tellName = FALSE; |
| + | tellName = TRUE; |
| break; | |
| case 'n': | |
| @@ -115,28 +116,24 @@ extern int grep_main (int argc, char **argv) | |
| needle = *argv++; | |
| argc--; | |
| + | if (argc==0) { |
| + | do_grep( stdin, needle, "stdin", FALSE, ignoreCase, tellLine); |
| + | } else { |
| + | while (argc-- > 0) { |
| + | fileName = *argv++; |
| - | while (argc-- > 0) { |
| - | |
| - | if (argc==0) { |
| - | file = stdin; |
| - | } |
| - | else |
| - | file = fopen(*argv, "r"); |
| - | |
| + | fp = fopen (fileName, "r"); |
| + | if (fp == NULL) { |
| + | perror (fileName); |
| + | continue; |
| + | } |
| - | name = *argv++; |
| + | do_grep( fp, needle, fileName, tellName, ignoreCase, tellLine); |
| - | fp = fopen (name, "r"); |
| - | if (fp == NULL) { |
| - | perror (name); |
| - | continue; |
| + | if (ferror (fp)) |
| + | perror (fileName); |
| + | fclose (fp); |
| } | |
| - | |
| - | if (ferror (fp)) |
| - | perror (name); |
| - | |
| - | fclose (fp); |
| } | |
| exit( TRUE); | |
| } | |
| @@ -40,7 +40,7 @@ | |
| * 1. requires lstat (BSD) - how do you do it without? | |
| */ | |
| - | //#define FEATURE_USERNAME /* show username/groupnames (libc6 uses NSS) */ |
| + | #define FEATURE_USERNAME /* show username/groupnames (bypasses libc6 NSS) */ |
| #define FEATURE_TIMESTAMPS /* show file timestamps */ | |
| #define FEATURE_AUTOWIDTH /* calculate terminal & column widths */ | |
| #define FEATURE_FILETYPECHAR /* enable -p and -F */ | |
| @@ -64,10 +64,6 @@ | |
| #include <dirent.h> | |
| #include <errno.h> | |
| #include <stdio.h> | |
| - | #ifdef FEATURE_USERNAME |
| - | #include <pwd.h> |
| - | #include <grp.h> |
| - | #endif |
| #ifdef FEATURE_TIMESTAMPS | |
| #include <time.h> | |
| #endif | |
| @@ -83,27 +79,6 @@ | |
| #define MINOR(dev) ((dev)&0xff) | |
| #endif | |
| - | #define MODE1 "rwxrwxrwx" |
| - | #define MODE0 "---------" |
| - | #define SMODE1 "..s..s..t" |
| - | #define SMODE0 "..S..S..T" |
| - | |
| - | /* The 9 mode bits to test */ |
| - | |
| - | static const mode_t MBIT[] = { |
| - | S_IRUSR, S_IWUSR, S_IXUSR, |
| - | S_IRGRP, S_IWGRP, S_IXGRP, |
| - | S_IROTH, S_IWOTH, S_IXOTH |
| - | }; |
| - | |
| - | /* The special bits. If set, display SMODE0/1 instead of MODE0/1 */ |
| - | |
| - | static const mode_t SBIT[] = { |
| - | 0, 0, S_ISUID, |
| - | 0, 0, S_ISGID, |
| - | 0, 0, S_ISVTX |
| - | }; |
| - | |
| #define FMT_AUTO 0 | |
| #define FMT_LONG 1 /* one record per line, extended info */ | |
| #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 | |
| if (display_fmt == FMT_LONG) { | |
| mode_t mode = info->st_mode; | |
| - | int i; |
| - | |
| - | scratch[0] = TYPECHAR(mode); |
| - | for (i=0; i<9; i++) |
| - | if (mode & SBIT[i]) |
| - | scratch[i+1] = (mode & MBIT[i]) |
| - | ? SMODE1[i] |
| - | : SMODE0[i]; |
| - | else |
| - | scratch[i+1] = (mode & MBIT[i]) |
| - | ? MODE1[i] |
| - | : MODE0[i]; |
| newline(); | |
| - | wr(scratch, 10); |
| + | wr(modeString(mode), 10); |
| column=10; | |
| - | writenum((long)info->st_nlink,(short)4); |
| + | writenum((long)info->st_nlink,(short)5); |
| fputs(" ", stdout); | |
| #ifdef FEATURE_USERNAME | |
| if (!(opts & DISP_NUMERIC)) { | |
| - | struct passwd *pw = getpwuid(info->st_uid); |
| - | if (pw) |
| - | fputs(pw->pw_name, stdout); |
| + | scratch[8]='\0'; |
| + | my_getpwuid( scratch, info->st_uid); |
| + | if (*scratch) |
| + | fputs(scratch, stdout); |
| else | |
| writenum((long)info->st_uid,(short)0); | |
| } else | |
| #endif | |
| writenum((long)info->st_uid,(short)0); | |
| - | tab(24); |
| + | tab(16); |
| #ifdef FEATURE_USERNAME | |
| if (!(opts & DISP_NUMERIC)) { | |
| - | struct group *gr = getgrgid(info->st_gid); |
| - | if (gr) |
| - | fputs(gr->gr_name, stdout); |
| + | scratch[8]='\0'; |
| + | my_getgrgid( scratch, info->st_gid); |
| + | if (*scratch) |
| + | fputs(scratch, stdout); |
| else | |
| writenum((long)info->st_gid,(short)0); | |
| } else | |
| #endif | |
| writenum((long)info->st_gid,(short)0); | |
| - | tab(33); |
| + | tab(17); |
| if (S_ISBLK(mode) || S_ISCHR(mode)) { | |
| writenum((long)MAJOR(info->st_rdev),(short)3); | |
| fputs(", ", stdout); | |
| @@ -25,7 +25,9 @@ | |
| /* Turning this off makes things a bit smaller (and less pretty) */ | |
| - | #define BB_MORE_TERM |
| + | #define BB_FEATURE_USE_TERMIOS |
| + | /* Turning this off makes things a bit smaller (and less pretty) */ |
| + | #define BB_FEATURE_AUTOWIDTH |
| @@ -33,18 +35,16 @@ | |
| #include <stdio.h> | |
| #include <fcntl.h> | |
| #include <signal.h> | |
| - | |
| + | #include <sys/ioctl.h> |
| static const char more_usage[] = "[file ...]"; | |
| - | |
| /* ED: sparc termios is broken: revert back to old termio handling. */ | |
| - | #ifdef BB_MORE_TERM |
| + | #ifdef BB_FEATURE_USE_TERMIOS |
| #if #cpu(sparc) | |
| # define USE_OLD_TERMIO | |
| # include <termio.h> | |
| - | # include <sys/ioctl.h> |
| # define termios termio | |
| # define stty(fd,argp) ioctl(fd,TCSETAF,argp) | |
| #else | |
| @@ -57,16 +57,35 @@ static const char more_usage[] = "[file ...]"; | |
| void gotsig(int sig) { | |
| stty(fileno(cin), &initial_settings); | |
| + | fprintf(stdout, "\n"); |
| exit( TRUE); | |
| } | |
| #endif | |
| + | |
| + | |
| + | #define TERMINAL_WIDTH 79 /* not 80 in case terminal has linefold bug */ |
| + | #define TERMINAL_HEIGHT 24 |
| + | |
| + | |
| + | #if defined BB_FEATURE_AUTOWIDTH && ! defined USE_OLD_TERMIO |
| + | static int terminal_width = 0, terminal_height = 0; |
| + | #else |
| + | #define terminal_width TERMINAL_WIDTH |
| + | #define terminal_height TERMINAL_HEIGHT |
| + | #endif |
| + | |
| + | |
| + | |
| extern int more_main(int argc, char **argv) | |
| { | |
| int c, lines=0, input=0; | |
| int next_page=0; | |
| struct stat st; | |
| FILE *file; | |
| + | #ifdef BB_FEATURE_AUTOWIDTH |
| + | struct winsize win; |
| + | #endif |
| argc--; | |
| argv++; | |
| @@ -87,7 +106,7 @@ extern int more_main(int argc, char **argv) | |
| } | |
| fstat(fileno(file), &st); | |
| - | #ifdef BB_MORE_TERM |
| + | #ifdef BB_FEATURE_USE_TERMIOS |
| cin = fopen("/dev/tty", "r"); | |
| if (!cin) | |
| cin = fopen("/dev/console", "r"); | |
| @@ -100,12 +119,19 @@ extern int more_main(int argc, char **argv) | |
| new_settings.c_lflag &= ~ICANON; | |
| new_settings.c_lflag &= ~ECHO; | |
| stty(fileno(cin), &new_settings); | |
| - | |
| + | |
| + | #ifdef BB_FEATURE_AUTOWIDTH |
| + | ioctl(STDOUT_FILENO, TIOCGWINSZ, &win); |
| + | if (win.ws_row > 4) |
| + | terminal_height = win.ws_row - 2; |
| + | if (win.ws_col > 0) |
| + | terminal_width = win.ws_col - 1; |
| + | #endif |
| + | |
| (void) signal(SIGINT, gotsig); | |
| (void) signal(SIGQUIT, gotsig); | |
| (void) signal(SIGTERM, gotsig); | |
| - | |
| #endif | |
| while ((c = getc(file)) != EOF) { | |
| if ( next_page ) { | |
| @@ -119,7 +145,7 @@ extern int more_main(int argc, char **argv) | |
| st.st_size); | |
| } | |
| len += fprintf(stdout, "%s", | |
| - | #ifdef BB_MORE_TERM |
| + | #ifdef BB_FEATURE_USE_TERMIOS |
| "" | |
| #else | |
| "\n" | |
| @@ -129,24 +155,31 @@ extern int more_main(int argc, char **argv) | |
| fflush(stdout); | |
| input = getc( cin); | |
| - | #ifdef BB_MORE_TERM |
| + | #ifdef BB_FEATURE_USE_TERMIOS |
| /* Erase the "More" message */ | |
| - | while(len-- > 0) |
| + | while(--len >= 0) |
| putc('\b', stdout); | |
| - | while(len++ < 79) |
| + | while(++len <= terminal_width) |
| putc(' ', stdout); | |
| - | while(len-- > 0) |
| + | while(--len >= 0) |
| putc('\b', stdout); | |
| fflush(stdout); | |
| #endif | |
| } | |
| - | if (input=='q') |
| - | goto end; |
| - | if (input=='\n' && c == '\n' ) |
| - | next_page = 1; |
| - | if ( c == ' ' && ++lines == 24 ) |
| - | next_page = 1; |
| + | if (c == '\n' ) { |
| + | switch(input) { |
| + | case 'q': |
| + | goto end; |
| + | case '\n': |
| + | /* increment by just one line if we are at |
| + | * the end of this line*/ |
| + | next_page = 1; |
| + | break; |
| + | } |
| + | if ( ++lines == terminal_height ) |
| + | next_page = 1; |
| + | } |
| putc(c, stdout); | |
| } | |
| fclose(file); | |
| @@ -155,7 +188,7 @@ extern int more_main(int argc, char **argv) | |
| argv++; | |
| } while (--argc > 0); | |
| end: | |
| - | #ifdef BB_MORE_TERM |
| + | #ifdef BB_FEATURE_USE_TERMIOS |
| gotsig(0); | |
| #endif | |
| exit(TRUE); | |
| @@ -74,7 +74,7 @@ static void parse_proc_status(char* S, proc_t* P) | |
| ); | |
| else fprintf(stderr, "Internal error!\n"); | |
| - | /* For busybox, ignoring effecting, saved, etc */ |
| + | /* For busybox, ignoring effective, saved, etc */ |
| tmp = strstr (S,"Uid:"); | |
| if(tmp) sscanf (tmp, | |
| "Uid:\t%d", &P->ruid); | |
| @@ -74,7 +74,7 @@ static void parse_proc_status(char* S, proc_t* P) | |
| ); | |
| else fprintf(stderr, "Internal error!\n"); | |
| - | /* For busybox, ignoring effecting, saved, etc */ |
| + | /* For busybox, ignoring effective, saved, etc */ |
| tmp = strstr (S,"Uid:"); | |
| if(tmp) sscanf (tmp, | |
| "Uid:\t%d", &P->ruid); | |
| @@ -50,7 +50,6 @@ extern int replace_match(char *haystack, char *needle, char *newNeedle, int igno | |
| } while (regexec(re, s, FALSE, ignoreCase) == TRUE); | |
| /* copy stuff from after the match */ | |
| while ( (*d++ = *s++) ) {} | |
| - | d[-1] = '\n'; |
| d[0] = '\0'; | |
| strcpy(haystack, buf); | |
| } | |
| @@ -84,7 +84,7 @@ extern int rm_main(int argc, char **argv) | |
| while (argc-- > 0) { | |
| srcName = *(argv++); | |
| - | if (recursiveAction( srcName, recursiveFlag, TRUE, TRUE, |
| + | if (recursiveAction( srcName, recursiveFlag, FALSE, TRUE, |
| fileAction, dirAction) == FALSE) { | |
| exit( FALSE); | |
| } | |
| @@ -45,9 +45,23 @@ static const char sed_usage[] = | |
| #else | |
| "This version of sed matches strings (not full regexps).\n"; | |
| #endif | |
| + | |
| + | static void do_sed(FILE *fp, char *needle, char *newNeedle, int ignoreCase, int printFlag, int quietFlag) |
| + | { |
| + | int foundOne=FALSE; |
| + | char haystack[1024]; |
| - | |
| + | while (fgets (haystack, 1023, fp)) { |
| + | foundOne = replace_match(haystack, needle, newNeedle, ignoreCase); |
| + | if (foundOne==TRUE && printFlag==TRUE) { |
| + | fprintf(stdout, haystack); |
| + | } |
| + | if (quietFlag==FALSE) { |
| + | fprintf(stdout, haystack); |
| + | } |
| + | } |
| + | } |
| extern int sed_main (int argc, char **argv) | |
| { | |
| @@ -56,11 +70,9 @@ extern int sed_main (int argc, char **argv) | |
| char *name; | |
| char *cp; | |
| int ignoreCase=FALSE; | |
| - | int foundOne=FALSE; |
| int printFlag=FALSE; | |
| int quietFlag=FALSE; | |
| int stopNow; | |
| - | char *haystack; |
| argc--; | |
| argv++; | |
| @@ -73,24 +85,23 @@ extern int sed_main (int argc, char **argv) | |
| cp = *argv++; | |
| stopNow=FALSE; | |
| - | while (*++cp && stopNow==FALSE) |
| + | while (*++cp && stopNow==FALSE) { |
| switch (*cp) { | |
| case 'n': | |
| quietFlag = TRUE; | |
| break; | |
| case 'e': | |
| if (*(cp+1)==0 && --argc < 0) { | |
| - | fprintf(stderr, "A\n"); |
| usage( sed_usage); | |
| } | |
| - | cp = *argv++; |
| + | if ( *++cp != 's') |
| + | cp = *argv++; |
| while( *cp ) { | |
| if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') { | |
| char* pos=needle=cp+2; | |
| for(;;) { | |
| pos = strchr(pos, '/'); | |
| if (pos==NULL) { | |
| - | fprintf(stderr, "B\n"); |
| usage( sed_usage); | |
| } | |
| if (*(pos-1) == '\\') { | |
| @@ -104,7 +115,6 @@ extern int sed_main (int argc, char **argv) | |
| for(;;) { | |
| pos = strchr(pos, '/'); | |
| if (pos==NULL) { | |
| - | fprintf(stderr, "C\n"); |
| usage( sed_usage); | |
| } | |
| if (*(pos-1) == '\\') { | |
| @@ -116,7 +126,6 @@ extern int sed_main (int argc, char **argv) | |
| *pos=0; | |
| if (pos+2 != 0) { | |
| while (*++pos) { | |
| - | fprintf(stderr, "pos='%s'\n", pos); |
| switch (*pos) { | |
| case 'i': | |
| ignoreCase=TRUE; | |
| @@ -134,42 +143,35 @@ extern int sed_main (int argc, char **argv) | |
| } | |
| cp++; | |
| } | |
| - | fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); |
| + | //fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); |
| stopNow=TRUE; | |
| break; | |
| default: | |
| - | fprintf(stderr, "D\n"); |
| usage(sed_usage); | |
| } | |
| + | } |
| } | |
| - | while (argc-- > 0) { |
| - | name = *argv++; |
| + | if (argc==0) { |
| + | do_sed( stdin, needle, newNeedle, ignoreCase, printFlag, quietFlag); |
| + | } else { |
| + | while (argc-- > 0) { |
| + | name = *argv++; |
| - | fp = fopen (name, "r"); |
| - | if (fp == NULL) { |
| - | perror (name); |
| - | continue; |
| - | } |
| + | fp = fopen (name, "r"); |
| + | if (fp == NULL) { |
| + | perror (name); |
| + | continue; |
| + | } |
| - | haystack = (char*)malloc( 1024); |
| - | while (fgets (haystack, 1023, fp)) { |
| - | |
| - | foundOne = replace_match(haystack, needle, newNeedle, ignoreCase); |
| - | if (foundOne==TRUE && printFlag==TRUE) |
| - | fputs (haystack, stdout); |
| - | if (quietFlag==FALSE) |
| - | fputs (haystack, stdout); |
| - | /* Avoid any mem leaks */ |
| - | free(haystack); |
| - | haystack = (char*)malloc( BUF_SIZE); |
| - | } |
| + | do_sed( fp, needle, newNeedle, ignoreCase, printFlag, quietFlag); |
| - | if (ferror (fp)) |
| - | perror (name); |
| + | if (ferror (fp)) |
| + | perror (name); |
| - | fclose (fp); |
| + | fclose (fp); |
| + | } |
| } | |
| exit( TRUE); | |
| } | |
| @@ -35,6 +35,16 @@ | |
| #include <signal.h> | |
| #include <time.h> | |
| + | /* Note that tar.c expects TRUE and FALSE to be defined |
| + | * exactly the opposite of how they are used everywhere else. |
| + | * Some time this should be integrated a bit better, but this |
| + | * does the job for now. |
| + | */ |
| + | #undef FALSE |
| + | #undef TRUE |
| + | #define FALSE ((int) 0) |
| + | #define TRUE ((int) 1) |
| + | |
| static const char tar_usage[] = | |
| "tar -[cxtvOf] [tarFileName] [FILE] ...\n" | |
| @@ -169,10 +179,9 @@ extern int tar_main (int argc, char **argv) | |
| /* | |
| * Parse the options. | |
| */ | |
| - | options = *argv++; |
| - | argc--; |
| - | |
| if (**argv == '-') { | |
| + | options = (*argv++) + 1; |
| + | argc--; |
| for (; *options; options++) { | |
| switch (*options) { | |
| case 'f': | |
| @@ -25,7 +25,9 @@ | |
| /* Turning this off makes things a bit smaller (and less pretty) */ | |
| - | #define BB_MORE_TERM |
| + | #define BB_FEATURE_USE_TERMIOS |
| + | /* Turning this off makes things a bit smaller (and less pretty) */ |
| + | #define BB_FEATURE_AUTOWIDTH |
| @@ -33,18 +35,16 @@ | |
| #include <stdio.h> | |
| #include <fcntl.h> | |
| #include <signal.h> | |
| - | |
| + | #include <sys/ioctl.h> |
| static const char more_usage[] = "[file ...]"; | |
| - | |
| /* ED: sparc termios is broken: revert back to old termio handling. */ | |
| - | #ifdef BB_MORE_TERM |
| + | #ifdef BB_FEATURE_USE_TERMIOS |
| #if #cpu(sparc) | |
| # define USE_OLD_TERMIO | |
| # include <termio.h> | |
| - | # include <sys/ioctl.h> |
| # define termios termio | |
| # define stty(fd,argp) ioctl(fd,TCSETAF,argp) | |
| #else | |
| @@ -57,16 +57,35 @@ static const char more_usage[] = "[file ...]"; | |
| void gotsig(int sig) { | |
| stty(fileno(cin), &initial_settings); | |
| + | fprintf(stdout, "\n"); |
| exit( TRUE); | |
| } | |
| #endif | |
| + | |
| + | |
| + | #define TERMINAL_WIDTH 79 /* not 80 in case terminal has linefold bug */ |
| + | #define TERMINAL_HEIGHT 24 |
| + | |
| + | |
| + | #if defined BB_FEATURE_AUTOWIDTH && ! defined USE_OLD_TERMIO |
| + | static int terminal_width = 0, terminal_height = 0; |
| + | #else |
| + | #define terminal_width TERMINAL_WIDTH |
| + | #define terminal_height TERMINAL_HEIGHT |
| + | #endif |
| + | |
| + | |
| + | |
| extern int more_main(int argc, char **argv) | |
| { | |
| int c, lines=0, input=0; | |
| int next_page=0; | |
| struct stat st; | |
| FILE *file; | |
| + | #ifdef BB_FEATURE_AUTOWIDTH |
| + | struct winsize win; |
| + | #endif |
| argc--; | |
| argv++; | |
| @@ -87,7 +106,7 @@ extern int more_main(int argc, char **argv) | |
| } | |
| fstat(fileno(file), &st); | |
| - | #ifdef BB_MORE_TERM |
| + | #ifdef BB_FEATURE_USE_TERMIOS |
| cin = fopen("/dev/tty", "r"); | |
| if (!cin) | |
| cin = fopen("/dev/console", "r"); | |
| @@ -100,12 +119,19 @@ extern int more_main(int argc, char **argv) | |
| new_settings.c_lflag &= ~ICANON; | |
| new_settings.c_lflag &= ~ECHO; | |
| stty(fileno(cin), &new_settings); | |
| - | |
| + | |
| + | #ifdef BB_FEATURE_AUTOWIDTH |
| + | ioctl(STDOUT_FILENO, TIOCGWINSZ, &win); |
| + | if (win.ws_row > 4) |
| + | terminal_height = win.ws_row - 2; |
| + | if (win.ws_col > 0) |
| + | terminal_width = win.ws_col - 1; |
| + | #endif |
| + | |
| (void) signal(SIGINT, gotsig); | |
| (void) signal(SIGQUIT, gotsig); | |
| (void) signal(SIGTERM, gotsig); | |
| - | |
| #endif | |
| while ((c = getc(file)) != EOF) { | |
| if ( next_page ) { | |
| @@ -119,7 +145,7 @@ extern int more_main(int argc, char **argv) | |
| st.st_size); | |
| } | |
| len += fprintf(stdout, "%s", | |
| - | #ifdef BB_MORE_TERM |
| + | #ifdef BB_FEATURE_USE_TERMIOS |
| "" | |
| #else | |
| "\n" | |
| @@ -129,24 +155,31 @@ extern int more_main(int argc, char **argv) | |
| fflush(stdout); | |
| input = getc( cin); | |
| - | #ifdef BB_MORE_TERM |
| + | #ifdef BB_FEATURE_USE_TERMIOS |
| /* Erase the "More" message */ | |
| - | while(len-- > 0) |
| + | while(--len >= 0) |
| putc('\b', stdout); | |
| - | while(len++ < 79) |
| + | while(++len <= terminal_width) |
| putc(' ', stdout); | |
| - | while(len-- > 0) |
| + | while(--len >= 0) |
| putc('\b', stdout); | |
| fflush(stdout); | |
| #endif | |
| } | |
| - | if (input=='q') |
| - | goto end; |
| - | if (input=='\n' && c == '\n' ) |
| - | next_page = 1; |
| - | if ( c == ' ' && ++lines == 24 ) |
| - | next_page = 1; |
| + | if (c == '\n' ) { |
| + | switch(input) { |
| + | case 'q': |
| + | goto end; |
| + | case '\n': |
| + | /* increment by just one line if we are at |
| + | * the end of this line*/ |
| + | next_page = 1; |
| + | break; |
| + | } |
| + | if ( ++lines == terminal_height ) |
| + | next_page = 1; |
| + | } |
| putc(c, stdout); | |
| } | |
| fclose(file); | |
| @@ -155,7 +188,7 @@ extern int more_main(int argc, char **argv) | |
| argv++; | |
| } while (--argc > 0); | |
| end: | |
| - | #ifdef BB_MORE_TERM |
| + | #ifdef BB_FEATURE_USE_TERMIOS |
| gotsig(0); | |
| #endif | |
| exit(TRUE); | |
| @@ -415,8 +415,12 @@ recursiveAction(const char *fileName, int recurse, int followLinks, int depthFir | |
| return (FALSE); | |
| } | |
| - | if ( (followLinks == FALSE) && (S_ISLNK(statbuf.st_mode)) ) |
| - | return (TRUE); |
| + | if ( (followLinks == FALSE) && (S_ISLNK(statbuf.st_mode)) ) { |
| + | if (fileAction == NULL) |
| + | return (TRUE); |
| + | else |
| + | return (fileAction(fileName, &statbuf)); |
| + | } |
| if (recurse == FALSE) { | |
| if (S_ISDIR(statbuf.st_mode)) { | |