summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2005-06-16 13:18:34 +1000
committerDamien Miller <djm@mindrot.org>2005-06-16 13:18:34 +1000
commit6476cad9bb6b8a9524a153639b4ebceb3427e743 (patch)
tree59e9068c25f8d9c6d7e51f66e3c8c983c52db0d9 /misc.c
parent05656967b111a7c2b1f831eab0c31002dfac6fa9 (diff)
downloadopenssh-git-6476cad9bb6b8a9524a153639b4ebceb3427e743.tar.gz
- djm@cvs.openbsd.org 2005/06/06 11:20:36
[auth.c auth.h misc.c misc.h ssh.c ssh_config.5 sshconnect.c] introduce a generic %foo expansion function. replace existing % expansion and add expansion to ControlPath; ok markus@
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/misc.c b/misc.c
index 4bc07a42..fc094f87 100644
--- a/misc.c
+++ b/misc.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
+ * Copyright (c) 2005 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,7 +24,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: misc.c,v 1.30 2005/04/09 04:32:54 djm Exp $");
+RCSID("$OpenBSD: misc.c,v 1.31 2005/06/06 11:20:36 djm Exp $");
#include "misc.h"
#include "log.h"
@@ -421,6 +422,68 @@ tilde_expand_filename(const char *filename, uid_t uid)
}
/*
+ * Expand a string with a set of %[char] escapes. A number of escapes may be
+ * specified as (char *escape_chars, char *replacement) pairs. The list must
+ * be terminated by an escape_char of -1. Returns replaced string in memory
+ * allocated by xmalloc.
+ */
+char *
+percent_expand(const char *string, ...)
+{
+#define EXPAND_MAX_KEYS 16
+ struct {
+ const char *key;
+ const char *repl;
+ } keys[EXPAND_MAX_KEYS];
+ int num_keys, i, j;
+ char buf[4096];
+ va_list ap;
+
+ /* Gather keys */
+ va_start(ap, string);
+ for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) {
+ keys[num_keys].key = va_arg(ap, char *);
+ if (keys[num_keys].key == NULL)
+ break;
+ keys[num_keys].repl = va_arg(ap, char *);
+ if (keys[num_keys].repl == NULL)
+ fatal("percent_expand: NULL replacement");
+ }
+ va_end(ap);
+
+ if (num_keys >= EXPAND_MAX_KEYS)
+ fatal("percent_expand: too many keys");
+
+ /* Expand string */
+ *buf = '\0';
+ for (i = 0; *string != '\0'; string++) {
+ if (*string != '%') {
+ append:
+ buf[i++] = *string;
+ if (i >= sizeof(buf))
+ fatal("percent_expand: string too long");
+ buf[i] = '\0';
+ continue;
+ }
+ string++;
+ if (*string == '%')
+ goto append;
+ for (j = 0; j < num_keys; j++) {
+ if (strchr(keys[j].key, *string) != NULL) {
+ i = strlcat(buf, keys[j].repl, sizeof(buf));
+ if (i >= sizeof(buf))
+ fatal("percent_expand: string too long");
+ break;
+ }
+ }
+ if (j >= num_keys)
+ fatal("percent_expand: unknown key %%%c", *string);
+ }
+ return (xstrdup(buf));
+#undef EXPAND_MAX_KEYS
+}
+
+/*
* Read an entire line from a public key file into a static buffer, discarding
* lines that exceed the buffer size. Returns 0 on success, -1 on failure.
*/