Merge "Extend to receive NFLOG packets."
diff --git a/include/cutils/debugger.h b/include/cutils/debugger.h
index 4bcc8e6..bae687d 100644
--- a/include/cutils/debugger.h
+++ b/include/cutils/debugger.h
@@ -64,11 +64,26 @@
*/
int dump_tombstone(pid_t tid, char* pathbuf, size_t pathlen);
+/* Dumps a process backtrace, registers, and stack to a tombstone file (requires root).
+ * Stores the tombstone path in the provided buffer.
+ * If reading debugger data from debuggerd ever takes longer than timeout_secs
+ * seconds, then stop and return an error.
+ * Returns 0 on success, -1 on error.
+ */
+int dump_tombstone_timeout(pid_t tid, char* pathbuf, size_t pathlen, int timeout_secs);
+
/* Dumps a process backtrace only to the specified file (requires root).
* Returns 0 on success, -1 on error.
*/
int dump_backtrace_to_file(pid_t tid, int fd);
+/* Dumps a process backtrace only to the specified file (requires root).
+ * If reading debugger data from debuggerd ever takes longer than timeout_secs
+ * seconds, then stop and return an error.
+ * Returns 0 on success, -1 on error.
+ */
+int dump_backtrace_to_file_timeout(pid_t tid, int fd, int timeout_secs);
+
#ifdef __cplusplus
}
#endif
diff --git a/libcutils/debugger.c b/libcutils/debugger.c
index 4035ee1..b8a2efc 100644
--- a/libcutils/debugger.c
+++ b/libcutils/debugger.c
@@ -19,11 +19,16 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
#include <unistd.h>
#include <cutils/debugger.h>
#include <cutils/sockets.h>
+#define LOG_TAG "DEBUG"
+#include <log/log.h>
+
#if defined(__LP64__)
#include <elf.h>
@@ -64,7 +69,7 @@
return result;
}
-static int make_dump_request(debugger_action_t action, pid_t tid) {
+static int make_dump_request(debugger_action_t action, pid_t tid, int timeout_secs) {
const char* socket_name;
debugger_msg_t msg;
size_t msg_len;
@@ -98,6 +103,19 @@
return -1;
}
+ if (timeout_secs > 0) {
+ struct timeval tm;
+ tm.tv_sec = timeout_secs;
+ tm.tv_usec = 0;
+ if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tm, sizeof(tm)) == -1) {
+ ALOGE("WARNING: Cannot set receive timeout value on socket: %s", strerror(errno));
+ }
+
+ if (setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, &tm, sizeof(tm)) == -1) {
+ ALOGE("WARNING: Cannot set send timeout value on socket: %s", strerror(errno));
+ }
+ }
+
if (send_request(sock_fd, msg_ptr, msg_len) < 0) {
TEMP_FAILURE_RETRY(close(sock_fd));
return -1;
@@ -107,7 +125,11 @@
}
int dump_backtrace_to_file(pid_t tid, int fd) {
- int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_BACKTRACE, tid);
+ return dump_backtrace_to_file_timeout(tid, fd, 0);
+}
+
+int dump_backtrace_to_file_timeout(pid_t tid, int fd, int timeout_secs) {
+ int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_BACKTRACE, tid, timeout_secs);
if (sock_fd < 0) {
return -1;
}
@@ -127,7 +149,11 @@
}
int dump_tombstone(pid_t tid, char* pathbuf, size_t pathlen) {
- int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_TOMBSTONE, tid);
+ return dump_tombstone_timeout(tid, pathbuf, pathlen, 0);
+}
+
+int dump_tombstone_timeout(pid_t tid, char* pathbuf, size_t pathlen, int timeout_secs) {
+ int sock_fd = make_dump_request(DEBUGGER_ACTION_DUMP_TOMBSTONE, tid, timeout_secs);
if (sock_fd < 0) {
return -1;
}
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 1c74ba5..6307bed 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -242,7 +242,7 @@
LastLogTimes::iterator t = mTimes.begin();
while(t != mTimes.end()) {
LogTimeEntry *entry = (*t);
- if (entry->owned_Locked()
+ if (entry->owned_Locked() && entry->isWatching(id)
&& (!oldest || (oldest->mStart > entry->mStart))) {
oldest = entry;
}
@@ -354,7 +354,7 @@
// kick a misbehaving log reader client off the island
oldest->release_Locked();
} else {
- oldest->triggerSkip_Locked(pruneRows);
+ oldest->triggerSkip_Locked(id, pruneRows);
}
}
break;
@@ -385,7 +385,7 @@
// kick a misbehaving log reader client off the island
oldest->release_Locked();
} else {
- oldest->triggerSkip_Locked(pruneRows);
+ oldest->triggerSkip_Locked(id, pruneRows);
}
break;
}
diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp
index ea4e8c8..5f9db8d 100644
--- a/logd/LogTimes.cpp
+++ b/logd/LogTimes.cpp
@@ -36,7 +36,6 @@
, mReader(reader)
, mLogMask(logMask)
, mPid(pid)
- , skipAhead(0)
, mCount(0)
, mTail(tail)
, mIndex(0)
@@ -46,6 +45,7 @@
, mEnd(CLOCK_MONOTONIC)
{
pthread_cond_init(&threadTriggeredCondition, NULL);
+ cleanSkip_Locked();
}
void LogTimeEntry::startReader_Locked(void) {
@@ -148,6 +148,8 @@
break;
}
+ me->cleanSkip_Locked();
+
pthread_cond_wait(&me->threadTriggeredCondition, ×Lock);
}
@@ -169,7 +171,7 @@
}
if ((!me->mPid || (me->mPid == element->getPid()))
- && (me->mLogMask & (1 << element->getLogId()))) {
+ && (me->isWatching(element->getLogId()))) {
++me->mCount;
}
@@ -184,19 +186,19 @@
LogTimeEntry::lock();
- if (me->skipAhead) {
- me->skipAhead--;
+ me->mStart = element->getMonotonicTime();
+
+ if (me->skipAhead[element->getLogId()]) {
+ me->skipAhead[element->getLogId()]--;
goto skip;
}
- me->mStart = element->getMonotonicTime();
-
// Truncate to close race between first and second pass
if (me->mNonBlock && me->mTail && (me->mIndex >= me->mCount)) {
goto skip;
}
- if ((me->mLogMask & (1 << element->getLogId())) == 0) {
+ if (!me->isWatching(element->getLogId())) {
goto skip;
}
@@ -223,7 +225,7 @@
}
ok:
- if (!me->skipAhead) {
+ if (!me->skipAhead[element->getLogId()]) {
LogTimeEntry::unlock();
return true;
}
@@ -233,3 +235,9 @@
LogTimeEntry::unlock();
return false;
}
+
+void LogTimeEntry::cleanSkip_Locked(void) {
+ for (log_id_t i = LOG_ID_MIN; i < LOG_ID_MAX; i = (log_id_t) (i + 1)) {
+ skipAhead[i] = 0;
+ }
+}
diff --git a/logd/LogTimes.h b/logd/LogTimes.h
index 0bfa7a2..81aedfb 100644
--- a/logd/LogTimes.h
+++ b/logd/LogTimes.h
@@ -22,6 +22,7 @@
#include <sys/types.h>
#include <sysutils/SocketClient.h>
#include <utils/List.h>
+#include <log/log.h>
class LogReader;
@@ -38,7 +39,7 @@
static void threadStop(void *me);
const unsigned int mLogMask;
const pid_t mPid;
- unsigned int skipAhead;
+ unsigned int skipAhead[LOG_ID_MAX];
unsigned long mCount;
unsigned long mTail;
unsigned long mIndex;
@@ -67,7 +68,8 @@
pthread_cond_signal(&threadTriggeredCondition);
}
- void triggerSkip_Locked(unsigned int skip) { skipAhead = skip; }
+ void triggerSkip_Locked(log_id_t id, unsigned int skip) { skipAhead[id] = skip; }
+ void cleanSkip_Locked(void);
// Called after LogTimeEntry removed from list, lock implicitly held
void release_Locked(void) {
@@ -99,7 +101,7 @@
// No one else is holding a reference to this
delete this;
}
-
+ bool isWatching(log_id_t id) { return (mLogMask & (1<<id)) != 0; }
// flushTo filter callbacks
static bool FilterFirstPass(const LogBufferElement *element, void *me);
static bool FilterSecondPass(const LogBufferElement *element, void *me);
diff --git a/sdcard/sdcard.c b/sdcard/sdcard.c
index a48906a..4d50bf0 100644
--- a/sdcard/sdcard.c
+++ b/sdcard/sdcard.c
@@ -169,6 +169,11 @@
__u32 refcount;
__u64 nid;
__u64 gen;
+ /*
+ * The inode number for this FUSE node. Note that this isn't stable across
+ * multiple invocations of the FUSE daemon.
+ */
+ __u32 ino;
/* State derived based on current position in hierarchy. */
perm_t perm;
@@ -225,6 +230,25 @@
struct node root;
char obbpath[PATH_MAX];
+ /* Used to allocate unique inode numbers for fuse nodes. We use
+ * a simple counter based scheme where inode numbers from deleted
+ * nodes aren't reused. Note that inode allocations are not stable
+ * across multiple invocation of the sdcard daemon, but that shouldn't
+ * be a huge problem in practice.
+ *
+ * Note that we restrict inodes to 32 bit unsigned integers to prevent
+ * truncation on 32 bit processes when unsigned long long stat.st_ino is
+ * assigned to an unsigned long ino_t type in an LP32 process.
+ *
+ * Also note that fuse_attr and fuse_dirent inode values are 64 bits wide
+ * on both LP32 and LP64, but the fuse kernel code doesn't squash 64 bit
+ * inode numbers into 32 bit values on 64 bit kernels (see fuse_squash_ino
+ * in fs/fuse/inode.c).
+ *
+ * Accesses must be guarded by |lock|.
+ */
+ __u32 inode_ctr;
+
Hashmap* package_to_appid;
Hashmap* appid_with_rw;
};
@@ -388,7 +412,7 @@
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
{
- attr->ino = node->nid;
+ attr->ino = node->ino;
attr->size = s->st_size;
attr->blocks = s->st_blocks;
attr->atime = s->st_atim.tv_sec;
@@ -576,6 +600,13 @@
struct node *node;
size_t namelen = strlen(name);
+ // Detect overflows in the inode counter. "4 billion nodes should be enough
+ // for everybody".
+ if (fuse->inode_ctr == 0) {
+ ERROR("No more inode numbers available");
+ return NULL;
+ }
+
node = calloc(1, sizeof(struct node));
if (!node) {
return NULL;
@@ -597,6 +628,7 @@
}
node->namelen = namelen;
node->nid = ptr_to_id(node);
+ node->ino = fuse->inode_ctr++;
node->gen = fuse->next_generation++;
derive_permissions_locked(fuse, parent, node);
@@ -701,6 +733,7 @@
fuse->derive = derive;
fuse->split_perms = split_perms;
fuse->write_gid = write_gid;
+ fuse->inode_ctr = 1;
memset(&fuse->root, 0, sizeof(fuse->root));
fuse->root.nid = FUSE_ROOT_ID; /* 1 */
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index f163cb8..3d568fc 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -13,13 +13,6 @@
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := upstream-netbsd/sbin/chown/chown.c
-LOCAL_CFLAGS += $(common_cflags) -Dmain=chown_main
-LOCAL_MODULE := libtoolbox_chown
-LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mk
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
upstream-netbsd/bin/dd/args.c \
upstream-netbsd/bin/dd/conv.c \
@@ -55,20 +48,16 @@
include $(CLEAR_VARS)
BSD_TOOLS := \
- chown \
dd \
du \
grep \
OUR_TOOLS := \
- cmp \
- date \
df \
getevent \
getprop \
getsebool \
id \
- ifconfig \
iftop \
ioctl \
ionice \
@@ -79,7 +68,6 @@
mount \
nandread \
newfs_msdos \
- notify \
ps \
renice \
restorecon \
@@ -108,7 +96,6 @@
upstream-netbsd/lib/libc/string/swab.c \
upstream-netbsd/lib/libutil/raise_default_signal.c \
dynarray.c \
- pwcache.c \
$(patsubst %,%.c,$(OUR_TOOLS)) \
toolbox.c \
diff --git a/toolbox/bsd-compatibility.h b/toolbox/bsd-compatibility.h
index 36ddca9..434d370 100644
--- a/toolbox/bsd-compatibility.h
+++ b/toolbox/bsd-compatibility.h
@@ -52,11 +52,6 @@
__BEGIN_DECLS
-/* From NetBSD <grp.h> and <pwd.h>. */
-char* group_from_gid(gid_t gid, int noname);
-int uid_from_user(const char* name, uid_t* uid);
-char* user_from_uid(uid_t uid, int noname);
-
/* From NetBSD <stdlib.h>. */
#define HN_DECIMAL 0x01
#define HN_NOSPACE 0x02
diff --git a/toolbox/cmp.c b/toolbox/cmp.c
deleted file mode 100644
index 80635ad..0000000
--- a/toolbox/cmp.c
+++ /dev/null
@@ -1,91 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-
-int cmp_main(int argc, char *argv[])
-{
- int c;
- int fd1, fd2;
- char buf1[4096], buf2[4096];
- int res, res1, res2;
- int rv = 0;
- int i;
- int filepos = 0;
-
- int show_byte = 0;
- int show_all = 0;
- int limit = 0;
-
- do {
- c = getopt(argc, argv, "bln:");
- if (c == EOF)
- break;
- switch (c) {
- case 'b':
- show_byte = 1;
- break;
- case 'l':
- show_all = 1;
- break;
- case 'n':
- limit = atoi(optarg);
- break;
- case '?':
- fprintf(stderr, "%s: invalid option -%c\n",
- argv[0], optopt);
- exit(1);
- }
- } while (1);
-
- if (optind + 2 != argc) {
- fprintf(stderr, "Usage: %s [-b] [-l] [-n count] file1 file2\n", argv[0]);
- exit(1);
- }
-
- fd1 = open(argv[optind], O_RDONLY);
- if(fd1 < 0) {
- fprintf(stderr, "could not open %s, %s\n", argv[optind], strerror(errno));
- return 1;
- }
-
- fd2 = open(argv[optind+1], O_RDONLY);
- if(fd2 < 0) {
- fprintf(stderr, "could not open %s, %s\n", argv[optind+1], strerror(errno));
- return 1;
- }
-
- while(1) {
- res1 = read(fd1, &buf1, sizeof(buf1));
- res2 = read(fd2, &buf2, sizeof(buf2));
- res = res1 < res2 ? res1 : res2;
- if(res1 == 0 && res2 == 0) {
- return rv;
- }
- for(i = 0; i < res; i++) {
- if(buf1[i] != buf2[i]) {
- printf("%s %s differ byte %d", argv[optind], argv[optind+1], filepos + i);
- if(show_byte)
- printf(" 0x%02x 0x%02x", buf1[i], buf2[i]);
- printf("\n");
- if(!show_all)
- return 1;
- rv = 1;
- }
- if(limit) {
- limit--;
- if(limit == 0)
- return rv;
- }
- }
- if(res1 != res2 || res < 0) {
- printf("%s on %s\n", res < 0 ? "Read error" : "EOF", res1 < res2 ? argv[optind] : argv[optind+1]);
- return 1;
- }
- filepos += res;
- }
-}
diff --git a/toolbox/date.c b/toolbox/date.c
deleted file mode 100644
index 70ce1d5..0000000
--- a/toolbox/date.c
+++ /dev/null
@@ -1,227 +0,0 @@
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <linux/android_alarm.h>
-#include <linux/rtc.h>
-#include <sys/ioctl.h>
-
-static int settime_alarm(struct timespec *ts) {
- int fd, ret;
-
- fd = open("/dev/alarm", O_RDWR);
- if (fd < 0)
- return fd;
-
- ret = ioctl(fd, ANDROID_ALARM_SET_RTC, ts);
- close(fd);
- return ret;
-}
-
-static int settime_alarm_tm(struct tm *tm) {
- time_t t;
- struct timespec ts;
-
- t = mktime(tm);
- ts.tv_sec = t;
- ts.tv_nsec = 0;
- return settime_alarm(&ts);
-}
-
-static int settime_alarm_timeval(struct timeval *tv) {
- struct timespec ts;
-
- ts.tv_sec = tv->tv_sec;
- ts.tv_nsec = tv->tv_usec * 1000;
- return settime_alarm(&ts);
-}
-
-static int settime_rtc_tm(struct tm *tm) {
- int fd, ret;
- struct timeval tv;
- struct rtc_time rtc;
-
- fd = open("/dev/rtc0", O_RDWR);
- if (fd < 0)
- return fd;
-
- tv.tv_sec = mktime(tm);
- tv.tv_usec = 0;
-
- ret = settimeofday(&tv, NULL);
- if (ret < 0)
- goto done;
-
- memset(&rtc, 0, sizeof(rtc));
- rtc.tm_sec = tm->tm_sec;
- rtc.tm_min = tm->tm_min;
- rtc.tm_hour = tm->tm_hour;
- rtc.tm_mday = tm->tm_mday;
- rtc.tm_mon = tm->tm_mon;
- rtc.tm_year = tm->tm_year;
- rtc.tm_wday = tm->tm_wday;
- rtc.tm_yday = tm->tm_yday;
- rtc.tm_isdst = tm->tm_isdst;
-
- ret = ioctl(fd, RTC_SET_TIME, rtc);
-done:
- close(fd);
- return ret;
-}
-
-static int settime_rtc_timeval(struct timeval *tv) {
- struct tm tm, *err;
- time_t t = tv->tv_sec;
-
- err = gmtime_r(&t, &tm);
- if (!err)
- return -1;
-
- return settime_rtc_tm(&tm);
-}
-
-static void settime(char *s) {
- struct tm tm;
- int day = atoi(s);
- int hour;
-
- while (*s && *s != '.')
- s++;
-
- if (*s)
- s++;
-
- hour = atoi(s);
-
- tm.tm_year = day / 10000 - 1900;
- tm.tm_mon = (day % 10000) / 100 - 1;
- tm.tm_mday = (day % 100);
- tm.tm_hour = hour / 10000;
- tm.tm_min = (hour % 10000) / 100;
- tm.tm_sec = (hour % 100);
- tm.tm_isdst = -1;
-
- if (settime_alarm_tm(&tm) < 0)
- settime_rtc_tm(&tm);
-}
-
-static char *parse_time(const char *str, struct timeval *ts) {
- char *s;
- long fs = 0; /* fractional seconds */
-
- ts->tv_sec = strtoumax(str, &s, 10);
-
- if (*s == '.') {
- s++;
- int count = 0;
-
- /* read up to 6 digits (microseconds) */
- while (*s && isdigit(*s)) {
- if (++count < 7) {
- fs = fs*10 + (*s - '0');
- }
- s++;
- }
-
- for (; count < 6; count++) {
- fs *= 10;
- }
- }
-
- ts->tv_usec = fs;
- return s;
-}
-
-int date_main(int argc, char *argv[])
-{
- int c;
- int res;
- struct tm tm;
- time_t t;
- struct timeval tv;
- char strbuf[260];
-
- int useutc = 0;
-
- tzset();
-
- do {
- c = getopt(argc, argv, "us:");
- if (c == EOF)
- break;
- switch (c) {
- case 'u':
- useutc = 1;
- break;
- case 's':
- settime(optarg);
- break;
- case '?':
- fprintf(stderr, "%s: invalid option -%c\n",
- argv[0], optopt);
- exit(1);
- }
- } while (1);
- if(optind + 2 < argc) {
- fprintf(stderr,"%s [-u] [date]\n", argv[0]);
- return 1;
- }
-
- int hasfmt = argc == optind + 1 && argv[optind][0] == '+';
- if(optind == argc || hasfmt) {
- time(&t);
- if (useutc) {
- gmtime_r(&t, &tm);
- strftime(strbuf, sizeof(strbuf),
- (hasfmt ? argv[optind] + 1 : "%a %b %e %H:%M:%S GMT %Y"),
- &tm);
- } else {
- localtime_r(&t, &tm);
- strftime(strbuf, sizeof(strbuf),
- (hasfmt ? argv[optind] + 1 : "%a %b %e %H:%M:%S %Z %Y"),
- &tm);
- }
- printf("%s\n", strbuf);
- }
- else if(optind + 1 == argc) {
-#if 0
- struct tm *tmptr;
- tmptr = getdate(argv[optind]);
- if(tmptr == NULL) {
- fprintf(stderr,"getdate_r failed\n");
- return 1;
- }
- tm = *tmptr;
-#if 0
- if(getdate_r(argv[optind], &tm) < 0) {
- fprintf(stderr,"getdate_r failed %s\n", strerror(errno));
- return 1;
- }
-#endif
-#endif
- //strptime(argv[optind], NULL, &tm);
- //tv.tv_sec = mktime(&tm);
- //tv.tv_usec = 0;
- parse_time(argv[optind], &tv);
- printf("time %s -> %lu.%lu\n", argv[optind], tv.tv_sec, tv.tv_usec);
- res = settime_alarm_timeval(&tv);
- if (res < 0)
- res = settime_rtc_timeval(&tv);
- if(res < 0) {
- fprintf(stderr,"settimeofday failed %s\n", strerror(errno));
- return 1;
- }
- }
- else {
- fprintf(stderr,"%s [-s 20070325.123456] [-u] [date]\n", argv[0]);
- return 1;
- }
-
- return 0;
-}
diff --git a/toolbox/ifconfig.c b/toolbox/ifconfig.c
deleted file mode 100644
index b953176..0000000
--- a/toolbox/ifconfig.c
+++ /dev/null
@@ -1,157 +0,0 @@
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <errno.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <linux/if.h>
-#include <linux/sockios.h>
-#include <arpa/inet.h>
-
-static void die(const char *s)
-{
- fprintf(stderr,"error: %s (%s)\n", s, strerror(errno));
- exit(-1);
-}
-
-static void setflags(int s, struct ifreq *ifr, int set, int clr)
-{
- if(ioctl(s, SIOCGIFFLAGS, ifr) < 0) die("SIOCGIFFLAGS");
- ifr->ifr_flags = (ifr->ifr_flags & (~clr)) | set;
- if(ioctl(s, SIOCSIFFLAGS, ifr) < 0) die("SIOCSIFFLAGS");
-}
-
-static inline void init_sockaddr_in(struct sockaddr_in *sin, const char *addr)
-{
- sin->sin_family = AF_INET;
- sin->sin_port = 0;
- sin->sin_addr.s_addr = inet_addr(addr);
-}
-
-static void setmtu(int s, struct ifreq *ifr, const char *mtu)
-{
- int m = atoi(mtu);
- ifr->ifr_mtu = m;
- if(ioctl(s, SIOCSIFMTU, ifr) < 0) die("SIOCSIFMTU");
-}
-static void setdstaddr(int s, struct ifreq *ifr, const char *addr)
-{
- init_sockaddr_in((struct sockaddr_in *) &ifr->ifr_dstaddr, addr);
- if(ioctl(s, SIOCSIFDSTADDR, ifr) < 0) die("SIOCSIFDSTADDR");
-}
-
-static void setnetmask(int s, struct ifreq *ifr, const char *addr)
-{
- init_sockaddr_in((struct sockaddr_in *) &ifr->ifr_netmask, addr);
- if(ioctl(s, SIOCSIFNETMASK, ifr) < 0) die("SIOCSIFNETMASK");
-}
-
-static void setaddr(int s, struct ifreq *ifr, const char *addr)
-{
- init_sockaddr_in((struct sockaddr_in *) &ifr->ifr_addr, addr);
- if(ioctl(s, SIOCSIFADDR, ifr) < 0) die("SIOCSIFADDR");
-}
-
-int ifconfig_main(int argc, char *argv[])
-{
- struct ifreq ifr;
- int s;
- unsigned int flags;
- char astring[20];
- char mstring[20];
- char *updown, *brdcst, *loopbk, *ppp, *running, *multi;
-
- argc--;
- argv++;
-
- if(argc == 0) return 0;
-
- memset(&ifr, 0, sizeof(struct ifreq));
- strncpy(ifr.ifr_name, argv[0], IFNAMSIZ);
- ifr.ifr_name[IFNAMSIZ-1] = 0;
- argc--, argv++;
-
- if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- die("cannot open control socket\n");
- }
-
- if (argc == 0) {
- if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
- perror(ifr.ifr_name);
- return -1;
- } else
- strlcpy(astring,
- inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr),
- sizeof(astring));
-
- if (ioctl(s, SIOCGIFNETMASK, &ifr) < 0) {
- perror(ifr.ifr_name);
- return -1;
- } else
- strlcpy(mstring,
- inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr),
- sizeof(mstring));
-
- if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) {
- perror(ifr.ifr_name);
- return -1;
- } else
- flags = ifr.ifr_flags;
-
- printf("%s: ip %s mask %s flags [", ifr.ifr_name,
- astring,
- mstring
- );
-
- updown = (flags & IFF_UP) ? "up" : "down";
- brdcst = (flags & IFF_BROADCAST) ? " broadcast" : "";
- loopbk = (flags & IFF_LOOPBACK) ? " loopback" : "";
- ppp = (flags & IFF_POINTOPOINT) ? " point-to-point" : "";
- running = (flags & IFF_RUNNING) ? " running" : "";
- multi = (flags & IFF_MULTICAST) ? " multicast" : "";
- printf("%s%s%s%s%s%s]\n", updown, brdcst, loopbk, ppp, running, multi);
- return 0;
- }
-
- while(argc > 0) {
- if (!strcmp(argv[0], "up")) {
- setflags(s, &ifr, IFF_UP, 0);
- } else if (!strcmp(argv[0], "mtu")) {
- argc--, argv++;
- if (!argc) {
- errno = EINVAL;
- die("expecting a value for parameter \"mtu\"");
- }
- setmtu(s, &ifr, argv[0]);
- } else if (!strcmp(argv[0], "-pointopoint")) {
- setflags(s, &ifr, IFF_POINTOPOINT, 1);
- } else if (!strcmp(argv[0], "pointopoint")) {
- argc--, argv++;
- if (!argc) {
- errno = EINVAL;
- die("expecting an IP address for parameter \"pointtopoint\"");
- }
- setdstaddr(s, &ifr, argv[0]);
- setflags(s, &ifr, IFF_POINTOPOINT, 0);
- } else if (!strcmp(argv[0], "down")) {
- setflags(s, &ifr, 0, IFF_UP);
- } else if (!strcmp(argv[0], "netmask")) {
- argc--, argv++;
- if (!argc) {
- errno = EINVAL;
- die("expecting an IP address for parameter \"netmask\"");
- }
- setnetmask(s, &ifr, argv[0]);
- } else if (isdigit(argv[0][0])) {
- setaddr(s, &ifr, argv[0]);
- setflags(s, &ifr, IFF_UP, 0);
- }
- argc--, argv++;
- }
- return 0;
-}
diff --git a/toolbox/notify.c b/toolbox/notify.c
deleted file mode 100644
index 8ce346c..0000000
--- a/toolbox/notify.c
+++ /dev/null
@@ -1,149 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <sys/inotify.h>
-#include <errno.h>
-
-int notify_main(int argc, char *argv[])
-{
- int c;
- int nfd, ffd;
- int res;
- char event_buf[512];
- struct inotify_event *event;
- int event_mask = IN_ALL_EVENTS;
- int event_count = 1;
- int print_files = 0;
- int verbose = 2;
- int width = 80;
- char **file_names;
- int file_count;
- int id_offset = 0;
- int i;
- char *buf;
-
- do {
- c = getopt(argc, argv, "m:c:pv:w:");
- if (c == EOF)
- break;
- switch (c) {
- case 'm':
- event_mask = strtol(optarg, NULL, 0);
- break;
- case 'c':
- event_count = atoi(optarg);
- break;
- case 'p':
- print_files = 1;
- break;
- case 'v':
- verbose = atoi(optarg);
- break;
- case 'w':
- width = atoi(optarg);
- break;
- case '?':
- fprintf(stderr, "%s: invalid option -%c\n",
- argv[0], optopt);
- exit(1);
- }
- } while (1);
-
- if (argc <= optind) {
- fprintf(stderr, "Usage: %s [-m eventmask] [-c count] [-p] [-v verbosity] path [path ...]\n", argv[0]);
- return 1;
- }
-
- nfd = inotify_init();
- if(nfd < 0) {
- fprintf(stderr, "inotify_init failed, %s\n", strerror(errno));
- return 1;
- }
- file_names = argv + optind;
- file_count = argc - optind;
- for(i = 0; i < file_count; i++) {
- res = inotify_add_watch(nfd, file_names[i], event_mask);
- if(res < 0) {
- fprintf(stderr, "inotify_add_watch failed for %s, %s\n", file_names[i], strerror(errno));
- return 1;
- }
- if(i == 0)
- id_offset = -res;
- if(res + id_offset != i) {
- fprintf(stderr, "%s got unexpected id %d instead of %d\n", file_names[i], res, i);
- return 1;
- }
- }
-
- buf = malloc(width + 2);
-
- while(1) {
- int event_pos = 0;
- res = read(nfd, event_buf, sizeof(event_buf));
- if(res < (int)sizeof(*event)) {
- if(errno == EINTR)
- continue;
- fprintf(stderr, "could not get event, %s\n", strerror(errno));
- return 1;
- }
- //printf("got %d bytes of event information\n", res);
- while(res >= (int)sizeof(*event)) {
- int event_size;
- event = (struct inotify_event *)(event_buf + event_pos);
- if(verbose >= 2)
- printf("%s: %08x %08x \"%s\"\n", file_names[event->wd + id_offset], event->mask, event->cookie, event->len ? event->name : "");
- else if(verbose >= 2)
- printf("%s: %08x \"%s\"\n", file_names[event->wd + id_offset], event->mask, event->len ? event->name : "");
- else if(verbose >= 1)
- printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
- if(print_files && (event->mask & IN_MODIFY)) {
- char* filename = file_names[event->wd + id_offset];
- char* alloc_buf = NULL;
- ssize_t read_len;
- char *display_name;
- int buflen;
- if(event->len) {
- if(asprintf(&alloc_buf, "%s/%s", filename, event->name) < 0) {
- fprintf(stderr, "asprintf failed, %s\n", strerror(errno));
- return 1;
- }
- filename = alloc_buf;
- }
- ffd = open(filename, O_RDONLY);
- display_name = (verbose >= 2 || event->len == 0) ? filename : event->name;
- buflen = width - strlen(display_name);
- read_len = read(ffd, buf, buflen);
- if(read_len > 0) {
- if(read_len < buflen && buf[read_len-1] != '\n') {
- buf[read_len] = '\n';
- read_len++;
- }
- if(read_len == buflen) {
- buf[--read_len] = '\0';
- buf[--read_len] = '\n';
- buf[--read_len] = '.';
- buf[--read_len] = '.';
- buf[--read_len] = '.';
- }
- else {
- buf[read_len] = '\0';
- }
- printf("%s: %s", display_name, buf);
- }
- close(ffd);
- free(alloc_buf);
- }
- if(event_count && --event_count == 0)
- return 0;
- event_size = sizeof(*event) + event->len;
- res -= event_size;
- event_pos += event_size;
- }
- }
-
- return 0;
-}
diff --git a/toolbox/pwcache.c b/toolbox/pwcache.c
deleted file mode 100644
index 9d81981..0000000
--- a/toolbox/pwcache.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2014, The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <grp.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-int uid_from_user(const char* name, uid_t* uid) {
- struct passwd* pw = getpwnam(name);
- if (pw == NULL) {
- return -1;
- }
- *uid = pw->pw_uid;
- return 0;
-}
-
-char* group_from_gid(gid_t gid, int noname) {
- struct group* g = getgrgid(gid);
- if (g == NULL) {
- static char buf[32];
- snprintf(buf, sizeof(buf), "%lu", (long) gid);
- return noname ? NULL : buf;
- }
- return g->gr_name;
-}
-
-char* user_from_uid(uid_t uid, int noname) {
- struct passwd* pw = getpwuid(uid);
- if (pw == NULL) {
- static char buf[32];
- snprintf(buf, sizeof(buf), "%lu", (long) uid);
- return noname ? NULL : buf;
- }
- return pw->pw_name;
-}
diff --git a/toolbox/upstream-netbsd/sbin/chown/chown.c b/toolbox/upstream-netbsd/sbin/chown/chown.c
deleted file mode 100644
index ee46eee..0000000
--- a/toolbox/upstream-netbsd/sbin/chown/chown.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/* $NetBSD: chown.c,v 1.8 2012/10/24 01:12:51 enami Exp $ */
-
-/*
- * Copyright (c) 1988, 1993, 1994, 2003
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#ifndef lint
-__COPYRIGHT("@(#) Copyright (c) 1988, 1993, 1994, 2003\
- The Regents of the University of California. All rights reserved.");
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)chown.c 8.8 (Berkeley) 4/4/94";
-#else
-__RCSID("$NetBSD: chown.c,v 1.8 2012/10/24 01:12:51 enami Exp $");
-#endif
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <ctype.h>
-#include <dirent.h>
-#include <err.h>
-#include <errno.h>
-#include <locale.h>
-#include <fts.h>
-#include <grp.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <getopt.h>
-
-static void a_gid(const char *);
-static void a_uid(const char *);
-static id_t id(const char *, const char *);
-__dead static void usage(void);
-
-static uid_t uid;
-static gid_t gid;
-static int ischown;
-static const char *myname;
-
-struct option chown_longopts[] = {
- { "reference", required_argument, 0,
- 1 },
- { NULL, 0, 0,
- 0 },
-};
-
-int
-main(int argc, char **argv)
-{
- FTS *ftsp;
- FTSENT *p;
- int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval, vflag;
- char *cp, *reference;
- int (*change_owner)(const char *, uid_t, gid_t);
-
- setprogname(*argv);
-
- (void)setlocale(LC_ALL, "");
-
- myname = getprogname();
- ischown = (myname[2] == 'o');
- reference = NULL;
-
- Hflag = Lflag = Rflag = fflag = hflag = vflag = 0;
- while ((ch = getopt_long(argc, argv, "HLPRfhv",
- chown_longopts, NULL)) != -1)
- switch (ch) {
- case 1:
- reference = optarg;
- break;
- case 'H':
- Hflag = 1;
- Lflag = 0;
- break;
- case 'L':
- Lflag = 1;
- Hflag = 0;
- break;
- case 'P':
- Hflag = Lflag = 0;
- break;
- case 'R':
- Rflag = 1;
- break;
- case 'f':
- fflag = 1;
- break;
- case 'h':
- /*
- * In System V the -h option causes chown/chgrp to
- * change the owner/group of the symbolic link.
- * 4.4BSD's symbolic links didn't have owners/groups,
- * so it was an undocumented noop.
- * In NetBSD 1.3, lchown(2) is introduced.
- */
- hflag = 1;
- break;
- case 'v':
- vflag = 1;
- break;
- case '?':
- default:
- usage();
- }
- argv += optind;
- argc -= optind;
-
- if (argc == 0 || (argc == 1 && reference == NULL))
- usage();
-
- fts_options = FTS_PHYSICAL;
- if (Rflag) {
- if (Hflag)
- fts_options |= FTS_COMFOLLOW;
- if (Lflag) {
- if (hflag)
- errx(EXIT_FAILURE,
- "the -L and -h options "
- "may not be specified together.");
- fts_options &= ~FTS_PHYSICAL;
- fts_options |= FTS_LOGICAL;
- }
- } else if (!hflag)
- fts_options |= FTS_COMFOLLOW;
-
- uid = (uid_t)-1;
- gid = (gid_t)-1;
- if (reference == NULL) {
- if (ischown) {
- if ((cp = strchr(*argv, ':')) != NULL) {
- *cp++ = '\0';
- a_gid(cp);
- }
-#ifdef SUPPORT_DOT
- else if ((cp = strrchr(*argv, '.')) != NULL) {
- if (uid_from_user(*argv, &uid) == -1) {
- *cp++ = '\0';
- a_gid(cp);
- }
- }
-#endif
- a_uid(*argv);
- } else
- a_gid(*argv);
- argv++;
- } else {
- struct stat st;
-
- if (stat(reference, &st) == -1)
- err(EXIT_FAILURE, "Cannot stat `%s'", reference);
- if (ischown)
- uid = st.st_uid;
- gid = st.st_gid;
- }
-
- if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL)
- err(EXIT_FAILURE, "fts_open");
-
- for (rval = EXIT_SUCCESS; (p = fts_read(ftsp)) != NULL;) {
- change_owner = chown;
- switch (p->fts_info) {
- case FTS_D:
- if (!Rflag) /* Change it at FTS_DP. */
- fts_set(ftsp, p, FTS_SKIP);
- continue;
- case FTS_DNR: /* Warn, chown, continue. */
- warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
- rval = EXIT_FAILURE;
- break;
- case FTS_ERR: /* Warn, continue. */
- case FTS_NS:
- warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
- rval = EXIT_FAILURE;
- continue;
- case FTS_SL: /* Ignore unless -h. */
- /*
- * All symlinks we found while doing a physical
- * walk end up here.
- */
- if (!hflag)
- continue;
- /*
- * Note that if we follow a symlink, fts_info is
- * not FTS_SL but FTS_F or whatever. And we should
- * use lchown only for FTS_SL and should use chown
- * for others.
- */
- change_owner = lchown;
- break;
- case FTS_SLNONE: /* Ignore. */
- /*
- * The only symlinks that end up here are ones that
- * don't point to anything. Note that if we are
- * doing a phisycal walk, we never reach here unless
- * we asked to follow explicitly.
- */
- continue;
- default:
- break;
- }
-
- if ((*change_owner)(p->fts_accpath, uid, gid) && !fflag) {
- warn("%s", p->fts_path);
- rval = EXIT_FAILURE;
- } else {
- if (vflag)
- printf("%s\n", p->fts_path);
- }
- }
- if (errno)
- err(EXIT_FAILURE, "fts_read");
- exit(rval);
- /* NOTREACHED */
-}
-
-static void
-a_gid(const char *s)
-{
- struct group *gr;
-
- if (*s == '\0') /* Argument was "uid[:.]". */
- return;
- gr = *s == '#' ? NULL : getgrnam(s);
- if (gr == NULL)
- gid = id(s, "group");
- else
- gid = gr->gr_gid;
- return;
-}
-
-static void
-a_uid(const char *s)
-{
- if (*s == '\0') /* Argument was "[:.]gid". */
- return;
- if (*s == '#' || uid_from_user(s, &uid) == -1) {
- uid = id(s, "user");
- }
- return;
-}
-
-static id_t
-id(const char *name, const char *type)
-{
- id_t val;
- char *ep;
-
- errno = 0;
- if (*name == '#')
- name++;
- val = (id_t)strtoul(name, &ep, 10);
- if (errno)
- err(EXIT_FAILURE, "%s", name);
- if (*ep != '\0')
- errx(EXIT_FAILURE, "%s: invalid %s name", name, type);
- return (val);
-}
-
-static void
-usage(void)
-{
-
- (void)fprintf(stderr,
- "Usage: %s [-R [-H | -L | -P]] [-fhv] %s file ...\n"
- "\t%s [-R [-H | -L | -P]] [-fhv] --reference=rfile file ...\n",
- myname, ischown ? "owner:group|owner|:group" : "group",
- myname);
- exit(EXIT_FAILURE);
-}