]> andersk Git - gssapi-openssh.git/blobdiff - openssh/misc.c
merged OpenSSH 4.2p1 to trunk
[gssapi-openssh.git] / openssh / misc.c
index dba91e606f1853bbc8414b35c5aff864734483cb..3f0478632bd480e98c3fef5003a5cdee4f62e675 100644 (file)
@@ -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.29 2005/03/10 22:01:05 deraadt Exp $");
+RCSID("$OpenBSD: misc.c,v 1.34 2005/07/08 09:26:18 dtucker Exp $");
 
 #include "misc.h"
 #include "log.h"
@@ -393,6 +394,114 @@ addargs(arglist *args, char *fmt, ...)
        args->list[args->num] = NULL;
 }
 
+/*
+ * Expands tildes in the file name.  Returns data allocated by xmalloc.
+ * Warning: this calls getpw*.
+ */
+char *
+tilde_expand_filename(const char *filename, uid_t uid)
+{
+       const char *path;
+       char user[128], ret[MAXPATHLEN];
+       struct passwd *pw;
+       u_int len, slash;
+
+       if (*filename != '~')
+               return (xstrdup(filename));
+       filename++;
+
+       path = strchr(filename, '/');
+       if (path != NULL && path > filename) {          /* ~user/path */
+               slash = path - filename;
+               if (slash > sizeof(user) - 1)
+                       fatal("tilde_expand_filename: ~username too long");
+               memcpy(user, filename, slash);
+               user[slash] = '\0';
+               if ((pw = getpwnam(user)) == NULL)
+                       fatal("tilde_expand_filename: No such user %s", user);
+       } else if ((pw = getpwuid(uid)) == NULL)        /* ~/path */
+               fatal("tilde_expand_filename: No such uid %d", uid);
+
+       if (strlcpy(ret, pw->pw_dir, sizeof(ret)) >= sizeof(ret))
+               fatal("tilde_expand_filename: Path too long");
+
+       /* Make sure directory has a trailing '/' */
+       len = strlen(pw->pw_dir);
+       if ((len == 0 || pw->pw_dir[len - 1] != '/') &&
+           strlcat(ret, "/", sizeof(ret)) >= sizeof(ret))
+               fatal("tilde_expand_filename: Path too long");
+
+       /* Skip leading '/' from specified path */
+       if (path != NULL)
+               filename = path + 1;
+       if (strlcat(ret, filename, sizeof(ret)) >= sizeof(ret))
+               fatal("tilde_expand_filename: Path too long");
+
+       return (xstrdup(ret));
+}
+
+/*
+ * 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 a NULL escape_char. 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];
+       u_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.
@@ -415,3 +524,20 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
        }
        return -1;
 }
+
+char *
+tohex(const u_char *d, u_int l)
+{
+       char b[3], *r;
+       u_int i, hl;
+
+       hl = l * 2 + 1;
+       r = xmalloc(hl);
+       *r = '\0';
+       for (i = 0; i < l; i++) {
+               snprintf(b, sizeof(b), "%02x", d[i]);
+               strlcat(r, b, hl);
+       }
+       return (r);
+}
+
This page took 0.041047 seconds and 4 git commands to generate.