diff --git a/include/xbps_api.h b/include/xbps_api.h index 386335e4721..9e61b51fa87 100644 --- a/include/xbps_api.h +++ b/include/xbps_api.h @@ -149,6 +149,8 @@ void xbps_set_rootdir(const char *); const char * xbps_get_rootdir(void); void xbps_set_flags(int); int xbps_get_flags(void); +bool xbps_yesno(const char *, ...); +bool xbps_noyes(const char *, ...); /* From lib/orphans.c */ prop_array_t xbps_find_orphan_packages(void); diff --git a/lib/util.c b/lib/util.c index 90faffc15ad..1975f04f66b 100644 --- a/lib/util.c +++ b/lib/util.c @@ -30,11 +30,14 @@ #include #include #include +#include #include #include #include +static bool question(bool, const char *, va_list); + static const char *rootdir; static int flags; @@ -258,3 +261,85 @@ xbps_xasprintf(const char *fmt, ...) return buf; } + +/* + * The following functions were taken from pacman (src/pacman/util.c) + * Copyright (c) 2002-2007 by Judd Vinet + */ +bool +xbps_yesno(const char *fmt, ...) +{ + va_list ap; + bool res; + + va_start(ap, fmt); + res = question(1, fmt, ap); + va_end(ap); + + return res; +} + +bool +xbps_noyes(const char *fmt, ...) +{ + va_list ap; + bool res; + + va_start(ap, fmt); + res = question(0, fmt, ap); + va_end(ap); + + return res; +} + +static char * +strtrim(char *str) +{ + char *pch = str; + + if (str == NULL || *str == '\0') + return str; + + while (isspace((unsigned char)*pch)) + pch++; + + if (pch != str) + memmove(str, pch, (strlen(pch) + 1)); + + if (*str == '\0') + return str; + + pch = (str + (strlen(str) - 1)); + while (isspace((unsigned char)*pch)) + pch--; + + *++pch = '\0'; + + return str; +} + +static bool +question(bool preset, const char *fmt, va_list ap) +{ + char response[32]; + + vfprintf(stderr, fmt, ap); + if (preset) + fprintf(stderr, " %s ", "[Y/n]"); + else + fprintf(stderr, " %s ", "[y/N]"); + + if (fgets(response, 32, stdin)) { + (void)strtrim(response); + if (strlen(response) == 0) + return preset; + + if ((strcasecmp(response, "y") == 0) || + (strcasecmp(response, "yes") == 0)) + return true; + else if ((strcasecmp(response, "n") == 0) || + (strcasecmp(response, "no") == 0)) + return false; + } + return false; +}