1c56215062c961402515daeef8330ed75cd94af29landley/* Toybox infrastructure.
2c56215062c961402515daeef8330ed75cd94af29landley *
3c56215062c961402515daeef8330ed75cd94af29landley * Copyright 2006 Rob Landley <rob@landley.net>
4c56215062c961402515daeef8330ed75cd94af29landley */
5c56215062c961402515daeef8330ed75cd94af29landley
65b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley// Stuff that needs to go before the standard headers
7fd1c5ba0cbbd31c4713d9283c4fa5c3265ad2296Rob Landley
85b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley#include "generated/config.h"
9901637760b4206e968e73dd5ff7430c107c27b57Rob Landley#include "lib/portability.h"
10901637760b4206e968e73dd5ff7430c107c27b57Rob Landley
115b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley// General posix-2008 headers
1209ea7ac1a269db3c9a3b76840b37a7cb1eccbc24landley#include <ctype.h>
13fd1c5ba0cbbd31c4713d9283c4fa5c3265ad2296Rob Landley#include <dirent.h>
1409ea7ac1a269db3c9a3b76840b37a7cb1eccbc24landley#include <errno.h>
1509ea7ac1a269db3c9a3b76840b37a7cb1eccbc24landley#include <fcntl.h>
169953f64c02ad754b2831e02651ae7f8bec9b67d1Isaac Dunham#include <fnmatch.h>
17c92fde0bc75ade9d06c0d843c4693b9e2e338938Rob Landley#include <grp.h>
1809ea7ac1a269db3c9a3b76840b37a7cb1eccbc24landley#include <inttypes.h>
194f344e356d2c36c4b1df46917eaef25f82ca79a9landley#include <limits.h>
20f05f660d9c4f18aa4702d723ed7b35f7053ce08cRob Landley#include <math.h>
21c92fde0bc75ade9d06c0d843c4693b9e2e338938Rob Landley#include <pwd.h>
225b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley#include <regex.h>
23f05f660d9c4f18aa4702d723ed7b35f7053ce08cRob Landley#include <sched.h>
246973a1d0e4c99e7bd07b239dee8a6c52c74ecb0fRob Landley#include <setjmp.h>
251bc522424f6bb21842366ccd11953136436b684bRob Landley#include <signal.h>
264f344e356d2c36c4b1df46917eaef25f82ca79a9landley#include <stdarg.h>
27caf39c26827f355c4e107f55c5c51f67c484bfd7Rob Landley#include <stddef.h>
2809ea7ac1a269db3c9a3b76840b37a7cb1eccbc24landley#include <stdint.h>
29c56215062c961402515daeef8330ed75cd94af29landley#include <stdio.h>
304f344e356d2c36c4b1df46917eaef25f82ca79a9landley#include <stdlib.h>
314f344e356d2c36c4b1df46917eaef25f82ca79a9landley#include <string.h>
32e3b171e6df244be8f7d5163ec5818406cce513f0Rob Landley#include <strings.h>
33c92fde0bc75ade9d06c0d843c4693b9e2e338938Rob Landley#include <sys/mman.h>
346da3be91efef92ebe27c06222212f99f28814ca5Rob Landley#include <sys/resource.h>
3500f87f150c3c9769e09e688bb9779947d64eb9d3landley#include <sys/stat.h>
3609ea7ac1a269db3c9a3b76840b37a7cb1eccbc24landley#include <sys/statvfs.h>
37503c8b839d8a40f08f8934940133d7574be43916Rob Landley#include <sys/time.h>
38628eb9b22032fb0f2e343f43efa60ec52b01d345Rob Landley#include <sys/times.h>
39f05f660d9c4f18aa4702d723ed7b35f7053ce08cRob Landley#include <sys/utsname.h>
4009ea7ac1a269db3c9a3b76840b37a7cb1eccbc24landley#include <sys/wait.h>
410b11a16626867a362ed9aff3950650af94d1cfa7Elie De Brauwer#include <syslog.h>
4246ddf0e34b03f7711a9c80f7a70dc8cbf732f782Isaac Dunham#include <termios.h>
43628eb9b22032fb0f2e343f43efa60ec52b01d345Rob Landley#include <time.h>
444f344e356d2c36c4b1df46917eaef25f82ca79a9landley#include <unistd.h>
4507c78d338b1adf0c3d32c3670f21e9b066d740daRob Landley#include <utime.h>
46250e0055fe0596f0f13d6e30f0bfe086702f5a25Felix Janda
475b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley// Posix networking
4898c322e881c6ab8d4f54c23feb1a106c23673640Rob Landley
4998c322e881c6ab8d4f54c23feb1a106c23673640Rob Landley#include <arpa/inet.h>
5098c322e881c6ab8d4f54c23feb1a106c23673640Rob Landley#include <netdb.h>
5198c322e881c6ab8d4f54c23feb1a106c23673640Rob Landley#include <net/if.h>
5298c322e881c6ab8d4f54c23feb1a106c23673640Rob Landley#include <netinet/in.h>
5398c322e881c6ab8d4f54c23feb1a106c23673640Rob Landley#include <netinet/tcp.h>
5498c322e881c6ab8d4f54c23feb1a106c23673640Rob Landley#include <poll.h>
5598c322e881c6ab8d4f54c23feb1a106c23673640Rob Landley#include <sys/socket.h>
5698c322e881c6ab8d4f54c23feb1a106c23673640Rob Landley#include <sys/un.h>
5798c322e881c6ab8d4f54c23feb1a106c23673640Rob Landley
585b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley// Internationalization support (also in POSIX and LSB)
595b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley
605b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley#include <locale.h>
615b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley#include <wchar.h>
625b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley#include <wctype.h>
635b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley
645b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley// LSB 4.1 headers
650a4bd4b89f9a17e4ba8c7873d1384fb04f79b14dRob Landley#include <pty.h>
665b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley#include <sys/ioctl.h>
675b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley#include <sys/statfs.h>
685b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley#include <sys/sysinfo.h>
695b405827a2fa4c928c488f3e7b0197dfec60dcc2Rob Landley
704f344e356d2c36c4b1df46917eaef25f82ca79a9landley#include "lib/lib.h"
71e2580dbebbd43f668913b3d2ae6c0636161636edRob Landley#include "toys/e2fs.h"
72c56215062c961402515daeef8330ed75cd94af29landley
7355928b1e0a08d84a5cbc50020f0a8c1024f5b6ceRob Landley// Get list of function prototypes for all enabled command_main() functions.
7455928b1e0a08d84a5cbc50020f0a8c1024f5b6ceRob Landley
7555928b1e0a08d84a5cbc50020f0a8c1024f5b6ceRob Landley#define NEWTOY(name, opts, flags) void name##_main(void);
76f3e56f4e4ff773de95fa2c9daf979734d826fc33Rob Landley#define OLDTOY(name, oldname, flags) void oldname##_main(void);
7755928b1e0a08d84a5cbc50020f0a8c1024f5b6ceRob Landley#include "generated/newtoys.h"
78207cadacd3cef42fa918981423c951f49443f032Rob Landley#include "generated/flags.h"
79b1aaba1fc8176ac0b7c202a664d2554aa0967116Rob Landley#include "generated/globals.h"
8055928b1e0a08d84a5cbc50020f0a8c1024f5b6ceRob Landley
81f2311a42a0751e7c039981857fcf60b40f36b475Rob Landley// These live in main.c
824f344e356d2c36c4b1df46917eaef25f82ca79a9landley
834f344e356d2c36c4b1df46917eaef25f82ca79a9landleystruct toy_list *toy_find(char *name);
84cd9dfc3b7b73715840b63180e2e4bfdb6e7ca9a4landleyvoid toy_init(struct toy_list *which, char *argv[]);
85cd9dfc3b7b73715840b63180e2e4bfdb6e7ca9a4landleyvoid toy_exec(char *argv[]);
86c56215062c961402515daeef8330ed75cd94af29landley
8743e9d331c8055dff7e243bd19d2d06df826d6f38Rob Landley// Flags describing command behavior.
88b1aaba1fc8176ac0b7c202a664d2554aa0967116Rob Landley
89b1aaba1fc8176ac0b7c202a664d2554aa0967116Rob Landley#define TOYFLAG_USR      (1<<0)
90b1aaba1fc8176ac0b7c202a664d2554aa0967116Rob Landley#define TOYFLAG_BIN      (1<<1)
91b1aaba1fc8176ac0b7c202a664d2554aa0967116Rob Landley#define TOYFLAG_SBIN     (1<<2)
92b1aaba1fc8176ac0b7c202a664d2554aa0967116Rob Landley#define TOYMASK_LOCATION ((1<<4)-1)
93b1aaba1fc8176ac0b7c202a664d2554aa0967116Rob Landley
9453dda1a9cfc453fa5b2e5ff0ed58f8a9c99749a9Rob Landley// This is a shell built-in function, running in the same process context.
95b1aaba1fc8176ac0b7c202a664d2554aa0967116Rob Landley#define TOYFLAG_NOFORK   (1<<4)
9653dda1a9cfc453fa5b2e5ff0ed58f8a9c99749a9Rob Landley
9743e9d331c8055dff7e243bd19d2d06df826d6f38Rob Landley// Start command with a umask of 0 (saves old umask in this.old_umask)
980f8c4c5998317e575f1afd47dad7f6967bc271abRob Landley#define TOYFLAG_UMASK    (1<<5)
99b1aaba1fc8176ac0b7c202a664d2554aa0967116Rob Landley
10043e9d331c8055dff7e243bd19d2d06df826d6f38Rob Landley// This command runs as root.
101e0377fb294821a68112d4da09f836ac42e3d5956Rob Landley#define TOYFLAG_STAYROOT (1<<6)
102e0377fb294821a68112d4da09f836ac42e3d5956Rob Landley#define TOYFLAG_NEEDROOT (1<<7)
103e0377fb294821a68112d4da09f836ac42e3d5956Rob Landley#define TOYFLAG_ROOTONLY (TOYFLAG_STAYROOT|TOYFLAG_NEEDROOT)
104e0377fb294821a68112d4da09f836ac42e3d5956Rob Landley
10589a62bf2907412cb562d22c875736357e314c8c8Rob Landley// Call setlocale to listen to environment variables.
10689a62bf2907412cb562d22c875736357e314c8c8Rob Landley// This invalidates sprintf("%.*s", size, string) as a valid length constraint.
10789a62bf2907412cb562d22c875736357e314c8c8Rob Landley#define TOYFLAG_LOCALE   (1<<8)
10889a62bf2907412cb562d22c875736357e314c8c8Rob Landley
109933919cd8094e870b3e7a554605fd49b20ddb1e0Rob Landley// Array of available commands
11053dda1a9cfc453fa5b2e5ff0ed58f8a9c99749a9Rob Landley
111b1aaba1fc8176ac0b7c202a664d2554aa0967116Rob Landleyextern struct toy_list {
1127aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  char *name;
1137aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  void (*toy_main)(void);
1147aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  char *options;
1157aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  int flags;
116b1aaba1fc8176ac0b7c202a664d2554aa0967116Rob Landley} toy_list[];
117b1aaba1fc8176ac0b7c202a664d2554aa0967116Rob Landley
11843e9d331c8055dff7e243bd19d2d06df826d6f38Rob Landley// Global context shared by all commands.
119c56215062c961402515daeef8330ed75cd94af29landley
120c56215062c961402515daeef8330ed75cd94af29landleyextern struct toy_context {
1217aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  struct toy_list *which;  // Which entry in toy_list is this one?
1227aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  char **argv;             // Original command line arguments
1237aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  char **optargs;          // Arguments left over from get_optflags()
12436aa7d7382f64695ef003e5616890188b9f1f61bRob Landley  unsigned optflags;       // Command line option flags from get_optflags()
12536aa7d7382f64695ef003e5616890188b9f1f61bRob Landley  int exitval;             // Value error_exit feeds to exit()
1267aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  int optc;                // Count of optargs
1277aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  int exithelp;            // Should error_exit print a usage message first?
1287aa651a6a4496d848f86de9b1e6b3a003256a01fRob Landley  int old_umask;           // Old umask preserved by TOYFLAG_UMASK
12936aa7d7382f64695ef003e5616890188b9f1f61bRob Landley  int toycount;            // Total number of commands in this build
1301bc522424f6bb21842366ccd11953136436b684bRob Landley  int signal;              // generic_signal() records what signal it saw here
1311bc522424f6bb21842366ccd11953136436b684bRob Landley  int signalfd;            // and writes signal to this fd, if set
1324c2bd6277d5966ea7ef7d59a34838066b5c130ebRob Landley
1334c2bd6277d5966ea7ef7d59a34838066b5c130ebRob Landley  // This is at the end so toy_init() doesn't zero it.
1344c2bd6277d5966ea7ef7d59a34838066b5c130ebRob Landley  jmp_buf *rebound;        // longjmp here instead of exit when do_rebound set
135d4bae7ddb771d32d35cc953a3fedbcc622820dbeRob Landley  int recursion;           // How many nested calls to toy_exec()
136c56215062c961402515daeef8330ed75cd94af29landley} toys;
1378324b89598b2aee0957a0378f0f63ff5755498beRob Landley
1388fdcfdb4479dff7a993a25a63253f0e749fd99feRob Landley// Two big temporary buffers: one for use by commands, one for library functions
1398324b89598b2aee0957a0378f0f63ff5755498beRob Landley
1408fdcfdb4479dff7a993a25a63253f0e749fd99feRob Landleyextern char toybuf[4096], libbuf[4096];
141b1aaba1fc8176ac0b7c202a664d2554aa0967116Rob Landley
14259bf7ce6a5114ed228cf3bf847ff96a35aa86f54Strakeextern char **environ;
14359bf7ce6a5114ed228cf3bf847ff96a35aa86f54Strake
144c0e56edaf256adb6c60c5a052525a1ffbb927901Rob Landley#define GLOBALS(...)
1459c1c5ecd688052c39574999a523fa95f022b69b8Rob Landley
1469c1c5ecd688052c39574999a523fa95f022b69b8Rob Landley#define ARRAY_LEN(array) (sizeof(array)/sizeof(*array))
147