commit - d84619f38238a58126adf8d62870c7fc8593aca5
commit + 2d331b3f3d70a5e5bf1362ff9e23627f0ca15288
blob - 4a9419a0ddac0891c65b10ea7ab7e5150a51e051
blob + 08c1f3f3b37b555c2e7c4d573e06af93601a01d3
--- commands.c
+++ commands.c
static int exitconfig(int, char**);
int rtable(int, char**);
int group(int, char**);
+static int pr_crontab(int, char **, FILE *);
static int pr_routes(int, char **);
static int pr_routes6(int, char **);
static int pr_arp(int, char **);
{ "monitor", "Monitor routing/arp table changes", CMPL0 0, 0, 0, 0, monitor },
{ "version", "Software information", CMPL0 0, 0, 0, 0, version },
{ "users", "System users", CMPL0 0, 0, 0, 0, who },
+ { "crontab", "Scheduled background jobs", CMPL0 0, 0, 0, 0, pr_crontab },
+ { "scheduler", "Scheduled background jobs", CMPL0 0, 0, 0, 0, pr_crontab },
{ "running-config", "Operating configuration", CMPL0 0, 0, 0, 0, pr_conf },
{ "startup-config", "Startup configuration", CMPL0 0, 0, 0, 0, pr_s_conf },
{ "active-config", "Configuration of active context", CMPL0 0, 0, 0, 0, pr_a_conf },
static char tracert6help[];
static char sshhelp[];
static char telnethelp[];
+static char crontabhelp[];
static char showhelp[];
static char whohelp[];
static char dohelp[];
tracert6help[] ="Print the route to IPv6 host",
sshhelp[] = "SSH connection to remote host",
telnethelp[] = "Telnet connection to remote host",
+ crontabhelp[] = "Configure scheduled background jobs",
quithelp[] = "Close current connection",
exithelp[] = "Leave configuration mode and return to privileged mode",
verbosehelp[] = "Set verbose diagnostics",
{ "carp", "Search for tag carp", CMPL0 NULL, 0 },
{ "config", "Search for tag config", CMPL0 NULL, 0 },
{ "configure", "Search for tag configure", CMPL0 NULL, 0 },
+ { "crontab", "Search for tag crontab", CMPL0 NULL, 0 },
{ "csh", "Search for tag csh", CMPL0 NULL, 0 },
{ "ddb", "Search for tag ddb", CMPL0 NULL, 0 },
{ "dhcp", "Search for tag dhcp", CMPL0 NULL, 0 },
{ "sadb", "Search for tag sadb", CMPL0 NULL, 0 },
{ "sasync", "Search for tag sasync", CMPL0 NULL, 0 },
{ "sasyncd", "Search for tag sasyncd", CMPL0 NULL, 0 },
+ { "scheduler", "Search for tag scheduler", CMPL0 NULL, 0 },
{ "sensor", "Search for tag sensor", CMPL0 NULL, 0 },
{ "sh", "Search for tag sh", CMPL0 NULL, 0 },
{ "shell", "Search for tag shell", CMPL0 NULL, 0 },
{ "tftp", tftphelp, CMPL(t) (char **)ctl_tftp, ssctl, ctlhandler, 1, 1, 0, 1 },
{ "resolv", resolvhelp, CMPL(t) (char **)ctl_resolv, ssctl, ctlhandler, 1, 1, 0, 1 },
{ "motd", motdhelp, CMPL(t) (char **)ctl_motd, ssctl, ctlhandler, 1, 1, 0, 1 },
+ { "crontab", crontabhelp, CMPL(t) (char **)ctl_crontab, ssctl, ctlhandler, 1, 1, 0, 1 },
+ { "scheduler", crontabhelp, CMPL(t) (char **)ctl_crontab, ssctl, ctlhandler, 1, 1, 0, 1 },
{ "inet", inethelp, CMPL(t) (char **)ctl_inet, ssctl, ctlhandler, 1, 1, 0, 1 },
{ "ping", pinghelp, CMPL0 0, 0, ping, 0, 0, 0, 0 },
{ "ping6", ping6help, CMPL0 0, 0, ping6, 0, 0, 0, 0 },
return 0;
}
+static int
+pr_crontab(int argc, char **argv, FILE *outfile)
+{
+ char *crontab_argv[] = { CRONTAB, "-l", "-u", "root", NULL };
+
+ if (priv != 1) {
+ printf("%% Privilege required\n");
+ return 0 ;
+ }
+
+ fprintf(outfile, "%% To view crontab syntax documentation in NSH, "
+ "run: !man 5 crontab\n\n");
+ fflush(outfile);
+
+ if (cmdargs_output(CRONTAB, crontab_argv, fileno(outfile), -1) != 0)
+ printf("%% crontab command failed\n");
+
+ return 0;
+}
+
int
pr_routes(int argc, char **argv)
{
blob - 224415e3acd5fe0a9b7ad75a76edc348fd0c37e5
blob + 84ff64c42be556f8392417b7ba5f35c45332fff5
--- conf.c
+++ conf.c
{
char cpass[_PASSWORD_LEN+1];
char hostbuf[MAXHOSTNAMELEN];
+ off_t offset;
fprintf(output, "!\n");
conf_ctl(output, "", "ftp-proxy", 0);
conf_ctl(output, "", "inet", 0);
conf_ctl(output, "", "sshd", 0);
+
+ offset = ftello(output);
+ conf_ctl(output, "", "crontab", 0);
+ if (offset != ftello(output)) /* we have custom crontab rules */
+ fprintf(output, "crontab install\n");
conf_rtables(output);
blob - b617dc27b60cd8856efb13d9b6dc0718eacfe45a
blob + e00aca8725b24f1c83a3c52d34067c81b03e0337
--- ctl.c
+++ ctl.c
static char table[16];
/* service routines */
+void edit_crontab(char *, char **, char *);
+void install_crontab(char *, char **, char *);
void call_editor(char *, char **, char *);
+int edit_file(char *, mode_t, char *, char **);
void ctl_symlink(char *, char *, char *);
int rule_writeline(char *, mode_t, char *);
int fill_tmpfile(char **, char *, char **);
{ "ldap", "LDAP", ctl_ldap, LDAPCONF_TEMP, 0600, 0, RT_TABLEID_MAX },
{ "ifstate", "If state",ctl_ifstate, IFSTATECONF_TEMP,0600, 0, RT_TABLEID_MAX },
{ "motd", "MOTD", ctl_motd, MOTD_TEMP,0644, 0, 0 },
+{ "crontab", "crontab", ctl_crontab, CRONTAB_TEMP, 0600, 0, 0 },
+{ "scheduler", "scheduler", ctl_crontab, CRONTAB_TEMP, 0600, 0, 0 },
{ 0, 0, 0, 0, 0, 0 }
};
/* per-daemon commands, and their C or executable functions */
+
+/* CRONTAB */
+struct ctl ctl_crontab[] = {
+ { "edit", "edit scheduled background jobs",
+ { "crontab", NULL, NULL }, edit_crontab, 0, T_HANDLER },
+ { "install", "install scheduled background job config",
+ { "crontab", NULL, NULL }, install_crontab, 0, T_HANDLER },
+ { 0, 0, { 0 }, 0, 0, 0 }
+};
+
/* MOTD */
struct ctl ctl_motd[] = {
{ "edit", "edit message-of-the-day",
}
void
-call_editor(char *name, char **args, char *z)
+edit_crontab(char *name, char **args, char *z)
+{
+ char *crontab_argv[] = { CRONTAB, "-u", "root", "-l", NULL };
+ char tmpfile[PATH_MAX];
+ int found = 0;
+ struct daemons *daemons;
+ int fd = -1;
+
+ for (daemons = ctl_daemons; daemons->name != 0; daemons++)
+ if (strncmp(daemons->name, name, strlen(name)) == 0) {
+ found = 1;
+ break;
+ }
+
+ if (!found) {
+ printf("%% edit_crontab internal error\n");
+ return;
+ }
+
+ snprintf(tmpfile, sizeof(tmpfile), "%s.%d", daemons->tmpfile,
+ cli_rtable);
+
+ fd = open(tmpfile, O_RDWR | O_EXCL);
+ if (fd == -1) {
+ if (errno != ENOENT) {
+ printf("%% open %s: %s\n", tmpfile, strerror(errno));
+ return;
+ }
+ fd = open(tmpfile, O_RDWR | O_CREAT | O_EXCL, daemons->mode);
+ if (fd == -1) {
+ printf("%% open %s: %s\n", tmpfile, strerror(errno));
+ return;
+ }
+
+ /* Populate temporary file with current crontab. */
+ if (cmdargs_output(CRONTAB, crontab_argv, fd, -1) != 0) {
+ printf("%% crontab -l command failed\n");
+ goto done;
+ }
+ }
+
+ if (edit_file(tmpfile, daemons->mode, daemons->propername, args) == 0) {
+ crontab_argv[3] = tmpfile;
+ if (cmdargs(CRONTAB, crontab_argv) != 0)
+ printf("%% failed to install crontab\n");
+ }
+done:
+ close(fd);
+}
+
+void
+install_crontab(char *name, char **args, char *z)
{
+ char *crontab_argv[] = { CRONTAB, "-u", "root", NULL, NULL };
+ char tmpfile[PATH_MAX];
int fd, found = 0;
- char *editor, tmpfile[64];
struct daemons *daemons;
for (daemons = ctl_daemons; daemons->name != 0; daemons++)
}
if (!found) {
+ printf("%% install_crontab internal error\n");
+ return;
+ }
+
+ snprintf(tmpfile, sizeof(tmpfile), "%s.%d", daemons->tmpfile,
+ cli_rtable);
+
+ if ((fd = acq_lock(tmpfile)) > 0) {
+ crontab_argv[3] = tmpfile;
+ if (cmdargs(CRONTAB, crontab_argv) != 0)
+ printf("%% failed to install crontab\n");
+ rls_lock(fd);
+ }
+}
+
+void
+call_editor(char *name, char **args, char *z)
+{
+ int found = 0;
+ char tmpfile[64];
+ struct daemons *daemons;
+
+ for (daemons = ctl_daemons; daemons->name != 0; daemons++)
+ if (strncmp(daemons->name, name, strlen(name)) == 0) {
+ found = 1;
+ break;
+ }
+
+ if (!found) {
printf("%% call_editor internal error\n");
return;
}
snprintf(tmpfile, sizeof(tmpfile), "%s.%d", daemons->tmpfile,
cli_rtable);
+ edit_file(tmpfile, daemons->mode, daemons->propername, args);
+}
+
+int
+edit_file(char *tmpfile, mode_t mode, char *propername, char **args)
+{
+ char *editor;
+ int fd;
+ int ret = 0;
+
/* acq lock, call editor, test config with cmd and args, release lock */
if ((editor = getenv("VISUAL")) == NULL) {
if ((editor = getenv("EDITOR")) == NULL)
}
if ((fd = acq_lock(tmpfile)) > 0) {
char *argv[] = { editor, tmpfile, NULL };
- cmdargs(editor, argv);
- chmod(tmpfile, daemons->mode);
- if (args != NULL)
- cmdargs(args[0], args);
+ ret = cmdargs(editor, argv);
+ if (ret == 0 && chmod(tmpfile, mode) == -1) {
+ printf("%% chmod %o %s: %s\n",
+ mode, tmpfile, strerror(errno));
+ ret = 1;
+ }
+ if (ret == 0 && args != NULL)
+ ret = cmdargs(args[0], args);
rls_lock(fd);
- } else
+ } else {
printf ("%% %s configuration is locked for editing\n",
- daemons->propername);
+ propername);
+ return 1;
+ }
+
+ return ret;
}
int
blob - 2ae9f799551bdf7081e8be62c03b4b7a8f97f104
blob + 23cea48dd84cd5bce7b4c64b2ebd91bbf33f4f0a
--- ctl.h
+++ ctl.h
#define LDAPCONF_TEMP "/var/run/ldapd.conf"
#define IFSTATECONF_TEMP "/var/run/ifstated.conf"
#define MOTD_TEMP "/var/run/motd"
+#define CRONTAB_TEMP "/var/run/crontab"
/* ctl tests*/
extern char *ctl_bgp_test[];
extern struct ctl ctl_inet[];
extern struct ctl ctl_ldap[];
extern struct ctl ctl_motd[];
+extern struct ctl ctl_crontab[];
extern struct ctl ctl_resolv[];
void flag_x(char *, char *, int, char *);
blob - 610184e1adf628ff1d5a11f25b77b38f302ad923
blob + a1f2ecea9d8252e146f3e086eba407199cdc685d
--- externs.h
+++ externs.h
#define SSH "/usr/bin/ssh"
#define PKILL "/usr/bin/pkill"
#define DIFF "/usr/bin/diff"
+#define CRONTAB "/usr/bin/crontab"
#define REBOOT "/sbin/reboot"
#define HALT "/sbin/halt"
#define SU "/usr/bin/su"
blob - 83288f6f5bc17abddbcf6da9eed5f016be75e964
blob + 1e1153b1ba8b2989aead1c19f5b9d61ee615af12
--- nsh.8
+++ nsh.8
.Ar options
are documented in
.Xr telnet 1 .
+.Pp
+.Tg crontab
+.Ic crontab Op Cm edit | install
+.Pp
+Edit the configuration of scheduled background jobs which are
+managed by
+.Xr cron 8 .
+Only the crontab file of the root user can be edited.
+See the
+.Xr crontab 5
+man page for information about configuration file syntax.
+.Pp
+.Nm
+stores a private copy of the root user's crontab in
+.Pa /var/run/crontab.0 .
+The
+.Cm crontab edit
+command edits this file and then installs it to the system by running the
+.Xr crontab 1
+command.
+.Pp
+The
+.Cm crontab install
+command skips editing but otherwise has the same effect.
+This command can be used to overwrite the system crontab in case it has
+become out of sync with the copy managed by
+.Nm .
+.Pp
+.Tg scheduler
+.Ic scheduler Op Cm edit | install
.Pp
+The
+.Cm scheduler
+command is an alias for the
+.Cm crontab
+command described above.
+.Pp
.Tg reboot
.Ic reboot
.Pp
.Op hostname | interface | autoconf | ip | inet | inet6 | route | route6\
| sadb | arp | ndp | vlan | kernel | bgp | ospf | ospf6 | pf | eigrp | rip\
| ldp | ike | ipsec | dvmrp | relay | dhcp | smtp | ldap | monitor\
- | version | users | running-config | startup-config |\&? | help
+ | version | users | crontab | running-config | startup-config |\&? | help
.Pp
The main diagnostic and informational command is 'show'.
show without arguments displays the available diagnostic show sub commands.
monitor Monitor routing/arp table changes
version Software information
users System users
+ crontab Scheduled background jobs
running-config Operating configuration
startup-config Startup configuration
? Options
kernel: OpenBSD 7.1 (GENERIC.MP) #459: Mon Apr 4 18:16:13 MDT 2022
deraadt@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP
.Ed
+.Pp
+.Ic show crontab
+.Pp
+Display the scheduled background jobs of the root user which are
+managed by
+.Xr cron 8 .
+See the
+.Xr crontab 5
+manual page for information about scheduling rules syntax.
+.Pp
+.Ic show scheduler
.Pp
+Alias for the
+.Cm show crontab
+command described above.
+.Pp
.Ic show running-config
.Pp
Display the current running configuration on the system, including