commit - 330fe27c7fd1e395ae626f5b6e64cf527f0ae951
commit + 0e324bf209a78fff0daca2edc14ddbf913717ea2
blob - 4011e0f3cb3a14e6359f82f82497db29b47dcd89
blob + b2437ee8b32e25362ea972f30849f0fc1fde5923
--- ctl.c
+++ ctl.c
#include <unistd.h>
#include <errno.h>
#include <libgen.h>
+#include <limits.h>
#include <histedit.h>
#include <sys/signal.h>
+#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
edit_file(tmpfile, daemons->mode, daemons->propername, args);
}
+const char *motd_example = "\n\n"
+ "Welcome to OpenBSD: The proactively secure Unix-like operating system.\n"
+ "\n"
+ "Please use the sendbug(1) utility to report bugs in the system.\n"
+ "Before reporting a bug, please try to reproduce it with the latest\n"
+ "version of the code. With bug reports, please try to ensure that\n"
+ "enough information to reproduce the problem is enclosed, and if a\n"
+ "known fix for it exists, include that as well.\n\n";
+
+static size_t
+make_example_motd(char *path, size_t size)
+{
+ char buf[1024];
+ int mib[] = { CTL_KERN, KERN_VERSION, INT_MAX };
+ int fd;
+ ssize_t w;
+ size_t len = 0;
+ char *eol;
+
+ if (strlcpy(path, "/tmp/nsh-motd-XXXXXXXXXX", size) >= size)
+ return 0;
+
+ fd = mkstemp(path);
+ if (fd == -1)
+ return 0;
+
+ if (sysctl_str(mib, buf, sizeof(buf), 1))
+ goto done;
+
+ eol = strchr(buf, '\n');
+ if (eol)
+ *eol = '\0';
+
+ len = strlen(buf);
+
+ w = write(fd, buf, len);
+ if (w != len) {
+ len = 0;
+ goto done;
+ }
+
+ len = strlen(motd_example);
+ w = write(fd, motd_example, len);
+ if (w != len)
+ len = 0;
+done:
+ close(fd);
+ if (len == 0)
+ unlink(path);
+ return len;
+}
+
+static size_t
+make_example_path(char *path, size_t size, const char *directory,
+ const char *name)
+{
+ size_t len;
+ int ret;
+
+ ret = snprintf(path, size, "%s/%s", directory, name);
+ if (ret < 0 || (size_t)ret >= size)
+ return 0;
+
+ /* Snip off rdomain trailer at end of filename. */
+ len = strlen(path);
+ while (len > 0) {
+ if (path[len - 1] >= '0' && path[len - 1] <= '9') {
+ path[len - 1] = '\0';
+ len--;
+ } else {
+ if (path[len - 1] == '.') {
+ path[len - 1] = '\0';
+ len--;
+ }
+ break;
+ }
+ }
+
+ return len;
+}
+
static void
provide_example_config(char *filename)
{
char path[PATH_MAX];
char tmpprompt[sizeof(prompt)];
FILE *f = NULL, *example = NULL;
- int ret, num;
+ int num, unlink_example = 0;
struct stat sb;
size_t len, remain;
if (name == NULL)
goto done;
- ret = snprintf(path, sizeof(path), "/etc/examples/%s", name);
- if (ret < 0 || (size_t)ret >= sizeof(path))
- goto done;
-
- /* Snip off rdomain trailer at end of filename. */
- len = strlen(path);
- while (len > 0) {
- if (path[len - 1] >= '0' && path[len - 1] <= '9') {
- path[len - 1] = '\0';
- len--;
- } else {
- if (path[len - 1] == '.') {
- path[len - 1] = '\0';
- len--;
- }
- break;
- }
+ /*
+ * Most examples are in /etc/examples. However, some daemons
+ * which are enabled by default have default configs elsewhere.
+ * In some cases nsh uses different names for configuration files.
+ */
+ if (strncmp(name, "motd", 4) == 0) {
+ len = make_example_motd(path, sizeof(path));
+ if (len > 0)
+ unlink_example = 1;
+ } else if (strncmp(name, "sshd.conf", 9) == 0) {
+ len = make_example_path(path, sizeof(path),
+ "/etc/ssh", "sshd_config");
+ } else if (strncmp(name, "smtpd.conf", 10) == 0) {
+ len = make_example_path(path, sizeof(path),
+ "/etc/mail", name);
+ } else {
+ len = make_example_path(path, sizeof(path),
+ "/etc/examples", name);
}
if (len == 0)
goto done;
example = fopen(path, "r");
- if (example == NULL)
- goto done;
+ if (example == NULL) {
+ if (errno != ENOENT)
+ goto done;
+ /* XXX npppd.conf should probably be in /etc/examples/ */
+ if (strncmp(name, "npppd.conf", 10) != 0)
+ goto done;
+ len = make_example_path(path, sizeof(path),
+ "/etc/npppd", name);
+ if (len == 0)
+ goto done;
+ example = fopen(path, "r");
+ if (example == NULL)
+ goto done;
+ }
+
if (fstat(fileno(example), &sb) == -1)
goto done;
const char *buf;
if ((buf = el_gets(elp, &num)) == NULL) {
- if (num == -1) {
- ret = -1;
+ if (num == -1)
goto done;
- }
/* EOF, e.g. ^X or ^D via exit_i() in complete.c */
goto done;
}
restoreprompt();
if (example)
fclose(example);
+ if (unlink_example)
+ unlink(path);
}
int
blob - 2e4977cfe088faa4a96086ab42f1262d2a78f9c1
blob + 1d8310a256e3112a05a6b6ea4c8ab55e5bdb6c6e
--- externs.h
+++ externs.h
/* sysctl.c */
int sysctl_int(int[], int, int);
+int sysctl_str(int[], char *, size_t, int);
int ipsysctl(int, char *, char *, int);
void conf_sysctls(FILE *);
blob - b987820def6eb3b7bc042da908ed72a34ef6a2fb
blob + 6716dbe41a1d02630972e4686cf7b7884311d8d2
--- sysctl.c
+++ sysctl.c
return(old);
}
+/*
+ * sysctl_str: get or set a string value
+ *
+ * val - value to read or set in sysctl
+ * read - are we just reading the value (1), or setting it? (0)
+ */
+
+int
+sysctl_str(int mib[], char *val, size_t val_size, int read)
+{
+ void *old = NULL, *new = NULL;
+ size_t oldlen = 0, newlen = 0;
+ int i;
+
+ if (read) {
+ old = val;
+ oldlen = val_size;
+ } else {
+ new = val;
+ newlen = val_size;
+ }
+
+ for (i = 0; i < 6; i++)
+ if (mib[i] == MIB_STOP)
+ break;
+
+ if (sysctl(mib, i, old, &oldlen, new, newlen) == -1) {
+ if (!read) {
+ printf("%% sysctl_str: sysctl: %s\n", strerror(errno));
+ } else if (errno != ENOPROTOOPT) {
+ printf("%% sysctl_str: sysctl: %s\n", strerror(errno));
+ for (i = 0; i < 6; i++) {
+ if (mib[i] == MIB_STOP)
+ break;
+ printf("%% mib[%i] == %d\n", i, mib[i]);
+ }
+ }
+ return -1;
+ }
+
+ return 0;
+}
+
struct sysctltab sysctls[] = {
{ "ip", PF_INET, iptab, ipsysctls },
{ "ip6", PF_INET6, ip6tab, ip6sysctls },