diff options
Diffstat (limited to 'rdiff-backup/rdiff_backup/cmodule.c')
-rw-r--r-- | rdiff-backup/rdiff_backup/cmodule.c | 129 |
1 files changed, 127 insertions, 2 deletions
diff --git a/rdiff-backup/rdiff_backup/cmodule.c b/rdiff-backup/rdiff_backup/cmodule.c index 30aac47..a5f1c65 100644 --- a/rdiff-backup/rdiff_backup/cmodule.c +++ b/rdiff-backup/rdiff_backup/cmodule.c @@ -27,6 +27,7 @@ #include <unistd.h> #include <errno.h> + /* Some of the following code to define major/minor taken from code by * Jörg Schilling's star archiver. */ @@ -202,7 +203,6 @@ static PyObject *c_make_file_dict(self, args) return return_val; } - /* Convert python long into 7 byte string */ static PyObject *long2str(self, args) PyObject *self; @@ -247,12 +247,138 @@ static PyObject *str2long(self, args) } +/* --------------------------------------------------------------------- * + * This section is still GPL'd, but was copied from the libmisc + * section of getfacl by Andreas Gruenbacher + * <a.gruenbacher@computer.org>. I'm just copying the code to + * preserve quoting compatibility between (get|set)f(acl|attr) and + * rdiff-backup. Taken on 8/24/2003. + * --------------------------------------------------------------------- */ + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> + +int high_water_alloc(void **buf, size_t *bufsize, size_t newsize) +{ +#define CHUNK_SIZE 256 + /* + * Goal here is to avoid unnecessary memory allocations by + * using static buffers which only grow when necessary. + * Size is increased in fixed size chunks (CHUNK_SIZE). + */ + if (*bufsize < newsize) { + void *newbuf; + + newsize = (newsize + CHUNK_SIZE-1) & ~(CHUNK_SIZE-1); + newbuf = realloc(*buf, newsize); + if (!newbuf) + return 1; + + *buf = newbuf; + *bufsize = newsize; + } + return 0; +} + +const char *quote(const char *str) +{ + static char *quoted_str; + static size_t quoted_str_len; + const unsigned char *s; + char *q; + size_t nonpr; + + if (!str) + return str; + + for (nonpr = 0, s = (unsigned char *)str; *s != '\0'; s++) + if (!isprint(*s) || isspace(*s) || *s == '\\' || *s == '=') + nonpr++; + if (nonpr == 0) + return str; + + if (high_water_alloc((void **)"ed_str, "ed_str_len, + nonpr * 3 + 1)) + return NULL; + for (s = (unsigned char *)str, q = quoted_str; *s != '\0'; s++) { + if (!isprint(*s) || isspace(*s) || *s == '\\' || *s == '=') { + *q++ = '\\'; + *q++ = '0' + ((*s >> 6) ); + *q++ = '0' + ((*s >> 3) & 7); + *q++ = '0' + ((*s ) & 7); + } else + *q++ = *s; + } + *q++ = '\0'; + + return quoted_str; +} + +char *unquote(char *str) +{ + unsigned char *s, *t; + + if (!str) + return str; + + for (s = (unsigned char *)str; *s != '\0'; s++) + if (*s == '\\') + break; + if (*s == '\0') + return str; + +#define isoctal(c) \ + ((c) >= '0' && (c) <= '7') + + t = s; + do { + if (*s == '\\' && + isoctal(*(s+1)) && isoctal(*(s+2)) && isoctal(*(s+3))) { + *t++ = ((*(s+1) - '0') << 6) + + ((*(s+2) - '0') << 3) + + ((*(s+3) - '0') ); + s += 3; + } else + *t++ = *s; + } while (*s++ != '\0'); + + return str; +} + +/* ------------- End Gruenbach section --------------------------------- */ + +/* Translate quote above into python */ +static PyObject *acl_quote(PyObject *self, PyObject *args) +{ + char *s; + + if (!PyArg_ParseTuple(args, "s", &s)) return NULL; + return Py_BuildValue("s", quote(s)); +} + +/* Translate unquote above into python */ +static PyObject *acl_unquote(PyObject *self, PyObject *args) +{ + char *s; + + if (!PyArg_ParseTuple(args, "s", &s)) return NULL; + return Py_BuildValue("s", unquote(s)); +} + + +/* ------------- Python export lists -------------------------------- */ + static PyMethodDef CMethods[] = { {"make_file_dict", c_make_file_dict, METH_VARARGS, "Make dictionary from file stat"}, {"long2str", long2str, METH_VARARGS, "Convert python long to 7 byte string"}, {"str2long", str2long, METH_VARARGS, "Convert 7 byte string to python long"}, {"sync", my_sync, METH_VARARGS, "sync buffers to disk"}, + {"acl_quote", acl_quote, METH_VARARGS, + "Quote string, escaping non-printables"}, + {"acl_unquote", acl_unquote, METH_VARARGS, + "Unquote string, producing original input to quote"}, {NULL, NULL, 0, NULL} }; @@ -266,4 +392,3 @@ void initC(void) NULL, NULL); PyDict_SetItemString(d, "UnknownFileTypeError", UnknownFileTypeError); } - |