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