diff options
-rw-r--r-- | AUTHORS | 3 | ||||
-rw-r--r-- | Changelog | 15 | ||||
-rw-r--r-- | Config.h | 3 | ||||
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | applets/busybox.c | 23 | ||||
-rw-r--r-- | archival/dpkg.c | 20 | ||||
-rw-r--r-- | busybox.c | 23 | ||||
-rw-r--r-- | cmdedit.c | 249 | ||||
-rw-r--r-- | coreutils/du.c | 17 | ||||
-rw-r--r-- | coreutils/echo.c | 2 | ||||
-rw-r--r-- | coreutils/pwd.c | 16 | ||||
-rw-r--r-- | coreutils/tr.c | 2 | ||||
-rw-r--r-- | cp_mv.c | 10 | ||||
-rw-r--r-- | docs/busybox.pod | 9 | ||||
-rw-r--r-- | docs/busybox_footer.pod | 9 | ||||
-rw-r--r-- | dpkg.c | 20 | ||||
-rw-r--r-- | du.c | 17 | ||||
-rw-r--r-- | echo.c | 2 | ||||
-rw-r--r-- | include/libbb.h | 7 | ||||
-rw-r--r-- | lash.c | 37 | ||||
-rw-r--r-- | libbb/concat_path_file.c | 24 | ||||
-rw-r--r-- | libbb/libbb.h | 7 | ||||
-rw-r--r-- | libbb/print_file.c | 29 | ||||
-rw-r--r-- | libbb/process_escape_sequence.c | 73 | ||||
-rw-r--r-- | libbb/xgetcwd.c | 52 | ||||
-rw-r--r-- | pwd.c | 16 | ||||
-rw-r--r-- | sh.c | 37 | ||||
-rw-r--r-- | shell/cmdedit.c | 249 | ||||
-rw-r--r-- | shell/lash.c | 37 | ||||
-rw-r--r-- | tr.c | 2 |
30 files changed, 500 insertions, 513 deletions
@@ -73,3 +73,6 @@ Charles P. Wright <cpwright@villagenet.com> Enrique Zanardi <ezanardi@ull.es> tarcat (since removed), loadkmap, various fixes, Debian maintenance +Vladimir Oleynik <dzo@simtreas.ru> + cmdedit, stty-port, locale, various fixes + and irreconcilable critic of everything not perfect. @@ -42,12 +42,15 @@ for init.c * Glenn McGrath -- Fixed problems with dpkg and dpkg-deb applets * Glenn McGrath -- Don't try to automount devfs - * Vladimir N. Oleynik -- optimizations for more.c - * Vladimir N. Oleynik -- Added locale support to the shell. - * Vladimir N. Oleynik -- moved struct applet from busybox.c to applets.c - * Vladimir N. Oleynik -- A size optimization for rdate - * Vladimir N. Oleynik -- Fixed printf applets's locale handling - * Vladimir N. Oleynik -- More cmdedit updates + * Vladimir Oleynik -- optimizations for more.c + * Vladimir Oleynik -- Added locale support to the shell, and fixed + locale support in several other places + * Vladimir Oleynik -- moved struct applet from busybox.c to applets.c + * Vladimir Oleynik -- A size optimization for rdate + * Vladimir Oleynik -- Fixed printf applets's locale handling + * Vladimir Oleynik -- More cmdedit updates + * Vladimir Oleynik -- Fixed `du' applet so it continues running + after permission errors. * Pierre Peiffer <pierre.peiffer@sxb.bsf.alcatel.fr> -- made find_pid_by_name() cope with swapped out processes. * Jari Ruusu <jari.ruusu@pp.inet.fi> -- updates so that setting @@ -349,6 +349,9 @@ #define BB_FEATURE_VI_SET // :set #define BB_FEATURE_VI_WIN_RESIZE // handle window resize // +// Enable a if you system have setuped locale +//#define BB_LOCALE_SUPPORT +// // End of Features List // // @@ -245,7 +245,8 @@ my_getgrgid.c my_getpwnamegid.c my_getpwuid.c my_getgrnam.c my_getpwnam.c \ recursive_action.c safe_read.c safe_strncpy.c syscalls.c module_syscalls.c \ syslog_msg_with_name.c time_string.c trim.c vdprintf.c wfopen.c xfuncs.c \ xregcomp.c error_msg_and_die.c perror_msg.c perror_msg_and_die.c \ -verror_msg.c vperror_msg.c mtab.c mtab_file.c +verror_msg.c vperror_msg.c mtab.c mtab_file.c xgetcwd.c concat_path_file.c + LIBBB_OBJS=$(patsubst %.c,$(LIBBB)/%.o, $(LIBBB_CSRC)) LIBBB_CFLAGS = -I$(LIBBB) ifneq ($(strip $(BB_SRC_DIR)),) diff --git a/applets/busybox.c b/applets/busybox.c index 5085556d6..9db26df27 100644 --- a/applets/busybox.c +++ b/applets/busybox.c @@ -10,6 +10,10 @@ #define BB_DECLARE_EXTERN #include "messages.c" +#ifdef BB_LOCALE_SUPPORT +#include <locale.h> +#endif + int been_there_done_that = 0; /* Also used in applets.c */ const char *applet_name; @@ -60,7 +64,7 @@ static void install_links(const char *busybox, int use_symbolic_links) { __link_f Link = link; - char command[256]; + char *fpc; int i; int rc; @@ -68,13 +72,13 @@ static void install_links(const char *busybox, int use_symbolic_links) Link = symlink; for (i = 0; applets[i].name != NULL; i++) { - sprintf ( command, "%s/%s", - install_dir[applets[i].location], applets[i].name); - rc = Link(busybox, command); - - if (rc) { - perror_msg("%s", command); + fpc = concat_path_file( + install_dir[applets[i].location], applets[i].name); + rc = Link(busybox, fpc); + if (rc!=0 && errno!=EEXIST) { + perror_msg("%s", fpc); } + free(fpc); } } @@ -97,6 +101,11 @@ int main(int argc, char **argv) } #endif +#ifdef BB_LOCALE_SUPPORT + if(getpid()!=1) /* Do not set locale for `init' */ + setlocale(LC_ALL, ""); +#endif + run_applet_by_name(applet_name, argc, argv); error_msg_and_die("applet not found"); } diff --git a/archival/dpkg.c b/archival/dpkg.c index 57b31697b..5687e00be 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c @@ -20,7 +20,7 @@ #define DODEPENDS 1 /* Should we do debugging? */ -#define DODEBUG 1 +//#define DODEBUG 1 #ifdef DODEBUG #define SYSTEM(x) do_system(x) @@ -274,7 +274,7 @@ static package_t *depends_resolve(package_t *pkgs, void *status) if (strcmp(chk->package, dependsvec[i]) == 0 || (chk->provides && strncmp(chk->provides, dependsvec[i], strlen(dependsvec[i])) == 0)) { if (chk->requiredcount >= DEPENDSMAX) { - fprintf(stderr, "Too many dependencies for %s\n", chk->package); + error_msg("Too many dependencies for %s", chk->package); return 0; } if (chk != pkg) { @@ -284,7 +284,7 @@ static package_t *depends_resolve(package_t *pkgs, void *status) } } if (chk == 0) { - fprintf(stderr, "%s depends on %s, but it is not going to be installed\n", pkg->package, dependsvec[i]); + error_msg("%s depends on %s, but it is not going to be installed", pkg->package, dependsvec[i]); return 0; } } @@ -382,7 +382,7 @@ static void *status_read(void) printf("(Reading database...)\n"); } - if ((f = fopen(statusfile, "r")) == NULL) { + if ((f = wfopen(statusfile, "r")) == NULL) { return(NULL); } @@ -483,8 +483,7 @@ static int status_merge(void *status, package_t *pkgs) status_words_flag[statpkg->status_flag - 1], status_words_status[statpkg->status_status - 1]); } - fputs(line, fout); - fputc('\n', fout); + fprintf(fout, "%s\n", line); } fclose(fin); } @@ -551,7 +550,7 @@ static int dpkg_doconfigure(package_t *pkg) if (is_file(postinst)) { snprintf(buf, sizeof(buf), "%s configure", postinst); if ((r = do_system(buf)) != 0) { - fprintf(stderr, "postinst exited with status %d\n", r); + error_msg("postinst exited with status %d\n", r); pkg->status_status = status_status_halfconfigured; return 1; } @@ -565,7 +564,7 @@ static int dpkg_dounpack(package_t *pkg) { int r = 0, i; int status = TRUE; - char *cwd; + char *cwd = xgetcwd(0); char *src_file = NULL; char *dst_file = NULL; // char *lst_file = NULL; @@ -574,7 +573,8 @@ static int dpkg_dounpack(package_t *pkg) DPRINTF("Unpacking %s\n", pkg->package); - cwd = getcwd(0, 0); + if(cwd==NULL) + exit(EXIT_FAILURE); chdir("/"); deb_extract(dpkg_deb_extract, "/", pkg->file); @@ -714,7 +714,7 @@ static int dpkg_configure(package_t *pkgs, void *status) found = tfind(pkg, &status, package_compare); if (found == 0) { - fprintf(stderr, "Trying to configure %s, but it is not installed\n", pkg->package); + error_msg("Trying to configure %s, but it is not installed", pkg->package); r = 1; } /* configure the package listed in the status file; @@ -10,6 +10,10 @@ #define BB_DECLARE_EXTERN #include "messages.c" +#ifdef BB_LOCALE_SUPPORT +#include <locale.h> +#endif + int been_there_done_that = 0; /* Also used in applets.c */ const char *applet_name; @@ -60,7 +64,7 @@ static void install_links(const char *busybox, int use_symbolic_links) { __link_f Link = link; - char command[256]; + char *fpc; int i; int rc; @@ -68,13 +72,13 @@ static void install_links(const char *busybox, int use_symbolic_links) Link = symlink; for (i = 0; applets[i].name != NULL; i++) { - sprintf ( command, "%s/%s", - install_dir[applets[i].location], applets[i].name); - rc = Link(busybox, command); - - if (rc) { - perror_msg("%s", command); + fpc = concat_path_file( + install_dir[applets[i].location], applets[i].name); + rc = Link(busybox, fpc); + if (rc!=0 && errno!=EEXIST) { + perror_msg("%s", fpc); } + free(fpc); } } @@ -97,6 +101,11 @@ int main(int argc, char **argv) } #endif +#ifdef BB_LOCALE_SUPPORT + if(getpid()!=1) /* Do not set locale for `init' */ + setlocale(LC_ALL, ""); +#endif + run_applet_by_name(applet_name, argc, argv); error_msg_and_die("applet not found"); } @@ -31,8 +31,6 @@ */ -//#define TEST - #include <stdio.h> #include <errno.h> #include <unistd.h> @@ -43,10 +41,16 @@ #include <signal.h> #include <limits.h> -#ifndef TEST - #include "busybox.h" +#ifdef BB_LOCALE_SUPPORT +#define Isprint(c) isprint((c)) +#else +#define Isprint(c) ( (c) >= ' ' && (c) != ((unsigned char)'\233') ) +#endif + +#ifndef TEST + #define D(x) #else @@ -59,13 +63,6 @@ #define D(x) x -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - #endif /* TEST */ #ifdef BB_FEATURE_COMMAND_TAB_COMPLETION @@ -92,29 +89,6 @@ #endif /* advanced FEATURES */ -#ifdef TEST -void *xrealloc(void *old, size_t size) -{ - return realloc(old, size); -} - -void *xmalloc(size_t size) -{ - return malloc(size); -} -char *xstrdup(const char *s) -{ - return strdup(s); -} - -void *xcalloc(size_t size, size_t se) -{ - return calloc(size, se); -} - -#define error_msg(s, d) fprintf(stderr, s, d) -#endif /* TEST */ - struct history { char *s; @@ -238,7 +212,7 @@ static void win_changed(int nsig) static void cmdedit_reset_term(void) { if ((handlers_sets & SET_RESET_TERM) != 0) { - /* sparc and other have broken termios support: use old termio handling. */ +/* sparc and other have broken termios support: use old termio handling. */ setTermSettings(fileno(stdin), (void *) &initial_settings); handlers_sets &= ~SET_RESET_TERM; } @@ -270,9 +244,9 @@ static void cmdedit_set_out_char(int next_char) int c = (int)((unsigned char) command_ps[cursor]); if (c == 0) - c = ' '; /* destroy end char? */ + c = ' '; /* destroy end char? */ #ifdef BB_FEATURE_NONPRINTABLE_INVERSE_PUT - if (!isprint(c)) { /* Inverse put non-printable characters */ + if (!Isprint(c)) { /* Inverse put non-printable characters */ if (c >= 128) c -= 128; if (c < ' ') @@ -328,7 +302,7 @@ static void input_backward(int num) { if (num > cursor) num = cursor; - cursor -= num; /* new cursor (in command, not terminal) */ + cursor -= num; /* new cursor (in command, not terminal) */ if (cmdedit_x >= num) { /* no to up line */ cmdedit_x -= num; @@ -369,147 +343,116 @@ static void parse_prompt(const char *prmt_ptr) put_prompt(); } #else -static void add_to_prompt(char **prmt_mem_ptr, int *alm, - int *prmt_len, const char *addb) -{ - *prmt_len += strlen(addb); - if (*alm < (*prmt_len) + 1) { - *alm = (*prmt_len) + 1; - *prmt_mem_ptr = xrealloc(*prmt_mem_ptr, *alm); - } - strcat(*prmt_mem_ptr, addb); -} - static void parse_prompt(const char *prmt_ptr) { - int alm = strlen(prmt_ptr) + 1; /* supposedly require memory */ int prmt_len = 0; int sub_len = 0; - int flg_not_length = '['; - char *prmt_mem_ptr = xstrdup(prmt_ptr); - char pwd_buf[PATH_MAX + 1]; - char buf[16]; - int c; - - pwd_buf[0] = 0; - *prmt_mem_ptr = 0; + char flg_not_length = '['; + char *prmt_mem_ptr = xcalloc(1, 1); + char *pwd_buf = xgetcwd(0); + char buf2[PATH_MAX + 1]; + char buf[2]; + char c; + char *pbuf; while (*prmt_ptr) { + pbuf = buf; + pbuf[1] = 0; c = *prmt_ptr++; if (c == '\\') { - c = *prmt_ptr; - if (c == 0) + const char *cp = prmt_ptr; + int l; + + c = process_escape_sequence(&prmt_ptr); + if(prmt_ptr==cp) { + if (*cp == 0) break; - prmt_ptr++; - switch (c) { + c = *prmt_ptr++; + switch (c) { #ifdef BB_FEATURE_GETUSERNAME_AND_HOMEDIR - case 'u': - add_to_prompt(&prmt_mem_ptr, &alm, &prmt_len, user_buf); - continue; + case 'u': + pbuf = user_buf; + break; #endif - case 'h': - if (hostname_buf[0] == 0) { - hostname_buf = xcalloc(256, 1); - if (gethostname(hostname_buf, 255) < 0) { - strcpy(hostname_buf, "?"); + case 'h': + pbuf = hostname_buf; + if (*pbuf == 0) { + pbuf = xcalloc(256, 1); + if (gethostname(pbuf, 255) < 0) { + strcpy(pbuf, "?"); } else { - char *s = strchr(hostname_buf, '.'); + char *s = strchr(pbuf, '.'); if (s) *s = 0; } + hostname_buf = pbuf; } - add_to_prompt(&prmt_mem_ptr, &alm, &prmt_len, - hostname_buf); - continue; - case '$': + break; + case '$': c = my_euid == 0 ? '#' : '$'; break; #ifdef BB_FEATURE_GETUSERNAME_AND_HOMEDIR - case 'w': - if (pwd_buf[0] == 0) { - int l; - - getcwd(pwd_buf, PATH_MAX); - l = strlen(home_pwd_buf); - if (home_pwd_buf[0] != 0 && - strncmp(home_pwd_buf, pwd_buf, l) == 0) { - strcpy(pwd_buf + 1, pwd_buf + l); - pwd_buf[0] = '~'; + case 'w': + pbuf = pwd_buf; + l = strlen(home_pwd_buf); + if (home_pwd_buf[0] != 0 && + strncmp(home_pwd_buf, pbuf, l) == 0 && + (pbuf[l]=='/' || pbuf[l]=='\0') && + strlen(pwd_buf+l)<PATH_MAX) { + pbuf = buf2; + *pbuf = '~'; + strcpy(pbuf+1, pwd_buf+l); } - } - add_to_prompt(&prmt_mem_ptr, &alm, &prmt_len, pwd_buf); - continue; + break; #endif - case 'W': - if (pwd_buf[0] == 0) { - char *z; - - getcwd(pwd_buf, PATH_MAX); - z = strrchr(pwd_buf,'/'); - if ( (z != NULL) && (z != pwd_buf) ) { - z++; - strcpy(pwd_buf,z); - } - } - add_to_prompt(&prmt_mem_ptr, &alm, &prmt_len, pwd_buf); - continue; - case '!': - snprintf(buf, sizeof(buf), "%d", num_ok_lines); - add_to_prompt(&prmt_mem_ptr, &alm, &prmt_len, buf); - continue; - case 'e': - case 'E': /* \e \E = \033 */ + case 'W': + pbuf = pwd_buf; + cp = strrchr(pbuf,'/'); + if ( (cp != NULL) && (cp != pbuf) ) + pbuf += (cp-pbuf)+1; + break; + case '!': + snprintf(pbuf = buf2, sizeof(buf2), "%d", num_ok_lines); + break; + case 'e': case 'E': /* \e \E = \033 */ c = '\033'; break; - case 'x': - case 'X': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7':{ - int l; - int ho = 0; - char *eho; - - if (c == 'X') - c = 'x'; - + case 'x': case 'X': for (l = 0; l < 3;) { - - buf[l++] = *prmt_ptr; - buf[l] = 0; - ho = strtol(buf, &eho, c == 'x' ? 16 : 8); - if (ho > UCHAR_MAX || (eho - buf) < l) { + int h; + buf2[l++] = *prmt_ptr; + buf2[l] = 0; + h = strtol(buf2, &pbuf, 16); + if (h > UCHAR_MAX || (pbuf - buf2) < l) { l--; break; } prmt_ptr++; } - buf[l] = 0; - ho = strtol(buf, 0, c == 'x' ? 16 : 8); - c = ho == 0 ? '?' : (char) ho; + buf2[l] = 0; + c = (char)strtol(buf2, 0, 16); + if(c==0) + c = '?'; + pbuf = buf; break; - } - case '[': - case ']': + case '[': case ']': if (c == flg_not_length) { flg_not_length = flg_not_length == '[' ? ']' : '['; continue; } break; - } + } + } } - buf[0] = c; - buf[1] = 0; - add_to_prompt(&prmt_mem_ptr, &alm, &prmt_len, buf); + if(pbuf == buf) + *pbuf = c; + prmt_len += strlen(pbuf); + prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf); if (flg_not_length == ']') sub_len++; } + free(pwd_buf); cmdedit_prompt = prmt_mem_ptr; cmdedit_prmt_len = prmt_len - sub_len; put_prompt(); @@ -789,7 +732,7 @@ static char **exe_n_cwd_tab_completion(char *command, int *num_matches, char **paths = path1; int npaths; int i; - char found[BUFSIZ + 4 + PATH_MAX]; + char *found; char *pfind = strrchr(command, '/'); path1[0] = "."; @@ -822,7 +765,6 @@ static char **exe_n_cwd_tab_completion(char *command, int *num_matches, continue; while ((next = readdir(dir)) != NULL) { - const char *str_merge = "%s/%s"; char *str_found = next->d_name; /* matched ? */ @@ -835,25 +777,23 @@ static char **exe_n_cwd_tab_completion(char *command, int *num_matches, else continue; } - if (paths[i][strlen(paths[i]) - 1] == '/') - str_merge = "%s%s"; - sprintf(found, str_merge, paths[i], str_found); + found = concat_path_file(paths[i], str_found); /* hmm, remover in progress? */ - if (stat(found, &st) < 0) - continue; + if (stat(found, &st) < 0) + goto cont; /* find with dirs ? */ if (paths[i] != dirbuf) strcpy(found, next->d_name); /* only name */ if (S_ISDIR(st.st_mode)) { /* name is directory */ - /* algorithmic only "/" ? */ - if (*str_found) - strcat(found, "/"); + str_found = found; + found = concat_path_file(found, ""); + free(str_found); str_found = add_quote_for_spec_chars(found); } else { /* not put found file if search only dirs for cd */ - if (type == FIND_DIR_ONLY) - continue; + if (type == FIND_DIR_ONLY) + goto cont; str_found = add_quote_for_spec_chars(found); if (type == FIND_FILE_ONLY || (type == FIND_EXE_ONLY && is_execute(&st) == TRUE)) @@ -863,6 +803,8 @@ static char **exe_n_cwd_tab_completion(char *command, int *num_matches, matches = xrealloc(matches, (nm + 1) * sizeof(char *)); matches[nm++] = str_found; +cont: + free(found); } closedir(dir); } @@ -1440,7 +1382,7 @@ extern void cmdedit_read_input(char *prompt, char command[BUFSIZ]) } } else #endif - if (!isprint(c)) /* Skip non-printable characters */ + if (!Isprint(c)) /* Skip non-printable characters */ break; if (len >= (BUFSIZ - 2)) /* Need to leave space for enter */ @@ -1554,6 +1496,9 @@ extern void cmdedit_terminate(void) #ifdef TEST +const char *applet_name = "debug stuff usage"; +const char *memory_exhausted = "Memory exhausted"; + #ifdef BB_FEATURE_NONPRINTABLE_INVERSE_PUT #include <locale.h> #endif diff --git a/coreutils/du.c b/coreutils/du.c index 7cb888de8..119895e49 100644 --- a/coreutils/du.c +++ b/coreutils/du.c @@ -83,7 +83,8 @@ static long du(char *filename) int len; if ((lstat(filename, &statbuf)) != 0) { - perror_msg_and_die("%s", filename); + perror_msg("%s", filename); + return 0; } du_depth++; @@ -110,22 +111,16 @@ static long du(char *filename) filename[--len] = '\0'; while ((entry = readdir(dir))) { - char newfile[BUFSIZ + 1]; + char *newfile; char *name = entry->d_name; if ((strcmp(name, "..") == 0) || (strcmp(name, ".") == 0)) { continue; } - - if (len + strlen(name) + 1 > BUFSIZ) { - error_msg(name_too_long); - du_depth--; - return 0; - } - sprintf(newfile, "%s/%s", filename, name); - + newfile = concat_path_file(filename, name); sum += du(newfile); + free(newfile); } closedir(dir); print(sum, filename); @@ -197,7 +192,7 @@ int du_main(int argc, char **argv) return status; } -/* $Id: du.c,v 1.43 2001/03/09 14:36:42 andersen Exp $ */ +/* $Id: du.c,v 1.44 2001/04/09 22:48:11 andersen Exp $ */ /* Local Variables: c-file-style: "linux" diff --git a/coreutils/echo.c b/coreutils/echo.c index 1ca373467..31c031528 100644 --- a/coreutils/echo.c +++ b/coreutils/echo.c @@ -81,7 +81,7 @@ echo_main(int argc, char** argv) just_echo: while (argc > 0) { - char *arg = argv[0]; + const char *arg = argv[0]; register int c; while ((c = *arg++)) { diff --git a/coreutils/pwd.c b/coreutils/pwd.c index 2f36b1f05..f6a00bf1e 100644 --- a/coreutils/pwd.c +++ b/coreutils/pwd.c @@ -32,11 +32,13 @@ extern int pwd_main(int argc, char **argv) { - char buf[BUFSIZ + 1]; - - if (getcwd(buf, sizeof(buf)) == NULL) - perror_msg_and_die("getcwd"); - - puts(buf); - return EXIT_SUCCESS; + static char *buf; + + buf = xgetcwd(buf); + + if (buf != NULL) { + puts(buf); + return EXIT_SUCCESS; + } + return EXIT_FAILURE; } diff --git a/coreutils/tr.c b/coreutils/tr.c index 32a4f2917..ce15cfdf8 100644 --- a/coreutils/tr.c +++ b/coreutils/tr.c @@ -93,7 +93,7 @@ static void map(register unsigned char *string1, unsigned int string1_len, } } -static unsigned int expand(char *arg, register unsigned char *buffer) +static unsigned int expand(const char *arg, register unsigned char *buffer) { unsigned char *buffer_start = buffer; int i, ac; @@ -256,18 +256,16 @@ extern int cp_mv_main(int argc, char **argv) int state = 0; char *pushd, *d, *p; - if ((pushd = getcwd(NULL, BUFSIZ + 1)) == NULL) { - perror_msg("getcwd()"); + if ((pushd = xgetcwd(0)) == NULL) continue; - } + if (chdir(baseDestName) < 0) { perror_msg("chdir(%s)", baseSrcName); continue; } - if ((d = getcwd(NULL, BUFSIZ + 1)) == NULL) { - perror_msg("getcwd()"); + if ((d = xgetcwd(0)) == NULL) continue; - } + while (!state && *d != '\0') { if (stat(d, &sb) < 0) { /* stat not lstat - always dereference targets */ perror_msg("stat(%s)", d); diff --git a/docs/busybox.pod b/docs/busybox.pod index 8283e4717..56a22b891 100644 --- a/docs/busybox.pod +++ b/docs/busybox.pod @@ -2505,6 +2505,13 @@ Glenn McGrath <bug1@netconnect.com.au> =for html <br> +Vladimir Oleynik <dzo@simtreas.ru> + + cmdedit, stty-port, locale, various fixes + and irreconcilable critic of everything not perfect. + +=for html <br> + Bruce Perens <bruce@pixar.com> Original author of BusyBox. His code is still in many apps. @@ -2553,4 +2560,4 @@ Enrique Zanardi <ezanardi@ull.es> =cut -# $Id: busybox.pod,v 1.96 2001/04/05 21:45:54 andersen Exp $ +# $Id: busybox.pod,v 1.97 2001/04/09 22:48:11 andersen Exp $ diff --git a/docs/busybox_footer.pod b/docs/busybox_footer.pod index 961f027cd..759f127e5 100644 --- a/docs/busybox_footer.pod +++ b/docs/busybox_footer.pod @@ -96,6 +96,13 @@ Glenn McGrath <bug1@netconnect.com.au> =for html <br> +Vladimir Oleynik <dzo@simtreas.ru> + + cmdedit, stty-port, locale, various fixes + and irreconcilable critic of everything not perfect. + +=for html <br> + Bruce Perens <bruce@pixar.com> Original author of BusyBox. His code is still in many apps. @@ -144,4 +151,4 @@ Enrique Zanardi <ezanardi@ull.es> =cut -# $Id: busybox_footer.pod,v 1.1 2001/04/05 19:41:23 beppu Exp $ +# $Id: busybox_footer.pod,v 1.2 2001/04/09 22:48:11 andersen Exp $ @@ -20,7 +20,7 @@ #define DODEPENDS 1 /* Should we do debugging? */ -#define DODEBUG 1 +//#define DODEBUG 1 #ifdef DODEBUG #define SYSTEM(x) do_system(x) @@ -274,7 +274,7 @@ static package_t *depends_resolve(package_t *pkgs, void *status) if (strcmp(chk->package, dependsvec[i]) == 0 || (chk->provides && strncmp(chk->provides, dependsvec[i], strlen(dependsvec[i])) == 0)) { if (chk->requiredcount >= DEPENDSMAX) { - fprintf(stderr, "Too many dependencies for %s\n", chk->package); + error_msg("Too many dependencies for %s", chk->package); return 0; } if (chk != pkg) { @@ -284,7 +284,7 @@ static package_t *depends_resolve(package_t *pkgs, void *status) } } if (chk == 0) { - fprintf(stderr, "%s depends on %s, but it is not going to be installed\n", pkg->package, dependsvec[i]); + error_msg("%s depends on %s, but it is not going to be installed", pkg->package, dependsvec[i]); return 0; } } @@ -382,7 +382,7 @@ static void *status_read(void) printf("(Reading database...)\n"); } - if ((f = fopen(statusfile, "r")) == NULL) { + if ((f = wfopen(statusfile, "r")) == NULL) { return(NULL); } @@ -483,8 +483,7 @@ static int status_merge(void *status, package_t *pkgs) status_words_flag[statpkg->status_flag - 1], status_words_status[statpkg->status_status - 1]); } - fputs(line, fout); - fputc('\n', fout); + fprintf(fout, "%s\n", line); } fclose(fin); } @@ -551,7 +550,7 @@ static int dpkg_doconfigure(package_t *pkg) if (is_file(postinst)) { snprintf(buf, sizeof(buf), "%s configure", postinst); if ((r = do_system(buf)) != 0) { - fprintf(stderr, "postinst exited with status %d\n", r); + error_msg("postinst exited with status %d\n", r); pkg->status_status = status_status_halfconfigured; return 1; } @@ -565,7 +564,7 @@ static int dpkg_dounpack(package_t *pkg) { int r = 0, i; int status = TRUE; - char *cwd; + char *cwd = xgetcwd(0); char *src_file = NULL; char *dst_file = NULL; // char *lst_file = NULL; @@ -574,7 +573,8 @@ static int dpkg_dounpack(package_t *pkg) DPRINTF("Unpacking %s\n", pkg->package); - cwd = getcwd(0, 0); + if(cwd==NULL) + exit(EXIT_FAILURE); chdir("/"); deb_extract(dpkg_deb_extract, "/", pkg->file); @@ -714,7 +714,7 @@ static int dpkg_configure(package_t *pkgs, void *status) found = tfind(pkg, &status, package_compare); if (found == 0) { - fprintf(stderr, "Trying to configure %s, but it is not installed\n", pkg->package); + error_msg("Trying to configure %s, but it is not installed", pkg->package); r = 1; } /* configure the package listed in the status file; @@ -83,7 +83,8 @@ static long du(char *filename) int len; if ((lstat(filename, &statbuf)) != 0) { - perror_msg_and_die("%s", filename); + perror_msg("%s", filename); + return 0; } du_depth++; @@ -110,22 +111,16 @@ static long du(char *filename) filename[--len] = '\0'; while ((entry = readdir(dir))) { - char newfile[BUFSIZ + 1]; + char *newfile; char *name = entry->d_name; if ((strcmp(name, "..") == 0) || (strcmp(name, ".") == 0)) { continue; } - - if (len + strlen(name) + 1 > BUFSIZ) { - error_msg(name_too_long); - du_depth--; - return 0; - } - sprintf(newfile, "%s/%s", filename, name); - + newfile = concat_path_file(filename, name); sum += du(newfile); + free(newfile); } closedir(dir); print(sum, filename); @@ -197,7 +192,7 @@ int du_main(int argc, char **argv) return status; } -/* $Id: du.c,v 1.43 2001/03/09 14:36:42 andersen Exp $ */ +/* $Id: du.c,v 1.44 2001/04/09 22:48:11 andersen Exp $ */ /* Local Variables: c-file-style: "linux" @@ -81,7 +81,7 @@ echo_main(int argc, char** argv) just_echo: while (argc > 0) { - char *arg = argv[0]; + const char *arg = argv[0]; register int c; while ((c = *arg++)) { diff --git a/include/libbb.h b/include/libbb.h index 05f61f25b..0001cac6f 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -131,7 +131,7 @@ extern int find_real_root_device_name(char* name); extern char *get_line_from_file(FILE *file); extern void print_file(FILE *file); extern int print_file_by_name(char *filename); -extern char process_escape_sequence(char **ptr); +extern char process_escape_sequence(const char **ptr); extern char *get_last_path_component(char *path); extern FILE *wfopen(const char *path, const char *mode); extern FILE *xfopen(const char *path, const char *mode); @@ -150,7 +150,7 @@ extern char *xstrndup (const char *s, int n); extern char * safe_strncpy(char *dst, const char *src, size_t size); struct suffix_mult { - char *suffix; + const char *suffix; int mult; }; @@ -213,4 +213,7 @@ enum { int ask_confirmation(void); int klogctl(int type, char * b, int len); +char *xgetcwd(char *cwd); +char *concat_path_file(const char *path, const char *filename); + #endif /* __LIBBB_H__ */ @@ -64,7 +64,10 @@ #include <sys/wait.h> #include <unistd.h> #include <getopt.h> + +#ifdef BB_LOCALE_SUPPORT #include <locale.h> +#endif //#define BB_FEATURE_SH_WORDEXP @@ -80,7 +83,6 @@ #include "cmdedit.h" -static const int MAX_LINE = 256; /* size of input buffer for cwd data */ static const int MAX_READ = 128; /* size of input buffer for `read' builtin */ #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" @@ -230,7 +232,7 @@ static char syntax_err[]="syntax error near unexpected token"; #endif static char *PS1; -static char *PS2; +static char *PS2 = "> "; #ifdef DEBUG_SHELL @@ -294,7 +296,7 @@ static int builtin_cd(struct child_prog *child) printf("cd: %s: %m\n", newdir); return EXIT_FAILURE; } - getcwd(cwd, sizeof(char)*MAX_LINE); + cwd = xgetcwd(cwd); return EXIT_SUCCESS; } @@ -410,7 +412,6 @@ static int builtin_jobs(struct child_prog *child) /* built-in 'pwd' handler */ static int builtin_pwd(struct child_prog *dummy) { - getcwd(cwd, MAX_LINE); printf( "%s\n", cwd); return EXIT_SUCCESS; } @@ -434,13 +435,14 @@ static int builtin_export(struct child_prog *child) #ifndef BB_FEATURE_SH_SIMPLE_PROMPT if (strncmp(v, "PS1=", 4)==0) PS1 = getenv("PS1"); - else if (strncmp(v, "PS2=", 4)==0) - PS2 = getenv("PS2"); #endif + +#ifdef BB_LOCALE_SUPPORT if(strncmp(v, "LC_ALL=", 7)==0) setlocale(LC_ALL, getenv("LC_ALL")); if(strncmp(v, "LC_CTYPE=", 9)==0) setlocale(LC_CTYPE, getenv("LC_CTYPE")); +#endif return (res); } @@ -623,10 +625,7 @@ static int builtin_unset(struct child_prog *child) */ static int run_command_predicate(char *cmd) { - int n=strlen(cmd); - local_pending_command = xmalloc(n+1); - strncpy(local_pending_command, cmd, n); - local_pending_command[n]='\0'; + local_pending_command = xstrdup(cmd); return( busy_loop(NULL)); } #endif @@ -808,15 +807,10 @@ static inline void cmdedit_set_initial_prompt(void) { #ifdef BB_FEATURE_SH_SIMPLE_PROMPT PS1 = NULL; - PS2 = "> "; #else PS1 = getenv("PS1"); - if(PS1==0) { + if(PS1==0) PS1 = "\\w \\$ "; - } - PS2 = getenv("PS2"); - if(PS2==0) - PS2 = "> "; #endif } @@ -954,7 +948,7 @@ static int expand_arguments(char *command) /* Fix up escape sequences to be the Real Thing(tm) */ while( command && command[ix]) { if (command[ix] == '\\') { - char *tmp = command+ix+1; + const char *tmp = command+ix+1; command[ix] = process_escape_sequence( &tmp ); memmove(command+ix + 1, tmp, strlen(tmp)+1); } @@ -1829,8 +1823,10 @@ static int busy_loop(FILE * input) #ifdef BB_FEATURE_CLEAN_UP void free_memory(void) { - if (cwd) + if (cwd) { free(cwd); + cwd = NULL; + } if (local_pending_command) free(local_pending_command); @@ -1850,7 +1846,6 @@ int shell_main(int argc_l, char **argv_l) /* These variables need re-initializing when recursing */ shell_context = 0; - cwd=NULL; local_pending_command = NULL; close_me_head = NULL; job_list.head = NULL; @@ -1921,8 +1916,7 @@ int shell_main(int argc_l, char **argv_l) } /* initialize the cwd -- this is never freed...*/ - cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1); - getcwd(cwd, sizeof(char)*MAX_LINE); + cwd = xgetcwd(0); #ifdef BB_FEATURE_CLEAN_UP atexit(free_memory); @@ -1932,7 +1926,6 @@ int shell_main(int argc_l, char **argv_l) cmdedit_set_initial_prompt(); #else PS1 = NULL; - PS2 = "> "; #endif return (busy_loop(input)); diff --git a/libbb/concat_path_file.c b/libbb/concat_path_file.c new file mode 100644 index 000000000..d53dc0e2e --- /dev/null +++ b/libbb/concat_path_file.c @@ -0,0 +1,24 @@ +/* + * busybox library eXtendet funcion + * + * concatenate path and file name to new allocation buffer, + * not addition '/' if path name already have '/' + * +*/ + +#include "libbb.h" + +extern char *concat_path_file(const char *path, const char *filename) +{ + char *outbuf; + int l; + int flg_slash = 1; + + l = strlen(path); + if(l>0 && path[l-1] == '/') + flg_slash--; + l += strlen(filename); + outbuf = xmalloc(l+1+flg_slash); + sprintf(outbuf, (flg_slash ? "%s/%s" : "%s%s"), path, filename); + return outbuf; +} diff --git a/libbb/libbb.h b/libbb/libbb.h index 05f61f25b..0001cac6f 100644 --- a/libbb/libbb.h +++ b/libbb/libbb.h @@ -131,7 +131,7 @@ extern int find_real_root_device_name(char* name); extern char *get_line_from_file(FILE *file); extern void print_file(FILE *file); extern int print_file_by_name(char *filename); -extern char process_escape_sequence(char **ptr); +extern char process_escape_sequence(const char **ptr); extern char *get_last_path_component(char *path); extern FILE *wfopen(const char *path, const char *mode); extern FILE *xfopen(const char *path, const char *mode); @@ -150,7 +150,7 @@ extern char *xstrndup (const char *s, int n); extern char * safe_strncpy(char *dst, const char *src, size_t size); struct suffix_mult { - char *suffix; + const char *suffix; int mult; }; @@ -213,4 +213,7 @@ enum { int ask_confirmation(void); int klogctl(int type, char * b, int len); +char *xgetcwd(char *cwd); +char *concat_path_file(const char *path, const char *filename); + #endif /* __LIBBB_H__ */ diff --git a/libbb/print_file.c b/libbb/print_file.c index 52a39774f..b47723454 100644 --- a/libbb/print_file.c +++ b/libbb/print_file.c @@ -2,9 +2,7 @@ /* * Utility routines. * - * Copyright (C) tons of folks. Tracking down who wrote what - * isn't something I'm going to worry about... If you wrote something - * here, please feel free to acknowledge your work. + * Copyright (C) 1999-2001 Erik Andersen <andersee@debian.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,13 +17,10 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Based in part on code from sash, Copyright (c) 1999 by David I. Bell - * Permission has been granted to redistribute this code under the GPL. - * */ #include <stdio.h> +#include <sys/stat.h> #include "libbb.h" @@ -41,11 +36,21 @@ extern void print_file(FILE *file) extern int print_file_by_name(char *filename) { - FILE *file; - if ((file = wfopen(filename, "r")) == NULL) - return FALSE; - print_file(file); - return TRUE; + struct stat statBuf; + int status = TRUE; + + if(is_directory(filename, TRUE, &statBuf)==TRUE) { + error_msg("%s: Is directory", filename); + status = FALSE; + } else { + FILE *f = wfopen(filename, "r"); + if(f!=NULL) + print_file(f); + else + status = FALSE; + } + + return status; } diff --git a/libbb/process_escape_sequence.c b/libbb/process_escape_sequence.c index ad2be94ee..67b0490ce 100644 --- a/libbb/process_escape_sequence.c +++ b/libbb/process_escape_sequence.c @@ -2,9 +2,8 @@ /* * Utility routines. * - * Copyright (C) tons of folks. Tracking down who wrote what - * isn't something I'm going to worry about... If you wrote something - * here, please feel free to acknowledge your work. + * Copyright (C) Manuel Nova III <mnovoa3@bellsouth.net> + * and Vladimir Oleynik <vodz@usa.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,9 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * Based in part on code from sash, Copyright (c) 1999 by David I. Bell - * Permission has been granted to redistribute this code under the GPL. - * + * */ #include <stdio.h> @@ -31,45 +28,45 @@ -char process_escape_sequence(char **ptr) +char process_escape_sequence(const char **ptr) { - static const char charmap[] = { - 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', 0, - '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '\\' }; - - const char *p; - char *q; - int num_digits; - unsigned int n; + static const char charmap[] = { + 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', 0, + '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '\\' }; - n = 0; - q = *ptr; + const char *p; + const char *q; + int num_digits; + unsigned int n; + + n = 0; + q = *ptr; - for ( num_digits = 0 ; num_digits < 3 ; ++num_digits) { - if ((*q < '0') || (*q > '7')) { /* not a digit? */ - break; - } - n = n * 8 + (*q++ - '0'); - } + for ( num_digits = 0 ; num_digits < 3 ; ++num_digits) { + if ((*q < '0') || (*q > '7')) { /* not a digit? */ + break; + } + n = n * 8 + (*q++ - '0'); + } - if (num_digits == 0) { /* mnemonic escape sequence? */ - for (p=charmap ; *p ; p++) { - if (*p == *q) { - q++; - break; - } - } - n = *(p+(sizeof(charmap)/2)); - } + if (num_digits == 0) { /* mnemonic escape sequence? */ + for (p=charmap ; *p ; p++) { + if (*p == *q) { + q++; + break; + } + } + n = *(p+(sizeof(charmap)/2)); + } /* doesn't hurt to fall through to here from mnemonic case */ - if (n > UCHAR_MAX) { /* is octal code too big for a char? */ - n /= 8; /* adjust value and */ - --q; /* back up one char */ - } + if (n > UCHAR_MAX) { /* is octal code too big for a char? */ + n /= 8; /* adjust value and */ + --q; /* back up one char */ + } - *ptr = q; - return (char) n; + *ptr = q; + return (char) n; } diff --git a/libbb/xgetcwd.c b/libbb/xgetcwd.c new file mode 100644 index 000000000..274668166 --- /dev/null +++ b/libbb/xgetcwd.c @@ -0,0 +1,52 @@ +/* + * xgetcwd.c -- return current directory with unlimited length + * Copyright (C) 1992, 1996 Free Software Foundation, Inc. + * Written by David MacKenzie <djm@gnu.ai.mit.edu>. + * + * Special function for busybox written by Vladimir Oleynik <vodz@usa.net> +*/ + +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> +#include <limits.h> +#include "libbb.h" + +/* Amount to increase buffer size by in each try. */ +#define PATH_INCR 32 + +/* Return the current directory, newly allocated, arbitrarily long. + Return NULL and set errno on error. + If argument is not NULL (previous usage allocate memory), call free() +*/ + +char * +xgetcwd (char *cwd) +{ + char *ret; + unsigned path_max; + + errno = 0; + path_max = (unsigned) PATH_MAX; + path_max += 2; /* The getcwd docs say to do this. */ + + if(cwd==0) + cwd = xmalloc (path_max); + + errno = 0; + while ((ret = getcwd (cwd, path_max)) == NULL && errno == ERANGE) { + path_max += PATH_INCR; + cwd = xrealloc (cwd, path_max); + errno = 0; + } + + if (ret == NULL) { + int save_errno = errno; + free (cwd); + errno = save_errno; + perror_msg("getcwd()"); + return NULL; + } + + return cwd; +} @@ -32,11 +32,13 @@ extern int pwd_main(int argc, char **argv) { - char buf[BUFSIZ + 1]; - - if (getcwd(buf, sizeof(buf)) == NULL) - perror_msg_and_die("getcwd"); - - puts(buf); - return EXIT_SUCCESS; + static char *buf; + + buf = xgetcwd(buf); + + if (buf != NULL) { + puts(buf); + return EXIT_SUCCESS; + } + return EXIT_FAILURE; } @@ -64,7 +64,10 @@ #include <sys/wait.h> #include <unistd.h> #include <getopt.h> + +#ifdef BB_LOCALE_SUPPORT #include <locale.h> +#endif //#define BB_FEATURE_SH_WORDEXP @@ -80,7 +83,6 @@ #include "cmdedit.h" -static const int MAX_LINE = 256; /* size of input buffer for cwd data */ static const int MAX_READ = 128; /* size of input buffer for `read' builtin */ #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" @@ -230,7 +232,7 @@ static char syntax_err[]="syntax error near unexpected token"; #endif static char *PS1; -static char *PS2; +static char *PS2 = "> "; #ifdef DEBUG_SHELL @@ -294,7 +296,7 @@ static int builtin_cd(struct child_prog *child) printf("cd: %s: %m\n", newdir); return EXIT_FAILURE; } - getcwd(cwd, sizeof(char)*MAX_LINE); + cwd = xgetcwd(cwd); return EXIT_SUCCESS; } @@ -410,7 +412,6 @@ static int builtin_jobs(struct child_prog *child) /* built-in 'pwd' handler */ static int builtin_pwd(struct child_prog *dummy) { - getcwd(cwd, MAX_LINE); printf( "%s\n", cwd); return EXIT_SUCCESS; } @@ -434,13 +435,14 @@ static int builtin_export(struct child_prog *child) #ifndef BB_FEATURE_SH_SIMPLE_PROMPT if (strncmp(v, "PS1=", 4)==0) PS1 = getenv("PS1"); - else if (strncmp(v, "PS2=", 4)==0) - PS2 = getenv("PS2"); #endif + +#ifdef BB_LOCALE_SUPPORT if(strncmp(v, "LC_ALL=", 7)==0) setlocale(LC_ALL, getenv("LC_ALL")); if(strncmp(v, "LC_CTYPE=", 9)==0) setlocale(LC_CTYPE, getenv("LC_CTYPE")); +#endif return (res); } @@ -623,10 +625,7 @@ static int builtin_unset(struct child_prog *child) */ static int run_command_predicate(char *cmd) { - int n=strlen(cmd); - local_pending_command = xmalloc(n+1); - strncpy(local_pending_command, cmd, n); - local_pending_command[n]='\0'; + local_pending_command = xstrdup(cmd); return( busy_loop(NULL)); } #endif @@ -808,15 +807,10 @@ static inline void cmdedit_set_initial_prompt(void) { #ifdef BB_FEATURE_SH_SIMPLE_PROMPT PS1 = NULL; - PS2 = "> "; #else PS1 = getenv("PS1"); - if(PS1==0) { + if(PS1==0) PS1 = "\\w \\$ "; - } - PS2 = getenv("PS2"); - if(PS2==0) - PS2 = "> "; #endif } @@ -954,7 +948,7 @@ static int expand_arguments(char *command) /* Fix up escape sequences to be the Real Thing(tm) */ while( command && command[ix]) { if (command[ix] == '\\') { - char *tmp = command+ix+1; + const char *tmp = command+ix+1; command[ix] = process_escape_sequence( &tmp ); memmove(command+ix + 1, tmp, strlen(tmp)+1); } @@ -1829,8 +1823,10 @@ static int busy_loop(FILE * input) #ifdef BB_FEATURE_CLEAN_UP void free_memory(void) { - if (cwd) + if (cwd) { free(cwd); + cwd = NULL; + } if (local_pending_command) free(local_pending_command); @@ -1850,7 +1846,6 @@ int shell_main(int argc_l, char **argv_l) /* These variables need re-initializing when recursing */ shell_context = 0; - cwd=NULL; local_pending_command = NULL; close_me_head = NULL; job_list.head = NULL; @@ -1921,8 +1916,7 @@ int shell_main(int argc_l, char **argv_l) } /* initialize the cwd -- this is never freed...*/ - cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1); - getcwd(cwd, sizeof(char)*MAX_LINE); + cwd = xgetcwd(0); #ifdef BB_FEATURE_CLEAN_UP atexit(free_memory); @@ -1932,7 +1926,6 @@ int shell_main(int argc_l, char **argv_l) cmdedit_set_initial_prompt(); #else PS1 = NULL; - PS2 = "> "; #endif return (busy_loop(input)); diff --git a/shell/cmdedit.c b/shell/cmdedit.c index a3710812f..eef1a88c8 100644 --- a/shell/cmdedit.c +++ b/shell/cmdedit.c @@ -31,8 +31,6 @@ */ -//#define TEST - #include <stdio.h> #include <errno.h> #include <unistd.h> @@ -43,10 +41,16 @@ #include <signal.h> #include <limits.h> -#ifndef TEST - #include "busybox.h" +#ifdef BB_LOCALE_SUPPORT +#define Isprint(c) isprint((c)) +#else +#define Isprint(c) ( (c) >= ' ' && (c) != ((unsigned char)'\233') ) +#endif + +#ifndef TEST + #define D(x) #else @@ -59,13 +63,6 @@ #define D(x) x -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - #endif /* TEST */ #ifdef BB_FEATURE_COMMAND_TAB_COMPLETION @@ -92,29 +89,6 @@ #endif /* advanced FEATURES */ -#ifdef TEST -void *xrealloc(void *old, size_t size) -{ - return realloc(old, size); -} - -void *xmalloc(size_t size) -{ - return malloc(size); -} -char *xstrdup(const char *s) -{ - return strdup(s); -} - -void *xcalloc(size_t size, size_t se) -{ - return calloc(size, se); -} - -#define error_msg(s, d) fprintf(stderr, s, d) -#endif /* TEST */ - struct history { char *s; @@ -238,7 +212,7 @@ static void win_changed(int nsig) static void cmdedit_reset_term(void) { if ((handlers_sets & SET_RESET_TERM) != 0) { - /* sparc and other have broken termios support: use old termio handling. */ +/* sparc and other have broken termios support: use old termio handling. */ setTermSettings(fileno(stdin), (void *) &initial_settings); handlers_sets &= ~SET_RESET_TERM; } @@ -270,9 +244,9 @@ static void cmdedit_set_out_char(int next_char) int c = (int)((unsigned char) command_ps[cursor]); if (c == 0) - c = ' '; /* destroy end char? */ + c = ' '; /* destroy end char? */ #ifdef BB_FEATURE_NONPRINTABLE_INVERSE_PUT - if (!isprint(c)) { /* Inverse put non-printable characters */ + if (!Isprint(c)) { /* Inverse put non-printable characters */ if (c >= 128) c -= 128; if (c < ' ') @@ -328,7 +302,7 @@ static void input_backward(int num) { if (num > cursor) num = cursor; - cursor -= num; /* new cursor (in command, not terminal) */ + cursor -= num; /* new cursor (in command, not terminal) */ if (cmdedit_x >= num) { /* no to up line */ cmdedit_x -= num; @@ -369,147 +343,116 @@ static void parse_prompt(const char *prmt_ptr) put_prompt(); } #else -static void add_to_prompt(char **prmt_mem_ptr, int *alm, - int *prmt_len, const char *addb) -{ - *prmt_len += strlen(addb); - if (*alm < (*prmt_len) + 1) { - *alm = (*prmt_len) + 1; - *prmt_mem_ptr = xrealloc(*prmt_mem_ptr, *alm); - } - strcat(*prmt_mem_ptr, addb); -} - static void parse_prompt(const char *prmt_ptr) { - int alm = strlen(prmt_ptr) + 1; /* supposedly require memory */ int prmt_len = 0; int sub_len = 0; - int flg_not_length = '['; - char *prmt_mem_ptr = xstrdup(prmt_ptr); - char pwd_buf[PATH_MAX + 1]; - char buf[16]; - int c; - - pwd_buf[0] = 0; - *prmt_mem_ptr = 0; + char flg_not_length = '['; + char *prmt_mem_ptr = xcalloc(1, 1); + char *pwd_buf = xgetcwd(0); + char buf2[PATH_MAX + 1]; + char buf[2]; + char c; + char *pbuf; while (*prmt_ptr) { + pbuf = buf; + pbuf[1] = 0; c = *prmt_ptr++; if (c == '\\') { - c = *prmt_ptr; - if (c == 0) + const char *cp = prmt_ptr; + int l; + + c = process_escape_sequence(&prmt_ptr); + if(prmt_ptr==cp) { + if (*cp == 0) break; - prmt_ptr++; - switch (c) { + c = *prmt_ptr++; + switch (c) { #ifdef BB_FEATURE_GETUSERNAME_AND_HOMEDIR - case 'u': - add_to_prompt(&prmt_mem_ptr, &alm, &prmt_len, user_buf); - continue; + case 'u': + pbuf = user_buf; + break; #endif - case 'h': - if (hostname_buf[0] == 0) { - hostname_buf = xcalloc(256, 1); - if (gethostname(hostname_buf, 255) < 0) { - strcpy(hostname_buf, "?"); + case 'h': + pbuf = hostname_buf; + if (*pbuf == 0) { + pbuf = xcalloc(256, 1); + if (gethostname(pbuf, 255) < 0) { + strcpy(pbuf, "?"); } else { - char *s = strchr(hostname_buf, '.'); + char *s = strchr(pbuf, '.'); if (s) *s = 0; } + hostname_buf = pbuf; } - add_to_prompt(&prmt_mem_ptr, &alm, &prmt_len, - hostname_buf); - continue; - case '$': + break; + case '$': c = my_euid == 0 ? '#' : '$'; break; #ifdef BB_FEATURE_GETUSERNAME_AND_HOMEDIR - case 'w': - if (pwd_buf[0] == 0) { - int l; - - getcwd(pwd_buf, PATH_MAX); - l = strlen(home_pwd_buf); - if (home_pwd_buf[0] != 0 && - strncmp(home_pwd_buf, pwd_buf, l) == 0) { - strcpy(pwd_buf + 1, pwd_buf + l); - pwd_buf[0] = '~'; + case 'w': + pbuf = pwd_buf; + l = strlen(home_pwd_buf); + if (home_pwd_buf[0] != 0 && + strncmp(home_pwd_buf, pbuf, l) == 0 && + (pbuf[l]=='/' || pbuf[l]=='\0') && + strlen(pwd_buf+l)<PATH_MAX) { + pbuf = buf2; + *pbuf = '~'; + strcpy(pbuf+1, pwd_buf+l); } - } - add_to_prompt(&prmt_mem_ptr, &alm, &prmt_len, pwd_buf); - continue; + break; #endif - case 'W': - if (pwd_buf[0] == 0) { - char *z; - - getcwd(pwd_buf, PATH_MAX); - z = strrchr(pwd_buf,'/'); - if ( (z != NULL) && (z != pwd_buf) ) { - z++; - strcpy(pwd_buf,z); - } - } - add_to_prompt(&prmt_mem_ptr, &alm, &prmt_len, pwd_buf); - continue; - case '!': - snprintf(buf, sizeof(buf), "%d", num_ok_lines); - add_to_prompt(&prmt_mem_ptr, &alm, &prmt_len, buf); - continue; - case 'e': - case 'E': /* \e \E = \033 */ + case 'W': + pbuf = pwd_buf; + cp = strrchr(pbuf,'/'); + if ( (cp != NULL) && (cp != pbuf) ) + pbuf += (cp-pbuf)+1; + break; + case '!': + snprintf(pbuf = buf2, sizeof(buf2), "%d", num_ok_lines); + break; + case 'e': case 'E': /* \e \E = \033 */ c = '\033'; break; - case 'x': - case 'X': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7':{ - int l; - int ho = 0; - char *eho; - - if (c == 'X') - c = 'x'; - + case 'x': case 'X': for (l = 0; l < 3;) { - - buf[l++] = *prmt_ptr; - buf[l] = 0; - ho = strtol(buf, &eho, c == 'x' ? 16 : 8); - if (ho > UCHAR_MAX || (eho - buf) < l) { + int h; + buf2[l++] = *prmt_ptr; + buf2[l] = 0; + h = strtol(buf2, &pbuf, 16); + if (h > UCHAR_MAX || (pbuf - buf2) < l) { l--; break; } prmt_ptr++; } - buf[l] = 0; - ho = strtol(buf, 0, c == 'x' ? 16 : 8); - c = ho == 0 ? '?' : (char) ho; + buf2[l] = 0; + c = (char)strtol(buf2, 0, 16); + if(c==0) + c = '?'; + pbuf = buf; break; - } - case '[': - case ']': + case '[': case ']': if (c == flg_not_length) { flg_not_length = flg_not_length == '[' ? ']' : '['; continue; } break; - } + } + } } - buf[0] = c; - buf[1] = 0; - add_to_prompt(&prmt_mem_ptr, &alm, &prmt_len, buf); + if(pbuf == buf) + *pbuf = c; + prmt_len += strlen(pbuf); + prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_len+1), pbuf); if (flg_not_length == ']') sub_len++; } + free(pwd_buf); cmdedit_prompt = prmt_mem_ptr; cmdedit_prmt_len = prmt_len - sub_len; put_prompt(); @@ -789,7 +732,7 @@ static char **exe_n_cwd_tab_completion(char *command, int *num_matches, char **paths = path1; int npaths; int i; - char found[BUFSIZ + 4 + PATH_MAX]; + char *found; char *pfind = strrchr(command, '/'); path1[0] = "."; @@ -822,7 +765,6 @@ static char **exe_n_cwd_tab_completion(char *command, int *num_matches, continue; while ((next = readdir(dir)) != NULL) { - const char *str_merge = "%s/%s"; char *str_found = next->d_name; /* matched ? */ @@ -835,25 +777,23 @@ static char **exe_n_cwd_tab_completion(char *command, int *num_matches, else continue; } - if (paths[i][strlen(paths[i]) - 1] == '/') - str_merge = "%s%s"; - sprintf(found, str_merge, paths[i], str_found); + found = concat_path_file(paths[i], str_found); /* hmm, remover in progress? */ - if (stat(found, &st) < 0) - continue; + if (stat(found, &st) < 0) + goto cont; /* find with dirs ? */ if (paths[i] != dirbuf) strcpy(found, next->d_name); /* only name */ if (S_ISDIR(st.st_mode)) { /* name is directory */ - /* algorithmic only "/" ? */ - if (*str_found) - strcat(found, "/"); + str_found = found; + found = concat_path_file(found, ""); + free(str_found); str_found = add_quote_for_spec_chars(found); } else { /* not put found file if search only dirs for cd */ - if (type == FIND_DIR_ONLY) - continue; + if (type == FIND_DIR_ONLY) + goto cont; str_found = add_quote_for_spec_chars(found); if (type == FIND_FILE_ONLY || (type == FIND_EXE_ONLY && is_execute(&st) == TRUE)) @@ -863,6 +803,8 @@ static char **exe_n_cwd_tab_completion(char *command, int *num_matches, matches = xrealloc(matches, (nm + 1) * sizeof(char *)); matches[nm++] = str_found; +cont: + free(found); } closedir(dir); } @@ -1440,7 +1382,7 @@ extern void cmdedit_read_input(char *prompt, char command[BUFSIZ]) } } else #endif - if (!isprint(c)) /* Skip non-printable characters */ + if (!Isprint(c)) /* Skip non-printable characters */ break; if (len >= (BUFSIZ - 2)) /* Need to leave space for enter */ @@ -1554,6 +1496,9 @@ extern void cmdedit_terminate(void) #ifdef TEST +const char *applet_name = "debug stuff usage"; +const char *memory_exhausted = "Memory exhausted"; + #ifdef BB_FEATURE_NONPRINTABLE_INVERSE_PUT #include <locale.h> #endif diff --git a/shell/lash.c b/shell/lash.c index 89325b63d..ee45b1a0d 100644 --- a/shell/lash.c +++ b/shell/lash.c @@ -64,7 +64,10 @@ #include <sys/wait.h> #include <unistd.h> #include <getopt.h> + +#ifdef BB_LOCALE_SUPPORT #include <locale.h> +#endif //#define BB_FEATURE_SH_WORDEXP @@ -80,7 +83,6 @@ #include "cmdedit.h" -static const int MAX_LINE = 256; /* size of input buffer for cwd data */ static const int MAX_READ = 128; /* size of input buffer for `read' builtin */ #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" @@ -230,7 +232,7 @@ static char syntax_err[]="syntax error near unexpected token"; #endif static char *PS1; -static char *PS2; +static char *PS2 = "> "; #ifdef DEBUG_SHELL @@ -294,7 +296,7 @@ static int builtin_cd(struct child_prog *child) printf("cd: %s: %m\n", newdir); return EXIT_FAILURE; } - getcwd(cwd, sizeof(char)*MAX_LINE); + cwd = xgetcwd(cwd); return EXIT_SUCCESS; } @@ -410,7 +412,6 @@ static int builtin_jobs(struct child_prog *child) /* built-in 'pwd' handler */ static int builtin_pwd(struct child_prog *dummy) { - getcwd(cwd, MAX_LINE); printf( "%s\n", cwd); return EXIT_SUCCESS; } @@ -434,13 +435,14 @@ static int builtin_export(struct child_prog *child) #ifndef BB_FEATURE_SH_SIMPLE_PROMPT if (strncmp(v, "PS1=", 4)==0) PS1 = getenv("PS1"); - else if (strncmp(v, "PS2=", 4)==0) - PS2 = getenv("PS2"); #endif + +#ifdef BB_LOCALE_SUPPORT if(strncmp(v, "LC_ALL=", 7)==0) setlocale(LC_ALL, getenv("LC_ALL")); if(strncmp(v, "LC_CTYPE=", 9)==0) setlocale(LC_CTYPE, getenv("LC_CTYPE")); +#endif return (res); } @@ -623,10 +625,7 @@ static int builtin_unset(struct child_prog *child) */ static int run_command_predicate(char *cmd) { - int n=strlen(cmd); - local_pending_command = xmalloc(n+1); - strncpy(local_pending_command, cmd, n); - local_pending_command[n]='\0'; + local_pending_command = xstrdup(cmd); return( busy_loop(NULL)); } #endif @@ -808,15 +807,10 @@ static inline void cmdedit_set_initial_prompt(void) { #ifdef BB_FEATURE_SH_SIMPLE_PROMPT PS1 = NULL; - PS2 = "> "; #else PS1 = getenv("PS1"); - if(PS1==0) { + if(PS1==0) PS1 = "\\w \\$ "; - } - PS2 = getenv("PS2"); - if(PS2==0) - PS2 = "> "; #endif } @@ -954,7 +948,7 @@ static int expand_arguments(char *command) /* Fix up escape sequences to be the Real Thing(tm) */ while( command && command[ix]) { if (command[ix] == '\\') { - char *tmp = command+ix+1; + const char *tmp = command+ix+1; command[ix] = process_escape_sequence( &tmp ); memmove(command+ix + 1, tmp, strlen(tmp)+1); } @@ -1829,8 +1823,10 @@ static int busy_loop(FILE * input) #ifdef BB_FEATURE_CLEAN_UP void free_memory(void) { - if (cwd) + if (cwd) { free(cwd); + cwd = NULL; + } if (local_pending_command) free(local_pending_command); @@ -1850,7 +1846,6 @@ int shell_main(int argc_l, char **argv_l) /* These variables need re-initializing when recursing */ shell_context = 0; - cwd=NULL; local_pending_command = NULL; close_me_head = NULL; job_list.head = NULL; @@ -1921,8 +1916,7 @@ int shell_main(int argc_l, char **argv_l) } /* initialize the cwd -- this is never freed...*/ - cwd=(char*)xmalloc(sizeof(char)*MAX_LINE+1); - getcwd(cwd, sizeof(char)*MAX_LINE); + cwd = xgetcwd(0); #ifdef BB_FEATURE_CLEAN_UP atexit(free_memory); @@ -1932,7 +1926,6 @@ int shell_main(int argc_l, char **argv_l) cmdedit_set_initial_prompt(); #else PS1 = NULL; - PS2 = "> "; #endif return (busy_loop(input)); @@ -93,7 +93,7 @@ static void map(register unsigned char *string1, unsigned int string1_len, } } -static unsigned int expand(char *arg, register unsigned char *buffer) +static unsigned int expand(const char *arg, register unsigned char *buffer) { unsigned char *buffer_start = buffer; int i, ac; |