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 [cjwat...@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);