diff --exclude CVS -uNr busybox-1.11.2/shell/Config.in busybox-1.11.2.modified/shell/Config.in
--- busybox-1.11.2/shell/Config.in	2008-08-21 13:40:12.000000000 -0600
+++ busybox-1.11.2.modified/shell/Config.in	2008-11-10 10:04:06.000000000 -0700
@@ -251,6 +251,13 @@
 	  on it and compare vs bash) but for most things it works quite well.
 	  It also uses only vfork, so it can be used on uClinux systems.
 
+config MSH_ALIAS
+	bool "alias support"
+	default y
+	depends on MSH
+	help
+	  Enable alias support in the msh shell.
+
 comment "Bourne Shell Options"
 	depends on MSH || LASH || HUSH || ASH
 
diff --exclude CVS -uNr busybox-1.11.2/shell/msh.c busybox-1.11.2.modified/shell/msh.c
--- busybox-1.11.2/shell/msh.c	2008-11-10 10:38:53.000000000 -0700
+++ busybox-1.11.2.modified/shell/msh.c	2008-11-10 10:04:06.000000000 -0700
@@ -247,6 +247,29 @@
 
 #define AREASIZE (90000)
 
+#if ENABLE_MSH_ALIAS
+#define ATABSIZE 39
+#define ALIASINUSE 1
+#define ALIASDEAD  2
+#define LONE_DASH(s)     ((s)[0] == '-' && !(s)[1])
+
+struct alias {
+	struct alias *next;
+	char *name;
+	char *val;
+	int flag;
+};
+
+static char **argptr;                  /* argument list for builtin commands */
+static char *optionarg;                /* set by nextopt (like getopt) */
+static char *optptr;                   /* used by nextopt */
+static struct alias **atab;
+
+#define INIT_G_alias() do { \
+	atab = xzalloc(ATABSIZE * sizeof(atab[0])); \
+} while (0)
+#endif
+
 /*
  * flags to control evaluation of words
  */
@@ -508,6 +531,10 @@
 static int doset(struct op *t, char **args);
 static int dotimes(struct op *t, char **args);
 static int docontinue(struct op *t, char **args);
+#if ENABLE_MSH_ALIAS
+static int doalias(struct op *t, char **args);
+static int dounalias(struct op *t, char **args);
+#endif
 
 static int forkexec(struct op *t, int *pin, int *pout, int no_fork, char **wp);
 static int execute(struct op *t, int *pin, int *pout, int no_fork);
@@ -585,6 +612,10 @@
 	{ "trap"    , dotrap     },
 	{ "umask"   , doumask    },
 	{ "wait"    , dowait     },
+#if ENABLE_MSH_ALIAS
+	{ "alias"   , doalias    },
+	{ "unalias" , dounalias  },
+#endif
 	{ NULL      , NULL       },
 };
 
@@ -2436,6 +2467,239 @@
 	return tp != NULL ? *tp : NULL;
 }
 
+#if ENABLE_MSH_ALIAS
+static struct alias **
+__lookupalias(const char *name) {
+	unsigned int hashval;
+	struct alias **app;
+	const char *p;
+	unsigned int ch;
+
+	p = name;
+	ch = (unsigned char)*p;
+	hashval = ch << 4;
+	while (ch) {
+		hashval += ch;
+		ch = (unsigned char)*++p;
+	}
+	app = &atab[hashval % ATABSIZE];
+
+	for (; *app; app = &(*app)->next) {
+		if (strcmp(name, (*app)->name) == 0)
+			break;
+	}
+
+	return app;
+}
+
+static struct alias *
+lookupalias(const char *name, int check)
+{
+	struct alias *ap = *__lookupalias(name);
+
+	if (check && ap && (ap->flag & ALIASINUSE))
+		return NULL;
+	return ap;
+}
+
+static struct alias *
+freealias(struct alias *ap)
+{
+	struct alias *nextone;
+
+	if (ap->flag & ALIASINUSE) {
+		ap->flag |= ALIASDEAD;
+		return ap;
+	}
+
+	nextone = ap->next;
+	free(ap->name);
+	free(ap->val);
+	free(ap);
+	return nextone;
+}
+
+static char *
+ckstrdup(const char *s)
+{
+	char *p = strdup(s);
+	return p;
+}
+
+static void *
+ckrealloc(void *p, size_t nbytes)
+{
+	p = realloc(p, nbytes);
+	return p;
+}
+
+static void *
+ckmalloc(size_t nbytes)
+{
+	return ckrealloc(NULL, nbytes);
+}
+
+static void *
+ckzalloc(size_t nbytes)
+{
+	return memset(ckmalloc(nbytes), 0, nbytes);
+}
+static void
+setalias(const char *name, const char *val)
+{
+	struct alias *ap, **app;
+
+	app = __lookupalias(name);
+	ap = *app;
+	if (ap) {
+		if (!(ap->flag & ALIASINUSE))
+			free(ap->val);
+
+		ap->val = ckstrdup(val);
+		ap->flag &= ~ALIASDEAD;
+	} else {
+		ap = ckzalloc(sizeof(struct alias));
+		ap->name = ckstrdup(name);
+		ap->val = ckstrdup(val);
+		*app = ap;
+	}
+}
+
+static int
+unalias(const char *name)
+{
+	struct alias **app;
+
+	app = __lookupalias(name);
+
+	if (*app) {
+		*app = freealias(*app);
+		return 0;
+	}
+
+	return 1;
+}
+
+static void
+rmaliases(void)
+{
+	struct alias *ap, **app;
+	int i;
+
+	for (i = 0; i < ATABSIZE; i++) {
+		app = &atab[i];
+		for (ap = *app; ap; ap = *app) {
+			*app = freealias(*app);
+			if (ap == *app)
+				app = &ap->next;
+		}
+	}
+}
+
+static void
+printalias(const struct alias *ap)
+{
+	printf("%s=%s\n", ap->name, ap->val);
+}
+
+static int
+nextopt(const char *optstring)
+{
+	char *p;
+	const char *q;
+	char c;
+
+	p = optptr;
+	if (p == NULL || *p == '\0') {
+		/* We ate entire "-param", take next one */
+		p = *argptr;
+		if (p == NULL)
+			return '\0';
+		if (*p != '-')
+			return '\0';
+		if (*++p == '\0') /* just "-" ? */
+			return '\0';
+		argptr++;
+		if (LONE_DASH(p)) /* "--" ? */
+			return '\0';
+	}
+	c = *p++;
+	for (q = optstring; *q != c;) {
+		if (*q == '\0')
+			printf("illegal option -%c", c);
+		if (*++q == ':')
+			q++;
+	}
+	if (*++q == ':') {
+		if (*p == '\0') {
+			p = *argptr++;
+			if (p == NULL)
+				printf("no arg for -%c option", c);
+		}
+		optionarg = p;
+		p = NULL;
+	}
+	optptr = p;
+	return c;
+}
+
+static int
+doalias(struct op *t ATTRIBUTE_UNUSED, char **args)
+{
+	char *n, *v;
+	int ret = 0;
+	struct alias *ap;
+
+	if (!args[1]) {
+		int i;
+		for (i = 0; i < ATABSIZE; i++) {
+			for (ap = atab[i]; ap; ap = ap->next)
+				printalias(ap);
+		}
+		return 0;
+	}
+
+	while ((n = *++args) != NULL) {
+		v = strchr(n+1, '=');
+		if (v == NULL) { /* n+1: funny ksh stuff */
+			ap = *__lookupalias(n);
+			if (ap == NULL) {
+				fprintf(stderr, "%s: %s not found\n", "alias", n);
+				ret = 1;
+			} else
+				printalias(ap);
+		} else {
+			*v++ = '\0';
+			setalias(n, v);
+		}
+	}
+
+	return ret;
+}
+
+static int
+dounalias(struct op *t ATTRIBUTE_UNUSED, char **args ATTRIBUTE_UNUSED)
+{
+	int i;
+
+	while ((i = nextopt("a")) != '\0') {
+		if (i == 'a') {
+			rmaliases();
+			return 0;
+		}
+	}
+
+	for (i = 0; *argptr; argptr++) {
+		if (unalias(*argptr)) {
+			fprintf(stderr, "%s: %s not found\n", "unalias", *argptr);
+			i = 1;
+		}
+	}
+
+	return i;
+}
+#endif /* MSH_ALIAS */
+
 /*
  * execute tree
  */
@@ -2449,6 +2713,7 @@
 	struct var *vp;
 	struct op *outtree_save;
 	struct brkcon bc;
+	struct alias *aliasp;
 
 #if __GNUC__
 	/* Avoid longjmp clobbering */
@@ -2467,6 +2732,14 @@
 	rv = 0;
 	a = areanum++;
 	wp2 = t->op_words;
+
+#if ENABLE_MSH_ALIAS
+	aliasp = lookupalias(wp2[0], 1);
+	if (aliasp != NULL) {
+		if (*aliasp->val)
+			wp2[0] = aliasp->val;
+	}
+#endif
 	wp = (wp2 != NULL)
 		? eval(wp2, t->op_type == TCOM ? DOALL : DOALL & ~DOKEY)
 		: NULL;
@@ -5090,6 +5363,9 @@
 	int (*iof) (struct ioarg *);
 
 	INIT_G();
+#if ENABLE_MSH_ALIAS
+	INIT_G_alias();
+#endif
 
 	sharedbuf.id = AFID_NOBUF;
 	mainbuf.id = AFID_NOBUF;
