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
|
From: Christian Kastner <ckk@kvr.at>
Date: Fri, 15 Jan 2016 21:47:32 +0100
Subject: Prompt on crontab deletion
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
Add an option -i that modifies the -r option to prompt the user for a y/n
response before actually deleting the crontab.
Contributed by Javier Fernández-Sanguino Peña <jfs@debian.org>.
Bug-Debian: https://bugs.debian.org/513379
Forwarded: no
Last-Update: 2016-01-15
---
crontab.1 | 6 +++++-
crontab.c | 40 ++++++++++++++++++++++++++++++++++++++--
2 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/crontab.1 b/crontab.1
index f432097..199bae8 100644
--- a/crontab.1
+++ b/crontab.1
@@ -24,7 +24,7 @@ crontab \- maintain crontab files for individual users (Vixie Cron)
.SH SYNOPSIS
crontab [ \-u user ] file
.br
-crontab [ \-u user ] [ \-e ] { \-l | \-r }
+crontab [ \-u user ] [ \-i ] { \-e | \-l | \-r }
.SH DESCRIPTION
.I crontab
is the program used to install, deinstall or list the tables
@@ -100,6 +100,10 @@ from the editor, the modified crontab will be installed automatically. If
neither of the environment variables is defined, then the
default editor /usr/bin/editor is used.
.PP
+The
+.I \-i
+option modifies the \-r option to prompt the user for a 'y/Y' response
+before actually removing the crontab.
.SH DEBIAN SPECIFIC
The "out-of-the-box" behaviour for
.I crontab \-l
diff --git a/crontab.c b/crontab.c
index 033d536..c48900c 100644
--- a/crontab.c
+++ b/crontab.c
@@ -59,6 +59,7 @@ static char Filename[MAX_FNAME];
static char Directory[MAX_FNAME];
static FILE *NewCrontab = NULL;
static int CheckErrorCount;
+static int PromptOnDelete;
static enum opt_t Option;
static struct passwd *pw;
static void list_cmd __P((void)),
@@ -80,11 +81,12 @@ usage(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] { -e | -l | -r }\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");
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-i\t(prompt before deleting user's crontab)\n");
exit(ERROR_EXIT);
}
@@ -176,6 +178,7 @@ parse_args(argc, argv)
}
Filename[0] = '\0';
Option = opt_unknown;
+ PromptOnDelete = 0;
while (EOF != (argch = getopt(argc, argv, getoptarg))) {
switch (argch) {
@@ -220,6 +223,9 @@ parse_args(argc, argv)
usage("only one operation permitted");
Option = opt_edit;
break;
+ case 'i':
+ PromptOnDelete = 1;
+ break;
default:
usage("unrecognized option");
}
@@ -345,9 +351,39 @@ list_cmd() {
static void
delete_cmd() {
char n[MAX_FNAME];
+ char q[MAX_TEMPSTR];
+ int ans;
+ struct stat fsbuf;
- log_it(RealUser, Pid, "DELETE", User);
+ /* Check if the user has a crontab file first */
(void) snprintf(n, MAX_FNAME, CRON_TAB(User));
+ if (stat(n, &fsbuf) < 0) {
+ fprintf(stderr, "no crontab for %s\n", User);
+ exit(ERROR_EXIT);
+ }
+
+ if (PromptOnDelete == 1) {
+ printf("crontab: really delete %s's crontab? (y/n) ", User);
+ fflush(stdout);
+ ans = 0;
+ q[0] = '\0';
+ while ( ans == 0 ) {
+ (void) fgets(q, sizeof q, stdin);
+ switch (islower(q[0]) ? q[0] : tolower(q[0])) {
+ case 'y':
+ case 'n':
+ ans = 1;
+ break;
+ default:
+ fprintf(stderr, "Please enter Y or N: ");
+ }
+ }
+ if ((q[0] == 'N') || (q[0] == 'n')) {
+ exit(OK_EXIT);
+ }
+ }
+
+ log_it(RealUser, Pid, "DELETE", User);
if (unlink(n)) {
if (errno == ENOENT)
fprintf(stderr, "no crontab for %s\n", User);
|