*/
#include "toys.h"
--#if defined(__ANDROID__)
--#include <asm/unistd.h>
-#endif
+
+ // We can't fork() on nommu systems, and vfork() requires an exec() or exit()
+ // before resuming the parent (because they share a heap until then). And no,
+ // we can't implement our own clone() call that does the equivalent of fork()
+ // because nommu heaps use physical addresses so if we copy the heap all our
+ // pointers are wrong. (You need an mmu in order to map two heaps to the same
+ // address range without interfering with each other.) In the absence of
+ // a portable way to tell malloc() to start a new heap without freeing the old
+ // one, you pretty much need the exec().)
+
+ // So we exec ourselves (via /proc/self/exe, if anybody knows a way to
+ // re-exec self without depending on the filesystem, I'm all ears),
+ // and use the arguments to signal reentry.
+
+ #if CFG_TOYBOX_FORK
+ pid_t xfork(void)
+ {
+ pid_t pid = fork();
+
+ if (pid < 0) perror_exit("fork");
+
+ return pid;
+ }
#endif
- #if defined(__APPLE__) || defined(__ANDROID__)
+ #if defined(__APPLE__)
ssize_t getdelim(char **linep, size_t *np, int delim, FILE *stream)
{
int ch;
--- /dev/null
- # Mon Dec 8 11:16:59 2014
+#
+# Automatically generated make config: don't edit
+# ToyBox version: KCONFIG_VERSION
- CONFIG_TOYBOX_PTY=y
++# Mon Jul 20 13:45:50 2015
+#
+CONFIG_TOYBOX_CONTAINER=y
+CONFIG_TOYBOX_FIFREEZE=y
+CONFIG_TOYBOX_ICONV=y
+CONFIG_TOYBOX_FALLOCATE=y
+CONFIG_TOYBOX_UTMPX=y
- CONFIG_CP_MV=y
- CONFIG_CP_MV_MORE=y
+CONFIG_TOYBOX_SHADOW=y
++# CONFIG_TOYBOX_ON_ANDROID is not set
++CONFIG_TOYBOX_FORK=y
+
+#
+# Posix commands
+#
+CONFIG_BASENAME=y
+# CONFIG_CAL is not set
+CONFIG_CAT=y
++# CONFIG_CAT_V is not set
++# CONFIG_CATV is not set
+CONFIG_CHGRP=y
++CONFIG_CHOWN=y
+CONFIG_CHMOD=y
+CONFIG_CKSUM=y
+CONFIG_CMP=y
+CONFIG_COMM=y
+CONFIG_CP=y
+CONFIG_CP_MORE=y
- CONFIG_DF_PEDANTIC=y
++CONFIG_CP_PRESERVE=y
++CONFIG_MV=y
++CONFIG_MV_MORE=y
+CONFIG_INSTALL=y
+CONFIG_CPIO=y
+CONFIG_CUT=y
+CONFIG_DATE=y
+CONFIG_DF=y
- # pending
+CONFIG_DIRNAME=y
+CONFIG_DU=y
+CONFIG_ECHO=y
+CONFIG_ENV=y
+CONFIG_EXPAND=y
+CONFIG_FALSE=y
+CONFIG_FIND=y
+CONFIG_GREP=y
++CONFIG_EGREP=y
++CONFIG_FGREP=y
+CONFIG_HEAD=y
+CONFIG_ID=y
++# CONFIG_ID_Z is not set
+CONFIG_GROUPS=y
+CONFIG_LOGNAME=y
+CONFIG_WHOAMI=y
+CONFIG_KILL=y
+# CONFIG_KILLALL5 is not set
+CONFIG_LINK=y
+CONFIG_LN=y
+CONFIG_LS=y
+CONFIG_LS_COLOR=y
+CONFIG_MKDIR=y
++# CONFIG_MKDIR_Z is not set
+CONFIG_MKFIFO=y
++# CONFIG_MKFIFO_Z is not set
+CONFIG_NICE=y
+CONFIG_NL=y
+CONFIG_NOHUP=y
+CONFIG_OD=y
+CONFIG_PASTE=y
+CONFIG_PATCH=y
++CONFIG_PRINTF=y
+CONFIG_PWD=y
+# CONFIG_RENICE is not set
+CONFIG_RM=y
+CONFIG_RMDIR=y
++CONFIG_SED=y
+CONFIG_SLEEP=y
+CONFIG_SLEEP_FLOAT=y
+CONFIG_SORT=y
+CONFIG_SORT_BIG=y
+CONFIG_SORT_FLOAT=y
+CONFIG_SPLIT=y
+CONFIG_STRINGS=y
+CONFIG_TAIL=y
+CONFIG_TAIL_SEEK=y
+CONFIG_TEE=y
+# CONFIG_TIME is not set
+CONFIG_TOUCH=y
+CONFIG_TRUE=y
+CONFIG_TTY=y
+CONFIG_UNAME=y
+CONFIG_UNIQ=y
+CONFIG_UNLINK=y
+# CONFIG_UUDECODE is not set
+# CONFIG_UUENCODE is not set
+CONFIG_WC=y
+CONFIG_WHO=y
+CONFIG_XARGS=y
+CONFIG_XARGS_PEDANTIC=y
+
+#
- CONFIG_ZCAT=y
++# pending (see toys/pending/README)
+#
+# CONFIG_ARP is not set
+# CONFIG_ARPING is not set
+# CONFIG_BOOTCHARTD is not set
+# CONFIG_BRCTL is not set
+CONFIG_COMPRESS=y
- # CONFIG_HWCLOCK is not set
++CONFIG_GZIP=y
++# CONFIG_GZIP_D is not set
++# CONFIG_DECOMPRESS is not set
++# CONFIG_ZCAT is not set
++# CONFIG_GUNZIP is not set
+# CONFIG_CROND is not set
+# CONFIG_CRONTAB is not set
+CONFIG_DD=y
+# CONFIG_DHCP is not set
+# CONFIG_DHCPD is not set
+# CONFIG_DEBUG_DHCP is not set
+CONFIG_DIFF=y
+# CONFIG_DUMPLEASES is not set
+CONFIG_EXPR=y
+# CONFIG_FDISK is not set
+CONFIG_FOLD=y
+CONFIG_FSCK=y
+# CONFIG_FTPGET is not set
+# CONFIG_GETTY is not set
+# CONFIG_GROUPADD is not set
+# CONFIG_GROUPDEL is not set
+# CONFIG_HOST is not set
- # CONFIG_MIX is not set
+# CONFIG_ICONV is not set
+# CONFIG_INIT is not set
+# CONFIG_IP is not set
+# CONFIG_IPCRM is not set
+# CONFIG_IPCS is not set
+# CONFIG_KLOGD is not set
+# CONFIG_KLOGD_SOURCE_RING_BUFFER is not set
+# CONFIG_LAST is not set
+# CONFIG_LOGGER is not set
+# CONFIG_MDEV is not set
+# CONFIG_MDEV_CONF is not set
- CONFIG_PRINTF=y
+# CONFIG_MKE2FS is not set
+# CONFIG_MKE2FS_JOURNAL is not set
+# CONFIG_MKE2FS_GEN is not set
+# CONFIG_MKE2FS_LABEL is not set
+# CONFIG_MKE2FS_EXTENDED is not set
+# CONFIG_MODPROBE is not set
+# CONFIG_MORE is not set
+# CONFIG_NETSTAT is not set
+# CONFIG_NSENTER is not set
+# CONFIG_OPENVT is not set
+# CONFIG_DEALLOCVT is not set
+# CONFIG_PGREP is not set
+# CONFIG_PING is not set
- # CONFIG_RESET is not set
+# CONFIG_PS is not set
- CONFIG_SED=y
+# CONFIG_ROUTE is not set
- CONFIG_SH_INTERACTIVE=y
+CONFIG_SH=y
- # CONFIG_TRACEROUTE is not set
+# CONFIG_EXIT is not set
+# CONFIG_CD is not set
+# CONFIG_SULOGIN is not set
+# CONFIG_SYSLOGD is not set
+CONFIG_TAR=y
+# CONFIG_TCPSVD is not set
+# CONFIG_TELNET is not set
+# CONFIG_TELNETD is not set
+CONFIG_TEST=y
+# CONFIG_TFTPD is not set
+# CONFIG_TOP is not set
- # CONFIG_CATV is not set
+CONFIG_TR=y
++# CONFIG_TRACEROUTE is not set
+# CONFIG_USERADD is not set
+# CONFIG_USERDEL is not set
+# CONFIG_WATCH is not set
+CONFIG_XZCAT=y
+
+#
+# Other commands
+#
+# CONFIG_ACPI is not set
++CONFIG_BASE64=y
+# CONFIG_BLKID is not set
++CONFIG_FSTYPE=y
+# CONFIG_BLOCKDEV is not set
+CONFIG_BZCAT=y
- # CONFIG_UNSHARE is not set
++# CONFIG_CHCON is not set
+CONFIG_CHROOT=y
+# CONFIG_CHVT is not set
+# CONFIG_CLEAR is not set
+# CONFIG_COUNT is not set
+CONFIG_DOS2UNIX=y
++CONFIG_UNIX2DOS=y
+# CONFIG_EJECT is not set
+CONFIG_FACTOR=y
+# CONFIG_FALLOCATE is not set
+# CONFIG_FREE is not set
+# CONFIG_FREERAMDISK is not set
+# CONFIG_FSFREEZE is not set
+CONFIG_HELP=y
+CONFIG_HELP_EXTRAS=y
++CONFIG_HEXEDIT=y
++# CONFIG_HWCLOCK is not set
+# CONFIG_IFCONFIG is not set
+# CONFIG_INOTIFYD is not set
+# CONFIG_INSMOD is not set
++CONFIG_IONICE=y
++CONFIG_IORENICE=y
+# CONFIG_LOGIN is not set
+# CONFIG_LOSETUP is not set
+# CONFIG_LSATTR is not set
+# CONFIG_CHATTR is not set
+# CONFIG_LSMOD is not set
+# CONFIG_LSPCI is not set
+# CONFIG_LSPCI_TEXT is not set
+# CONFIG_LSUSB is not set
+# CONFIG_MAKEDEVS is not set
++# CONFIG_MIX is not set
+# CONFIG_MKPASSWD is not set
+# CONFIG_MKSWAP is not set
+# CONFIG_MODINFO is not set
+# CONFIG_MOUNTPOINT is not set
+# CONFIG_NBD_CLIENT is not set
+# CONFIG_NETCAT is not set
+# CONFIG_NETCAT_LISTEN is not set
++# CONFIG_UNSHARE is not set
+# CONFIG_ONEIT is not set
+CONFIG_PARTPROBE=y
+# CONFIG_PIVOT_ROOT is not set
+# CONFIG_PMAP is not set
+CONFIG_PRINTENV=y
+# CONFIG_PWDX is not set
+# CONFIG_READAHEAD is not set
+CONFIG_READLINK=y
+CONFIG_REALPATH=y
+# CONFIG_REBOOT is not set
++# CONFIG_RESET is not set
+# CONFIG_REV is not set
+# CONFIG_RFKILL is not set
+# CONFIG_RMMOD is not set
+# CONFIG_SETSID is not set
++CONFIG_SHRED=y
+CONFIG_STAT=y
+# CONFIG_SWAPOFF is not set
+# CONFIG_SWAPON is not set
+# CONFIG_SWITCH_ROOT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_TAC=y
++CONFIG_NPROC=y
+# CONFIG_TASKSET is not set
+CONFIG_TIMEOUT=y
+CONFIG_TRUNCATE=y
- # CONFIG_NFSMOUNT is not set
+# CONFIG_UPTIME is not set
+# CONFIG_USLEEP is not set
+# CONFIG_VCONFIG is not set
+# CONFIG_VMSTAT is not set
+# CONFIG_W is not set
+# CONFIG_WHICH is not set
++CONFIG_XXD=y
+CONFIG_YES=y
+
+#
+# Linux Standard Base commands
+#
+# CONFIG_DMESG is not set
+# CONFIG_HOSTNAME is not set
+# CONFIG_KILLALL is not set
+CONFIG_MD5SUM=y
+CONFIG_SHA1SUM=y
+CONFIG_MKNOD=y
++# CONFIG_MKNOD_Z is not set
+CONFIG_MKTEMP=y
+# CONFIG_MOUNT is not set
+# CONFIG_PASSWD is not set
+# CONFIG_PIDOF is not set
+CONFIG_SEQ=y
+# CONFIG_SU is not set
+CONFIG_SYNC=y
+# CONFIG_UMOUNT is not set
+
+#
+# Example commands
+#
+# CONFIG_HELLO is not set
+# CONFIG_SKELETON is not set
+# CONFIG_SKELETON_ALIAS is not set
+
+#
++# Android
++#
++# CONFIG_GETENFORCE is not set
++# CONFIG_GETPROP is not set
++# CONFIG_LOAD_POLICY is not set
++# CONFIG_RESTORECON is not set
++# CONFIG_RUNCON is not set
++# CONFIG_SETENFORCE is not set
++# CONFIG_SETPROP is not set
++
++#
+#
+#
+
+#
+# Toybox global settings
+#
+CONFIG_TOYBOX=y
+CONFIG_TOYBOX_SUID=y
++CONFIG_TOYBOX_LSM_NONE=y
++# CONFIG_TOYBOX_SELINUX is not set
++# CONFIG_TOYBOX_SMACK is not set
+CONFIG_TOYBOX_FLOAT=y
+CONFIG_TOYBOX_HELP=y
+CONFIG_TOYBOX_HELP_DASHDASH=y
+CONFIG_TOYBOX_I18N=y
+# CONFIG_TOYBOX_FREE is not set
+# CONFIG_TOYBOX_NORECURSE is not set
+CONFIG_TOYBOX_DEBUG=y
+CONFIG_TOYBOX_UID_SYS=100
+CONFIG_TOYBOX_UID_USR=500
#include <wctype.h>
// LSB 4.1 headers
++#include <pty.h>
#include <sys/ioctl.h>
#include <sys/statfs.h>
#include <sys/sysinfo.h>
bool "netcat server options (-let)"
default y
depends on NETCAT
-- depends on TOYBOX_PTY
help
usage: netcat [-t] [-lL COMMAND...]
+++ /dev/null
--/* hwclock.c - get and set the hwclock
-- *
-- * Copyright 2014 Bilal Qureshi <bilal.jmi@gmail.com>
-- *
-- * No Standard.
-- *
--USE_HWCLOCK(NEWTOY(hwclock, ">0(fast)f(rtc):u(utc)l(localtime)t(systz)w(systohc)s(hctosys)r(show)[!ul][!rsw]", TOYFLAG_USR|TOYFLAG_BIN))
--
--config HWCLOCK
-- bool "hwclock"
-- default n
-- help
-- usage: hwclock [-rswtluf]
--
-- -f FILE Use specified device file instead of /dev/rtc (--show)
-- -l Hardware clock uses localtime (--localtime)
-- -r Show hardware clock time (--show)
-- -s Set system time from hardware clock (--hctosys)
-- -t Set the system time based on the current timezone (--systz)
-- -u Hardware clock uses UTC (--utc)
-- -w Set hardware clock from system time (--systohc)
--*/
--#define FOR_hwclock
--#include "toys.h"
--#include <linux/rtc.h>
--
--GLOBALS(
-- char *fname;
--
-- int utc;
--)
--
--static int rtc_open(int flag)
--{
-- if (!TT.fname) {
-- int fd;
--
-- if ((fd = open((TT.fname = "/dev/rtc"), flag)) != -1) return fd;
-- else if ((fd = open((TT.fname = "/dev/rtc0"), flag)) != -1) return fd;
-- else TT.fname = "/dev/misc/rtc";
-- }
-- return xopen(TT.fname, flag);
--}
--
--static time_t get_rtc()
--{
-- struct tm time;
-- time_t tm;
-- char *ptz_old = 0;
-- int fd = rtc_open(O_RDONLY);
--
-- xioctl(fd, RTC_RD_TIME, &time);
-- close(fd);
-- if (TT.utc) {
-- ptz_old = getenv("TZ");
-- if (putenv((char*)"TZ=UTC0")) perror_exit("putenv");
-- tzset();
-- }
-- if ((tm = mktime(&time)) < 0) error_exit("mktime failed");
-- if (TT.utc) {
-- if (unsetenv("TZ") < 0) perror_exit("unsetenv");
-- if (ptz_old && putenv(ptz_old - 3)) perror_exit("putenv");
-- tzset();
-- }
-- return tm;
--}
--
--static void set_sysclock_from_hwclock()
--{
-- struct timezone tmzone;
-- struct timeval tmval;
--
-- tmzone.tz_minuteswest = timezone / 60 - 60 * daylight;
-- tmzone.tz_dsttime = 0;
-- tmval.tv_sec = get_rtc();
-- tmval.tv_usec = 0;
-- if (settimeofday(&tmval, &tmzone) < 0) perror_exit("settimeofday");
--}
--
--static void set_hwclock_from_sysclock()
--{
-- struct timeval tmval;
-- struct tm time;
-- int fd = rtc_open(O_WRONLY);
--
-- if (gettimeofday(&tmval, NULL) < 0) perror_exit("gettimeofday");
-- // converting a time value to broken-down UTC time
-- if (TT.utc && !gmtime_r((time_t*)&tmval.tv_sec, &time))
-- error_exit("gmtime_r failed");
-- // converting a time value to a broken-down localtime
-- else if (!(localtime_r((time_t*)&tmval.tv_sec, &time)))
-- error_exit("localtime_r failed");
--
-- /* The value of tm_isdst will positive if daylight saving time is in effect,
-- * zero if it is not and negative if the information is not available.
-- * */
-- time.tm_isdst = 0;
-- xioctl(fd, RTC_SET_TIME, &time);
-- close(fd);
--}
--
--static void set_sysclock_timezone()
--{
-- struct timezone tmzone;
-- struct timeval tmval;
-- struct tm *pb;
--
-- if (gettimeofday(&tmval, NULL) < 0) perror_exit("gettimeofday");
-- if (!(pb = localtime(&tmval.tv_sec))) error_exit("localtime failed");
-- // extern long timezone => defined in header sys/time.h
-- tmzone.tz_minuteswest = timezone / 60;
-- if (pb->tm_isdst) tmzone.tz_minuteswest -= 60;
-- tmzone.tz_dsttime = 0; // daylight saving time is not in effect
-- if (gettimeofday(&tmval, NULL) < 0) perror_exit("gettimeofday");
-- if (!TT.utc) tmval.tv_sec += tmzone.tz_minuteswest * 60;
-- if (settimeofday(&tmval, &tmzone) < 0) perror_exit("settimeofday");
--}
--
--void hwclock_main()
--{
-- // check for UTC
-- if (!(toys.optflags & FLAG_u)) {
-- FILE *fp = fopen("/etc/adjtime", "r");
--
-- if (fp) {
-- char *line = NULL;
-- size_t st;
--
-- while (0 < getline(&line, &st, fp)) {
-- if (!strncmp(line, "UTC", 3)) {
-- TT.utc = 1;
-- break;
-- }
-- free(line);
-- }
-- fclose(fp);
-- }
-- } else TT.utc = 1;
--
-- if (toys.optflags & FLAG_w) set_hwclock_from_sysclock();
-- else if (toys.optflags & FLAG_s) set_sysclock_from_hwclock();
-- else if (toys.optflags & FLAG_t) set_sysclock_timezone();
-- else if ((toys.optflags & FLAG_r) || (toys.optflags & FLAG_l)
-- || !*toys.optargs)
-- {
-- time_t tm = get_rtc();
-- char *s, *pctm = ctime(&tm);
--
-- // ctime() is defined as equivalent to asctime(localtime(t)),
-- // which is defined to overflow its buffer rather than return NULL.
-- // if (!pctm) error_exit("can't happen");
-- if ((s = strrchr(pctm, '\n'))) *s = '\0';
-- // TODO: implement this.
-- xprintf("%s 0.000000 seconds\n", pctm);
-- }
--}
+++ /dev/null
--/* nsenter.c - Enter existing namespaces
-- *
-- * Copyright 2014 andy Lutomirski <luto@amacapital.net>
--
--USE_NSENTER(NEWTOY(nsenter, "<1F(no-fork)t#(target)i:(ipc);m:(mount);n:(net);p:(pid);u:(uts);U:(user);", TOYFLAG_USR|TOYFLAG_BIN))
--
--config NSENTER
-- bool "nsenter"
-- default n
-- help
-- usage: nsenter [-t pid] [-F] [-i] [-m] [-n] [-p] [-u] [-U] COMMAND...
--
-- Run COMMAND in a different set of namespaces.
--
-- -T PID to take namespaces from
-- -F don't fork, even if -p is set
--
-- The namespaces to switch are:
--
-- -i SysV IPC (message queues, semaphores, shared memory)
-- -m Mount/unmount tree
-- -n Network address, sockets, routing, iptables
-- -p Process IDs and init (will fork unless -F is used)
-- -u Host and domain names
-- -U UIDs, GIDs, capabilities
--
-- Each of those options takes an optional argument giving the path of
-- the namespace file (usually in /proc). This optional argument is
-- mandatory unless -t is used.
--*/
--
--#define FOR_nsenter
--#define _GNU_SOURCE
--#include "toys.h"
--#include <errno.h>
--#include <sched.h>
--#include <linux/sched.h>
--
--#define NUM_NSTYPES 6
--
--struct nstype {
-- int type;
-- const char *name;
--};
--
--struct nstype nstypes[NUM_NSTYPES] = {
-- {CLONE_NEWUSER, "user"}, /* must be first to allow non-root operation */
-- {CLONE_NEWUTS, "uts"},
-- {CLONE_NEWPID, "pid"},
-- {CLONE_NEWNET, "net"},
-- {CLONE_NEWNS, "mnt"},
-- {CLONE_NEWIPC, "ipc"},
--};
--
--GLOBALS(
-- char *nsnames[6];
-- long targetpid;
--)
--
--static void enter_by_name(int idx)
--{
-- int fd, rc;
-- char buf[64];
-- char *filename = TT.nsnames[idx];
--
-- if (!(toys.optflags & (1<<idx))) return;
--
-- if (!filename || !*filename) {
-- if (!(toys.optflags & (1<<NUM_NSTYPES)))
-- error_exit("either -t or an ns filename is required");
-- sprintf(buf, "/proc/%ld/ns/%s", TT.targetpid, nstypes[idx].name);
-- filename = buf;
-- }
--
-- fd = open(filename, O_RDONLY | O_CLOEXEC);
-- if (fd == -1) perror_exit(filename);
--
-- rc = setns(fd, nstypes[idx].type);
-- if (CFG_TOYBOX_FREE) close(fd);
-- if (rc != 0) perror_exit("setns");
--}
--
--void nsenter_main(void)
--{
-- int i;
--
-- for (i = 0; i < NUM_NSTYPES; i++)
-- enter_by_name(i);
--
-- if ((toys.optflags & (1<<2)) && !(toys.optflags & 1<<(NUM_NSTYPES+1))) {
-- /* changed PID ns and --no-fork wasn't set, so fork. */
-- pid_t pid = fork();
--
-- if (pid == -1) {
-- perror_exit("fork");
-- } else if (pid != 0) {
-- while (waitpid(pid, 0, 0) == -1 && errno == EINTR)
-- ;
-- return;
-- }
-- }
--
-- xexec_optargs(0);
--}
config TELNETD
bool "telnetd"
default n
-- depends on TOYBOX_PTY
help
Handle incoming telnet connections