summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko2006-09-26 17:41:00 +0000
committerDenis Vlasenko2006-09-26 17:41:00 +0000
commite175ff252f9abb7267000571207c9d612728e1b9 (patch)
treebc6843cbc8ca3d0d2257a9e2349c03358b70b85a
parent22f6dcb47c32909ca0a3d720b11df5ea86b1e76c (diff)
downloadbusybox-e175ff252f9abb7267000571207c9d612728e1b9.zip
busybox-e175ff252f9abb7267000571207c9d612728e1b9.tar.gz
several fixes from openWRT project
-rw-r--r--editors/awk.c31
-rw-r--r--include/usage.h1
-rw-r--r--loginutils/passwd.c2
-rw-r--r--networking/udhcp/dhcpc.c14
-rw-r--r--networking/udhcp/dhcpc.h1
-rw-r--r--networking/udhcp/options.c3
-rw-r--r--networking/udhcp/options.h2
-rw-r--r--shell/ash.c39
8 files changed, 88 insertions, 5 deletions
diff --git a/editors/awk.c b/editors/awk.c
index c934fe0..bebc780 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -249,7 +249,8 @@ enum {
/* builtins */
enum {
B_a2=0, B_ix, B_ma, B_sp, B_ss, B_ti, B_lo, B_up,
- B_ge, B_gs, B_su
+ B_ge, B_gs, B_su,
+ B_an, B_co, B_ls, B_or, B_rs, B_xo,
};
/* tokens and their corresponding info values */
@@ -289,6 +290,8 @@ static char * const tokenlist =
"\5while" NTC
"\4else" NTC
+ "\3and" "\5compl" "\6lshift" "\2or"
+ "\6rshift" "\3xor"
"\5close" "\6system" "\6fflush" "\5atan2" /* BUILTIN */
"\3cos" "\3exp" "\3int" "\3log"
"\4rand" "\3sin" "\4sqrt" "\5srand"
@@ -342,6 +345,8 @@ static const uint32_t tokeninfo[] = {
ST_WHILE,
0,
+ OC_B|B_an|P(0x83), OC_B|B_co|P(0x41), OC_B|B_ls|P(0x83), OC_B|B_or|P(0x83),
+ OC_B|B_rs|P(0x83), OC_B|B_xo|P(0x83),
OC_FBLTIN|Sx|F_cl, OC_FBLTIN|Sx|F_sy, OC_FBLTIN|Sx|F_ff, OC_B|B_a2|P(0x83),
OC_FBLTIN|Nx|F_co, OC_FBLTIN|Nx|F_ex, OC_FBLTIN|Nx|F_in, OC_FBLTIN|Nx|F_lg,
OC_FBLTIN|F_rn, OC_FBLTIN|Nx|F_si, OC_FBLTIN|Nx|F_sq, OC_FBLTIN|Nx|F_sr,
@@ -1923,6 +1928,30 @@ static var *exec_builtin(node *op, var *res)
s[n] = '\0';
setvar_p(res, s);
break;
+
+ case B_an:
+ setvar_i(res, (long)getvar_i(av[0]) & (long)getvar_i(av[1]));
+ break;
+
+ case B_co:
+ setvar_i(res, ~(long)getvar_i(av[0]));
+ break;
+
+ case B_ls:
+ setvar_i(res, (long)getvar_i(av[0]) << (long)getvar_i(av[1]));
+ break;
+
+ case B_or:
+ setvar_i(res, (long)getvar_i(av[0]) | (long)getvar_i(av[1]));
+ break;
+
+ case B_rs:
+ setvar_i(res, (long)((unsigned long)getvar_i(av[0]) >> (unsigned long)getvar_i(av[1])));
+ break;
+
+ case B_xo:
+ setvar_i(res, (long)getvar_i(av[0]) ^ (long)getvar_i(av[1]));
+ break;
case B_lo:
to_xxx = tolower;
diff --git a/include/usage.h b/include/usage.h
index 6ef7f1e..da176d1 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -3211,6 +3211,7 @@ USE_FEATURE_START_STOP_DAEMON_FANCY( \
"\t-n,\t--now\tExit with failure if lease cannot be immediately negotiated\n" \
"\t-p,\t--pidfile=file\tStore process ID of daemon in file\n" \
"\t-q,\t--quit\tQuit after obtaining lease\n" \
+ "\t-R,\t--release\tRelease IP on quit\n" \
"\t-r,\t--request=IP\tIP address to request (default: none)\n" \
"\t-s,\t--script=file\tRun file at dhcp events (default: /usr/share/udhcpc/default.script)\n" \
"\t-t,\t--retries=NUM\tSend up to NUM request packets\n"\
diff --git a/loginutils/passwd.c b/loginutils/passwd.c
index f48f15f..211a49e 100644
--- a/loginutils/passwd.c
+++ b/loginutils/passwd.c
@@ -318,7 +318,7 @@ static int new_password(const struct passwd *pw, int amroot, int algo)
} else {
orig[0] = '\0';
}
- cp = bb_askpass(0, "Enter the new password (minimum of 5, maximum of 8 characters).\n"
+ cp = bb_askpass(0, "Enter the new password (minimum of 5 characters).\n"
"Please use a combination of upper and lower case letters and numbers.\n"
"Enter new password: ");
if (!cp ) {
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index ff4d501..499183f 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -53,6 +53,7 @@ struct client_config_t client_config = {
.abort_if_no_lease = 0,
.foreground = 0,
.quit_after_lease = 0,
+ .release_on_quit = 0,
.background_if_no_lease = 0,
.interface = "eth0",
.pidfile = NULL,
@@ -169,6 +170,7 @@ int udhcpc_main(int argc, char *argv[])
{"now", no_argument, 0, 'n'},
{"pidfile", required_argument, 0, 'p'},
{"quit", no_argument, 0, 'q'},
+ {"release", no_argument, 0, 'R'},
{"request", required_argument, 0, 'r'},
{"script", required_argument, 0, 's'},
{"timeout", required_argument, 0, 'T'},
@@ -180,7 +182,7 @@ int udhcpc_main(int argc, char *argv[])
/* get options */
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "c:CV:fbH:h:F:i:np:qr:s:T:t:v", arg_options, &option_index);
+ c = getopt_long(argc, argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:v", arg_options, &option_index);
if (c == -1) break;
switch (c) {
@@ -250,6 +252,9 @@ int udhcpc_main(int argc, char *argv[])
case 'q':
client_config.quit_after_lease = 1;
break;
+ case 'R':
+ client_config.release_on_quit = 1;
+ break;
case 'r':
requested_ip = inet_addr(optarg);
break;
@@ -495,8 +500,11 @@ int udhcpc_main(int argc, char *argv[])
state = BOUND;
change_mode(LISTEN_NONE);
- if (client_config.quit_after_lease)
+ if (client_config.quit_after_lease) {
+ if (client_config.release_on_quit)
+ perform_release();
return 0;
+ }
if (!client_config.foreground)
client_background();
@@ -526,6 +534,8 @@ int udhcpc_main(int argc, char *argv[])
break;
case SIGTERM:
bb_info_msg("Received SIGTERM");
+ if (client_config.release_on_quit)
+ perform_release();
return 0;
}
} else if (retval == -1 && errno == EINTR) {
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h
index 3dff11a..6cf59a9 100644
--- a/networking/udhcp/dhcpc.h
+++ b/networking/udhcp/dhcpc.h
@@ -19,6 +19,7 @@
struct client_config_t {
char foreground; /* Do not fork */
char quit_after_lease; /* Quit after obtaining lease */
+ char release_on_quit; /* perform release on quit */
char abort_if_no_lease; /* Abort if no lease */
char background_if_no_lease; /* Fork to background if no lease */
char *interface; /* The name of the interface to use */
diff --git a/networking/udhcp/options.c b/networking/udhcp/options.c
index 6526472..ded0f7b 100644
--- a/networking/udhcp/options.c
+++ b/networking/udhcp/options.c
@@ -42,8 +42,11 @@ struct dhcp_option dhcp_options[] = {
{"dhcptype", OPTION_U8, 0x35},
{"serverid", OPTION_IP, 0x36},
{"message", OPTION_STRING, 0x38},
+ {"vendorclass", OPTION_STRING, 0x3C},
+ {"clientid", OPTION_STRING, 0x3D},
{"tftp", OPTION_STRING, 0x42},
{"bootfile", OPTION_STRING, 0x43},
+ {"userclass", OPTION_STRING, 0x4D},
{"", 0x00, 0x00}
};
diff --git a/networking/udhcp/options.h b/networking/udhcp/options.h
index b0a649f..3c1f5b9 100644
--- a/networking/udhcp/options.h
+++ b/networking/udhcp/options.h
@@ -23,7 +23,7 @@ enum {
#define OPTION_LIST 0x20 /* There can be a list of 1 or more of these */
struct dhcp_option {
- char name[10];
+ char name[12];
char flags;
uint8_t code;
};
diff --git a/shell/ash.c b/shell/ash.c
index 754c1d7..7d4da43 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -1384,6 +1384,13 @@ static const struct builtincmd builtincmd[] = {
#define NUMBUILTINS (sizeof (builtincmd) / sizeof (struct builtincmd) )
+static const char *safe_applets[] = {
+ "[", "test", "echo", "cat",
+ "ln", "cp", "touch", "mkdir", "rm",
+ "cut", "hexdump", "awk", "sort",
+ "find", "xargs", "ls", "dd",
+ "chown", "chmod"
+};
struct cmdentry {
@@ -2034,6 +2041,19 @@ static int dotrap(void);
static void setinteractive(int);
static void exitshell(void) ATTRIBUTE_NORETURN;
+
+static int is_safe_applet(char *name)
+{
+ int n = sizeof(safe_applets) / sizeof(char *);
+ int i;
+ for (i = 0; i < n; i++)
+ if (strcmp(safe_applets[i], name) == 0)
+ return 1;
+
+ return 0;
+}
+
+
/*
* This routine is called when an error or an interrupt occurs in an
* interactive shell and control is returned to the main command loop.
@@ -3681,6 +3701,7 @@ shellexec(char **argv, const char *path, int idx)
clearredir(1);
envp = environment();
if (strchr(argv[0], '/') != NULL
+ || is_safe_applet(argv[0])
#ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
|| find_applet_by_name(argv[0])
#endif
@@ -3723,6 +3744,18 @@ static void
tryexec(char *cmd, char **argv, char **envp)
{
int repeated = 0;
+ struct BB_applet *a;
+ int argc = 0;
+ char **c;
+
+ if(strchr(cmd, '/') == NULL && is_safe_applet(cmd) && (a = find_applet_by_name(cmd)) != NULL) {
+ c = argv;
+ while (*c != NULL) {
+ c++; argc++;
+ }
+ bb_applet_name = cmd;
+ exit(a->main(argc, argv));
+ }
#ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
if(find_applet_by_name(cmd) != NULL) {
/* re-exec ourselves with the new arguments */
@@ -3905,6 +3938,12 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
}
#endif
+ if (is_safe_applet(name)) {
+ entry->cmdtype = CMDNORMAL;
+ entry->u.index = -1;
+ return;
+ }
+
updatetbl = (path == pathval());
if (!updatetbl) {
act |= DO_ALTPATH;