Bug#537535: other missing utilities for debconf replacement
On Sun, Jul 19, 2009 at 11:31:55AM +0200, Joey Hess wrote:
> * debconf-escape (the perl script could be copied into cdebconf
> and would work ok, but cdebconf is also missing the escape CAPB)
I found the attached patch lying around my working tree, which purports
to implement debconf-escape and makes a start at the escape capability.
It's dated 2007-12-31, so at this point I don't remember what state it
was in. It'll be at least as useful in the BTS as in my working tree
though!
--
Colin Watson [cjwatson@debian.org]
Property changes on: src
___________________________________________________________________
Name: svn:ignore
- commands-list.h
config.h
libdebconf.so*
libdebconfclient.so*
*.a
debconf
debconf-communicate
debconf-copydb
debconf-dumpdb
debconf-loadtemplate
dpkg-reconfigure
debconf.conf
cdebconf.conf-dist
*.opic
Makefile
*.o
+ commands-list.h
config.h
libdebconf.so*
libdebconfclient.so*
*.a
debconf
debconf-communicate
debconf-copydb
debconf-dumpdb
debconf-escape
debconf-loadtemplate
dpkg-reconfigure
debconf.conf
cdebconf.conf-dist
*.opic
Makefile
*.o
Index: src/Makefile.in
===================================================================
--- src/Makefile.in (revision 50731)
+++ src/Makefile.in (working copy)
@@ -13,7 +13,7 @@
CLISONAME=$(CLILIB).$(MAJOR)
DEBCONF=debconf
TOOLS=debconf-loadtemplate debconf-copydb debconf-communicate \
- debconf-dumpdb \
+ debconf-dumpdb debconf-escape \
dpkg-reconfigure #dpkg-preconfigure
BIN=$(DEBCONF) $(TOOLS)
@@ -63,6 +63,7 @@
install -d -m 755 $(DESTDIR)${moddir}
install -m 755 debconf debconf-loadtemplate $(DESTDIR)${moddir}
install -m 755 debconf-copydb debconf-dumpdb $(DESTDIR)${moddir}
+ install -m 755 debconf-escape $(DESTDIR)${moddir}
ifneq ($(TARGET),udeb)
install -m 755 debconf-communicate $(DESTDIR)${moddir}
install -m 755 dpkg-reconfigure $(DESTDIR)${moddir}
@@ -78,7 +79,7 @@
install -d -m 755 $(DESTDIR)${sbindir}
install -d -m 755 $(DESTDIR)${sharedir}
set -e; for p in debconf debconf-loadtemplate \
- debconf-copydb debconf-dumpdb; do \
+ debconf-copydb debconf-dumpdb debconf-escape; do \
ln -sf ../lib/cdebconf/$$p $(DESTDIR)${bindir}; \
done
install -m 644 client/confmodule $(DESTDIR)${sharedir}
Index: src/commands.c
===================================================================
--- src/commands.c (revision 50731)
+++ src/commands.c (working copy)
@@ -127,9 +127,11 @@
mod->frontend->capability |= DCF_CAPB_BACKUP;
else if (strcmp(argv[i], "progresscancel") == 0)
mod->frontend->capability |= DCF_CAPB_PROGRESSCANCEL;
+ else if (strcmp(argv[i], "escape") == 0)
+ mod->frontend->capability |= DCF_CAPB_ESCAPE;
}
- if (asprintf(&out, "%u multiselect backup progresscancel", CMDSTATUS_SUCCESS) == -1)
+ if (asprintf(&out, "%u multiselect backup progresscancel escape", CMDSTATUS_SUCCESS) == -1)
DIE("Out of memory");
plugin_state = NULL;
Index: src/frontend.h
===================================================================
--- src/frontend.h (revision 50731)
+++ src/frontend.h (working copy)
@@ -20,6 +20,7 @@
#define DCF_CAPB_BACKUP (1UL << 0)
#define DCF_CAPB_PROGRESSCANCEL (1UL << 1)
+#define DCF_CAPB_ESCAPE (1UL << 2)
struct frontend_module {
int (*initialize)(struct frontend *, struct configuration *);
Index: src/strutl.c
===================================================================
--- src/strutl.c (revision 50731)
+++ src/strutl.c (working copy)
@@ -327,15 +327,15 @@
int i = 0;
while (*p != 0 && i < maxlen-1)
{
- /* Debconf only escapes \n */
+ /* Debconf only escapes \ and \n */
if (*p == '\\')
{
- if (*(p+1) == 'n')
+ if (*(p+1) == '\\' || *(p+1) == 'n')
{
- outbuf[i++] = '\n';
+ outbuf[i++] = (*(p+1) == '\\') ? '\\' : '\n';
p += 2;
}
- else if (quote != 0 && (*(p+1) == '"' || *(p+1) == '\\'))
+ else if (quote != 0 && *(p+1) == '"')
{
outbuf[i++] = *(p+1);
p += 2;
@@ -355,15 +355,15 @@
int i = 0;
while (*p != 0 && i < maxlen-1)
{
- /* Debconf only escapes \n */
- if (*p == '\n')
+ /* Debconf only escapes \ and \n */
+ if (*p == '\\' || *p == '\n')
{
if (i + 2 >= maxlen) break;
outbuf[i++] = '\\';
- outbuf[i++] = 'n';
+ outbuf[i++] = (*p == '\\') ? '\\' : 'n';
p++;
}
- else if (quote != 0 && (*p == '"' || *p == '\\'))
+ else if (quote != 0 && *p == '"')
{
if (i + 2 >= maxlen) break;
outbuf[i++] = '\\';
Index: src/debconf-escape.c
===================================================================
--- src/debconf-escape.c (revision 0)
+++ src/debconf-escape.c (revision 0)
@@ -0,0 +1,130 @@
+/**
+ * @file debconf-escape.c
+ * @brief helper when working with debconf's escape capability
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <getopt.h>
+
+static int escape = 0;
+static int unescape = 0;
+
+static struct option options[] = {
+ { "help", 0, 0, 'h' },
+ { "escape", 0, &escape, 'e' },
+ { "unescape", 0, &unescape, 'u' },
+ { 0, 0, 0, 0 },
+};
+
+static void help(FILE *f, const char *exename)
+{
+ fprintf(f, "%s -e|-u < input-text\n", exename);
+}
+
+static void parsecmdline(int argc, char **argv)
+{
+ int c;
+
+ while ((c = getopt_long(argc, argv, "eu", options, NULL)) != -1)
+ {
+ switch (c)
+ {
+ case 'h':
+ help(stdout, argv[0]);
+ exit(0);
+ break;
+ case 'e':
+ escape = 1;
+ break;
+ case 'u':
+ unescape = 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (optind > argc || escape == unescape)
+ {
+ help(stderr, argv[0]);
+ exit(1);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ char buf[1024];
+ const char *p;
+ size_t r;
+
+ parsecmdline(argc, argv);
+
+ if (escape)
+ {
+ while (!feof(stdin) && !ferror(stdin))
+ {
+ r = fread(buf, sizeof(*buf), 1024, stdin);
+ for (p = buf; p < buf + r; ++p)
+ {
+ switch (*p)
+ {
+ case '\\':
+ fputs("\\\\", stdout);
+ break;
+ case '\n':
+ fputs("\\n", stdout);
+ break;
+ default:
+ fputc(*p, stdout);
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ while (!feof(stdin) && !ferror(stdin))
+ {
+ const char *pos, *backslash;
+ r = fread(buf, sizeof(*buf), 1024, stdin);
+ pos = buf;
+ while (r > 0)
+ {
+ backslash = memchr(pos, '\\', r);
+ if (!backslash)
+ {
+ fwrite(pos, sizeof(*pos), r, stdout);
+ break;
+ }
+ if (backslash - pos > 0)
+ fwrite(pos, sizeof(*pos), backslash - pos, stdout);
+ if (backslash - pos == r - 1)
+ {
+ fputc('\\', stdout);
+ break;
+ }
+ else
+ {
+ if (*(backslash + 1) == '\n')
+ fputs("\\\n", stdout);
+ else if (*(backslash + 1) == 'n')
+ fputc('\n', stdout);
+ else
+ fputc(*(backslash + 1), stdout);
+ r -= (backslash + 2 - pos);
+ pos = backslash + 2;
+ }
+ }
+ }
+ }
+
+ if (ferror(stdin))
+ {
+ fprintf(stderr, "%s: error reading stdin\n", argv[0]);
+ return 1;
+ }
+
+ return 0;
+}
Index: src/strutl.h
===================================================================
--- src/strutl.h (revision 50731)
+++ src/strutl.h (working copy)
@@ -46,7 +46,7 @@
int strgetargc(const char *inbuf);
int strchoicesplit(const char *inbuf, char **argv, size_t maxnarg);
int strchoicesplitsort(const char *origbuf, const char *transbuf, const char *listorder, char **oargv, char **targv, int *tindex, size_t maxnarg);
-int strcmdsplit(char *inbuf, char **argv, size_t maxnarg);
+int strcmdsplit(char *inbuf, char **argv, size_t maxnarg, int unescape);
void strunescape(const char *inbuf, char *outbuf, const size_t maxlen, const int quote);
void strescape(const char *inbuf, char *outbuf, const size_t maxlen, const int quote);
char *unescapestr(const char *in);
Reply to: