Changeset View
Changeset View
Standalone View
Standalone View
head/usr.sbin/jls/jls.c
/*- | /*- | ||||
* Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org> | * Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org> | ||||
* Copyright (c) 2008 Bjoern A. Zeeb <bz@FreeBSD.org> | * Copyright (c) 2008 Bjoern A. Zeeb <bz@FreeBSD.org> | ||||
* Copyright (c) 2009 James Gritton <jamie@FreeBSD.org> | * Copyright (c) 2009 James Gritton <jamie@FreeBSD.org> | ||||
* Copyright (c) 2015 Emmanuel Vadot <manu@bocal.org> | |||||
* All rights reserved. | * All rights reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
* notice, this list of conditions and the following disclaimer. | * notice, this list of conditions and the following disclaimer. | ||||
* 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright | ||||
Show All 27 Lines | |||||
#include <err.h> | #include <err.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <jail.h> | #include <jail.h> | ||||
#include <limits.h> | #include <limits.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <libxo/xo.h> | |||||
#define JP_USER 0x01000000 | #define JP_USER 0x01000000 | ||||
#define JP_OPT 0x02000000 | #define JP_OPT 0x02000000 | ||||
#define JLS_XO_VERSION "1" | |||||
#define PRINT_DEFAULT 0x01 | #define PRINT_DEFAULT 0x01 | ||||
#define PRINT_HEADER 0x02 | #define PRINT_HEADER 0x02 | ||||
#define PRINT_NAMEVAL 0x04 | #define PRINT_NAMEVAL 0x04 | ||||
#define PRINT_QUOTED 0x08 | #define PRINT_QUOTED 0x08 | ||||
#define PRINT_SKIP 0x10 | #define PRINT_SKIP 0x10 | ||||
#define PRINT_VERBOSE 0x20 | #define PRINT_VERBOSE 0x20 | ||||
#define PRINT_JAIL_NAME 0x40 | #define PRINT_JAIL_NAME 0x40 | ||||
static struct jailparam *params; | static struct jailparam *params; | ||||
static int *param_parent; | static int *param_parent; | ||||
static int nparams; | static int nparams; | ||||
#ifdef INET6 | #ifdef INET6 | ||||
static int ip6_ok; | static int ip6_ok; | ||||
#endif | #endif | ||||
#ifdef INET | #ifdef INET | ||||
static int ip4_ok; | static int ip4_ok; | ||||
#endif | #endif | ||||
static int add_param(const char *name, void *value, size_t valuelen, | static int add_param(const char *name, void *value, size_t valuelen, | ||||
struct jailparam *source, unsigned flags); | struct jailparam *source, unsigned flags); | ||||
static int sort_param(const void *a, const void *b); | static int sort_param(const void *a, const void *b); | ||||
static char *noname(const char *name); | static char *noname(const char *name); | ||||
static char *nononame(const char *name); | static char *nononame(const char *name); | ||||
static int print_jail(int pflags, int jflags); | static int print_jail(int pflags, int jflags); | ||||
static void quoted_print(char *str); | static void quoted_print(int pflags, char *name, char *value); | ||||
int | int | ||||
main(int argc, char **argv) | main(int argc, char **argv) | ||||
{ | { | ||||
char *dot, *ep, *jname, *pname; | char *dot, *ep, *jname, *pname; | ||||
int c, i, jflags, jid, lastjid, pflags, spc; | int c, i, jflags, jid, lastjid, pflags, spc; | ||||
argc = xo_parse_args(argc, argv); | |||||
if (argc < 0) | |||||
exit(1); | |||||
xo_set_version(JLS_XO_VERSION); | |||||
jname = NULL; | jname = NULL; | ||||
pflags = jflags = jid = 0; | pflags = jflags = jid = 0; | ||||
while ((c = getopt(argc, argv, "adj:hNnqsv")) >= 0) | while ((c = getopt(argc, argv, "adj:hNnqsv")) >= 0) | ||||
switch (c) { | switch (c) { | ||||
case 'a': | case 'a': | ||||
case 'd': | case 'd': | ||||
jflags |= JAIL_DYING; | jflags |= JAIL_DYING; | ||||
break; | break; | ||||
Show All 22 Lines | case 's': | ||||
PRINT_NAMEVAL | PRINT_QUOTED | PRINT_SKIP; | PRINT_NAMEVAL | PRINT_QUOTED | PRINT_SKIP; | ||||
break; | break; | ||||
case 'v': | case 'v': | ||||
pflags = (pflags & | pflags = (pflags & | ||||
~(PRINT_HEADER | PRINT_NAMEVAL | PRINT_SKIP)) | | ~(PRINT_HEADER | PRINT_NAMEVAL | PRINT_SKIP)) | | ||||
PRINT_VERBOSE; | PRINT_VERBOSE; | ||||
break; | break; | ||||
default: | default: | ||||
errx(1, "usage: jls [-dhNnqv] [-j jail] [param ...]"); | xo_errx(1, "usage: jls [-dhNnqv] [-j jail] [param ...]"); | ||||
} | } | ||||
#ifdef INET6 | #ifdef INET6 | ||||
ip6_ok = feature_present("inet6"); | ip6_ok = feature_present("inet6"); | ||||
#endif | #endif | ||||
#ifdef INET | #ifdef INET | ||||
ip4_ok = feature_present("inet"); | ip4_ok = feature_present("inet"); | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | #endif | ||||
if (jid != 0) | if (jid != 0) | ||||
add_param("jid", &jid, sizeof(jid), NULL, 0); | add_param("jid", &jid, sizeof(jid), NULL, 0); | ||||
else if (jname != NULL) | else if (jname != NULL) | ||||
add_param("name", jname, strlen(jname), NULL, 0); | add_param("name", jname, strlen(jname), NULL, 0); | ||||
else | else | ||||
add_param("lastjid", &lastjid, sizeof(lastjid), NULL, 0); | add_param("lastjid", &lastjid, sizeof(lastjid), NULL, 0); | ||||
/* Print a header line if requested. */ | /* Print a header line if requested. */ | ||||
if (pflags & PRINT_VERBOSE) | if (pflags & PRINT_VERBOSE) { | ||||
printf(" JID Hostname Path\n" | xo_emit("{T:/%3s}{T:JID}{P: }{T:Hostname}{Pd:/%22s}{T:Path}\n", | ||||
" Name State\n" | "", ""); | ||||
" CPUSetID\n" | xo_emit("{P:/%8s}{T:Name}{Pd:/%26s}{T:State}\n", "", ""); | ||||
" IP Address(es)\n"); | xo_emit("{P:/%8s}{T:CPUSetID}\n", ""); | ||||
xo_emit("{P:/%8s}{T:IP Address(es)}\n", ""); | |||||
} | |||||
else if (pflags & PRINT_DEFAULT) | else if (pflags & PRINT_DEFAULT) | ||||
if (pflags & PRINT_JAIL_NAME) | if (pflags & PRINT_JAIL_NAME) | ||||
printf(" JID IP Address " | xo_emit("{P: }{T:JID/%-15s}{P: }{T:IP Address/%-15s}" | ||||
"Hostname Path\n"); | "{P: }{T:Hostname/%-29s}{P: }{T:Path}\n"); | ||||
else | else | ||||
printf(" JID IP Address " | xo_emit("{T:JID/%6s}{P: }{T:IP Address}{P:/%6s}" | ||||
"Hostname Path\n"); | "{T:Hostname}{P:/%22s}{T:Path}\n", "", ""); | ||||
else if (pflags & PRINT_HEADER) { | else if (pflags & PRINT_HEADER) { | ||||
for (i = spc = 0; i < nparams; i++) | for (i = spc = 0; i < nparams; i++) | ||||
if (params[i].jp_flags & JP_USER) { | if (params[i].jp_flags & JP_USER) { | ||||
if (spc) | if (spc) | ||||
putchar(' '); | xo_emit("{P: }"); | ||||
else | else | ||||
spc = 1; | spc = 1; | ||||
fputs(params[i].jp_name, stdout); | xo_emit(params[i].jp_name); | ||||
} | } | ||||
putchar('\n'); | xo_emit("{P:\n}"); | ||||
} | } | ||||
xo_open_container("jail-information"); | |||||
xo_open_list("jail"); | |||||
/* Fetch the jail(s) and print the parameters. */ | /* Fetch the jail(s) and print the parameters. */ | ||||
if (jid != 0 || jname != NULL) { | if (jid != 0 || jname != NULL) { | ||||
if (print_jail(pflags, jflags) < 0) | if (print_jail(pflags, jflags) < 0) | ||||
errx(1, "%s", jail_errmsg); | xo_errx(1, "%s", jail_errmsg); | ||||
} else { | } else { | ||||
for (lastjid = 0; | for (lastjid = 0; | ||||
(lastjid = print_jail(pflags, jflags)) >= 0; ) | (lastjid = print_jail(pflags, jflags)) >= 0; ) | ||||
; | ; | ||||
if (errno != 0 && errno != ENOENT) | if (errno != 0 && errno != ENOENT) | ||||
errx(1, "%s", jail_errmsg); | xo_errx(1, "%s", jail_errmsg); | ||||
} | } | ||||
xo_close_list("jail"); | |||||
xo_close_container("jail-information"); | |||||
xo_finish(); | |||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
add_param(const char *name, void *value, size_t valuelen, | add_param(const char *name, void *value, size_t valuelen, | ||||
struct jailparam *source, unsigned flags) | struct jailparam *source, unsigned flags) | ||||
{ | { | ||||
struct jailparam *param, *tparams; | struct jailparam *param, *tparams; | ||||
int i, tnparams; | int i, tnparams; | ||||
static int paramlistsize; | static int paramlistsize; | ||||
/* The pseudo-parameter "all" scans the list of available parameters. */ | /* The pseudo-parameter "all" scans the list of available parameters. */ | ||||
if (!strcmp(name, "all")) { | if (!strcmp(name, "all")) { | ||||
tnparams = jailparam_all(&tparams); | tnparams = jailparam_all(&tparams); | ||||
if (tnparams < 0) | if (tnparams < 0) | ||||
errx(1, "%s", jail_errmsg); | xo_errx(1, "%s", jail_errmsg); | ||||
qsort(tparams, (size_t)tnparams, sizeof(struct jailparam), | qsort(tparams, (size_t)tnparams, sizeof(struct jailparam), | ||||
sort_param); | sort_param); | ||||
for (i = 0; i < tnparams; i++) | for (i = 0; i < tnparams; i++) | ||||
add_param(tparams[i].jp_name, NULL, (size_t)0, | add_param(tparams[i].jp_name, NULL, (size_t)0, | ||||
tparams + i, flags); | tparams + i, flags); | ||||
free(tparams); | free(tparams); | ||||
return -1; | return -1; | ||||
} | } | ||||
/* Check for repeat parameters. */ | /* Check for repeat parameters. */ | ||||
for (i = 0; i < nparams; i++) | for (i = 0; i < nparams; i++) | ||||
if (!strcmp(name, params[i].jp_name)) { | if (!strcmp(name, params[i].jp_name)) { | ||||
if (value != NULL && jailparam_import_raw(params + i, | if (value != NULL && jailparam_import_raw(params + i, | ||||
value, valuelen) < 0) | value, valuelen) < 0) | ||||
errx(1, "%s", jail_errmsg); | xo_errx(1, "%s", jail_errmsg); | ||||
params[i].jp_flags |= flags; | params[i].jp_flags |= flags; | ||||
if (source != NULL) | if (source != NULL) | ||||
jailparam_free(source, 1); | jailparam_free(source, 1); | ||||
return i; | return i; | ||||
} | } | ||||
/* Make sure there is room for the new param record. */ | /* Make sure there is room for the new param record. */ | ||||
if (!nparams) { | if (!nparams) { | ||||
paramlistsize = 32; | paramlistsize = 32; | ||||
params = malloc(paramlistsize * sizeof(*params)); | params = malloc(paramlistsize * sizeof(*params)); | ||||
param_parent = malloc(paramlistsize * sizeof(*param_parent)); | param_parent = malloc(paramlistsize * sizeof(*param_parent)); | ||||
if (params == NULL || param_parent == NULL) | if (params == NULL || param_parent == NULL) | ||||
err(1, "malloc"); | xo_err(1, "malloc"); | ||||
} else if (nparams >= paramlistsize) { | } else if (nparams >= paramlistsize) { | ||||
paramlistsize *= 2; | paramlistsize *= 2; | ||||
params = realloc(params, paramlistsize * sizeof(*params)); | params = realloc(params, paramlistsize * sizeof(*params)); | ||||
param_parent = realloc(param_parent, | param_parent = realloc(param_parent, | ||||
paramlistsize * sizeof(*param_parent)); | paramlistsize * sizeof(*param_parent)); | ||||
if (params == NULL || param_parent == NULL) | if (params == NULL || param_parent == NULL) | ||||
err(1, "realloc"); | xo_err(1, "realloc"); | ||||
} | } | ||||
/* Look up the parameter. */ | /* Look up the parameter. */ | ||||
param_parent[nparams] = -1; | param_parent[nparams] = -1; | ||||
param = params + nparams++; | param = params + nparams++; | ||||
if (source != NULL) { | if (source != NULL) { | ||||
*param = *source; | *param = *source; | ||||
param->jp_flags |= flags; | param->jp_flags |= flags; | ||||
return param - params; | return param - params; | ||||
} | } | ||||
if (jailparam_init(param, name) < 0 || | if (jailparam_init(param, name) < 0 || | ||||
(value != NULL ? jailparam_import_raw(param, value, valuelen) | (value != NULL ? jailparam_import_raw(param, value, valuelen) | ||||
: jailparam_import(param, value)) < 0) { | : jailparam_import(param, value)) < 0) { | ||||
if (flags & JP_OPT) { | if (flags & JP_OPT) { | ||||
nparams--; | nparams--; | ||||
return (-1); | return (-1); | ||||
} | } | ||||
errx(1, "%s", jail_errmsg); | xo_errx(1, "%s", jail_errmsg); | ||||
} | } | ||||
param->jp_flags = flags; | param->jp_flags = flags; | ||||
return param - params; | return param - params; | ||||
} | } | ||||
static int | static int | ||||
sort_param(const void *a, const void *b) | sort_param(const void *a, const void *b) | ||||
{ | { | ||||
Show All 14 Lines | |||||
static char * | static char * | ||||
noname(const char *name) | noname(const char *name) | ||||
{ | { | ||||
char *nname, *p; | char *nname, *p; | ||||
nname = malloc(strlen(name) + 3); | nname = malloc(strlen(name) + 3); | ||||
if (nname == NULL) | if (nname == NULL) | ||||
err(1, "malloc"); | xo_err(1, "malloc"); | ||||
p = strrchr(name, '.'); | p = strrchr(name, '.'); | ||||
if (p != NULL) | if (p != NULL) | ||||
sprintf(nname, "%.*s.no%s", (int)(p - name), name, p + 1); | sprintf(nname, "%.*s.no%s", (int)(p - name), name, p + 1); | ||||
else | else | ||||
sprintf(nname, "no%s", name); | sprintf(nname, "no%s", name); | ||||
return nname; | return nname; | ||||
} | } | ||||
static char * | static char * | ||||
nononame(const char *name) | nononame(const char *name) | ||||
{ | { | ||||
char *nname, *p; | char *nname, *p; | ||||
p = strrchr(name, '.'); | p = strrchr(name, '.'); | ||||
if (strncmp(p ? p + 1 : name, "no", 2)) | if (strncmp(p ? p + 1 : name, "no", 2)) | ||||
return NULL; | return NULL; | ||||
nname = malloc(strlen(name) - 1); | nname = malloc(strlen(name) - 1); | ||||
if (nname == NULL) | if (nname == NULL) | ||||
err(1, "malloc"); | xo_err(1, "malloc"); | ||||
if (p != NULL) | if (p != NULL) | ||||
sprintf(nname, "%.*s.%s", (int)(p - name), name, p + 3); | sprintf(nname, "%.*s.%s", (int)(p - name), name, p + 3); | ||||
else | else | ||||
strcpy(nname, name + 2); | strcpy(nname, name + 2); | ||||
return nname; | return nname; | ||||
} | } | ||||
static int | static int | ||||
print_jail(int pflags, int jflags) | print_jail(int pflags, int jflags) | ||||
{ | { | ||||
char *nname; | char *nname, *xo_nname; | ||||
char **param_values; | char **param_values; | ||||
int i, ai, jid, count, n, spc; | int i, ai, jid, count, n, spc; | ||||
char ipbuf[INET6_ADDRSTRLEN]; | char ipbuf[INET6_ADDRSTRLEN]; | ||||
jid = jailparam_get(params, nparams, jflags); | jid = jailparam_get(params, nparams, jflags); | ||||
if (jid < 0) | if (jid < 0) | ||||
return jid; | return jid; | ||||
xo_open_instance("jail"); | |||||
if (pflags & PRINT_VERBOSE) { | if (pflags & PRINT_VERBOSE) { | ||||
printf("%6d %-29.29s %.74s\n" | xo_emit("{:jid/%6d}{P: }{:hostname/%-29.29s/%s}{P: }" | ||||
"%6s %-29.29s %.74s\n" | "{:path/%.74s/%s}\n", | ||||
"%6s %-6d\n", | |||||
*(int *)params[0].jp_value, | *(int *)params[0].jp_value, | ||||
(char *)params[1].jp_value, | (char *)params[1].jp_value, | ||||
(char *)params[2].jp_value, | (char *)params[2].jp_value); | ||||
"", | xo_emit("{P: }{:name/%-29.29s/%s}{P: }{:state/%.74s}\n", | ||||
(char *)params[3].jp_value, | (char *)params[3].jp_value, | ||||
*(int *)params[4].jp_value ? "DYING" : "ACTIVE", | *(int *)params[4].jp_value ? "DYING" : "ACTIVE"); | ||||
"", | xo_emit("{P: }{:cpusetid/%d}\n", *(int *)params[5].jp_value); | ||||
*(int *)params[5].jp_value); | |||||
n = 6; | n = 6; | ||||
#ifdef INET | #ifdef INET | ||||
if (ip4_ok && !strcmp(params[n].jp_name, "ip4.addr")) { | if (ip4_ok && !strcmp(params[n].jp_name, "ip4.addr")) { | ||||
count = params[n].jp_valuelen / sizeof(struct in_addr); | count = params[n].jp_valuelen / sizeof(struct in_addr); | ||||
for (ai = 0; ai < count; ai++) | for (ai = 0; ai < count; ai++) | ||||
if (inet_ntop(AF_INET, | if (inet_ntop(AF_INET, | ||||
&((struct in_addr *)params[n].jp_value)[ai], | &((struct in_addr *)params[n].jp_value)[ai], | ||||
ipbuf, sizeof(ipbuf)) == NULL) | ipbuf, sizeof(ipbuf)) == NULL) | ||||
err(1, "inet_ntop"); | xo_err(1, "inet_ntop"); | ||||
else | else { | ||||
printf("%6s %-15.15s\n", "", ipbuf); | xo_emit("{P: }{l:ipv4_addrs}{P:\n}", ipbuf); | ||||
} | |||||
n++; | n++; | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef INET6 | #ifdef INET6 | ||||
if (ip6_ok && !strcmp(params[n].jp_name, "ip6.addr")) { | if (ip6_ok && !strcmp(params[n].jp_name, "ip6.addr")) { | ||||
count = params[n].jp_valuelen / sizeof(struct in6_addr); | count = params[n].jp_valuelen / sizeof(struct in6_addr); | ||||
for (ai = 0; ai < count; ai++) | for (ai = 0; ai < count; ai++) | ||||
if (inet_ntop(AF_INET6, | if (inet_ntop(AF_INET6, | ||||
&((struct in6_addr *) | &((struct in6_addr *) | ||||
params[n].jp_value)[ai], | params[n].jp_value)[ai], | ||||
ipbuf, sizeof(ipbuf)) == NULL) | ipbuf, sizeof(ipbuf)) == NULL) | ||||
err(1, "inet_ntop"); | xo_err(1, "inet_ntop"); | ||||
else | else | ||||
printf("%6s %s\n", "", ipbuf); | xo_emit("{P: }{l:ipv6_addrs}{P:\n}", ipbuf); | ||||
n++; | n++; | ||||
} | } | ||||
#endif | #endif | ||||
} else if (pflags & PRINT_DEFAULT) { | } else if (pflags & PRINT_DEFAULT) { | ||||
if (pflags & PRINT_JAIL_NAME) | if (pflags & PRINT_JAIL_NAME) | ||||
printf(" %-15s ", (char *)params[0].jp_value); | xo_emit("{P: }{:name/%-15s/%s}{P: }", | ||||
(char *)params[0].jp_value); | |||||
else | else | ||||
printf("%6d ", *(int *)params[0].jp_value); | xo_emit("{:jid/%6d}{P: }", *(int *)params[0].jp_value); | ||||
printf("%-15.15s %-29.29s %.74s\n", | xo_emit("{:ipv4/%-15.15s/%s}{P: }{:hostname/%-29.29s/%s}{P: }{:path/%.74s/%s}\n", | ||||
#ifdef INET | #ifdef INET | ||||
(!ip4_ok || params[1].jp_valuelen == 0) ? "-" | (!ip4_ok || params[1].jp_valuelen == 0) ? "" | ||||
: inet_ntoa(*(struct in_addr *)params[1].jp_value), | : inet_ntoa(*(struct in_addr *)params[1].jp_value), | ||||
(char *)params[2-!ip4_ok].jp_value, | (char *)params[2-!ip4_ok].jp_value, | ||||
(char *)params[3-!ip4_ok].jp_value); | (char *)params[3-!ip4_ok].jp_value); | ||||
#else | #else | ||||
"-", | "-", | ||||
(char *)params[1].jp_value, | (char *)params[1].jp_value, | ||||
(char *)params[2].jp_value); | (char *)params[2].jp_value); | ||||
#endif | #endif | ||||
} else { | } else { | ||||
param_values = alloca(nparams * sizeof(*param_values)); | param_values = alloca(nparams * sizeof(*param_values)); | ||||
for (i = 0; i < nparams; i++) { | for (i = 0; i < nparams; i++) { | ||||
if (!(params[i].jp_flags & JP_USER)) | if (!(params[i].jp_flags & JP_USER)) | ||||
continue; | continue; | ||||
param_values[i] = jailparam_export(params + i); | param_values[i] = jailparam_export(params + i); | ||||
if (param_values[i] == NULL) | if (param_values[i] == NULL) | ||||
errx(1, "%s", jail_errmsg); | xo_errx(1, "%s", jail_errmsg); | ||||
} | } | ||||
for (i = spc = 0; i < nparams; i++) { | for (i = spc = 0; i < nparams; i++) { | ||||
if (!(params[i].jp_flags & JP_USER)) | if (!(params[i].jp_flags & JP_USER)) | ||||
continue; | continue; | ||||
if ((pflags & PRINT_SKIP) && | if ((pflags & PRINT_SKIP) && | ||||
((!(params[i].jp_ctltype & | ((!(params[i].jp_ctltype & | ||||
(CTLFLAG_WR | CTLFLAG_TUN))) || | (CTLFLAG_WR | CTLFLAG_TUN))) || | ||||
(param_parent[i] >= 0 && | (param_parent[i] >= 0 && | ||||
*(int *)params[param_parent[i]].jp_value != | *(int *)params[param_parent[i]].jp_value != | ||||
JAIL_SYS_NEW))) | JAIL_SYS_NEW))) | ||||
continue; | continue; | ||||
if (spc) | if (spc) | ||||
putchar(' '); | xo_emit("{P: }"); | ||||
else | else | ||||
spc = 1; | spc = 1; | ||||
if (pflags & PRINT_NAMEVAL) { | if (pflags & PRINT_NAMEVAL) { | ||||
/* | /* | ||||
* Generally "name=value", but for booleans | * Generally "name=value", but for booleans | ||||
* either "name" or "noname". | * either "name" or "noname". | ||||
*/ | */ | ||||
if (params[i].jp_flags & | if (params[i].jp_flags & | ||||
(JP_BOOL | JP_NOBOOL)) { | (JP_BOOL | JP_NOBOOL)) { | ||||
if (*(int *)params[i].jp_value) | if (*(int *)params[i].jp_value) { | ||||
printf("%s", params[i].jp_name); | asprintf(&xo_nname, "{en:%s/true}", params[i].jp_name); | ||||
xo_emit(xo_nname); | |||||
xo_emit("{d:/%s}", params[i].jp_name); | |||||
} | |||||
else { | else { | ||||
nname = (params[i].jp_flags & | nname = (params[i].jp_flags & | ||||
JP_NOBOOL) ? | JP_NOBOOL) ? | ||||
nononame(params[i].jp_name) | nononame(params[i].jp_name) | ||||
: noname(params[i].jp_name); | : noname(params[i].jp_name); | ||||
printf("%s", nname); | if (params[i].jp_flags & JP_NOBOOL) { | ||||
asprintf(&xo_nname, "{en:%s/true}", params[i].jp_name); | |||||
xo_emit(xo_nname); | |||||
} else { | |||||
asprintf(&xo_nname, "{en:%s/false}", params[i].jp_name); | |||||
xo_emit(xo_nname); | |||||
} | |||||
xo_emit("{d:/%s}", nname); | |||||
free(nname); | free(nname); | ||||
} | } | ||||
free(xo_nname); | |||||
continue; | continue; | ||||
} | } | ||||
printf("%s=", params[i].jp_name); | xo_emit("{d:%s}=", params[i].jp_name); | ||||
} | } | ||||
if (params[i].jp_valuelen == 0) { | if (params[i].jp_valuelen == 0) { | ||||
if (pflags & PRINT_QUOTED) | if (pflags & PRINT_QUOTED) | ||||
printf("\"\""); | xo_emit("{P:\"\"}"); | ||||
else if (!(pflags & PRINT_NAMEVAL)) | else if (!(pflags & PRINT_NAMEVAL)) | ||||
putchar('-'); | xo_emit("{P:-}"); | ||||
} else | } else { | ||||
quoted_print(param_values[i]); | quoted_print(pflags, params[i].jp_name, param_values[i]); | ||||
} | } | ||||
putchar('\n'); | } | ||||
xo_emit("{P:\n}"); | |||||
for (i = 0; i < nparams; i++) | for (i = 0; i < nparams; i++) | ||||
if (params[i].jp_flags & JP_USER) | if (params[i].jp_flags & JP_USER) | ||||
free(param_values[i]); | free(param_values[i]); | ||||
} | } | ||||
xo_close_instance("jail"); | |||||
return (jid); | return (jid); | ||||
} | } | ||||
static void | static void | ||||
quoted_print(char *str) | quoted_print(int pflags, char *name, char *value) | ||||
{ | { | ||||
int c, qc; | int qc; | ||||
char *p = str; | char *p = value; | ||||
char *param_name_value; | |||||
/* An empty string needs quoting. */ | /* An empty string needs quoting. */ | ||||
if (!*p) { | if (!*p) { | ||||
fputs("\"\"", stdout); | asprintf(¶m_name_value, "{k:%s}{d:%s/\"\"}", name, name); | ||||
xo_emit(param_name_value); | |||||
free(param_name_value); | |||||
return; | return; | ||||
} | } | ||||
asprintf(¶m_name_value, "{:%s/%%s}", name); | |||||
/* | /* | ||||
* The value will be surrounded by quotes if it contains spaces | * The value will be surrounded by quotes if it contains spaces | ||||
* or quotes. | * or quotes. | ||||
*/ | */ | ||||
qc = strchr(p, '\'') ? '"' | qc = strchr(p, '\'') ? '"' | ||||
: strchr(p, '"') ? '\'' | : strchr(p, '"') ? '\'' | ||||
: strchr(p, ' ') || strchr(p, '\t') ? '"' | : strchr(p, ' ') || strchr(p, '\t') ? '"' | ||||
: 0; | : 0; | ||||
if (qc) | |||||
putchar(qc); | if (qc && pflags & PRINT_QUOTED) | ||||
while ((c = *p++)) { | xo_emit("{P:/%c}", qc); | ||||
if (c == '\\' || c == qc) | |||||
putchar('\\'); | xo_emit(param_name_value, value); | ||||
putchar(c); | |||||
} | free(param_name_value); | ||||
if (qc) | |||||
putchar(qc); | if (qc && pflags & PRINT_QUOTED) | ||||
xo_emit("{P:/%c}", qc); | |||||
} | } |