diff --git a/Changelog b/Changelog index 1dd93c3c7..750768b61 100644 --- a/Changelog +++ b/Changelog @@ -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. 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") # 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... 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 @@ #include #include +/* 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': 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 @@ #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 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 @@ * 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 #include #include -#ifdef FEATURE_USERNAME -#include -#include -#endif #ifdef FEATURE_TIMESTAMPS #include #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); 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) while (argc-- > 0) { srcName = *(argv++); - if (recursiveAction( srcName, recursiveFlag, TRUE, TRUE, + if (recursiveAction( srcName, recursiveFlag, FALSE, TRUE, fileAction, dirAction) == FALSE) { exit( FALSE); } 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[] = #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; + } + + do_sed( fp, needle, newNeedle, ignoreCase, printFlag, quietFlag); + + if (ferror (fp)) + perror (name); + + fclose (fp); } - - 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); - } - - if (ferror (fp)) - perror (name); - - fclose (fp); } exit( TRUE); } 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[] = #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) { + fp = fopen (fileName, "r"); + if (fp == NULL) { + perror (fileName); + continue; + } - if (argc==0) { - file = stdin; + do_grep( fp, needle, fileName, tellName, ignoreCase, tellLine); + + if (ferror (fp)) + perror (fileName); + fclose (fp); } - else - file = fopen(*argv, "r"); - - - name = *argv++; - - fp = fopen (name, "r"); - if (fp == NULL) { - perror (name); - continue; - } - - if (ferror (fp)) - perror (name); - - fclose (fp); } exit( TRUE); } 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[] = #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) { + fp = fopen (fileName, "r"); + if (fp == NULL) { + perror (fileName); + continue; + } - if (argc==0) { - file = stdin; + do_grep( fp, needle, fileName, tellName, ignoreCase, tellLine); + + if (ferror (fp)) + perror (fileName); + fclose (fp); } - else - file = fopen(*argv, "r"); - - - name = *argv++; - - fp = fopen (name, "r"); - if (fp == NULL) { - perror (name); - continue; - } - - if (ferror (fp)) - perror (name); - - fclose (fp); } exit( TRUE); } diff --git a/ls.c b/ls.c index 4eb486f87..f09cbbc22 100644 --- a/ls.c +++ b/ls.c @@ -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 #include #include -#ifdef FEATURE_USERNAME -#include -#include -#endif #ifdef FEATURE_TIMESTAMPS #include #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); diff --git a/more.c b/more.c index ea5e22562..469316128 100644 --- a/more.c +++ b/more.c @@ -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 #include #include - +#include 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 -# include # 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); 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) ); 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); 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) ); 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); 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 } 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); } 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) while (argc-- > 0) { srcName = *(argv++); - if (recursiveAction( srcName, recursiveFlag, TRUE, TRUE, + if (recursiveAction( srcName, recursiveFlag, FALSE, TRUE, fileAction, dirAction) == FALSE) { exit( FALSE); } 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[] = #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; + } + + do_sed( fp, needle, newNeedle, ignoreCase, printFlag, quietFlag); + + if (ferror (fp)) + perror (name); + + fclose (fp); } - - 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); - } - - if (ferror (fp)) - perror (name); - - fclose (fp); } exit( TRUE); } diff --git a/tar.c b/tar.c index cd255f85c..9ad41bea8 100644 --- a/tar.c +++ b/tar.c @@ -35,6 +35,16 @@ #include #include +/* 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': 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 @@ /* 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 #include #include - +#include 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 -# include # 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); 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 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)) {