#include "ssl_io.h"
#endif
-static unsigned verbose;
-static unsigned max_per_host;
-static unsigned cur_per_host;
-static unsigned cnum;
-static unsigned cmax = 30;
+struct globals {
+ unsigned verbose;
+ unsigned max_per_host;
+ unsigned cur_per_host;
+ unsigned cnum;
+ unsigned cmax;
+};
+#define G (*(struct globals*)&bb_common_bufsiz1)
+#define verbose (G.verbose )
+#define max_per_host (G.max_per_host)
+#define cur_per_host (G.cur_per_host)
+#define cnum (G.cnum )
+#define cmax (G.cmax )
+#define INIT_G() \
+ do { \
+ cmax = 30; \
+ } while (0)
+
static void xsetenv_proto(const char *proto, const char *n, const char *v)
{
int conn;
unsigned backlog = 20;
+ INIT_G();
+
tcp = (applet_name[0] == 't');
/* 3+ args, -i at most once, -p implies -h, -v is counter */
#define MAX_LIFETIME 2*60 /* lifetime of an xid entry in sec. */
#define MAX_INTERFACES 9
-
/* This list holds information about clients. The xid_* functions manipulate this list. */
-static struct xid_item {
+struct xid_item {
+ time_t timestamp;
+ int client;
uint32_t xid;
struct sockaddr_in ip;
- int client;
- time_t timestamp;
struct xid_item *next;
-} dhcprelay_xid_list = {0, {0}, 0, 0, NULL};
+};
+#define dhcprelay_xid_list (*(struct xid_item*)&bb_common_bufsiz1)
static struct xid_item *xid_add(uint32_t xid, struct sockaddr_in *ip, int client)
{
return -1;
}
-/**
- * signal_handler - handles signals ;-)
- * sig - sent signal
- */
-static smallint dhcprelay_stopflag;
-
-static void dhcprelay_signal_handler(int sig)
-{
- dhcprelay_stopflag = 1;
-}
-
/**
* get_client_devices - parses the devices list
* dev_list - comma separated list of devices
}
-/* Creates listen sockets (in fds) and returns the number allocated. */
+/* Creates listen sockets (in fds) and returns numerically max fd. */
static int init_sockets(char **client, int num_clients,
- char *server, int *fds, int *max_socket)
+ char *server, int *fds)
{
- int i;
+ int i, n;
/* talk to real server on bootps */
fds[0] = listen_socket(/*INADDR_ANY,*/ 67, server);
- *max_socket = fds[0];
-
- /* array starts at 1 since server is 0 */
- num_clients++;
+ n = fds[0];
for (i = 1; i < num_clients; i++) {
/* listen for clients on bootps */
fds[i] = listen_socket(/*NADDR_ANY,*/ 67, client[i-1]);
- if (fds[i] > *max_socket)
- *max_socket = fds[i];
+ if (fds[i] > n)
+ n = fds[i];
}
-
- return i;
+ return n;
}
xid_del(p->xid);
}
+static void dhcprelay_loop(int *fds, int num_sockets, int max_socket, char **clients,
+ struct sockaddr_in *server_addr, uint32_t gw_ip) ATTRIBUTE_NORETURN;
static void dhcprelay_loop(int *fds, int num_sockets, int max_socket, char **clients,
struct sockaddr_in *server_addr, uint32_t gw_ip)
{
struct timeval tv;
int i;
- while (!dhcprelay_stopflag) {
+ while (1) {
FD_ZERO(&rfds);
for (i = 0; i < num_sockets; i++)
FD_SET(fds[i], &rfds);
int dhcprelay_main(int argc, char **argv);
int dhcprelay_main(int argc, char **argv)
{
- int i, num_sockets, max_socket, fds[MAX_INTERFACES];
+ int num_sockets, max_socket, fds[MAX_INTERFACES];
uint32_t gw_ip;
char **clients;
struct sockaddr_in server_addr;
clients = get_client_devices(argv[1], &num_sockets);
if (!clients) return 0;
- signal(SIGTERM, dhcprelay_signal_handler);
- signal(SIGQUIT, dhcprelay_signal_handler);
- signal(SIGINT, dhcprelay_signal_handler);
-
- num_sockets = init_sockets(clients, num_sockets, argv[2], fds, &max_socket);
+ num_sockets++; /* for server socket at fds[0] */
+ max_socket = init_sockets(clients, num_sockets, argv[2], fds);
if (read_interface(argv[2], NULL, &gw_ip, NULL))
return 1;
+ /* doesn't return */
dhcprelay_loop(fds, num_sockets, max_socket, clients, &server_addr, gw_ip);
-
- if (ENABLE_FEATURE_CLEAN_UP) {
- for (i = 0; i < num_sockets; i++) {
- close(fds[i]);
- free(clients[i]);
- }
- }
-
- return 0;
+ /* return 0; - not reached */
}
/* Compare possibly overflowing unsigned counters */
#define LESS(a,b) ((int)((unsigned)(b) - (unsigned)(a)) > 0)
-static int selfpipe[2];
-
/* state */
#define S_DOWN 0
#define S_RUN 1
int fdcontrolwrite;
};
-static struct svdir svd[2];
-static smallint sigterm;
-static smallint haslog;
-static smallint pidchanged = 1;
-static int logpipe[2];
-static char *dir;
+struct globals {
+ smallint haslog;
+ smallint sigterm;
+ smallint pidchanged;
+ int selfpipe[2];
+ int logpipe[2];
+ char *dir;
+ struct svdir svd[2];
+};
+#define G (*(struct globals*)&bb_common_bufsiz1)
+#define haslog (G.haslog )
+#define sigterm (G.sigterm )
+#define pidchanged (G.pidchanged )
+#define selfpipe (G.selfpipe )
+#define logpipe (G.logpipe )
+#define dir (G.dir )
+#define svd (G.svd )
+#define INIT_G() \
+ do { \
+ pidchanged = 1; \
+ } while (0)
static void fatal2_cannot(const char *m1, const char *m2)
{
int r;
char buf[256];
+ INIT_G();
+
if (!argv[1] || argv[2])
bb_show_usage();
dir = argv[1];
#include "libbb.h"
#include "runit_lib.h"
-static const char *acts;
-static char **service;
-static unsigned rc;
+struct globals {
+ const char *acts;
+ char **service;
+ unsigned rc;
/* "Bernstein" time format: unix + 0x400000000000000aULL */
-static uint64_t tstart, tnow;
-static svstatus_t svstatus;
+ uint64_t tstart, tnow;
+ svstatus_t svstatus;
+};
+#define G (*(struct globals*)&bb_common_bufsiz1)
+#define acts (G.acts )
+#define service (G.service )
+#define rc (G.rc )
+#define tstart (G.tstart )
+#define tnow (G.tnow )
+#define svstatus (G.svstatus )
+#define INIT_G() do { } while (0)
static void fatal_cannot(const char *m1) ATTRIBUTE_NORETURN;
int (*cbk)(const char*);
int curdir;
+ INIT_G();
+
xfunc_error_retval = 100;
x = getenv("SVDIR");
/* Standard mount options (from -o options or --options), with corresponding
* flags */
-struct {
+static const struct {
const char *name;
long flags;
-} static mount_options[] = {
+} mount_options[] = {
// MS_FLAGS set a bit. ~MS_FLAGS disable that bit. 0 flags are NOPs.
USE_FEATURE_MOUNT_LOOP(
return list;
}
-llist_t *fslist = 0;
+static llist_t *fslist;
#if ENABLE_FEATURE_CLEAN_UP
static void delete_block_backed_filesystems(void)
static char *nfs_strerror(int status)
{
int i;
- static char buf[sizeof("unknown nfs status return value: ") + sizeof(int)*3];
for (i = 0; nfs_errtbl[i].stat != -1; i++) {
if (nfs_errtbl[i].stat == status)
return strerror(nfs_errtbl[i].errnum);
}
- sprintf(buf, "unknown nfs status return value: %d", status);
- return buf;
+ return xasprintf("unknown nfs status return value: %d", status);
}
static bool_t xdr_fhandle(XDR *xdrs, fhandle objp)
#define MAX_NFSPROT ((nfs_mount_version >= 4) ? 3 : 2)
-/*
- * nfs_mount_version according to the sources seen at compile time.
- */
-static int nfs_mount_version;
-static int kernel_version;
+static smalluint nfs_mount_version;
/*
* Unfortunately, the kernel prints annoying console messages
static void
find_kernel_nfs_mount_version(void)
{
- if (kernel_version)
+ int kernel_version;
+
+ if (nfs_mount_version)
return;
nfs_mount_version = 4; /* default */
}
}
-static struct pmap *
-get_mountport(struct sockaddr_in *server_addr,
+static void
+get_mountport(struct pmap *pm_mnt,
+ struct sockaddr_in *server_addr,
long unsigned prog,
long unsigned version,
long unsigned proto,
long unsigned port)
{
struct pmaplist *pmap;
- static struct pmap p = {0, 0, 0, 0};
server_addr->sin_port = PMAPPORT;
/* glibc 2.4 (still) has pmap_getmaps(struct sockaddr_in *).
version = MAX_NFSPROT;
if (!prog)
prog = MOUNTPROG;
- p.pm_prog = prog;
- p.pm_vers = version;
- p.pm_prot = proto;
- p.pm_port = port;
+ pm_mnt->pm_prog = prog;
+ pm_mnt->pm_vers = version;
+ pm_mnt->pm_prot = proto;
+ pm_mnt->pm_port = port;
while (pmap) {
if (pmap->pml_map.pm_prog != prog)
goto next;
- if (!version && p.pm_vers > pmap->pml_map.pm_vers)
+ if (!version && pm_mnt->pm_vers > pmap->pml_map.pm_vers)
goto next;
if (version > 2 && pmap->pml_map.pm_vers != version)
goto next;
if (version && version <= 2 && pmap->pml_map.pm_vers > 2)
goto next;
if (pmap->pml_map.pm_vers > MAX_NFSPROT ||
- (proto && p.pm_prot && pmap->pml_map.pm_prot != proto) ||
+ (proto && pm_mnt->pm_prot && pmap->pml_map.pm_prot != proto) ||
(port && pmap->pml_map.pm_port != port))
goto next;
- memcpy(&p, &pmap->pml_map, sizeof(p));
-next:
+ memcpy(pm_mnt, &pmap->pml_map, sizeof(*pm_mnt));
+ next:
pmap = pmap->pml_next;
}
- if (!p.pm_vers)
- p.pm_vers = MOUNTVERS;
- if (!p.pm_port)
- p.pm_port = MOUNTPORT;
- if (!p.pm_prot)
- p.pm_prot = IPPROTO_TCP;
- return &p;
+ if (!pm_mnt->pm_vers)
+ pm_mnt->pm_vers = MOUNTVERS;
+ if (!pm_mnt->pm_port)
+ pm_mnt->pm_port = MOUNTPORT;
+ if (!pm_mnt->pm_prot)
+ pm_mnt->pm_prot = IPPROTO_TCP;
}
#if BB_MMU
{
struct timeval total_timeout;
struct timeval retry_timeout;
- struct pmap* pm_mnt;
+ struct pmap pm_mnt;
time_t t;
time_t prevt;
time_t timeout;
if (t - prevt < 30)
sleep(30);
- pm_mnt = get_mountport(&mount_server_addr,
+ get_mountport(&pm_mnt, &mount_server_addr,
mountprog,
mountvers,
proto,
mountport);
- nfsvers = (pm_mnt->pm_vers < 2) ? 2 : pm_mnt->pm_vers;
+ nfsvers = (pm_mnt.pm_vers < 2) ? 2 : pm_mnt.pm_vers;
/* contact the mount daemon via TCP */
- mount_server_addr.sin_port = htons(pm_mnt->pm_port);
+ mount_server_addr.sin_port = htons(pm_mnt.pm_port);
msock = RPC_ANYSOCK;
- switch (pm_mnt->pm_prot) {
+ switch (pm_mnt.pm_prot) {
case IPPROTO_UDP:
mclient = clntudp_create(&mount_server_addr,
- pm_mnt->pm_prog,
- pm_mnt->pm_vers,
+ pm_mnt.pm_prog,
+ pm_mnt.pm_vers,
retry_timeout,
&msock);
if (mclient)
break;
- mount_server_addr.sin_port = htons(pm_mnt->pm_port);
+ mount_server_addr.sin_port = htons(pm_mnt.pm_port);
msock = RPC_ANYSOCK;
case IPPROTO_TCP:
mclient = clnttcp_create(&mount_server_addr,
- pm_mnt->pm_prog,
- pm_mnt->pm_vers,
+ pm_mnt.pm_prog,
+ pm_mnt.pm_vers,
&msock, 0, 0);
break;
default:
*/
memset(&status, 0, sizeof(status));
- if (pm_mnt->pm_vers == 3)
+ if (pm_mnt.pm_vers == 3)
clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
(xdrproc_t) xdr_dirpath,
(caddr_t) &pathname,