? busybox-dietlibc.diff
? loop.i
? loop.s
? networking/ping.c.new
Index: Rules.mak
===================================================================
RCS file: /var/cvs/busybox/Rules.mak,v
retrieving revision 1.25
diff -u -r1.25 Rules.mak
--- Rules.mak	21 Dec 2003 09:04:54 -0000	1.25
+++ Rules.mak	30 Jan 2004 12:53:33 -0000
@@ -140,6 +140,15 @@
 # prone to casual user adjustment.
 # 
 
+ifeq ($(strip $(CONFIG_DIETLIBC)),y)
+    # For dietlibc support
+    CC=diet gcc
+    # Dietlibc is roughly BSD
+    CFLAGS+=-D_BSD_SOURCE
+    LIBRARIES:=-lcompat -lrpc
+else
+    CFLAGS+=-D_GNU_SOURCE
+endif
 ifeq ($(strip $(CONFIG_LFS)),y)
     # For large file summit support
     CFLAGS+=-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
@@ -154,11 +163,11 @@
     endif
 endif
 ifeq ($(strip $(CONFIG_DEBUG)),y)
-    CFLAGS  +=$(WARNINGS) -g -D_GNU_SOURCE
+    CFLAGS  +=$(WARNINGS) -g
     LDFLAGS +=-Wl,-warn-common
     STRIPCMD:=/bin/true -Not_stripping_since_we_are_debugging
 else
-    CFLAGS+=$(WARNINGS) $(OPTIMIZATIONS) -D_GNU_SOURCE -DNDEBUG
+    CFLAGS+=$(WARNINGS) $(OPTIMIZATIONS) -DNDEBUG
     LDFLAGS += -s -Wl,-warn-common
     STRIPCMD:=$(STRIP) --remove-section=.note --remove-section=.comment
 endif
Index: coreutils/tail.c
===================================================================
RCS file: /var/cvs/busybox/coreutils/tail.c,v
retrieving revision 1.46
diff -u -r1.46 tail.c
--- coreutils/tail.c	31 Oct 2003 00:35:58 -0000	1.46
+++ coreutils/tail.c	30 Jan 2004 12:53:34 -0000
@@ -62,7 +62,13 @@
 static void tail_xprint_header(const char *fmt, const char *filename)
 {
 	/* If we get an output error, there is really no sense in continuing. */
-	if (dprintf(STDOUT_FILENO, fmt, filename) < 0) {
+	if (bb_full_write(STDOUT_FILENO, "\n===> ", 6) < 0) {
+		bb_perror_nomsg_and_die();
+	}
+	if (bb_full_write(STDOUT_FILENO, filename, strlen(filename)) < 0) {
+		bb_perror_nomsg_and_die();
+	}
+	if (bb_full_write(STDOUT_FILENO, " <===\n", 6) < 0) {
 		bb_perror_nomsg_and_die();
 	}
 }
Index: include/libbb.h
===================================================================
RCS file: /var/cvs/busybox/include/libbb.h,v
retrieving revision 1.125
diff -u -r1.125 libbb.h
--- include/libbb.h	17 Jan 2004 05:03:30 -0000	1.125
+++ include/libbb.h	30 Jan 2004 12:53:34 -0000
@@ -33,6 +33,9 @@
 #include <stdint.h>
 
 #include <netdb.h>
+#ifdef __dietlibc__
+#include <netinet/in.h>
+#endif
 
 #ifdef DMALLOC
 #include <dmalloc.h>
Index: libbb/printf.c
===================================================================
RCS file: /var/cvs/busybox/libbb/printf.c,v
retrieving revision 1.2
diff -u -r1.2 printf.c
--- libbb/printf.c	16 Apr 2003 23:02:35 -0000	1.2
+++ libbb/printf.c	30 Jan 2004 12:53:35 -0000
@@ -116,7 +116,23 @@
  * you can extract the information you need from dietstdio.h.  See the
  * other library implementations for examples.
  */
-#error dietlibc is currently not supported.  Please see the commented source.
+
+struct __stdio_file {
+  int fd;
+  int flags;
+  unsigned int bs;	/* read: bytes in buffer */
+  unsigned int bm;	/* position in buffer */
+  unsigned int buflen;	/* length of buf */
+  char *buf;
+  struct __stdio_file *next;	/* for fflush */
+  pid_t popen_kludge;
+  unsigned char ungetbuf;
+  char ungotten;
+};
+
+#define ERRORINDICATOR 1
+
+#define SET_FERROR_UNLOCKED(S)    (((struct __stdio_file *)S)->flags |= ERRORINDICATOR)
 
 #else /* some other lib */
 /* Please see the comments for the above supported libaries for examples
Index: networking/ping.c
===================================================================
RCS file: /var/cvs/busybox/networking/ping.c,v
retrieving revision 1.55
diff -u -r1.55 ping.c
--- networking/ping.c	22 Jul 2003 08:56:51 -0000	1.55
+++ networking/ping.c	30 Jan 2004 12:53:35 -0000
@@ -51,6 +51,83 @@
 #include <stdlib.h>
 #include "busybox.h"
 
+#ifdef __dietlibc__
+/* Dietlibc is missing the BSD definition 'struct icmp' */
+/*
+ * Internal of an ICMP Router Advertisement
+ */
+struct icmp_ra_addr
+{
+    uint32_t ira_addr;
+    uint32_t ira_preference;
+};
+
+struct icmp
+{
+    uint8_t  icmp_type;  /* type of message, see below */
+    uint8_t  icmp_code;  /* type sub code */
+    uint16_t icmp_cksum; /* ones complement checksum of struct */
+    union
+    {
+	uint8_t ih_pptr;             /* ICMP_PARAMPROB */
+	struct in_addr ih_gwaddr;   /* gateway address */
+	struct ih_idseq             /* echo datagram */
+	{
+	    uint16_t icd_id;
+	    uint16_t icd_seq;
+	} ih_idseq;
+	uint32_t ih_void;
+
+	/* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
+	struct ih_pmtu
+	{
+	    uint16_t ipm_void;
+	    uint16_t ipm_nextmtu;
+	} ih_pmtu;
+
+	struct ih_rtradv
+	{
+	    uint8_t irt_num_addrs;
+	    uint8_t irt_wpa;
+	    uint16_t irt_lifetime;
+	} ih_rtradv;
+    } icmp_hun;
+#define icmp_pptr       icmp_hun.ih_pptr
+#define icmp_gwaddr     icmp_hun.ih_gwaddr
+#define icmp_id         icmp_hun.ih_idseq.icd_id
+#define icmp_seq        icmp_hun.ih_idseq.icd_seq
+#define icmp_void       icmp_hun.ih_void
+#define icmp_pmvoid     icmp_hun.ih_pmtu.ipm_void
+#define icmp_nextmtu    icmp_hun.ih_pmtu.ipm_nextmtu
+#define icmp_num_addrs  icmp_hun.ih_rtradv.irt_num_addrs
+#define icmp_wpa        icmp_hun.ih_rtradv.irt_wpa
+#define icmp_lifetime   icmp_hun.ih_rtradv.irt_lifetime
+    union
+    {
+	struct
+	{
+	    uint32_t its_otime;
+	    uint32_t its_rtime;
+	    uint32_t its_ttime;
+	} id_ts;
+	struct
+	{
+	    struct ip idi_ip;
+	    /* options and then 64 bits of data */
+	} id_ip;
+	struct icmp_ra_addr id_radv;
+	uint32_t   id_mask;
+	uint8_t    id_data[1];
+    } icmp_dun;
+#define icmp_otime      icmp_dun.id_ts.its_otime
+#define icmp_rtime      icmp_dun.id_ts.its_rtime
+#define icmp_ttime      icmp_dun.id_ts.its_ttime
+#define icmp_ip         icmp_dun.id_ip.idi_ip
+#define icmp_radv       icmp_dun.id_radv
+#define icmp_mask       icmp_dun.id_mask
+#define icmp_data       icmp_dun.id_data
+};
+#endif /* __dietlibc__ */
 
 static const int DEFDATALEN = 56;
 static const int MAXIPLEN = 60;
Index: shell/ash.c
===================================================================
RCS file: /var/cvs/busybox/shell/ash.c,v
retrieving revision 1.87
diff -u -r1.87 ash.c
--- shell/ash.c	25 Jan 2004 08:46:10 -0000	1.87
+++ shell/ash.c	30 Jan 2004 12:53:37 -0000
@@ -57,9 +57,11 @@
 
 #define PROFILE 0
 
+#ifndef __dietlibc__
 #ifdef DEBUG
 #define _GNU_SOURCE
 #endif
+#endif
 
 #include <sys/types.h>
 #include <sys/cdefs.h>
@@ -2531,9 +2533,17 @@
 static void
 onint(void) {
 	int i;
+#ifdef __dietlibc__
+	sigset_t signals;
+#endif
 
 	intpending = 0;
+#ifndef __dietlibc__
 	sigsetmask(0);
+#else
+	sigemptyset(&signals);
+	sigprocmask(SIG_SETMASK,&signals,NULL);
+#endif
 	i = EXSIG;
 	if (gotsig[SIGINT - 1] && !trap[SIGINT]) {
 		if (!(rootshell && iflag)) {
@@ -3263,16 +3273,14 @@
 		const char *p = " %s";
 
 		p++;
-		dprintf(preverrout_fd, p, ps4val());
+		xwrite(preverrout_fd,ps4val(),strlen(ps4val()));
 
 		sp = varlist.list;
 		for(n = 0; n < 2; n++) {
 			while (sp) {
-				dprintf(preverrout_fd, p, sp->text);
+				xwrite(preverrout_fd, sp->text,strlen(sp->text));
+				xwrite(preverrout_fd, " ",1);
 				sp = sp->next;
-				if(*p == '%') {
-					p--;
-				}
 			}
 			sp = arglist.list;
 		}
@@ -5817,7 +5825,12 @@
 		}
 		q = r;
 		if (len > 0) {
+#ifdef _GNU_SOURCE
 			q = mempcpy(q, str, len);
+#else
+			memcpy(q, str, len);
+			q += len;
+#endif
 		}
 	}
 	inquotes = (flag & RMESCAPE_QUOTED) ^ RMESCAPE_QUOTED;
@@ -6354,6 +6367,10 @@
 /* pgrp of shell on invocation */
 static int initialpgrp;
 static int ttyfd = -1;
+#ifndef _PATH_TTY
+/* dietlibc has no _PATH_TTY defined */
+#define _PATH_TTY "/dev/tty"
+#endif
 #endif
 /* current job */
 static struct job *curjob;
@@ -6674,7 +6691,15 @@
 #endif
 		}
 		st &= 0x7f;
+#ifdef _GNU_SOURCE		
 		col = fmtstr(s, 32, strsignal(st));
+#else
+		if (st < NSIG && sys_siglist[st]) {
+			col += fmtstr(s, 32, sys_siglist[st]);
+		} else {
+			col += fmtstr(s, 64, "Signal %d", st );
+		}
+#endif
 		if (WCOREDUMP(status)) {
 			col += fmtstr(s + col, 16, " (core dumped)");
 		}
@@ -8373,7 +8398,12 @@
 stnputs(const char *s, size_t n, char *p)
 {
 	p = makestrspace(n, p);
+#ifdef __GNU_SOURCE
 	p = mempcpy(p, s, n);
+#else
+	memcpy(p, s, n);
+	p += n;
+#endif
 	return p;
 }
 
@@ -8452,12 +8482,25 @@
 		char *q;
 		size_t len;
 
+#ifdef __GNU_SOURCE
 		len = strchrnul(s, '\'') - s;
+#else
+		if ((q = strchr(s,'\'')) == NULL) {
+		    len = strlen(s);
+		} else {
+		    len = q - s;
+		}
+#endif
 
 		q = p = makestrspace(len + 3, p);
 
 		*q++ = '\'';
+#ifdef __GNU_SOURCE
 		q = mempcpy(q, s, len);
+#else
+		memcpy(q, s, len);
+		q += len;
+#endif
 		*q++ = '\'';
 		s += len;
 
@@ -8470,7 +8513,12 @@
 		q = p = makestrspace(len + 3, p);
 
 		*q++ = '"';
+#ifdef __GNU_SOURCE
 		q = mempcpy(q, s, len);
+#else
+		memcpy(q, s, len);
+		q += len;
+#endif
 		*q++ = '"';
 		s += len;
 
@@ -11921,7 +11969,13 @@
 	size_t vallen;
 
 	q = endofname(name);
+#ifdef _GNU_SOURCE
 	p = strchrnul(q, '=');
+#else
+	if ((p = strchr(q,'\'')) == NULL) {
+	    p = q + strlen(q);
+	}
+#endif
 	namelen = p - name;
 	if (!namelen || p != q)
 		error("%.*s: bad variable name", namelen, name);
@@ -11932,11 +11986,21 @@
 		vallen = strlen(val);
 	}
 	INTOFF;
+#ifdef _GNU_SOURCE
 	p = mempcpy(nameeq = ckmalloc(namelen + vallen + 2), name, namelen);
+#else
+	memcpy(nameeq = ckmalloc(namelen + vallen + 2), name, namelen);
+	p = nameeq + namelen;
+#endif
 	*p++ = '\0';
 	if (vallen) {
 		p[-1] = '=';
+#ifdef _GNU_SOURCE
 		p = mempcpy(p, val, vallen);
+#else
+		memcpy(p, val, vallen);
+		p += vallen;
+#endif
 	}
 	*p = '\0';
 	setvareq(nameeq, flags | VNOSAVE);
@@ -11964,14 +12028,27 @@
 		if (vp->flags & VREADONLY) {
 			if (flags & VNOSAVE)
 				free(s);
+#ifdef _GNU_SOURCE
 			error("%.*s: is read only", strchrnul(s, '=') - s, s);
+#else
+			if (strchr(s,'=') == NULL) {
+				error("%.*s: is read only", strlen(s), s);
+			} else {
+				error("%.*s: is read only", strchr(s, '=') - s, s);
+			}
+#endif
 		}
 
 		if (flags & VNOSET)
 			return;
 
-		if (vp->func && (flags & VNOFUNC) == 0)
-			(*vp->func)(strchrnul(s, '=') + 1);
+		if (vp->func && (flags & VNOFUNC) == 0) {
+			if (strchr(s, '=')) {
+				(*vp->func)(strchr(s, '=') + 1);
+			} else {
+				(*vp->func)(s);
+			}
+		}
 
 		if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
 			ckfree(vp->text);
@@ -12022,7 +12099,9 @@
 	struct var *v;
 
 	if ((v = *findvar(hashvar(name), name)) && !(v->flags & VUNSET)) {
-		return strchrnul(v->text, '=') + 1;
+		if (strchr(v->text, '=')) {
+			return strchr(v->text, '=') + 1;
+		}
 	}
 	return NULL;
 }
@@ -12039,7 +12118,7 @@
 
 	for (sp = cmdenviron ; sp ; sp = sp->next) {
 		if (varequal(sp->text, name))
-			return strchrnul(sp->text, '=') + 1;
+			return strchr(sp->text, '=')?strchr(sp->text, '=') + 1:sp->text;
 	}
 	return lookupvar(name);
 }
@@ -12100,7 +12179,14 @@
 		const char *p;
 		const char *q;
 
+#ifdef _GNU_SOURCE
 		p = strchrnul(*ep, '=');
+#else
+		p = strchr(*ep, '=');
+		if (!p) {
+			p = *ep + strlen(*ep);
+		}
+#endif
 		q = nullstr;
 		if (*p)
 			q = single_quote(++p);
@@ -12235,7 +12321,7 @@
 			unsetvar(vp->text);
 		} else {
 			if (vp->func)
-				(*vp->func)(strchrnul(lvp->text, '=') + 1);
+				(*vp->func)(strchr(lvp->text, '=')?strchr(lvp->text, '=') + 1:lvp->text + strlen(lvp->text));
 			if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
 				ckfree(vp->text);
 			vp->flags = lvp->flags;
Index: sysdeps/linux/Config.in
===================================================================
RCS file: /var/cvs/busybox/sysdeps/linux/Config.in,v
retrieving revision 1.12
diff -u -r1.12 Config.in
--- sysdeps/linux/Config.in	22 Oct 2003 09:58:50 -0000	1.12
+++ sysdeps/linux/Config.in	30 Jan 2004 12:53:38 -0000
@@ -135,9 +135,19 @@
 
 menu 'Build Options'
 
+config CONFIG_DIETLIBC
+	bool "Build BusyBox as a static binary against DietLibc"
+	default n
+	help
+	  If you want to build a static BusyBox binary linked against
+	  dietlibc (e.g. for initrd or initramfs), then enable this option.  
+
+	  Most people will leave this set to 'N'.
+
 config CONFIG_STATIC
 	bool "Build BusyBox as a static binary (no shared libs)"
 	default n
+	depends on CONFIG_DIETLIBC = 'n'
 	help
 	  If you want to build a static BusyBox binary, which does not 
 	  use or require any shared libraries, then enable this option.  
