summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/lib-managesieve/managesieve-arg.c
diff options
context:
space:
mode:
Diffstat (limited to 'pigeonhole/src/lib-managesieve/managesieve-arg.c')
-rw-r--r--pigeonhole/src/lib-managesieve/managesieve-arg.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/pigeonhole/src/lib-managesieve/managesieve-arg.c b/pigeonhole/src/lib-managesieve/managesieve-arg.c
new file mode 100644
index 0000000..178bf45
--- /dev/null
+++ b/pigeonhole/src/lib-managesieve/managesieve-arg.c
@@ -0,0 +1,207 @@
+/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file
+ */
+
+#include "lib.h"
+#include "str.h"
+#include "strescape.h"
+#include "managesieve-arg.h"
+
+bool managesieve_arg_get_atom(const struct managesieve_arg *arg,
+ const char **str_r)
+{
+ if (arg->type != MANAGESIEVE_ARG_ATOM)
+ return FALSE;
+
+ *str_r = arg->_data.str;
+ return TRUE;
+}
+
+bool managesieve_arg_get_number(const struct managesieve_arg *arg,
+ uoff_t *number_r)
+{
+ const char *data;
+ uoff_t num = 0;
+ size_t i;
+
+ if (arg->type != MANAGESIEVE_ARG_ATOM)
+ return FALSE;
+
+ data = arg->_data.str;
+ for (i = 0; i < arg->str_len; i++) {
+ uoff_t newnum;
+
+ if (data[i] < '0' || data[i] > '9')
+ return FALSE;
+
+ newnum = num*10 + (data[i] -'0');
+ if (newnum < num)
+ return FALSE;
+
+ num = newnum;
+ }
+
+ *number_r = num;
+ return TRUE;
+}
+
+bool managesieve_arg_get_quoted(const struct managesieve_arg *arg,
+ const char **str_r)
+{
+ if (arg->type != MANAGESIEVE_ARG_STRING)
+ return FALSE;
+
+ *str_r = arg->_data.str;
+ return TRUE;
+}
+
+bool managesieve_arg_get_string(const struct managesieve_arg *arg,
+ const char **str_r)
+{
+ if (arg->type != MANAGESIEVE_ARG_STRING &&
+ arg->type != MANAGESIEVE_ARG_LITERAL)
+ return FALSE;
+
+ *str_r = arg->_data.str;
+ return TRUE;
+}
+
+bool managesieve_arg_get_string_stream(const struct managesieve_arg *arg,
+ struct istream **stream_r)
+{
+ if (arg->type != MANAGESIEVE_ARG_STRING_STREAM)
+ return FALSE;
+
+ *stream_r = arg->_data.str_stream;
+ return TRUE;
+}
+
+bool managesieve_arg_get_list(const struct managesieve_arg *arg,
+ const struct managesieve_arg **list_r)
+{
+ unsigned int count;
+
+ return managesieve_arg_get_list_full(arg, list_r, &count);
+}
+
+bool managesieve_arg_get_list_full(const struct managesieve_arg *arg,
+ const struct managesieve_arg **list_r,
+ unsigned int *list_count_r)
+{
+ unsigned int count;
+
+ if (arg->type != MANAGESIEVE_ARG_LIST)
+ return FALSE;
+
+ *list_r = array_get(&arg->_data.list, &count);
+
+ /* drop MANAGESIEVE_ARG_EOL from list size */
+ i_assert(count > 0);
+ *list_count_r = count - 1;
+ return TRUE;
+}
+
+const char *managesieve_arg_as_atom(const struct managesieve_arg *arg)
+{
+ const char *str;
+
+ if (!managesieve_arg_get_atom(arg, &str))
+ i_unreached();
+ return str;
+}
+
+const char *managesieve_arg_as_string(const struct managesieve_arg *arg)
+{
+ const char *str;
+
+ if (!managesieve_arg_get_string(arg, &str))
+ i_unreached();
+ return str;
+}
+
+struct istream *
+managesieve_arg_as_string_stream(const struct managesieve_arg *arg)
+{
+ struct istream *stream;
+
+ if (!managesieve_arg_get_string_stream(arg, &stream))
+ i_unreached();
+ return stream;
+}
+
+const struct managesieve_arg *
+managesieve_arg_as_list(const struct managesieve_arg *arg)
+{
+ const struct managesieve_arg *ret;
+
+ if (!managesieve_arg_get_list(arg, &ret))
+ i_unreached();
+ return ret;
+}
+
+bool managesieve_arg_atom_equals(const struct managesieve_arg *arg,
+ const char *str)
+{
+ const char *value;
+
+ if (!managesieve_arg_get_atom(arg, &value))
+ return FALSE;
+ return strcasecmp(value, str) == 0;
+}
+
+void managesieve_write_arg(string_t *dest, const struct managesieve_arg *arg)
+{
+ const char *strval;
+
+ switch (arg->type) {
+ case MANAGESIEVE_ARG_ATOM:
+ str_append(dest, managesieve_arg_as_atom(arg));
+ break;
+ case MANAGESIEVE_ARG_STRING:
+ strval = managesieve_arg_as_string(arg);
+ str_append_c(dest, '"');
+ str_append_escaped(dest, strval, strlen(strval));
+ str_append_c(dest, '"');
+ break;
+ case MANAGESIEVE_ARG_STRING_STREAM:
+ str_append(dest, "\"<too large>\"");
+ break;
+ case MANAGESIEVE_ARG_LITERAL: {
+ const char *strarg = managesieve_arg_as_string(arg);
+ str_printfa(dest, "{%zu}\r\n",
+ strlen(strarg));
+ str_append(dest, strarg);
+ break;
+ }
+ case MANAGESIEVE_ARG_LIST:
+ str_append_c(dest, '(');
+ managesieve_write_args(dest, managesieve_arg_as_list(arg));
+ str_append_c(dest, ')');
+ break;
+ case MANAGESIEVE_ARG_NONE:
+ case MANAGESIEVE_ARG_EOL:
+ i_unreached();
+ }
+}
+
+void managesieve_write_args(string_t *dest, const struct managesieve_arg *args)
+{
+ bool first = TRUE;
+
+ for (; !MANAGESIEVE_ARG_IS_EOL(args); args++) {
+ if (first)
+ first = FALSE;
+ else
+ str_append_c(dest, ' ');
+ managesieve_write_arg(dest, args);
+ }
+}
+
+const char *managesieve_args_to_str(const struct managesieve_arg *args)
+{
+ string_t *str;
+
+ str = t_str_new(128);
+ managesieve_write_args(str, args);
+ return str_c(str);
+}
+