From 76df98da17f576b71e6cbc83bbf527b685be1178 Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Sat, 4 Dec 2010 12:19:50 +0200 Subject: Introduce stdstream module; move deprecated functions to libmu_compat. * include/mailutils/log.h: New file. * include/mailutils/stdstream.h: New file. * include/mailutils/Makefile.am (pkginclude_HEADERS): Add stdstream.h and log.h. * include/mailutils/argcv.h: Include mailutils/types.h * include/mailutils/mailutils.h: Include stdstream.h Remove vartab.h * include/mailutils/types.hin (MU_DEPRECATED): New define. * include/mailutils/vartab.h: Mark this header and all prototypes it defines as deprecated. * libmailutils/stdstream/Makefile.am: New file. * libmailutils/stdstream/basestr.c: New file. * libmailutils/stdstream/strerr.c: New file. * libmu_compat/Makefile.am: New file. * libmu_compat/tests/.gitignore: New file. * libmu_compat/tests/Makefile.am: New file. * libmu_compat/tests/atlocal.in: New file. * libmu_compat/tests/testsuite.at: New file. * libmailutils/base/Makefile.am (noinst_LTLIBRARIES): Remove argcv.c and vartab.c. * libmailutils/Makefile.am (SUBDIRS): Add stdstream. (libmailutils_la_LIBADD): Add stdstream/libstdstream.la. * libmailutils/tests/Makefile.am (noinst_PROGRAMS): Remove argcv (TESTSUITE_AT): Remove argcv.at * libmailutils/tests/testsuite.at: Do not include argcv.at. * libmailutils/base/argcv.c: Move to libmu_compat/argcv.c * libmailutils/tests/argcv.at: Move to libmu_compat/tests/argcv.at * libmailutils/tests/argcv.c: Move to libmu_compat/tests/argcv.c * libmailutils/base/vartab.c: Move to libmu_compat/vartab.c * Makefile.am (SUBDIRS): Add libmu_compat. * configure.ac: Add libmu_compat/tests, libmu_compat/tests/Makefile, libmu_compat/tests/atlocal, libmu_compat/Makefile and libmailutils/stdstream/Makefile to config file list. * mu/ldflags.c (lib_descr): Add mu_compat. * mu/logger.c (logger_parse_opt): -t does not imply --syslog. (mutool_logger): Use inline-comment filter to insert "tag: " prefix. Flush and destroy both streams before returning. * po/POTFILES.in: Add libmailutils/stream/logstream.c, libmailutils/stdstream/baseio.c, libmailutils/stdstream/strerr.c and mu/logger.c. --- Makefile.am | 1 + configure.ac | 5 + include/mailutils/Makefile.am | 2 + include/mailutils/argcv.h | 14 +- include/mailutils/log.h | 49 +++++ include/mailutils/mailutils.h | 2 +- include/mailutils/stdstream.h | 46 ++++ include/mailutils/stream.h | 2 +- include/mailutils/types.hin | 4 + include/mailutils/vartab.h | 24 +- libmailutils/Makefile.am | 3 +- libmailutils/base/Makefile.am | 2 - libmailutils/base/argcv.c | 440 ------------------------------------- libmailutils/base/vartab.c | 346 ----------------------------- libmailutils/stdstream/Makefile.am | 24 ++ libmailutils/stdstream/basestr.c | 80 +++++++ libmailutils/stdstream/strerr.c | 101 +++++++++ libmailutils/stream/logstream.c | 2 +- libmailutils/stream/syslogstream.c | 2 +- libmailutils/tests/Makefile.am | 2 - libmailutils/tests/argcv.at | 91 -------- libmailutils/tests/argcv.c | 59 ----- libmailutils/tests/testsuite.at | 1 - libmu_compat/Makefile.am | 25 +++ libmu_compat/argcv.c | 440 +++++++++++++++++++++++++++++++++++++ libmu_compat/tests/.gitignore | 7 + libmu_compat/tests/Makefile.am | 75 +++++++ libmu_compat/tests/argcv.at | 95 ++++++++ libmu_compat/tests/argcv.c | 59 +++++ libmu_compat/tests/atlocal.in | 5 + libmu_compat/tests/testsuite.at | 19 ++ libmu_compat/vartab.c | 347 +++++++++++++++++++++++++++++ mu/ldflags.c | 1 + mu/logger.c | 27 ++- po/POTFILES.in | 5 + 35 files changed, 1444 insertions(+), 963 deletions(-) create mode 100644 include/mailutils/log.h create mode 100644 include/mailutils/stdstream.h delete mode 100644 libmailutils/base/argcv.c delete mode 100644 libmailutils/base/vartab.c create mode 100644 libmailutils/stdstream/Makefile.am create mode 100644 libmailutils/stdstream/basestr.c create mode 100644 libmailutils/stdstream/strerr.c delete mode 100644 libmailutils/tests/argcv.at delete mode 100644 libmailutils/tests/argcv.c create mode 100644 libmu_compat/Makefile.am create mode 100644 libmu_compat/argcv.c create mode 100644 libmu_compat/tests/.gitignore create mode 100644 libmu_compat/tests/Makefile.am create mode 100644 libmu_compat/tests/argcv.at create mode 100644 libmu_compat/tests/argcv.c create mode 100644 libmu_compat/tests/atlocal.in create mode 100644 libmu_compat/tests/testsuite.at create mode 100644 libmu_compat/vartab.c diff --git a/Makefile.am b/Makefile.am index aed3f5ac4..d17f724e5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -94,6 +94,7 @@ SUBDIRS = . \ sql\ libmu_auth\ libproto\ + libmu_compat\ testsuite\ lib\ libmu_argp\ diff --git a/configure.ac b/configure.ac index abcf5c9fb..aafad7f31 100644 --- a/configure.ac +++ b/configure.ac @@ -1205,6 +1205,7 @@ AC_ARG_WITH([mh-bindir], # Initialize the (autotest) test suite. AC_CONFIG_TESTDIR(libmailutils/tests) AC_CONFIG_TESTDIR(testsuite) +AC_CONFIG_TESTDIR(libmu_compat/tests) AC_CONFIG_TESTDIR(frm/tests) AC_CONFIG_TESTDIR(maidag/tests) AC_CONFIG_TESTDIR(messages/tests) @@ -1214,6 +1215,8 @@ AC_CONFIG_TESTDIR(mh/tests) AC_CONFIG_FILES([libmailutils/tests/Makefile libmailutils/tests/atlocal + libmu_compat/tests/Makefile + libmu_compat/tests/atlocal testsuite/Makefile testsuite/atlocal frm/tests/Makefile @@ -1368,6 +1371,7 @@ AC_CONFIG_FILES([ libproto/pop/Makefile libproto/nntp/Makefile libproto/imap/Makefile + libmu_compat/Makefile maidag/Makefile mail/Makefile mail/testsuite/Makefile @@ -1384,6 +1388,7 @@ AC_CONFIG_FILES([ libmailutils/server/Makefile libmailutils/string/Makefile libmailutils/stream/Makefile + libmailutils/stdstream/Makefile libmailutils/url/Makefile libmailutils/Makefile messages/Makefile diff --git a/include/mailutils/Makefile.am b/include/mailutils/Makefile.am index b52db2c78..b31515819 100644 --- a/include/mailutils/Makefile.am +++ b/include/mailutils/Makefile.am @@ -61,6 +61,7 @@ pkginclude_HEADERS = \ libcfg.h\ list.h\ locker.h\ + log.h\ mailbox.h\ mailcap.h\ mailer.h\ @@ -90,6 +91,7 @@ pkginclude_HEADERS = \ server.h\ sieve.h\ smtp.h\ + stdstream.h\ stream.h\ syslog.h\ sql.h\ diff --git a/include/mailutils/argcv.h b/include/mailutils/argcv.h index 49d3bfa2d..4a8f29399 100644 --- a/include/mailutils/argcv.h +++ b/include/mailutils/argcv.h @@ -24,6 +24,8 @@ #include #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -37,20 +39,22 @@ enum mu_argcv_escape mu_argcv_escape_c /* mu_argcv_escape_sh */ }; + int mu_argcv_join (int argc, char **argv, char *delim, enum mu_argcv_escape esc, char **pstring); -int mu_argcv_string (int argc, char **argv, char **string); - void mu_argcv_remove (int *pargc, char ***pargv, int (*sel) (const char *, void *), void *); - +int mu_argcv_string (int argc, char **argv, char **string); + + /* Deprecated interfaces */ + #define MU_ARGCV_RETURN_DELIMS 0x01 #ifndef MU_ARCGV_DEPRECATED -# define MU_ARCGV_DEPRECATED __attribute__((deprecated)) -#endif +# define MU_ARCGV_DEPRECATED MU_DEPRECATED +#endif int mu_argcv_get (const char *command, const char *delim, const char *cmnt, diff --git a/include/mailutils/log.h b/include/mailutils/log.h new file mode 100644 index 000000000..a36b85ab5 --- /dev/null +++ b/include/mailutils/log.h @@ -0,0 +1,49 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2010 Free Software Foundation, Inc. + + GNU Mailutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GNU Mailutils is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Mailutils. If not, see . */ + +#ifndef _MAILUTILS_LOG_H +#define _MAILUTILS_LOG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define MU_LOG_DEBUG 0 +#define MU_LOG_INFO 1 +#define MU_LOG_NOTICE 2 +#define MU_LOG_WARNING 3 +#define MU_LOG_ERROR 4 +#define MU_LOG_CRIT 5 +#define MU_LOG_ALERT 6 +#define MU_LOG_EMERG 7 + +#define MU_LOGMODE_SEVERITY 0x0001 +#define MU_LOGMODE_LOCUS 0x0002 + +int mu_log_stream_create (mu_stream_t *, mu_stream_t); +int mu_syslog_stream_create (mu_stream_t *, int); + +extern char *_mu_severity_str[]; +extern int _mu_severity_num; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/mailutils/mailutils.h b/include/mailutils/mailutils.h index ccaa3d5e6..19b8e773f 100644 --- a/include/mailutils/mailutils.h +++ b/include/mailutils/mailutils.h @@ -59,12 +59,12 @@ #include #include #include -#include #include #include #include #include #include #include +#include /* EOF */ diff --git a/include/mailutils/stdstream.h b/include/mailutils/stdstream.h new file mode 100644 index 000000000..fcb971fdb --- /dev/null +++ b/include/mailutils/stdstream.h @@ -0,0 +1,46 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2009 Free Software Foundation, Inc. + + GNU Mailutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GNU Mailutils is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Mailutils. If not, see . */ + +#ifndef _MAILUTILS_STDSTREAM_H +#define _MAILUTILS_STDSTREAM_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern mu_stream_t mu_strin; +extern mu_stream_t mu_strout; +extern mu_stream_t mu_strerr; + +extern const char *mu_program_name; + +#define MU_STRERR_STDERR 0 +#define MU_STRERR_SYSLOG 1 +/* #define MU_STRERR_FILE 2 */ + +void mu_stdstream_setup (void); +int mu_stdstream_strerr_create (mu_stream_t *str, int type, int facility, + int priority, const char *tag, + const char *fname); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/mailutils/stream.h b/include/mailutils/stream.h index f1fc4f51b..a7bbfe1ec 100644 --- a/include/mailutils/stream.h +++ b/include/mailutils/stream.h @@ -106,7 +106,7 @@ enum mu_buffer_type */ #define MU_IOCTL_LOGSTREAM_GET_MODE 22 #define MU_IOCTL_LOGSTREAM_SET_MODE 23 - + #define MU_TRANSPORT_INPUT 0 #define MU_TRANSPORT_OUTPUT 1 #define MU_TRANSPORT_VALID_TYPE(n) \ diff --git a/include/mailutils/types.hin b/include/mailutils/types.hin index e0b356618..26916e559 100644 --- a/include/mailutils/types.hin +++ b/include/mailutils/types.hin @@ -33,6 +33,10 @@ # define MU_PRINTFLIKE(fmt,narg) __attribute__ ((__format__ (__printf__, fmt, narg))) #endif +#ifndef MU_DEPRECATED +# define MU_DEPRECATED __attribute__ ((deprecated)) +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/include/mailutils/vartab.h b/include/mailutils/vartab.h index 26f46bb3f..5d0598295 100644 --- a/include/mailutils/vartab.h +++ b/include/mailutils/vartab.h @@ -20,17 +20,27 @@ #include +#ifdef MU_SUPPRESS_DEPRECATION +# undef MU_DEPRECATED +# define MU_DEPRECATED +#else +# warning "Mailutils support for vartab functions has been deprecated." +# warning "Revise your code to use ." +#endif + typedef int (*mu_var_expansion_fp) (const char *name, void *data, char **p); typedef void (*mu_var_free_fp) (void *data, char *value); -int mu_vartab_create (mu_vartab_t *pvar); -int mu_vartab_destroy (mu_vartab_t *pvar); +int mu_vartab_create (mu_vartab_t *pvar) MU_DEPRECATED; +int mu_vartab_destroy (mu_vartab_t *pvar) MU_DEPRECATED; int mu_vartab_define (mu_vartab_t var, const char *name, const char *value, - int isstatic); + int isstatic) MU_DEPRECATED; int mu_vartab_define_exp (mu_vartab_t var, const char *name, mu_var_expansion_fp fun, mu_var_free_fp free, - void *data); -int mu_vartab_count (mu_vartab_t vt, size_t *pcount); -int mu_vartab_getvar (mu_vartab_t vt, const char *name, const char **pvalue); -int mu_vartab_expand (mu_vartab_t vt, const char *str, char **pres); + void *data) MU_DEPRECATED; +int mu_vartab_count (mu_vartab_t vt, size_t *pcount) MU_DEPRECATED; +int mu_vartab_getvar (mu_vartab_t vt, const char *name, const char **pvalue) + MU_DEPRECATED; +int mu_vartab_expand (mu_vartab_t vt, const char *str, char **pres) + MU_DEPRECATED; #endif diff --git a/libmailutils/Makefile.am b/libmailutils/Makefile.am index 34246dcf8..bac6aa994 100644 --- a/libmailutils/Makefile.am +++ b/libmailutils/Makefile.am @@ -17,7 +17,7 @@ # . SUBDIRS = auth base address cfg diag filter mailbox mailer mime\ - server string stream property url . tests + server string stream stdstream property url . tests lib_LTLIBRARIES = libmailutils.la @@ -38,6 +38,7 @@ libmailutils_la_LIBADD = \ server/libserver.la\ string/libstring.la\ stream/libstream.la\ + stdstream/libstdstream.la\ url/liburl.la libmailutils_la_LDFLAGS = -version-info @VI_CURRENT@:@VI_REVISION@:@VI_AGE@ diff --git a/libmailutils/base/Makefile.am b/libmailutils/base/Makefile.am index ae9d2a972..b50781c20 100644 --- a/libmailutils/base/Makefile.am +++ b/libmailutils/base/Makefile.am @@ -20,7 +20,6 @@ noinst_LTLIBRARIES = libbase.la libbase_la_SOURCES = \ alloc.c\ amd.c\ - argcv.c\ argcvfree.c\ argcvjoin.c\ argcvrem.c\ @@ -65,7 +64,6 @@ libbase_la_SOURCES = \ ticket.c\ tilde.c\ usremail.c\ - vartab.c\ version.c\ wicket.c diff --git a/libmailutils/base/argcv.c b/libmailutils/base/argcv.c deleted file mode 100644 index 142de6b6a..000000000 --- a/libmailutils/base/argcv.c +++ /dev/null @@ -1,440 +0,0 @@ -/* argcv.c - simple functions for parsing input based on whitespace - Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2010 Free - Software Foundation, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with this library. If not, see - . */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#define MU_ARCGV_DEPRECATED -#include - -/* Keep mailutils namespace clean */ -#define argcv_get mu_argcv_get -#define argcv_get_n mu_argcv_get_n -#define argcv_get_np mu_argcv_get_np -#define argcv_unquote_char mu_argcv_unquote_char -#define argcv_quote_char mu_argcv_quote_char -#define argcv_quoted_length mu_argcv_quoted_length -#define argcv_unquote_copy mu_argcv_unquote_copy -#define argcv_quote_copy mu_argcv_quote_copy - -/* - * takes a string and splits it into several strings, breaking at ' ' - * command is the string to split - * the number of strings is placed into argc - * the split strings are put into argv - * returns 0 on success, nonzero on failure - */ - -#define isws(c) ((c)==' '||(c)=='\t'||(c)=='\n') -#define isdelim(c,delim) (strchr(delim,(c))!=NULL) - -struct argcv_info -{ - int len; - const char *command; - const char *delim; - const char *comment; - int flags; - - int start; - int end; - int save; - int finish_pos; -}; - -static void -init_argcv_info (struct argcv_info *ap, int flags, - int len, const char *command, const char *delim, - const char *comment) -{ - memset (ap, 0, sizeof *ap); - ap->len = len; - ap->command = command; - ap->delim = delim; - ap->comment = comment; - ap->flags = flags; -} - -static int -argcv_scan (struct argcv_info *ap) -{ - int i = 0; - int len = ap->len; - const char *command = ap->command; - const char *delim = ap->delim; - const char *comment = ap->comment; - - for (;;) - { - i = ap->save; - - if (i >= len) - return i + 1; - - /* Skip initial whitespace */ - while (i < len && isws (command[i])) - i++; - ap->start = i; - - if (!isdelim (command[i], delim)) - { - while (i < len) - { - if (command[i] == '\\') - { - if (++i == len) - break; - i++; - continue; - } - - if (command[i] == '\'' || command[i] == '"') - { - int j; - for (j = i + 1; j < len && command[j] != command[i]; j++) - if (command[j] == '\\') - j++; - if (j < len) - i = j + 1; - else - i++; - } - else if (isws (command[i]) || isdelim (command[i], delim)) - break; - else - i++; /* skip the escaped character */ - } - i--; - } - else if (!(ap->flags & MU_ARGCV_RETURN_DELIMS)) - { - while (i < len && isdelim (command[i], delim)) - i++; - ap->save = i; - continue; - } - - - ap->end = i; - ap->save = ap->finish_pos = i + 1; - - /* If we have a token, and it starts with a comment character, skip - to the newline and restart the token search. */ - if (ap->save <= len) - { - if (strchr (comment, command[ap->start]) != NULL) - { - ap->finish_pos = ap->start; - i = ap->save; - while (i < len && command[i] != '\n') - i++; - - ap->save = i; - continue; - } - } - break; - } - return ap->save; -} - -static char quote_transtab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v"; - -int -argcv_unquote_char (int c) -{ - char *p; - - for (p = quote_transtab; *p; p += 2) - { - if (*p == c) - return p[1]; - } - return c; -} - -int -argcv_quote_char (int c) -{ - char *p; - - for (p = quote_transtab + sizeof(quote_transtab) - 2; - p > quote_transtab; p -= 2) - { - if (*p == c) - return p[-1]; - } - return -1; -} - -#define to_num(c) \ - (isdigit(c) ? c - '0' : (isxdigit(c) ? toupper(c) - 'A' + 10 : 255 )) - -static int -xtonum (int *pval, const char *src, int base, int cnt) -{ - int i, val; - - for (i = 0, val = 0; i < cnt; i++, src++) - { - int n = *(unsigned char*)src; - if (n > 127 || (n = to_num(n)) >= base) - break; - val = val*base + n; - } - *pval = val; - return i; -} - -size_t -argcv_quoted_length (const char *str, int *quote) -{ - size_t len = 0; - - *quote = 0; - for (; *str; str++) - { - if (*str == ' ') - { - len++; - *quote = 1; - } - else if (*str == '"') - { - len += 2; - *quote = 1; - } - else if (*str != '\t' && *str != '\\' && isprint (*str)) - len++; - else if (argcv_quote_char (*str) != -1) - len += 2; - else - len += 4; - } - return len; -} - -void -argcv_unquote_copy (char *dst, const char *src, size_t n) -{ - int i = 0; - int c; - int expect_delim = 0; - - while (i < n) - { - switch (src[i]) - { - case '\'': - case '"': - if (!expect_delim) - { - const char *p; - - for (p = src+i+1; *p && *p != src[i]; p++) - if (*p == '\\') - p++; - if (*p) - expect_delim = src[i++]; - else - *dst++ = src[i++]; - } - else if (expect_delim == src[i]) - ++i; - else - *dst++ = src[i++]; - break; - - case '\\': - ++i; - if (src[i] == 'x' || src[i] == 'X') - { - if (n - i < 2) - { - *dst++ = '\\'; - *dst++ = src[i++]; - } - else - { - int off = xtonum(&c, src + i + 1, 16, 2); - if (off == 0) - { - *dst++ = '\\'; - *dst++ = src[i++]; - } - else - { - *dst++ = c; - i += off + 1; - } - } - } - else if ((unsigned char)src[i] < 128 && isdigit (src[i])) - { - if (n - i < 1) - { - *dst++ = '\\'; - *dst++ = src[i++]; - } - else - { - int off = xtonum (&c, src+i, 8, 3); - if (off == 0) - { - *dst++ = '\\'; - *dst++ = src[i++]; - } - else - { - *dst++ = c; - i += off; - } - } - } - else - *dst++ = argcv_unquote_char (src[i++]); - break; - - default: - *dst++ = src[i++]; - } - } - *dst = 0; -} - -void -argcv_quote_copy (char *dst, const char *src) -{ - for (; *src; src++) - { - if (*src == '"') - { - *dst++ = '\\'; - *dst++ = *src; - } - else if (*src != '\t' && *src != '\\' && isprint(*src)) - *dst++ = *src; - else - { - int c = argcv_quote_char (*src); - *dst++ = '\\'; - if (c != -1) - *dst++ = c; - else - { - char tmp[4]; - snprintf (tmp, sizeof tmp, "%03o", *(unsigned char*)src); - memcpy (dst, tmp, 3); - dst += 3; - } - } - } -} - -int -argcv_get_np (const char *command, int len, - const char *delim, const char *cmnt, - int flags, - int *pargc, char ***pargv, char **endp) -{ - int i = 0; - struct argcv_info info; - int argc; - char **argv; - - if (!delim) - delim = ""; - if (!cmnt) - cmnt = ""; - - init_argcv_info (&info, flags, len, command, delim, cmnt); - - /* Count number of arguments */ - argc = 0; - while (argcv_scan (&info) <= len) - argc++; - - argv = calloc ((argc + 1), sizeof (char *)); - if (argv == NULL) - return ENOMEM; - - i = 0; - info.save = 0; - for (i = 0; i < argc; i++) - { - int n; - int unquote; - - argcv_scan (&info); - - if ((command[info.start] == '"' || command[info.end] == '\'') - && command[info.end] == command[info.start]) - { - if (info.start < info.end) - { - info.start++; - info.end--; - } - unquote = 0; - } - else - unquote = 1; - - n = info.end - info.start + 1; - argv[i] = calloc (n + 1, sizeof (char)); - if (argv[i] == NULL) - { - mu_argcv_free (i, argv); - return ENOMEM; - } - if (unquote) - argcv_unquote_copy (argv[i], &command[info.start], n); - else - memcpy (argv[i], &command[info.start], n); - argv[i][n] = 0; - } - argv[i] = NULL; - - *pargc = argc; - *pargv = argv; - if (endp) - *endp = (char*) (command + info.finish_pos); - return 0; -} - -int -argcv_get_n (const char *command, int len, const char *delim, const char *cmnt, - int *pargc, char ***pargv) -{ - return argcv_get_np (command, len, delim, cmnt, MU_ARGCV_RETURN_DELIMS, - pargc, pargv, NULL); -} - -int -argcv_get (const char *command, const char *delim, const char *cmnt, - int *argc, char ***argv) -{ - return argcv_get_n (command, strlen (command), delim, cmnt, argc, argv); -} - - - - diff --git a/libmailutils/base/vartab.c b/libmailutils/base/vartab.c deleted file mode 100644 index 566a5077b..000000000 --- a/libmailutils/base/vartab.c +++ /dev/null @@ -1,346 +0,0 @@ -/* GNU Mailutils -- a suite of utilities for electronic mail - Copyright (C) 2007, 2010 Free Software Foundation, Inc. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General - Public License along with this library; If not, see - . */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include - -struct _mu_vartab -{ - mu_assoc_t assoc; - mu_stream_t stream; - char *buf; - size_t bufsize; -}; - -#define MU_VARDEFN_STATIC 0x1 -#define MU_VARDEFN_FUNC 0x2 - -struct vardefn -{ - int flags; - char *value; - mu_var_expansion_fp fun; - mu_var_free_fp free; - void *data; -}; - -int -mu_vartab_create (mu_vartab_t *pvar) -{ - int rc; - struct _mu_vartab *p = calloc (1, sizeof *p); - if (!p) - return ENOMEM; - rc = mu_assoc_create (&p->assoc, sizeof (struct vardefn), 0); - if (rc) - { - free (p); - return rc; - } - *pvar = p; - return 0; -} - -static void -vardefn_free (struct vardefn *vd) -{ - if (vd->value) - { - if (vd->free) - vd->free (vd->data, vd->value); - else if (!(vd->flags & MU_VARDEFN_STATIC)) - free (vd->value); - } - memset (vd, 0, sizeof vd); -} - -int -mu_vartab_destroy (mu_vartab_t *pvar) -{ - int rc; - mu_vartab_t var = *pvar; - mu_iterator_t itr; - - if (!var) - return EINVAL; - rc = mu_assoc_get_iterator (var->assoc, &itr); - if (rc) - return rc; - for (mu_iterator_first (itr); !mu_iterator_is_done (itr); - mu_iterator_next (itr)) - { - struct vardefn *vd; - mu_iterator_current (itr, (void**)&vd); - vardefn_free (vd); - } - mu_iterator_destroy (&itr); - - mu_assoc_destroy (&var->assoc); - mu_stream_destroy (&var->stream); - free (var->buf); - free (var); - *pvar = NULL; - return 0; -} - -int -mu_vartab_define (mu_vartab_t var, const char *name, const char *value, - int isstatic) -{ - int rc; - struct vardefn *vd; - - if (!var) - return EINVAL; - rc = mu_assoc_ref_install (var->assoc, name, (void **) &vd); - if (rc == MU_ERR_EXISTS) - vardefn_free (vd); - else if (rc != 0) - return rc; - - if (isstatic) - { - vd->flags = MU_VARDEFN_STATIC; - vd->value = (char*) value; - } - else - { - vd->flags = 0; - vd->value = strdup (value); - if (!vd->value) - return ENOMEM; - } - return 0; -} - -int -mu_vartab_define_exp (mu_vartab_t var, const char *name, - mu_var_expansion_fp fun, mu_var_free_fp free, - void *data) -{ - int rc; - struct vardefn *vd; - - if (!var) - return EINVAL; - rc = mu_assoc_ref_install (var->assoc, name, (void **) &vd); - if (rc == MU_ERR_EXISTS) - vardefn_free (vd); - else if (rc != 0) - return rc; - - vd->flags = MU_VARDEFN_FUNC; - vd->fun = fun; - vd->free = free; - vd->data = data; - return 0; -} - -int -mu_vartab_count (mu_vartab_t vt, size_t *pcount) -{ - if (!vt) - return EINVAL; - return mu_assoc_count (vt->assoc, pcount); -} - -static int -vardefn_expand (const char *name, struct vardefn *vd, const char **pvalue) -{ - if (!vd->value) - { - if (vd->fun) - { - int rc = vd->fun (name, vd->data, &vd->value); - if (rc) - return rc; - } - else - return EINVAL; - } - *pvalue = vd->value; - return 0; -} - -int -mu_vartab_getvar (mu_vartab_t vt, const char *name, const char **pvalue) -{ - struct vardefn *vdefn; - - if (!vt) - return EINVAL; - vdefn = mu_assoc_ref (vt->assoc, name); - if (!vdefn) - return MU_ERR_NOENT; - return vardefn_expand (name, vdefn, pvalue); -} - -static char * -copy_name (mu_vartab_t vt, const char *name, size_t len) -{ - if (len + 1 > vt->bufsize) - { - char *p = realloc (vt->buf, len + 1); - if (!p) - return NULL; - vt->buf = p; - vt->bufsize = len + 1; - } - memcpy (vt->buf, name, len); - vt->buf[len] = 0; - return vt->buf; -} - -int -mu_vartab_expand (mu_vartab_t vt, const char *str, char **pres) -{ - int rc; - mu_off_t size; - const char *p; - - if (!vt) - return EINVAL; - if (!vt->stream) - { - rc = mu_memory_stream_create (&vt->stream, 0); - if (rc) - return rc; - } - else - mu_stream_truncate (vt->stream, 0); - mu_stream_seek (vt->stream, 0, MU_SEEK_SET, NULL); - - for (p = str; *p; ) - { - if (*p == '$') - { - switch (*++p) - { - case '$': - mu_stream_write (vt->stream, str, p - str, NULL); - str = p + 1; - p = str + 1; - break; - - case '{': - { - const char *e = strchr (p + 1, '}'); - if (e) - { - const char *pvalue; - size_t len = e - p - 1; - char *name = copy_name (vt, p + 1, len); - rc = mu_vartab_getvar (vt, name, &pvalue); - if (rc == 0) - { - mu_stream_write (vt->stream, str, p - str - 1, NULL); - mu_stream_write (vt->stream, pvalue, strlen (pvalue), - NULL); - str = e + 1; - p = str + 1; - } - else if (rc == MU_ERR_NOENT) - p = e + 1; - else - return rc; - } - else - p++; - } - break; - - default: - { - char *name = copy_name (vt, p, 1); - const char *pvalue; - rc = mu_vartab_getvar (vt, name, &pvalue); - if (rc == 0) - { - mu_stream_write (vt->stream, str, p - str - 1, NULL); - mu_stream_write (vt->stream, pvalue, strlen (pvalue), - NULL); - str = p + 1; - p = str + 1; - } - else if (rc == MU_ERR_NOENT) - p++; - else - return rc; - } - break; - } - } - else if (*p == '%') - { - /* allow `%' as prefix for single-character entities, for - compatibility with v. prior to 1.2.91 */ - if (*++p == '%') - { - mu_stream_write (vt->stream, str, p - str, NULL); - str = p + 1; - p = str + 1; - } - else - { - char *name = copy_name (vt, p, 1); - const char *pvalue; - rc = mu_vartab_getvar (vt, name, &pvalue); - if (rc == 0) - { - mu_stream_write (vt->stream, str, p - str - 1, NULL); - mu_stream_write (vt->stream, pvalue, strlen (pvalue), - NULL); - str = p + 1; - p = str + 1; - } - else if (rc == MU_ERR_NOENT) - p++; - else - return rc; - } - } - else - p++; - } - - if (p > str) - mu_stream_write (vt->stream, str, p - str, NULL); - - mu_stream_size (vt->stream, &size); - *pres = malloc (size + 1); - if (!*pres) - return ENOMEM; - mu_stream_seek (vt->stream, 0, MU_SEEK_SET, NULL); - mu_stream_read (vt->stream, *pres, size, NULL); - (*pres)[size] = 0; - return 0; -} - - - - - - - diff --git a/libmailutils/stdstream/Makefile.am b/libmailutils/stdstream/Makefile.am new file mode 100644 index 000000000..feede72b3 --- /dev/null +++ b/libmailutils/stdstream/Makefile.am @@ -0,0 +1,24 @@ +# GNU Mailutils -- a suite of utilities for electronic mail +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 3 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General +# Public License along with this library. If not, see +# . + +noinst_LTLIBRARIES = libstdstream.la + +libstdstream_la_SOURCES = \ + basestr.c\ + strerr.c + +INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils diff --git a/libmailutils/stdstream/basestr.c b/libmailutils/stdstream/basestr.c new file mode 100644 index 000000000..28759aaf3 --- /dev/null +++ b/libmailutils/stdstream/basestr.c @@ -0,0 +1,80 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2010 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with GNU Mailutils. If not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +mu_stream_t mu_strin; +mu_stream_t mu_strout; +mu_stream_t mu_strerr; + +void +mu_stdstream_setup () +{ + int rc; + int fd; + + /* Ensure that first 3 descriptors are open in proper mode */ + fd = open ("/dev/null", O_WRONLY); + switch (fd) + { + case 2: + /* keep it open */; + break; + + case 1: + /* keep it open and try 0 */ + fd = open ("/dev/null", O_RDONLY); + if (fd != 0) + close (fd); + break; + + default: + close (fd); + break; + } + + /* Create the corresponding streams */ + rc = mu_stdio_stream_create (&mu_strin, MU_STDIN_FD, 0); + if (rc) + { + fprintf (stderr, "mu_stdio_stream_create(%d): %s\n", + MU_STDIN_FD, mu_strerror (rc)); + abort (); + } + rc = mu_stdio_stream_create (&mu_strout, MU_STDOUT_FD, 0); + if (rc) + { + fprintf (stderr, "mu_stdio_stream_create(%d): %s\n", + MU_STDOUT_FD, mu_strerror (rc)); + abort (); + } + + if (mu_stdstream_strerr_create (&mu_strerr, MU_STRERR_STDERR, 0, 0, + NULL, NULL)) + abort (); +} diff --git a/libmailutils/stdstream/strerr.c b/libmailutils/stdstream/strerr.c new file mode 100644 index 000000000..76dd2cb7f --- /dev/null +++ b/libmailutils/stdstream/strerr.c @@ -0,0 +1,101 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2010 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with GNU Mailutils. If not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +mu_stdstream_strerr_create (mu_stream_t *plogger, int type, int facility, + int priority, const char *tag, + const char *fname MU_ARG_UNUSED) +{ + int rc; + mu_stream_t transport; + + if (!tag) + tag = mu_program_name; + switch (type) + { + case MU_STRERR_STDERR: + { + mu_stream_t str; + char *fltargs[3] = { "INLINE-COMMENT", }; + + rc = mu_stdio_stream_create (&str, MU_STDERR_FD, 0); + if (rc) + { + fprintf (stderr, _("%s: cannot open error stream: %s\n"), + tag, mu_strerror (rc)); + return MU_ERR_FAILURE; + } + mu_asprintf (&fltargs[1], "%s: ", tag); + fltargs[2] = NULL; + rc = mu_filter_create_args (&transport, str, + "INLINE-COMMENT", 2, (const char**)fltargs, + MU_FILTER_ENCODE, MU_STREAM_WRITE); + mu_stream_unref (str); + free (fltargs[1]); + if (rc) + { + fprintf (stderr, + _("%s: cannot open output filter stream: %s"), + tag, mu_strerror (rc)); + return MU_ERR_FAILURE; + } + } + break; + + case MU_STRERR_SYSLOG: + openlog (tag, LOG_PID, facility); + rc = mu_syslog_stream_create (&transport, priority); + if (rc) + { + fprintf (stderr, _("%s: cannot create syslog stream: %s\n"), + tag, mu_strerror (rc)); + return MU_ERR_FAILURE; + } + break; + + default: + fprintf (stderr, _("%s: cannot create error stream: %s\n"), + tag, mu_strerror (EINVAL)); + return EINVAL; + } + + rc = mu_log_stream_create (plogger, transport); + mu_stream_unref (transport); + if (rc) + { + fprintf (stderr, _("%s: cannot open logger stream: %s\n"), + tag , mu_strerror (rc)); + return MU_ERR_FAILURE; + } + return 0; +} + diff --git a/libmailutils/stream/logstream.c b/libmailutils/stream/logstream.c index 5908a27ec..ece636e74 100644 --- a/libmailutils/stream/logstream.c +++ b/libmailutils/stream/logstream.c @@ -158,7 +158,7 @@ _log_write (struct _mu_stream *str, const char *buf, size_t size, if (severity >= _mu_severity_num) severity = MU_LOG_EMERG; - + if (logmode & MU_LOGMODE_LOCUS) { if (fname) diff --git a/libmailutils/stream/syslogstream.c b/libmailutils/stream/syslogstream.c index 384694e59..c81815f38 100644 --- a/libmailutils/stream/syslogstream.c +++ b/libmailutils/stream/syslogstream.c @@ -57,7 +57,7 @@ _syslog_ctl (struct _mu_stream *str, int op, void *arg) return EINVAL; sp->prio = *(int*)arg; break; - + default: return ENOSYS; } diff --git a/libmailutils/tests/Makefile.am b/libmailutils/tests/Makefile.am index cfcea3997..b7960bfc3 100644 --- a/libmailutils/tests/Makefile.am +++ b/libmailutils/tests/Makefile.am @@ -41,7 +41,6 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac INCLUDES = @MU_LIB_COMMON_INCLUDES@ noinst_PROGRAMS = \ addr\ - argcv\ decode2047\ encode2047\ fltst\ @@ -63,7 +62,6 @@ EXTRA_DIST += Encode Decode Wicketfile TESTSUITE_AT = \ address.at\ - argcv.at\ base64d.at\ base64e.at\ decode2047.at\ diff --git a/libmailutils/tests/argcv.at b/libmailutils/tests/argcv.at deleted file mode 100644 index 857f500c4..000000000 --- a/libmailutils/tests/argcv.at +++ /dev/null @@ -1,91 +0,0 @@ -# This file is part of GNU Mailutils. -*- Autotest -*- -# Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. -# -# GNU Mailutils is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 3, or (at -# your option) any later version. -# -# GNU Mailutils is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Mailutils. If not, see . - -dnl ------------------------------------------------------------ -dnl TESTARGS([NAME], [KW = `'], [INPUT], [STDOUT = `'], -dnl [STDERR = `'], [RUN-IF-FAIL], [RUN-IF-PASS]) -dnl -m4_pushdef([TESTARGS],[ -m4_pushdef([MU_TEST_GROUP],[Argcv]) -m4_pushdef([MU_TEST_KEYWORDS],[argcv]) -m4_pushdef([MU_TEST_COMMAND],[argcv]) -MU_GENERIC_TEST([$1],[$2],[$3],[],[$4],[$5]) -m4_popdef([MU_TEST_COMMAND]) -m4_popdef([MU_TEST_KEYWORDS]) -m4_popdef([MU_TEST_GROUP]) -]) - -dnl ------------------------------------------------------------ -TESTARGS([simple input],[], -[1 2 3], -[3: 1 2 3 -]) - -TESTARGS([quoted space],[], -[quoted\ space], -[1: "quoted space" -]) - -TESTARGS([tab character],[], -[a "tab character"], -[2: a tab\tcharacter -]) - -TESTARGS([octal and hex escapes],[], -[\157\143\164\141\154\40and\x20\x68\x65\x78], -[1: "octal and hex" -]) - -TESTARGS([octal and hex escapes 2],[], -[\157\143\164\141\154\40 and \x20\x68\x65\x78], -[3: "octal " and " hex" -]) - -TESTARGS([escape representation],[], -[A\x3-\48\39], -[1: A\003-\0048\0039 -]) - -TESTARG([8-bit input],[], -[верхняя половина таблицы], -[3: \327\305\322\310\316\321\321 \320\317\314\317\327\311\316\301 \324\301\302\314\311\303\331]) - -TESTARG([misquoted input],[], -[messed up'quotations ' in "a single'" "command" lin"e], -[6: messed "upquotations " in "a single'" command "lin\"e" -]) - -TESTARG([unbalanced quote],[], -['unbalanced "quote], -[2: 'unbalanced "\"quote" -]) - -TESTARG([unbalanced quote 2],[], -[unbalanced "quote], -[2: unbalanced "\"quote" -]) - -TESTARG([unbalanced quote 3],[], -["], -[1: "\"" -]) - -m4_popdef([TESTARGS]) - - - - - diff --git a/libmailutils/tests/argcv.c b/libmailutils/tests/argcv.c deleted file mode 100644 index 66e9060a4..000000000 --- a/libmailutils/tests/argcv.c +++ /dev/null @@ -1,59 +0,0 @@ -/* GNU Mailutils -- a suite of utilities for electronic mail - Copyright (C) 2005, 2007, 2009, 2010 Free Software Foundation, Inc. - - GNU Mailutils is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - GNU Mailutils is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNU Mailutils. If not, see . */ - -#ifdef HAVE_CONFIG_H -# include -#endif -#include -#include -#include -#include -#include -#define MU_ARCGV_DEPRECATED -#include -#include - -int -main (int argc, char **argv) -{ - char *delim = ""; - char *comment = "#"; - char buf[512]; - - while (fgets (buf, sizeof buf, stdin)) - { - int status, c; - char **v; - char *s; - - status = mu_argcv_get (buf, delim, comment, &c, &v); - if (status) - { - fprintf (stderr, "cannot parse: %s\n", mu_strerror (status)); - continue; - } - status = mu_argcv_string (c, v, &s); - if (status) - fprintf (stderr, "cannot create string: %s\n", mu_strerror (status)); - else - { - printf ("%d: %s\n", c, s); - free (s); - } - mu_argcv_free (c, v); - } - exit (0); -} diff --git a/libmailutils/tests/testsuite.at b/libmailutils/tests/testsuite.at index 722e83946..fa3118954 100644 --- a/libmailutils/tests/testsuite.at +++ b/libmailutils/tests/testsuite.at @@ -55,7 +55,6 @@ AT_INIT m4_include([list.at]) m4_include([address.at]) -m4_include([argcv.at]) m4_include([wordsplit.at]) m4_include([url.at]) m4_include([mailcap.at]) diff --git a/libmu_compat/Makefile.am b/libmu_compat/Makefile.am new file mode 100644 index 000000000..c55590830 --- /dev/null +++ b/libmu_compat/Makefile.am @@ -0,0 +1,25 @@ +# This file is part of GNU Mailutils +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GNU Mailutils is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3, or (at +# your option) any later version. +# +# GNU Mailutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Mailutils. If not, see . + +SUBDIRS = . tests +lib_LTLIBRARIES = libmu_compat.la + +libmu_compat_la_SOURCES = \ + argcv.c\ + vartab.c + +INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils + diff --git a/libmu_compat/argcv.c b/libmu_compat/argcv.c new file mode 100644 index 000000000..142de6b6a --- /dev/null +++ b/libmu_compat/argcv.c @@ -0,0 +1,440 @@ +/* argcv.c - simple functions for parsing input based on whitespace + Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2010 Free + Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library. If not, see + . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#define MU_ARCGV_DEPRECATED +#include + +/* Keep mailutils namespace clean */ +#define argcv_get mu_argcv_get +#define argcv_get_n mu_argcv_get_n +#define argcv_get_np mu_argcv_get_np +#define argcv_unquote_char mu_argcv_unquote_char +#define argcv_quote_char mu_argcv_quote_char +#define argcv_quoted_length mu_argcv_quoted_length +#define argcv_unquote_copy mu_argcv_unquote_copy +#define argcv_quote_copy mu_argcv_quote_copy + +/* + * takes a string and splits it into several strings, breaking at ' ' + * command is the string to split + * the number of strings is placed into argc + * the split strings are put into argv + * returns 0 on success, nonzero on failure + */ + +#define isws(c) ((c)==' '||(c)=='\t'||(c)=='\n') +#define isdelim(c,delim) (strchr(delim,(c))!=NULL) + +struct argcv_info +{ + int len; + const char *command; + const char *delim; + const char *comment; + int flags; + + int start; + int end; + int save; + int finish_pos; +}; + +static void +init_argcv_info (struct argcv_info *ap, int flags, + int len, const char *command, const char *delim, + const char *comment) +{ + memset (ap, 0, sizeof *ap); + ap->len = len; + ap->command = command; + ap->delim = delim; + ap->comment = comment; + ap->flags = flags; +} + +static int +argcv_scan (struct argcv_info *ap) +{ + int i = 0; + int len = ap->len; + const char *command = ap->command; + const char *delim = ap->delim; + const char *comment = ap->comment; + + for (;;) + { + i = ap->save; + + if (i >= len) + return i + 1; + + /* Skip initial whitespace */ + while (i < len && isws (command[i])) + i++; + ap->start = i; + + if (!isdelim (command[i], delim)) + { + while (i < len) + { + if (command[i] == '\\') + { + if (++i == len) + break; + i++; + continue; + } + + if (command[i] == '\'' || command[i] == '"') + { + int j; + for (j = i + 1; j < len && command[j] != command[i]; j++) + if (command[j] == '\\') + j++; + if (j < len) + i = j + 1; + else + i++; + } + else if (isws (command[i]) || isdelim (command[i], delim)) + break; + else + i++; /* skip the escaped character */ + } + i--; + } + else if (!(ap->flags & MU_ARGCV_RETURN_DELIMS)) + { + while (i < len && isdelim (command[i], delim)) + i++; + ap->save = i; + continue; + } + + + ap->end = i; + ap->save = ap->finish_pos = i + 1; + + /* If we have a token, and it starts with a comment character, skip + to the newline and restart the token search. */ + if (ap->save <= len) + { + if (strchr (comment, command[ap->start]) != NULL) + { + ap->finish_pos = ap->start; + i = ap->save; + while (i < len && command[i] != '\n') + i++; + + ap->save = i; + continue; + } + } + break; + } + return ap->save; +} + +static char quote_transtab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v"; + +int +argcv_unquote_char (int c) +{ + char *p; + + for (p = quote_transtab; *p; p += 2) + { + if (*p == c) + return p[1]; + } + return c; +} + +int +argcv_quote_char (int c) +{ + char *p; + + for (p = quote_transtab + sizeof(quote_transtab) - 2; + p > quote_transtab; p -= 2) + { + if (*p == c) + return p[-1]; + } + return -1; +} + +#define to_num(c) \ + (isdigit(c) ? c - '0' : (isxdigit(c) ? toupper(c) - 'A' + 10 : 255 )) + +static int +xtonum (int *pval, const char *src, int base, int cnt) +{ + int i, val; + + for (i = 0, val = 0; i < cnt; i++, src++) + { + int n = *(unsigned char*)src; + if (n > 127 || (n = to_num(n)) >= base) + break; + val = val*base + n; + } + *pval = val; + return i; +} + +size_t +argcv_quoted_length (const char *str, int *quote) +{ + size_t len = 0; + + *quote = 0; + for (; *str; str++) + { + if (*str == ' ') + { + len++; + *quote = 1; + } + else if (*str == '"') + { + len += 2; + *quote = 1; + } + else if (*str != '\t' && *str != '\\' && isprint (*str)) + len++; + else if (argcv_quote_char (*str) != -1) + len += 2; + else + len += 4; + } + return len; +} + +void +argcv_unquote_copy (char *dst, const char *src, size_t n) +{ + int i = 0; + int c; + int expect_delim = 0; + + while (i < n) + { + switch (src[i]) + { + case '\'': + case '"': + if (!expect_delim) + { + const char *p; + + for (p = src+i+1; *p && *p != src[i]; p++) + if (*p == '\\') + p++; + if (*p) + expect_delim = src[i++]; + else + *dst++ = src[i++]; + } + else if (expect_delim == src[i]) + ++i; + else + *dst++ = src[i++]; + break; + + case '\\': + ++i; + if (src[i] == 'x' || src[i] == 'X') + { + if (n - i < 2) + { + *dst++ = '\\'; + *dst++ = src[i++]; + } + else + { + int off = xtonum(&c, src + i + 1, 16, 2); + if (off == 0) + { + *dst++ = '\\'; + *dst++ = src[i++]; + } + else + { + *dst++ = c; + i += off + 1; + } + } + } + else if ((unsigned char)src[i] < 128 && isdigit (src[i])) + { + if (n - i < 1) + { + *dst++ = '\\'; + *dst++ = src[i++]; + } + else + { + int off = xtonum (&c, src+i, 8, 3); + if (off == 0) + { + *dst++ = '\\'; + *dst++ = src[i++]; + } + else + { + *dst++ = c; + i += off; + } + } + } + else + *dst++ = argcv_unquote_char (src[i++]); + break; + + default: + *dst++ = src[i++]; + } + } + *dst = 0; +} + +void +argcv_quote_copy (char *dst, const char *src) +{ + for (; *src; src++) + { + if (*src == '"') + { + *dst++ = '\\'; + *dst++ = *src; + } + else if (*src != '\t' && *src != '\\' && isprint(*src)) + *dst++ = *src; + else + { + int c = argcv_quote_char (*src); + *dst++ = '\\'; + if (c != -1) + *dst++ = c; + else + { + char tmp[4]; + snprintf (tmp, sizeof tmp, "%03o", *(unsigned char*)src); + memcpy (dst, tmp, 3); + dst += 3; + } + } + } +} + +int +argcv_get_np (const char *command, int len, + const char *delim, const char *cmnt, + int flags, + int *pargc, char ***pargv, char **endp) +{ + int i = 0; + struct argcv_info info; + int argc; + char **argv; + + if (!delim) + delim = ""; + if (!cmnt) + cmnt = ""; + + init_argcv_info (&info, flags, len, command, delim, cmnt); + + /* Count number of arguments */ + argc = 0; + while (argcv_scan (&info) <= len) + argc++; + + argv = calloc ((argc + 1), sizeof (char *)); + if (argv == NULL) + return ENOMEM; + + i = 0; + info.save = 0; + for (i = 0; i < argc; i++) + { + int n; + int unquote; + + argcv_scan (&info); + + if ((command[info.start] == '"' || command[info.end] == '\'') + && command[info.end] == command[info.start]) + { + if (info.start < info.end) + { + info.start++; + info.end--; + } + unquote = 0; + } + else + unquote = 1; + + n = info.end - info.start + 1; + argv[i] = calloc (n + 1, sizeof (char)); + if (argv[i] == NULL) + { + mu_argcv_free (i, argv); + return ENOMEM; + } + if (unquote) + argcv_unquote_copy (argv[i], &command[info.start], n); + else + memcpy (argv[i], &command[info.start], n); + argv[i][n] = 0; + } + argv[i] = NULL; + + *pargc = argc; + *pargv = argv; + if (endp) + *endp = (char*) (command + info.finish_pos); + return 0; +} + +int +argcv_get_n (const char *command, int len, const char *delim, const char *cmnt, + int *pargc, char ***pargv) +{ + return argcv_get_np (command, len, delim, cmnt, MU_ARGCV_RETURN_DELIMS, + pargc, pargv, NULL); +} + +int +argcv_get (const char *command, const char *delim, const char *cmnt, + int *argc, char ***argv) +{ + return argcv_get_n (command, strlen (command), delim, cmnt, argc, argv); +} + + + + diff --git a/libmu_compat/tests/.gitignore b/libmu_compat/tests/.gitignore new file mode 100644 index 000000000..81721a669 --- /dev/null +++ b/libmu_compat/tests/.gitignore @@ -0,0 +1,7 @@ +atconfig +atlocal +package.m4 +testsuite +testsuite.dir +testsuite.log +argcv diff --git a/libmu_compat/tests/Makefile.am b/libmu_compat/tests/Makefile.am new file mode 100644 index 000000000..14bb70ce0 --- /dev/null +++ b/libmu_compat/tests/Makefile.am @@ -0,0 +1,75 @@ +# This file is part of GNU Mailutils. +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GNU Mailutils is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3, or (at +# your option) any later version. +# +# GNU Mailutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Mailutils. If not, see . + +EXTRA_DIST = $(TESTSUITE_AT) testsuite package.m4 +DISTCLEANFILES = atconfig $(check_SCRIPTS) +MAINTAINERCLEANFILES = Makefile.in $(TESTSUITE) + +## ------------ ## +## package.m4. ## +## ------------ ## + +$(srcdir)/package.m4: $(top_srcdir)/configure.ac + $(AM_V_GEN){ \ + echo '# Signature of the current package.'; \ + echo 'm4_define([AT_PACKAGE_NAME], [@PACKAGE_NAME@])'; \ + echo 'm4_define([AT_PACKAGE_TARNAME], [@PACKAGE_TARNAME@])'; \ + echo 'm4_define([AT_PACKAGE_VERSION], [@PACKAGE_VERSION@])'; \ + echo 'm4_define([AT_PACKAGE_STRING], [@PACKAGE_STRING@])'; \ + echo 'm4_define([AT_PACKAGE_BUGREPORT], [@PACKAGE_BUGREPORT@])'; \ + } >$(srcdir)/package.m4 + +# + +## -------------------------- ## +## Non-installable programs +## -------------------------- ## + +INCLUDES = @MU_LIB_COMMON_INCLUDES@ +noinst_PROGRAMS = argcv + +LDADD = ../libmu_compat.la ${MU_LIB_MAILUTILS} + +## ------------ ## +## Test suite. ## +## ------------ ## + +TESTSUITE_AT = \ + argcv.at\ + testsuite.at + +TESTSUITE = $(srcdir)/testsuite +M4=m4 + +AUTOTEST = $(AUTOM4TE) --language=autotest +$(TESTSUITE): package.m4 $(TESTSUITE_AT) $(top_srcdir)/testsuite/testsuite.inc + $(AM_V_GEN)$(AUTOTEST) -I $(srcdir) -I $(top_srcdir)/testsuite testsuite.at -o $@.tmp + $(AM_V_at)mv $@.tmp $@ + +atconfig: $(top_builddir)/config.status + cd $(top_builddir) && ./config.status tests/$@ + +clean-local: + @test ! -f $(TESTSUITE) || $(SHELL) $(TESTSUITE) --clean + +check-local: atconfig atlocal $(TESTSUITE) + @$(SHELL) $(TESTSUITE) + +# Run the test suite on the *installed* tree. +#installcheck-local: +# $(SHELL) $(TESTSUITE) AUTOTEST_PATH=$(exec_prefix)/bin + + diff --git a/libmu_compat/tests/argcv.at b/libmu_compat/tests/argcv.at new file mode 100644 index 000000000..6877cd5c3 --- /dev/null +++ b/libmu_compat/tests/argcv.at @@ -0,0 +1,95 @@ +# This file is part of GNU Mailutils. -*- Autotest -*- +# Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +# +# GNU Mailutils is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3, or (at +# your option) any later version. +# +# GNU Mailutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Mailutils. If not, see . + +dnl ------------------------------------------------------------ +dnl TESTARGS([NAME], [KW = `'], [INPUT], [STDOUT = `'], +dnl [STDERR = `'], [RUN-IF-FAIL], [RUN-IF-PASS]) +dnl +m4_pushdef([TESTARGS],[ +m4_pushdef([MU_TEST_GROUP],[Argcv]) +m4_pushdef([MU_TEST_KEYWORDS],[argcv]) +m4_pushdef([MU_TEST_COMMAND],[argcv]) + +AT_SETUP([Argcv: m4_if([$1],[],mu_firstline([$3]),[$1])]) +AT_KEYWORDS([argcv $2]) +AT_CHECK([ +AT_DATA([input],[$3 +]) +argcv < input],[0],[$4],[$5],[$6],[$7]) +AT_CLEANUP +]) + +dnl ------------------------------------------------------------ +TESTARGS([simple input],[], +[1 2 3], +[3: 1 2 3 +]) + +TESTARGS([quoted space],[], +[quoted\ space], +[1: "quoted space" +]) + +TESTARGS([tab character],[], +[a "tab character"], +[2: a tab\tcharacter +]) + +TESTARGS([octal and hex escapes],[], +[\157\143\164\141\154\40and\x20\x68\x65\x78], +[1: "octal and hex" +]) + +TESTARGS([octal and hex escapes 2],[], +[\157\143\164\141\154\40 and \x20\x68\x65\x78], +[3: "octal " and " hex" +]) + +TESTARGS([escape representation],[], +[A\x3-\48\39], +[1: A\003-\0048\0039 +]) + +TESTARG([8-bit input],[], +[верхняя половина таблицы], +[3: \327\305\322\310\316\321\321 \320\317\314\317\327\311\316\301 \324\301\302\314\311\303\331]) + +TESTARG([misquoted input],[], +[messed up'quotations ' in "a single'" "command" lin"e], +[6: messed "upquotations " in "a single'" command "lin\"e" +]) + +TESTARG([unbalanced quote],[], +['unbalanced "quote], +[2: 'unbalanced "\"quote" +]) + +TESTARG([unbalanced quote 2],[], +[unbalanced "quote], +[2: unbalanced "\"quote" +]) + +TESTARG([unbalanced quote 3],[], +["], +[1: "\"" +]) + +m4_popdef([TESTARGS]) + + + + + diff --git a/libmu_compat/tests/argcv.c b/libmu_compat/tests/argcv.c new file mode 100644 index 000000000..66e9060a4 --- /dev/null +++ b/libmu_compat/tests/argcv.c @@ -0,0 +1,59 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2005, 2007, 2009, 2010 Free Software Foundation, Inc. + + GNU Mailutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GNU Mailutils is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Mailutils. If not, see . */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include +#include +#include +#include +#include +#define MU_ARCGV_DEPRECATED +#include +#include + +int +main (int argc, char **argv) +{ + char *delim = ""; + char *comment = "#"; + char buf[512]; + + while (fgets (buf, sizeof buf, stdin)) + { + int status, c; + char **v; + char *s; + + status = mu_argcv_get (buf, delim, comment, &c, &v); + if (status) + { + fprintf (stderr, "cannot parse: %s\n", mu_strerror (status)); + continue; + } + status = mu_argcv_string (c, v, &s); + if (status) + fprintf (stderr, "cannot create string: %s\n", mu_strerror (status)); + else + { + printf ("%d: %s\n", c, s); + free (s); + } + mu_argcv_free (c, v); + } + exit (0); +} diff --git a/libmu_compat/tests/atlocal.in b/libmu_compat/tests/atlocal.in new file mode 100644 index 000000000..1f0b81345 --- /dev/null +++ b/libmu_compat/tests/atlocal.in @@ -0,0 +1,5 @@ +# @configure_input@ -*- shell-script -*- +# Configurable variable values for Mailutils test suite. +# Copyright (C) 2004, 2010 Free Software Foundation, Inc. + +PATH=@abs_builddir@:@abs_top_builddir@/libmailutils/tests:$top_srcdir:$srcdir:$PATH diff --git a/libmu_compat/tests/testsuite.at b/libmu_compat/tests/testsuite.at new file mode 100644 index 000000000..0721f84f6 --- /dev/null +++ b/libmu_compat/tests/testsuite.at @@ -0,0 +1,19 @@ +# This file is part of GNU Mailutils. -*- Autotest -*- +# Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +# +# GNU Mailutils is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3, or (at +# your option) any later version. +# +# GNU Mailutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Mailutils. If not, see . + +m4_include([testsuite.inc]) +AT_INIT +m4_include([argcv.at]) diff --git a/libmu_compat/vartab.c b/libmu_compat/vartab.c new file mode 100644 index 000000000..3e487dd25 --- /dev/null +++ b/libmu_compat/vartab.c @@ -0,0 +1,347 @@ +/* GNU Mailutils -- a suite of utilities for electronic mail + Copyright (C) 2007, 2010 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; If not, see + . */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#define MU_SUPPRESS_DEPRECATION +#include + +struct _mu_vartab +{ + mu_assoc_t assoc; + mu_stream_t stream; + char *buf; + size_t bufsize; +}; + +#define MU_VARDEFN_STATIC 0x1 +#define MU_VARDEFN_FUNC 0x2 + +struct vardefn +{ + int flags; + char *value; + mu_var_expansion_fp fun; + mu_var_free_fp free; + void *data; +}; + +int +mu_vartab_create (mu_vartab_t *pvar) +{ + int rc; + struct _mu_vartab *p = calloc (1, sizeof *p); + if (!p) + return ENOMEM; + rc = mu_assoc_create (&p->assoc, sizeof (struct vardefn), 0); + if (rc) + { + free (p); + return rc; + }