1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
From: Georges Khaznadar <georgesk@debian.org>
Date: Wed, 11 Oct 2023 11:43:22 +0200
Subject: dry-run
Implement two switches:
Implement two switches:
-n to make a "dry run" (syntax crontab -n foo)
-h to display a help message
---
crontab.1 | 19 +++++++++++++++++--
crontab.c | 40 +++++++++++++++++++++++++++++++---------
2 files changed, 48 insertions(+), 11 deletions(-)
diff --git a/crontab.1 b/crontab.1
index 199bae8..2c87bc9 100644
--- a/crontab.1
+++ b/crontab.1
@@ -22,7 +22,9 @@
.SH NAME
crontab \- maintain crontab files for individual users (Vixie Cron)
.SH SYNOPSIS
-crontab [ \-u user ] file
+crontab [ \-h]
+.br
+crontab [ \-u user ] [\-n] file
.br
crontab [ \-u user ] [ \-i ] { \-e | \-l | \-r }
.SH DESCRIPTION
@@ -62,6 +64,12 @@ user is always allowed to setup a crontab. For standard Debian systems, all
users may use this command.
.PP
If the
+.I \-h
+option is given,
+.I crontab
+shows a help message and quits immediately.
+.PP
+If the
.I \-u
option is given, it specifies the name of the user whose crontab is to be
used (when listing) or modified (when editing). If this option is not given,
@@ -80,6 +88,13 @@ option for safety's sake.
The first form of this command is used to install a new crontab from some
named file or standard input if the pseudo-filename ``-'' is given.
.PP
+If the
+.I \-n
+option is given, it means "dry run":
+.I crontab
+examines "your" crontab for its syntax, and outputs a success message if
+this syntax is correct, but nothing is written to any crontab.
+.PP
The
.I \-l
option causes the current crontab to be displayed on standard output. See
@@ -137,7 +152,7 @@ The files
.I /etc/cron.allow
and
.I /etc/cron.deny
-if, they exist, must be either world-readable, or readable by group
+if they exist, must be either world-readable, or readable by group
``crontab''. If they are not, then cron will deny access to all users until the
permissions are fixed.
.PP
diff --git a/crontab.c b/crontab.c
index 8fe6f90..e403e34 100644
--- a/crontab.c
+++ b/crontab.c
@@ -46,7 +46,7 @@ static char rcsid[] = "$Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $";
#endif
-enum opt_t { opt_unknown, opt_list, opt_delete, opt_edit, opt_replace };
+enum opt_t { opt_unknown, opt_list, opt_delete, opt_edit, opt_replace, opt_help };
#if DEBUGGING
static char *Options[] = { "???", "list", "delete", "edit", "replace" };
@@ -60,6 +60,7 @@ static char Directory[MAX_FNAME];
static FILE *NewCrontab = NULL;
static int CheckErrorCount;
static int PromptOnDelete;
+static int dry_run;
static enum opt_t Option;
static struct passwd *pw;
static void list_cmd __P((void)),
@@ -79,13 +80,17 @@ static void
usage(msg)
char *msg;
{
- fprintf(stderr, "%s: usage error: %s\n", ProgramName, msg);
- fprintf(stderr, "usage:\t%s [-u user] file\n", ProgramName);
- fprintf(stderr, "\t%s [ -u user ] [ -i ] { -e | -l | -r }\n", ProgramName);
- fprintf(stderr, "\t\t(default operation is replace, per 1003.2)\n");
+ if (strlen(msg) > 0)
+ fprintf(stderr, "%s: usage error: %s\n", ProgramName, msg);
+ fprintf(stderr, "usage:\t%s [-u user] [-n] file\n", ProgramName);
+ fprintf(stderr, "\t%s [ -u user ] [ -i ] { -e | -l | -r }\n\n", ProgramName);
+ fprintf(stderr, "\t-h\t(displays this help message)\n\n");
+ fprintf(stderr, "\tfile\t(default operation is replace, per 1003.2)\n");
+ fprintf(stderr, "\t-n\t(dry run: checks the syntax, then bails out)\n");
+ fprintf(stderr, "\t-u user\t(choose the user whose crontab is touched)\n\n");
fprintf(stderr, "\t-e\t(edit user's crontab)\n");
fprintf(stderr, "\t-l\t(list user's crontab)\n");
- fprintf(stderr, "\t-r\t(delete user's crontab)\n");
+ fprintf(stderr, "\t-r\t(delete user's crontab)\n\n");
fprintf(stderr, "\t-i\t(prompt before deleting user's crontab)\n");
exit(ERROR_EXIT);
}
@@ -133,6 +138,8 @@ main(argc, argv)
switch (Option) {
case opt_list: list_cmd();
break;
+ case opt_help: usage("");
+ break;
case opt_delete: delete_cmd();
break;
case opt_edit: edit_cmd();
@@ -152,9 +159,9 @@ main(argc, argv)
}
#if DEBUGGING
-const char *getoptarg = "u:lerix:";
+const char *getoptarg = "u:hnlerix:";
#else
-const char *getoptarg = "u:leri";
+const char *getoptarg = "u:hnleri";
#endif
static void
@@ -188,6 +195,14 @@ parse_args(argc, argv)
usage("bad debug option");
break;
#endif
+ case 'h':
+ if (Option != opt_unknown)
+ usage("only one operation permitted");
+ Option = opt_help;
+ break;
+ case 'n':
+ dry_run = 1;
+ break;
case 'u':
if (!(pw = getpwnam(optarg)))
{
@@ -916,7 +931,14 @@ replace_cmd() {
return (-1);
}
-
+ if (dry_run) {
+ /* the option switch -n was used. Do not write the crontab file */
+ /* instead display a pleasant message. */
+ fprintf(stderr, "The syntax of the crontab file was successfully checked.\n");
+ fclose(tmp); unlink(tn);
+ return (0);
+ }
+
#ifdef HAS_FCHMOD
if (fchmod(fileno(tmp), 0600) < OK)
#else
|