aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorBjørn Mork <bjorn@mork.no>2015-05-15 10:23:51 +0200
committerBjørn Mork <bjorn@mork.no>2015-05-15 10:23:51 +0200
commit02013228914a1d17e8df15d4e2b7950469395a5c (patch)
tree48d2fbe2f5a5adb60cbeabc26fadaec8e0fa82ed /libbb
parent9b3dbb454e8f8a463d5fe4541ee2001585527bc6 (diff)
ripe-atlas-fw: imported version 45204520
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Diffstat (limited to 'libbb')
-rw-r--r--libbb/Kbuild5
-rw-r--r--libbb/atlas_bb64.c126
-rw-r--r--libbb/atlas_bb64.h18
-rw-r--r--libbb/atlas_probe.c35
-rw-r--r--libbb/atlas_probe.h6
-rw-r--r--libbb/find_pid_by_name.c2
-rw-r--r--libbb/getopt32.c22
-rw-r--r--libbb/strlcat.c46
-rw-r--r--libbb/strlcpy.c64
-rw-r--r--libbb/validate_filename.c33
-rw-r--r--libbb/xconnect.c38
-rw-r--r--libbb/xfuncs_printf.c56
12 files changed, 445 insertions, 6 deletions
diff --git a/libbb/Kbuild b/libbb/Kbuild
index 786cbee..dead4bf 100644
--- a/libbb/Kbuild
+++ b/libbb/Kbuild
@@ -8,6 +8,8 @@ lib-y:=
lib-y += appletlib.o
lib-y += ask_confirmation.o
+lib-y += atlas_bb64.o
+lib-y += atlas_probe.o
lib-y += bb_askpass.o
lib-y += bb_basename.o
lib-y += bb_do_delay.o
@@ -97,6 +99,7 @@ lib-y += trim.o
lib-y += u_signal_names.o
lib-y += udp_io.o
lib-y += uuencode.o
+lib-y += validate_filename.o
lib-y += vdprintf.o
lib-y += verror_msg.o
lib-y += vfork_daemon_rexec.o
@@ -113,6 +116,8 @@ lib-y += xgetcwd.o
lib-y += xgethostbyname.o
lib-y += xreadlink.o
lib-y += xrealloc_vector.o
+lib-y += strlcat.o
+lib-y += strlcpy.o
# conditionally compiled objects:
lib-$(CONFIG_FEATURE_MOUNT_LOOP) += loop.o
diff --git a/libbb/atlas_bb64.c b/libbb/atlas_bb64.c
new file mode 100644
index 0000000..bcd073b
--- /dev/null
+++ b/libbb/atlas_bb64.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "libbb.h"
+#define BUF_CHUNK 256
+
+struct buf
+{
+ size_t offset;
+ size_t size;
+ size_t maxsize;
+ unsigned char *buf;
+ int fd;
+};
+
+void buf_init(struct buf *buf, int fd)
+{
+ buf->maxsize= 0;
+ buf->size= 0;
+ buf->offset= 0;
+ buf->buf= NULL;
+ buf->fd= fd;
+}
+
+int buf_add(struct buf *buf, const void *data, size_t len )
+{
+ size_t maxsize;
+ void *newbuf;
+
+ if (buf->size+len <= buf->maxsize)
+ {
+ /* Easy case, just add data */
+ memcpy(buf->buf+buf->size, data, len);
+ buf->size += len;
+ return 0;
+ }
+
+ /* Just get a new buffer */
+ maxsize= buf->size-buf->offset + len + BUF_CHUNK;
+
+ newbuf= malloc(maxsize);
+ if (!newbuf)
+ {
+ fprintf(stderr, "unable to allocate %ld bytes\n", maxsize);
+ return (1);
+ }
+
+ if (buf->offset < buf->size)
+ {
+ /* Copy existing data */
+ memcpy(newbuf, buf->buf+buf->offset, buf->size-buf->offset);
+ buf->size -= buf->offset;
+ buf->offset= 0;
+ }
+ else
+ {
+ buf->size= buf->offset= 0;
+ }
+ buf->maxsize= maxsize;
+ free(buf->buf);
+ buf->buf= newbuf;
+
+ memcpy(buf->buf+buf->size, data, len);
+ buf->size += len;
+ return 0;
+}
+
+int buf_add_b64(struct buf *buf, void *data, size_t len, int mime_nl)
+{
+ char b64[]=
+ "ABCDEFGHIJKLMNOP"
+ "QRSTUVWXYZabcdef"
+ "ghijklmnopqrstuv"
+ "wxyz0123456789+/";
+ int i;
+ uint8_t *p;
+ uint32_t v;
+ char str[4];
+
+ p= data;
+
+ for (i= 0; i+3 <= len; i += 3, p += 3)
+ {
+ v= (p[0] << 16) + (p[1] << 8) + p[2];
+ str[0]= b64[(v >> 18) & 63];
+ str[1]= b64[(v >> 12) & 63];
+ str[2]= b64[(v >> 6) & 63];
+ str[3]= b64[(v >> 0) & 63];
+ buf_add(buf, str, 4);
+ if(mime_nl)
+ if (i % 48 == 45)
+ buf_add(buf, "\n", 1);
+ }
+ switch(len-i)
+ {
+ case 0: break; /* Nothing to do */
+ case 1:
+ v= (p[0] << 16);
+ str[0]= b64[(v >> 18) & 63];
+ str[1]= b64[(v >> 12) & 63];
+ str[2]= '=';
+ str[3]= '=';
+ buf_add(buf, str, 4);
+ break;
+ case 2:
+ v= (p[0] << 16) + (p[1] << 8);
+ str[0]= b64[(v >> 18) & 63];
+ str[1]= b64[(v >> 12) & 63];
+ str[2]= b64[(v >> 6) & 63];
+ str[3]= '=';
+ buf_add(buf, str, 4);
+ break;
+ default:
+ fprintf(stderr, "bad state in buf_add_b64");
+ }
+}
+
+void buf_cleanup(struct buf *buf)
+{
+ if(buf->maxsize)
+ free(buf->buf);
+ buf->buf = NULL;
+ buf->offset= buf->size= buf->maxsize= 0;
+}
diff --git a/libbb/atlas_bb64.h b/libbb/atlas_bb64.h
new file mode 100644
index 0000000..d745a9b
--- /dev/null
+++ b/libbb/atlas_bb64.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+struct buf
+{
+ size_t offset;
+ size_t size;
+ size_t maxsize;
+ char *buf;
+ int fd;
+};
+
+void buf_init(struct buf *buf, int fd);
+int buf_add(struct buf *buf, const void *data, size_t len );
+int buf_add_b64(struct buf *buf, void *data, size_t len, int mime_nl);
+void buf_cleanup(struct buf *buf);
diff --git a/libbb/atlas_probe.c b/libbb/atlas_probe.c
new file mode 100644
index 0000000..a3264fb
--- /dev/null
+++ b/libbb/atlas_probe.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include "libbb.h"
+int get_probe_id(void)
+{
+ int probe_id;
+ size_t len;
+ char *check;
+ const char *key;
+ FILE *fp;
+ char buf[80];
+
+ fp= fopen("/home/atlas/status/reg_init_reply.txt", "r");
+ if (!fp)
+ return -1;
+
+ probe_id= -1;
+ while (fgets(buf, sizeof(buf), fp) != NULL)
+ {
+ if (strchr(buf, '\n') == NULL)
+ continue;
+ key= "PROBE_ID ";
+ len= strlen(key);
+
+ if (strncmp(buf, key, len) != 0 || strlen(buf) <= len)
+ continue;
+ probe_id= strtol(buf+len, &check, 10);
+ break;
+ }
+ fclose(fp);
+ return probe_id;
+}
diff --git a/libbb/atlas_probe.h b/libbb/atlas_probe.h
new file mode 100644
index 0000000..2787985
--- /dev/null
+++ b/libbb/atlas_probe.h
@@ -0,0 +1,6 @@
+/*
+ * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+int get_probe_id(void);
diff --git a/libbb/find_pid_by_name.c b/libbb/find_pid_by_name.c
index 92d6d02..90851eb 100644
--- a/libbb/find_pid_by_name.c
+++ b/libbb/find_pid_by_name.c
@@ -38,7 +38,7 @@ execXXX("/proc/self/exe", applet_name, params....)
and therefore comm field contains "exe".
*/
-static int comm_match(procps_status_t *p, const char *procName)
+int comm_match(procps_status_t *p, const char *procName)
{
int argv1idx;
diff --git a/libbb/getopt32.c b/libbb/getopt32.c
index 17babcd..198149d 100644
--- a/libbb/getopt32.c
+++ b/libbb/getopt32.c
@@ -3,6 +3,7 @@
* universal getopt32 implementation for busybox
*
* Copyright (C) 2003-2005 Vladimir Oleynik <dzo@simtreas.ru>
+ * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
*
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
@@ -327,6 +328,7 @@ getopt32(char **argv, const char *applet_opts, ...)
unsigned flags = 0;
unsigned requires = 0;
t_complementary complementary[33]; /* last stays zero-filled */
+ char first_char;
int c;
const unsigned char *s;
t_complementary *on_off;
@@ -357,6 +359,11 @@ getopt32(char **argv, const char *applet_opts, ...)
on_off = complementary;
memset(on_off, 0, sizeof(complementary));
+ /* skip bbox extension */
+ first_char = applet_opts[0];
+ if (first_char == '!')
+ applet_opts++;
+
/* skip GNU extension */
s = (const unsigned char *)applet_opts;
if (*s == '+' || *s == '-')
@@ -549,11 +556,11 @@ getopt32(char **argv, const char *applet_opts, ...)
* is always NULL (see above) */
if (on_off->opt_char == '\0' /* && c != '\0' */) {
/* c is probably '?' - "bad option" */
- bb_show_usage();
+ goto error;
}
}
if (flags & on_off->incongruously)
- bb_show_usage();
+ goto error;
trigger = on_off->switch_on & on_off->switch_off;
flags &= ~(on_off->switch_off ^ trigger);
flags |= on_off->switch_on ^ trigger;
@@ -579,14 +586,19 @@ getopt32(char **argv, const char *applet_opts, ...)
for (on_off = complementary; on_off->opt_char; on_off++) {
if (on_off->requires && (flags & on_off->switch_on) &&
(flags & on_off->requires) == 0)
- bb_show_usage();
+ goto error;
}
if (requires && (flags & requires) == 0)
- bb_show_usage();
+ goto error;
argc -= optind;
if (argc < min_arg || (max_arg >= 0 && argc > max_arg))
- bb_show_usage();
+ goto error;
option_mask32 = flags;
return flags;
+
+ error:
+ if (first_char != '!')
+ bb_show_usage();
+ return (int32_t)-1;
}
diff --git a/libbb/strlcat.c b/libbb/strlcat.c
new file mode 100644
index 0000000..6dd7747
--- /dev/null
+++ b/libbb/strlcat.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2002 Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+/* OpenBSD function:
+ * Append at most n-1-strlen(dst) chars from src to dst and nul-terminate dst.
+ * Returns strlen(src) + strlen({original} dst), so truncation occurred if the
+ * return val is >= n.
+ * Note: If dst doesn't contain a nul in the first n chars, strlen(dst) is
+ * taken as n. */
+
+#include "libbb.h"
+
+size_t strlcat(register char *__restrict dst,
+ register const char *__restrict src,
+ size_t n)
+{
+ size_t len;
+ char dummy[1];
+
+ len = 0;
+
+ while (1) {
+ if (len >= n) {
+ dst = dummy;
+ break;
+ }
+ if (!*dst) {
+ break;
+ }
+ ++dst;
+ ++len;
+ }
+
+ while ((*dst = *src) != 0) {
+ if (++len < n) {
+ ++dst;
+ }
+ ++src;
+ }
+
+ return len;
+}
diff --git a/libbb/strlcpy.c b/libbb/strlcpy.c
new file mode 100644
index 0000000..02cd55a
--- /dev/null
+++ b/libbb/strlcpy.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2002 Manuel Novoa III
+ * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "libbb.h"
+
+#ifdef WANT_WIDE
+# define Wstrlcpy __wcslcpy
+# define Wstrxfrm wcsxfrm
+#else
+// libc_hidden_proto(strlcpy)
+# define Wstrlcpy strlcpy
+# define Wstrxfrm strxfrm
+# define Wchar char
+#endif
+
+
+/* OpenBSD function:
+ * Copy at most n-1 chars from src to dst and nul-terminate dst.
+ * Returns strlen(src), so truncation occurred if the return value is >= n. */
+
+#ifdef WANT_WIDE
+size_t Wstrlcpy(register Wchar *__restrict dst,
+ register const Wchar *__restrict src,
+ size_t n) attribute_hidden;
+#endif
+size_t Wstrlcpy(register Wchar *__restrict dst,
+ register const Wchar *__restrict src,
+ size_t n)
+{
+ const Wchar *src0 = src;
+ Wchar dummy[1];
+
+ if (!n) {
+ dst = dummy;
+ } else {
+ --n;
+ }
+
+ while ((*dst = *src) != 0) {
+ if (n) {
+ --n;
+ ++dst;
+ }
+ ++src;
+ }
+
+ return src - src0;
+}
+#ifndef WANT_WIDE
+//libc_hidden_def(strlcpy)
+#ifndef __UCLIBC_HAS_LOCALE__
+//libc_hidden_proto(strxfrm)
+//strong_alias(strlcpy,strxfrm)
+//libc_hidden_def(strxfrm)
+#endif
+#else
+#ifndef __UCLIBC_HAS_LOCALE__
+strong_alias(__wcslcpy,wcsxfrm)
+#endif
+#endif
diff --git a/libbb/validate_filename.c b/libbb/validate_filename.c
new file mode 100644
index 0000000..2b9b80a
--- /dev/null
+++ b/libbb/validate_filename.c
@@ -0,0 +1,33 @@
+#include "libbb.h"
+
+int validate_filename(const char *path, const char *prefix)
+{
+ size_t path_len, prefix_len;
+
+ /* Check for the following properties:
+ * 1) path start with prefix
+ * 2) the next character after prefix is a '/'
+ * 3) path does not contain '/../'
+ * 4) path does not end in '/..'
+ * return 0 if any of the properties does not hold
+ * return 1 if all properties hold
+ */
+ path_len= strlen(path);
+ prefix_len= strlen(prefix);
+ if (path_len < prefix_len)
+ return 0;
+
+ if (memcmp(path, prefix, prefix_len) != 0)
+ return 0; /* property 1 */
+
+ if (path[prefix_len] != '/')
+ return 0; /* property 2 */
+
+ if (strstr(path, "/../") != NULL)
+ return 0; /* property 3 */
+
+ if (path_len >= 3 && strcmp(&path[path_len-3], "/..") == 0)
+ return 0; /* property 4 */
+
+ return 1;
+}
diff --git a/libbb/xconnect.c b/libbb/xconnect.c
index 27c7424..f313655 100644
--- a/libbb/xconnect.c
+++ b/libbb/xconnect.c
@@ -32,6 +32,24 @@ int FAST_FUNC setsockopt_bindtodevice(int fd, const char *iface)
return r;
}
+len_and_sockaddr* FAST_FUNC get_sock_lsa(int fd)
+{
+ len_and_sockaddr lsa;
+ len_and_sockaddr *lsa_ptr;
+
+ lsa.len = LSA_SIZEOF_SA;
+ if (getsockname(fd, &lsa.u.sa, &lsa.len) != 0)
+ return NULL;
+
+ lsa_ptr = xzalloc(LSA_LEN_SIZE + lsa.len);
+ if (lsa.len > LSA_SIZEOF_SA) { /* rarely (if ever) happens */
+ lsa_ptr->len = lsa.len;
+ getsockname(fd, &lsa_ptr->u.sa, &lsa_ptr->len);
+ } else {
+ memcpy(lsa_ptr, &lsa, LSA_LEN_SIZE + lsa.len);
+ }
+ return lsa_ptr;
+}
void FAST_FUNC xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen)
{
@@ -46,6 +64,26 @@ void FAST_FUNC xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen)
}
}
+void FAST_FUNC xrconnect(int s,
+ const struct sockaddr *s_addr, socklen_t addrlen,
+ void (*reportf)(int err))
+{
+ if (connect(s, s_addr, addrlen) < 0) {
+ if (reportf) {
+ int t_errno= errno;
+ reportf(t_errno);
+ errno= t_errno;
+ }
+ if (ENABLE_FEATURE_CLEAN_UP)
+ close(s);
+ if (s_addr->sa_family == AF_INET)
+ bb_perror_msg_and_die("%s (%s)",
+ "cannot connect to remote host",
+ inet_ntoa(((struct sockaddr_in *)s_addr)->sin_addr));
+ bb_perror_msg_and_die("cannot connect to remote host");
+ }
+}
+
/* Return port number for a service.
* If "port" is a number use it as the port.
* If "port" is a name it is looked up in /etc/services, if it isnt found return
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c
index 108e140..0bee40a 100644
--- a/libbb/xfuncs_printf.c
+++ b/libbb/xfuncs_printf.c
@@ -409,6 +409,21 @@ void FAST_FUNC xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind");
}
+// Call a user supplied reporting function and die with an error message if we
+// can't bind a socket to an address.
+void FAST_FUNC xrbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen,
+ void (*reportf)(int err))
+{
+ if (bind(sockfd, my_addr, addrlen)) {
+ if (reportf) {
+ int t_errno= errno;
+ reportf(t_errno);
+ errno= t_errno;
+ }
+ bb_perror_msg_and_die("bind");
+ }
+}
+
// Die with an error message if we can't listen for connections on a socket.
void FAST_FUNC xlisten(int s, int backlog)
{
@@ -429,6 +444,47 @@ ssize_t FAST_FUNC xsendto(int s, const void *buf, size_t len, const struct sock
return ret;
}
+/* Call a user supplied function and die with an error message if sendto failed.
+ * Return bytes sent otherwise */
+ssize_t FAST_FUNC xrsendto(int s, const void *buf, size_t len,
+ const struct sockaddr *to, socklen_t tolen,
+ void (*reportf)(int err))
+{
+ ssize_t ret = sendto(s, buf, len, 0, to, tolen);
+ if (ret < 0) {
+ if (reportf) {
+ int t_errno= errno;
+ reportf(t_errno);
+ t_errno= errno;
+ }
+ if (ENABLE_FEATURE_CLEAN_UP)
+ close(s);
+ bb_perror_msg_and_die("sendto");
+ }
+ return ret;
+}
+
+/* Call a user supplied function with an error message if sendto failed.
+ * Return bytes sent otherwise */
+ssize_t FAST_FUNC rsendto(int s, const void *buf, size_t len,
+ const struct sockaddr *to, socklen_t tolen,
+ void (*reportf)(int err))
+{
+ ssize_t ret = sendto(s, buf, len, 0, to, tolen);
+ if (ret < 0) {
+ int t_errno= errno;
+ if (reportf) {
+ reportf(t_errno);
+ }
+ if (ENABLE_FEATURE_CLEAN_UP)
+ close(s);
+ errno= t_errno;
+ bb_perror_msg("sendto");
+ errno= t_errno;
+ }
+ return ret;
+}
+
// xstat() - a stat() which dies on failure with meaningful error message
void FAST_FUNC xstat(const char *name, struct stat *stat_buf)
{