summaryrefslogtreecommitdiffstats
path: root/rfc2045/rfc2231encode.c
diff options
context:
space:
mode:
authorSam Varshavchik2013-08-19 16:39:41 -0400
committerSam Varshavchik2013-08-25 14:43:51 -0400
commit9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch)
tree7a81a04cb51efb078ee350859a64be2ebc6b8813 /rfc2045/rfc2231encode.c
parenta9520698b770168d1f33d6301463bb70a19655ec (diff)
downloadcourier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2
Initial checkin
Imported from subversion report, converted to git. Updated all paths in scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'rfc2045/rfc2231encode.c')
-rw-r--r--rfc2045/rfc2231encode.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/rfc2045/rfc2231encode.c b/rfc2045/rfc2231encode.c
new file mode 100644
index 0000000..941dffe
--- /dev/null
+++ b/rfc2045/rfc2231encode.c
@@ -0,0 +1,147 @@
+/*
+** Copyright 2002-2004 Double Precision, Inc. See COPYING for
+** distribution information.
+*/
+
+/*
+*/
+
+#if HAVE_CONFIG_H
+#include "rfc2045_config.h"
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "rfc2045.h"
+#include <errno.h>
+
+static const char xdigit[]="0123456789ABCDEFabcdef";
+
+#define DOENCODE(c) \
+ (strchr("()'\"\\%:;=", (c)) || (c) <= ' ' || (c) >= 127)
+
+static int docreate(const char *name,
+ char *attrvalue,
+ int (*cb_func)(const char *param,
+ const char *value,
+ void *void_arg),
+ void *cb_arg);
+
+int rfc2231_attrCreate(const char *name, const char *value,
+ const char *charset,
+ const char *language,
+ int (*cb_func)(const char *param,
+ const char *value,
+ void *void_arg),
+ void *cb_arg)
+{
+ size_t l;
+ const char *cp;
+ char *p, *q;
+ int rc;
+
+ if (strlen(name)>60)
+ {
+ errno=EINVAL;
+ return -1; /* You kidding me? */
+ }
+
+ for (l=0; value[l]; l++)
+ if (DOENCODE(value[l]))
+ break;
+
+ if (value[l] == 0 && strlen(name)+strlen(value)<75) /* No need to encode */
+ {
+ char *p=malloc(strlen(value)+3);
+
+ if (!p)
+ return -1;
+
+ strcat(strcat(strcpy(p, "\""), value), "\"");
+
+ rc=(*cb_func)(name, p, cb_arg);
+ free(p);
+ return rc;
+ }
+
+ if (!charset) charset="";
+ if (!language) language="";
+
+ l=strlen(charset)+strlen(language)+strlen(value)+3;
+
+ for (cp=value; *cp; cp++)
+ if (DOENCODE(*cp))
+ l += 2;
+
+ p=malloc(l);
+ if (!p)
+ return -1;
+
+ strcat(strcat(strcat(strcpy(p, charset), "'"),language), "'");
+ q=p+strlen(p);
+ for (cp=value; *cp; cp++)
+ {
+ if (DOENCODE(*cp))
+ {
+ *q++='%';
+ *q++ = xdigit[ ((unsigned char)*cp / 16) & 15];
+ *q++ = xdigit[ *cp & 15];
+ }
+ else
+ *q++= *cp;
+ }
+ *q=0;
+
+ rc=docreate(name, p, cb_func, cb_arg);
+ free(p);
+ return rc;
+}
+
+static int docreate(const char *name,
+ char *q,
+ int (*cb_func)(const char *param,
+ const char *value,
+ void *void_arg),
+ void *cb_arg)
+{
+ char c;
+ char *r;
+ int rc;
+ size_t l;
+ int n;
+
+ r=malloc(strlen(name)+20);
+ if (!r)
+ return -1;
+
+ rc=0;
+ n=0;
+
+ while (*q)
+ {
+ sprintf(r, "%s*%d*", name, n++);
+
+ l=strlen(q);
+ if (l > 70-strlen(r))
+ l=70-strlen(r);
+
+ if (q[l] == '%')
+ l += 3;
+ else if (l && q[l-1] == '%')
+ l += 2;
+ else if (l > 1 && q[l-2] == '%')
+ l += 1;
+
+ c=q[l];
+ q[l]=0;
+
+ rc=(*cb_func)(r, q, cb_arg);
+ if (rc)
+ break;
+ q[l]=c;
+ q += l;
+ }
+ free(r);
+ return rc;
+}