commit: 59a64b48f468b19a6a2aa8322e6807fcc7ce2892
parent 29c71c751b82e06d6ec8bcd0cc722c0f2500657d
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Wed, 10 Apr 2024 12:33:02 +0200
lib/consent: split off consent functions from cmd/rm.c
Diffstat:
M | Makefile | 4 | ++++ |
M | cmd/rm.c | 138 | ++++++------------------------------------------------------------------------- |
A | lib/consent.c | 137 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | lib/consent.h | 12 | ++++++++++++ |
4 files changed, 162 insertions(+), 129 deletions(-)
diff --git a/Makefile b/Makefile
@@ -102,3 +102,7 @@ cmd/mknod: cmd/mknod.c lib/mode.c Makefile
cmd/seq: cmd/seq.c Makefile
rm -f ${<:=.gcov} ${@:=.gcda} ${@:=.gcno}
$(CC) -std=c99 $(CFLAGS) -o $@ cmd/seq.c -lm $(LDFLAGS) $(LDSTATIC)
+
+cmd/rm: cmd/rm.c lib/consent.c lib/consent.h Makefile
+ rm -f ${<:=.gcov} ${@:=.gcda} ${@:=.gcno}
+ $(CC) -std=c99 $(CFLAGS) -o $@ cmd/rm.c lib/consent.c $(LDFLAGS) $(LDSTATIC)
diff --git a/cmd/rm.c b/cmd/rm.c
@@ -9,16 +9,16 @@
#define _NETBSD_SOURCE
#endif
+#include "../lib/consent.h"
+
#include <assert.h>
-#include <ctype.h> // isprint
-#include <dirent.h> // fdopendir, readdir, closedir
-#include <errno.h> // errno
-#include <fcntl.h> // AT_FDCWD
-#include <langinfo.h> // nl_langinfo
-#include <limits.h> // PATH_MAX
-#include <locale.h> // setlocale
-#include <regex.h> // regcomp
-#include <stdarg.h> // va_list
+#include <ctype.h> // isprint
+#include <dirent.h> // fdopendir, readdir, closedir
+#include <errno.h> // errno
+#include <fcntl.h> // AT_FDCWD
+#include <limits.h> // PATH_MAX
+#include <locale.h> // setlocale
+#include <stdarg.h> // va_list
#include <stdbool.h>
#include <stdio.h> // fprintf, getline
#include <stdlib.h> // free
@@ -29,126 +29,6 @@
bool opt_d = false, force = false, recurse = false, verbose = false, opt_i = false;
char *argv0 = "rm";
-// Needs to be executed after setlocale
-regex_t consent_yesexpr_r;
-regex_t consent_noexpr_r;
-static void
-consent_init()
-{
- char *yesexpr = nl_langinfo(YESEXPR);
- int yesexpr_ret = regcomp(&consent_yesexpr_r, yesexpr, REG_EXTENDED | REG_NOSUB);
- if(yesexpr_ret != 0)
- {
- char errstr[64] = "";
- regerror(yesexpr_ret, &consent_yesexpr_r, errstr, 100);
- fprintf(
- stderr, "%s: Got errorneous yesexpr regex /%s/ from locale: %s\n", argv0, yesexpr, errstr);
-
- errno = 0;
- fprintf(stderr, "%s: Fallbacking to /^[Yy]/\n", argv0);
- yesexpr_ret = regcomp(&consent_yesexpr_r, "^[Yy]", REG_EXTENDED | REG_NOSUB);
- assert(yesexpr_ret == 0);
- }
- assert(errno == 0);
-
- char *noexpr = nl_langinfo(NOEXPR);
- int noexpr_ret = regcomp(&consent_noexpr_r, noexpr, REG_EXTENDED | REG_NOSUB);
- if(noexpr_ret != 0)
- {
- char errstr[64] = "";
- regerror(noexpr_ret, &consent_noexpr_r, errstr, 100);
- fprintf(
- stderr, "%s: Got errorneous noexpr regex /%s/ from locale: %s\n", argv0, noexpr, errstr);
-
- errno = 0;
- fprintf(stderr, "%s: Fallbacking to /^[Nn]/\n", argv0);
- noexpr_ret = regcomp(&consent_noexpr_r, "^[Nn]", REG_EXTENDED | REG_NOSUB);
- assert(noexpr_ret == 0);
- }
- assert(errno == 0);
-}
-
-static void
-consent_finish()
-{
- regfree(&consent_yesexpr_r);
- regfree(&consent_noexpr_r);
-}
-
-// Consent therefore defaults to no
-static bool
-consentf(const char *restrict fmt, ...)
-{
- bool result = false;
- char *line = NULL;
- size_t len = 0;
-
- va_list ap;
-
- assert(errno == 0);
- va_start(ap, fmt);
- /* flawfinder: ignore */
- int ret = vfprintf(stderr, fmt, ap);
- va_end(ap);
-
- if(ret < 0)
- {
- fprintf(stderr, "%s: Failed to print user prompt: %s\n", argv0, strerror(errno));
- errno = 0;
- goto end;
- }
-
- assert(errno == 0);
- ssize_t nread = getline(&line, &len, stdin);
- if(nread < 0)
- {
- fprintf(stderr, "\n%s: Failed getting user entry via getline: %s\n", argv0, strerror(errno));
- errno = 0;
- goto end;
- }
-
- if(nread == 0)
- {
- fprintf(stderr, "%s: Got empty response, considering it false\n", argv0);
- errno = 0;
- goto end;
- }
-
- // Doesn't echoes if not a TTY
- if(!isatty(0)) write(2, line, nread);
- // isatty changes errno if not a TTY *sigh*
- errno = 0;
-
- if(line[nread - 1] == '\n') line[--nread] = 0;
-
- if(line[0] == 0 || line[0] == '\n' || line[0] == '\r')
- {
- fprintf(stderr, "%s: Got empty response, considering it false\n", argv0);
- goto end;
- }
-
- if(regexec(&consent_yesexpr_r, line, 0, 0, 0) == 0)
- {
- result = true;
- goto end;
- }
-
- if(regexec(&consent_noexpr_r, line, 0, 0, 0) == 0)
- {
- result = false;
- goto end;
- }
-
- fprintf(stderr,
- "%s: User entry \"%s\" neither affirmative nor negative, considering it false\n",
- argv0,
- line);
-
-end:
- if(len != 0) free(line);
- return result;
-}
-
static int
do_unlinkat(int fd, char *name, char *acc_path)
{
diff --git a/lib/consent.c b/lib/consent.c
@@ -0,0 +1,137 @@
+// utils-std: Collection of commonly available Unix tools
+// SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
+// SPDX-License-Identifier: MPL-2.0
+
+#define _POSIX_C_SOURCE 200809L
+
+#include "./consent.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <langinfo.h> // nl_langinfo
+#include <regex.h> // regcomp
+#include <stdarg.h> // va_list
+#include <stdio.h> // fprintf, getline,
+#include <stdlib.h> // free
+#include <string.h> // strerror
+#include <unistd.h> // isatty, write
+
+// Needs to be executed after setlocale
+regex_t consent_yesexpr_r;
+regex_t consent_noexpr_r;
+void
+consent_init()
+{
+ char *yesexpr = nl_langinfo(YESEXPR);
+ int yesexpr_ret = regcomp(&consent_yesexpr_r, yesexpr, REG_EXTENDED | REG_NOSUB);
+ if(yesexpr_ret != 0)
+ {
+ char errstr[64] = "";
+ regerror(yesexpr_ret, &consent_yesexpr_r, errstr, 100);
+ fprintf(
+ stderr, "%s: Got errorneous yesexpr regex /%s/ from locale: %s\n", argv0, yesexpr, errstr);
+
+ errno = 0;
+ fprintf(stderr, "%s: Fallbacking to /^[Yy]/\n", argv0);
+ yesexpr_ret = regcomp(&consent_yesexpr_r, "^[Yy]", REG_EXTENDED | REG_NOSUB);
+ assert(yesexpr_ret == 0);
+ }
+ assert(errno == 0);
+
+ char *noexpr = nl_langinfo(NOEXPR);
+ int noexpr_ret = regcomp(&consent_noexpr_r, noexpr, REG_EXTENDED | REG_NOSUB);
+ if(noexpr_ret != 0)
+ {
+ char errstr[64] = "";
+ regerror(noexpr_ret, &consent_noexpr_r, errstr, 100);
+ fprintf(
+ stderr, "%s: Got errorneous noexpr regex /%s/ from locale: %s\n", argv0, noexpr, errstr);
+
+ errno = 0;
+ fprintf(stderr, "%s: Fallbacking to /^[Nn]/\n", argv0);
+ noexpr_ret = regcomp(&consent_noexpr_r, "^[Nn]", REG_EXTENDED | REG_NOSUB);
+ assert(noexpr_ret == 0);
+ }
+ assert(errno == 0);
+}
+
+void
+consent_finish()
+{
+ regfree(&consent_yesexpr_r);
+ regfree(&consent_noexpr_r);
+}
+
+// Consent therefore defaults to no
+bool
+consentf(const char *restrict fmt, ...)
+{
+ bool result = false;
+ char *line = NULL;
+ size_t len = 0;
+
+ va_list ap;
+
+ assert(errno == 0);
+ va_start(ap, fmt);
+ /* flawfinder: ignore */
+ int ret = vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ if(ret < 0)
+ {
+ fprintf(stderr, "%s: Failed to print user prompt: %s\n", argv0, strerror(errno));
+ errno = 0;
+ goto end;
+ }
+
+ assert(errno == 0);
+ ssize_t nread = getline(&line, &len, stdin);
+ if(nread < 0)
+ {
+ fprintf(stderr, "\n%s: Failed getting user entry via getline: %s\n", argv0, strerror(errno));
+ errno = 0;
+ goto end;
+ }
+
+ if(nread == 0)
+ {
+ fprintf(stderr, "%s: Got empty response, considering it false\n", argv0);
+ errno = 0;
+ goto end;
+ }
+
+ // Doesn't echoes if not a TTY
+ if(!isatty(0)) write(2, line, nread);
+ // isatty changes errno if not a TTY *sigh*
+ errno = 0;
+
+ if(line[nread - 1] == '\n') line[--nread] = 0;
+
+ if(line[0] == 0 || line[0] == '\n' || line[0] == '\r')
+ {
+ fprintf(stderr, "%s: Got empty response, considering it false\n", argv0);
+ goto end;
+ }
+
+ if(regexec(&consent_yesexpr_r, line, 0, 0, 0) == 0)
+ {
+ result = true;
+ goto end;
+ }
+
+ if(regexec(&consent_noexpr_r, line, 0, 0, 0) == 0)
+ {
+ result = false;
+ goto end;
+ }
+
+ fprintf(stderr,
+ "%s: User entry \"%s\" neither affirmative nor negative, considering it false\n",
+ argv0,
+ line);
+
+end:
+ if(len != 0) free(line);
+ return result;
+}
diff --git a/lib/consent.h b/lib/consent.h
@@ -0,0 +1,12 @@
+// utils-std: Collection of commonly available Unix tools
+// SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
+// SPDX-License-Identifier: MPL-2.0
+
+#include <stdbool.h>
+
+extern char *argv0;
+
+// Consent therefore defaults to no, including in cases of error
+bool consentf(const char *restrict fmt, ...);
+void consent_finish();
+void consent_init();