+/* ----------------------------------------------------------------------
+ * String handling routines.
+ */
+
+char *dupstr(char *s)
+{
+ int len = strlen(s);
+ char *p = smalloc(len + 1);
+ strcpy(p, s);
+ return p;
+}
+
+/* Allocate the concatenation of N strings. Terminate arg list with NULL. */
+char *dupcat(char *s1, ...)
+{
+ int len;
+ char *p, *q, *sn;
+ va_list ap;
+
+ len = strlen(s1);
+ va_start(ap, s1);
+ while (1) {
+ sn = va_arg(ap, char *);
+ if (!sn)
+ break;
+ len += strlen(sn);
+ }
+ va_end(ap);
+
+ p = smalloc(len + 1);
+ strcpy(p, s1);
+ q = p + strlen(p);
+
+ va_start(ap, s1);
+ while (1) {
+ sn = va_arg(ap, char *);
+ if (!sn)
+ break;
+ strcpy(q, sn);
+ q += strlen(q);
+ }
+ va_end(ap);
+
+ return p;
+}
+
+/* ----------------------------------------------------------------------
+ * Base64 encoding routine. This is required in public-key writing
+ * but also in HTTP proxy handling, so it's centralised here.
+ */
+
+void base64_encode_atom(unsigned char *data, int n, char *out)
+{
+ static const char base64_chars[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ unsigned word;
+
+ word = data[0] << 16;
+ if (n > 1)
+ word |= data[1] << 8;
+ if (n > 2)
+ word |= data[2];
+ out[0] = base64_chars[(word >> 18) & 0x3F];
+ out[1] = base64_chars[(word >> 12) & 0x3F];
+ if (n > 1)
+ out[2] = base64_chars[(word >> 6) & 0x3F];
+ else
+ out[2] = '=';
+ if (n > 2)
+ out[3] = base64_chars[word & 0x3F];
+ else
+ out[3] = '=';
+}
+
+/* ----------------------------------------------------------------------