summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLaMont Jones <lamont@debian.org>2011-01-31 20:15:49 -0700
committerLaMont Jones <lamont@debian.org>2011-01-31 20:15:49 -0700
commit11292d25510e67c83c6580401eccd42d6d6da931 (patch)
treeca5850da93c90f8798d7ff115e0124edffb8bb97 /lib
parent4f9e177060fb5ad6e574598aefdf2d5f50a8b54f (diff)
parent9f55bf3794ca98852dd1f352f993dea60d83a2e1 (diff)
downloadutil-linux-old-11292d25510e67c83c6580401eccd42d6d6da931.tar.gz
Merge remote branch 'origin/master'
Conflicts: mount/mount.8 mount/mount.c
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am4
-rw-r--r--lib/at.c100
-rw-r--r--lib/cpuset.c1
-rw-r--r--lib/env.c36
-rw-r--r--lib/mangle.c44
-rw-r--r--lib/mbsalign.c6
-rw-r--r--lib/md5.c7
-rw-r--r--lib/strutils.c20
-rw-r--r--lib/tt.c33
9 files changed, 224 insertions, 27 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 9a3bf35b..0f13237f 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -3,7 +3,7 @@ include $(top_srcdir)/config/include-Makefile.am
AM_CPPFLAGS += -DTEST_PROGRAM
noinst_PROGRAMS = test_blkdev test_ismounted test_wholedisk test_mangle \
- test_tt test_canonicalize
+ test_tt test_canonicalize test_at test_strutils
if LINUX
if HAVE_CPU_SET_T
noinst_PROGRAMS += test_cpuset
@@ -14,6 +14,8 @@ test_blkdev_SOURCES = blkdev.c
test_ismounted_SOURCES = ismounted.c
test_wholedisk_SOURCES = wholedisk.c
test_mangle_SOURCES = mangle.c
+test_at_SOURCES = at.c
+test_strutils_SOURCES = strutils.c
if LINUX
test_cpuset_SOURCES = cpuset.c
endif
diff --git a/lib/at.c b/lib/at.c
new file mode 100644
index 00000000..1993f998
--- /dev/null
+++ b/lib/at.c
@@ -0,0 +1,100 @@
+/*
+ * Portable xxxat() functions.
+ *
+ * Copyright (C) 2010 Karel Zak <kzak@redhat.com>
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include "at.h"
+
+int fstat_at(int dir, const char *dirname, const char *filename,
+ struct stat *st, int nofollow)
+{
+#ifdef HAVE_FSTATAT
+ return fstatat(dir, filename, st,
+ nofollow ? AT_SYMLINK_NOFOLLOW : 0);
+#else
+ char path[PATH_MAX];
+ int len;
+
+ len = snprintf(path, sizeof(path), "%s/%s", dirname, filename);
+ if (len < 0 || len + 1 > sizeof(path))
+ return -1;
+
+ return nofollow ? lstat(path, st) : stat(path, st);
+#endif
+}
+
+int open_at(int dir, const char *dirname, const char *filename, int flags)
+{
+#ifdef HAVE_FSTATAT
+ return openat(dir, filename, flags);
+#else
+ char path[PATH_MAX];
+ int len;
+
+ len = snprintf(path, sizeof(path), "%s/%s", dirname, filename);
+ if (len < 0 || len + 1 > sizeof(path))
+ return -1;
+
+ return open(path, flags);
+#endif
+}
+
+FILE *fopen_at(int dir, const char *dirname, const char *filename, int flags,
+ const char *mode)
+{
+ int fd = open_at(dir, dirname, filename, flags);
+
+ if (fd < 0)
+ return NULL;
+
+ return fdopen(fd, mode);
+}
+
+#ifdef TEST_PROGRAM
+#include <err.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <string.h>
+
+int main(int argc, char *argv[])
+{
+ DIR *dir;
+ struct dirent *d;
+ char *dirname;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s <directory>\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ dirname = argv[1];
+
+ dir = opendir(dirname);
+ if (!dir)
+ err(EXIT_FAILURE, "%s: open failed", dirname);
+
+ while ((d = readdir(dir))) {
+ struct stat st;
+ FILE *f;
+
+ printf("%32s ", d->d_name);
+
+ if (fstat_at(dirfd(dir), dirname, d->d_name, &st, 0) == 0)
+ printf("%16jd bytes ", st.st_size);
+ else
+ printf("%16s bytes ", "???");
+
+ f = fopen_at(dirfd(dir), dirname, d->d_name, O_RDONLY, "r");
+ printf(" %s\n", f ? "OK" : strerror(errno));
+ if (f)
+ fclose(f);
+ }
+ closedir(dir);
+ return EXIT_SUCCESS;
+}
+#endif
diff --git a/lib/cpuset.c b/lib/cpuset.c
index 27b23498..0c483fa5 100644
--- a/lib/cpuset.c
+++ b/lib/cpuset.c
@@ -13,7 +13,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include <getopt.h>
#include <sched.h>
#include <errno.h>
#include <string.h>
diff --git a/lib/env.c b/lib/env.c
index 82fadf52..770cadff 100644
--- a/lib/env.c
+++ b/lib/env.c
@@ -3,11 +3,22 @@
* Added from shadow-utils package
* by Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
*
- */
+ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#else
+#define PR_GET_DUMPABLE 3
+#endif
+#if (!defined(HAVE_PRCTL) && defined(linux))
+#include <sys/syscall.h>
+#endif
+#include <unistd.h>
+#include <sys/types.h>
+
#include "env.h"
extern char **environ;
@@ -71,3 +82,26 @@ sanitize_env(void)
}
}
+
+char *safe_getenv(const char *arg)
+{
+ uid_t ruid = getuid();
+
+ if (ruid != 0 || (ruid != geteuid()) || (getgid() != getegid()))
+ return NULL;
+#if HAVE_PRCTL
+ if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
+ return NULL;
+#else
+#if (defined(linux) && defined(SYS_prctl))
+ if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
+ return NULL;
+#endif
+#endif
+
+#ifdef HAVE___SECURE_GETENV
+ return __secure_getenv(arg);
+#else
+ return getenv(arg);
+#endif
+}
diff --git a/lib/mangle.c b/lib/mangle.c
index 766d479d..17ca8095 100644
--- a/lib/mangle.c
+++ b/lib/mangle.c
@@ -21,6 +21,9 @@ char *mangle(const char *s)
char *ss, *sp;
int n;
+ if (!s)
+ return NULL;
+
n = strlen(s);
ss = sp = malloc(4*n+1);
if (!sp)
@@ -44,10 +47,13 @@ char *mangle(const char *s)
return ss;
}
-void unmangle_to_buffer(char *s, char *buf, size_t len)
+void unmangle_to_buffer(const char *s, char *buf, size_t len)
{
size_t sz = 0;
+ if (!s)
+ return;
+
while(*s && sz < len - 1) {
if (*s == '\\' && sz + 4 < len - 1 && isoctal(s[1]) &&
isoctal(s[2]) && isoctal(s[3])) {
@@ -63,23 +69,30 @@ void unmangle_to_buffer(char *s, char *buf, size_t len)
*buf = '\0';
}
-static inline char *skip_nonspaces(char *s)
+static inline char *skip_nonspaces(const char *s)
{
while (*s && !(*s == ' ' || *s == '\t'))
s++;
- return s;
+ return (char *) s;
}
/*
* Returns mallocated buffer or NULL in case of error.
*/
-char *unmangle(char *s)
+char *unmangle(const char *s, char **end)
{
- char *buf, *end;
+ char *buf;
+ char *e;
size_t sz;
- end = skip_nonspaces(s);
- sz = end - s + 1;
+ if (!s)
+ return NULL;
+
+ e = skip_nonspaces(s);
+ sz = e - s + 1;
+
+ if (end)
+ *end = e;
buf = malloc(sz);
if (!buf)
@@ -104,11 +117,20 @@ int main(int argc, char *argv[])
printf("mangled: '%s'\n", mangle(argv[2]));
else if (!strcmp(argv[1], "--unmangle")) {
- char *x = unmangle(argv[2]);
- if (x)
+ char *x = unmangle(argv[2], NULL);
+
+ if (x) {
printf("unmangled: '%s'\n", x);
- else
- err(EXIT_FAILURE, "unmangle failed");
+ free(x);
+ }
+
+ x = strdup(argv[2]);
+ unmangle_to_buffer(x, x, strlen(x) + 1);
+
+ if (x) {
+ printf("self-unmangled: '%s'\n", x);
+ free(x);
+ }
}
return EXIT_SUCCESS;
diff --git a/lib/mbsalign.c b/lib/mbsalign.c
index 82ffc09c..468e35b5 100644
--- a/lib/mbsalign.c
+++ b/lib/mbsalign.c
@@ -106,12 +106,12 @@ rpl_wcswidth (const wchar_t *s, size_t n)
size_t
mbs_truncate(char *str, size_t *width)
{
- size_t bytes = strlen(str);
+ ssize_t bytes = strlen(str);
#ifdef HAVE_WIDECHAR
- size_t sz = mbstowcs(NULL, str, 0);
+ ssize_t sz = mbstowcs(NULL, str, 0);
wchar_t *wcs = NULL;
- if (sz == (size_t) -1)
+ if (sz == (ssize_t) -1)
goto done;
wcs = malloc((sz + 1) * sizeof(wchar_t));
diff --git a/lib/md5.c b/lib/md5.c
index 6ad4b684..071630f1 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -14,16 +14,11 @@
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*/
-#include <endian.h>
#include <string.h> /* for memcpy() */
#include "md5.h"
-#if !defined __BYTE_ORDER || !(__BYTE_ORDER == __LITTLE_ENDIAN) && !(__BYTE_ORDER == __BIG_ENDIAN)
-#error missing __BYTE_ORDER
-#endif
-
-#if (__BYTE_ORDER == __LITTLE_ENDIAN)
+#if !defined(WORDS_BIGENDIAN)
#define byteReverse(buf, len) /* Nothing */
#else
void byteReverse(unsigned char *buf, unsigned longs);
diff --git a/lib/strutils.c b/lib/strutils.c
index e8e86865..94635b1e 100644
--- a/lib/strutils.c
+++ b/lib/strutils.c
@@ -273,3 +273,23 @@ char *size_to_human_string(uint64_t bytes)
return strdup(buf);
}
+
+
+#ifdef TEST_PROGRAM
+
+int main(int argc, char *argv[])
+{
+ uintmax_t size = 0;
+
+ if (argc < 2) {
+ fprintf(stderr, "usage: %s <number>[suffix]\n", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ if (strtosize(argv[1], &size))
+ errx(EXIT_FAILURE, "invalid size '%s' value", argv[1]);
+
+ printf("%25s : %20ju\n", argv[1], size);
+ return EXIT_FAILURE;
+}
+#endif /* TEST_PROGRAM */
diff --git a/lib/tt.c b/lib/tt.c
index 1043ee32..3bcdea9e 100644
--- a/lib/tt.c
+++ b/lib/tt.c
@@ -276,7 +276,13 @@ int tt_line_set_data(struct tt_line *ln, int colnum, const char *data)
cl = tt_get_column(ln->table, colnum);
if (!cl)
return -1;
+
+ if (ln->data[cl->seqnum])
+ ln->data_sz -= strlen(ln->data[cl->seqnum]);
+
ln->data[cl->seqnum] = data;
+ if (data)
+ ln->data_sz += strlen(data);
return 0;
}
@@ -304,6 +310,14 @@ static int get_terminal_width(void)
return 0;
}
+int tt_line_set_userdata(struct tt_line *ln, void *data)
+{
+ if (!ln)
+ return -1;
+ ln->userdata = data;
+ return 0;
+}
+
static char *line_get_ascii_art(struct tt_line *ln, char *buf, size_t *bufsz)
{
const char *art;
@@ -624,6 +638,8 @@ static void print_tree(struct tt *tb, char *buf, size_t bufsz)
int tt_print_table(struct tt *tb)
{
char *line;
+ size_t line_sz;
+ struct list_head *p;
if (!tb)
return -1;
@@ -632,15 +648,24 @@ int tt_print_table(struct tt *tb)
if (tb->termwidth <= 0)
tb->termwidth = 80;
}
- line = malloc(tb->termwidth);
+
+ line_sz = tb->termwidth;
+
+ list_for_each(p, &tb->tb_lines) {
+ struct tt_line *ln = list_entry(p, struct tt_line, ln_lines);
+ if (ln->data_sz > line_sz)
+ line_sz = ln->data_sz;
+ }
+
+ line = malloc(line_sz);
if (!line)
return -1;
if (!(tb->flags & TT_FL_RAW))
- recount_widths(tb, line, tb->termwidth);
+ recount_widths(tb, line, line_sz);
if (tb->flags & TT_FL_TREE)
- print_tree(tb, line, tb->termwidth);
+ print_tree(tb, line, line_sz);
else
- print_table(tb, line, tb->termwidth);
+ print_table(tb, line, line_sz);
free(line);
return 0;