summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c128
1 files changed, 127 insertions, 1 deletions
diff --git a/misc.c b/misc.c
index 7adbcea1c..2dd8ae6e3 100644
--- a/misc.c
+++ b/misc.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2000 Markus Friedl. All rights reserved. 2 * Copyright (c) 2000 Markus Friedl. All rights reserved.
3 * Copyright (c) 2005 Damien Miller. All rights reserved.
3 * 4 *
4 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -23,7 +24,7 @@
23 */ 24 */
24 25
25#include "includes.h" 26#include "includes.h"
26RCSID("$OpenBSD: misc.c,v 1.29 2005/03/10 22:01:05 deraadt Exp $"); 27RCSID("$OpenBSD: misc.c,v 1.34 2005/07/08 09:26:18 dtucker Exp $");
27 28
28#include "misc.h" 29#include "misc.h"
29#include "log.h" 30#include "log.h"
@@ -376,6 +377,114 @@ addargs(arglist *args, char *fmt, ...)
376} 377}
377 378
378/* 379/*
380 * Expands tildes in the file name. Returns data allocated by xmalloc.
381 * Warning: this calls getpw*.
382 */
383char *
384tilde_expand_filename(const char *filename, uid_t uid)
385{
386 const char *path;
387 char user[128], ret[MAXPATHLEN];
388 struct passwd *pw;
389 u_int len, slash;
390
391 if (*filename != '~')
392 return (xstrdup(filename));
393 filename++;
394
395 path = strchr(filename, '/');
396 if (path != NULL && path > filename) { /* ~user/path */
397 slash = path - filename;
398 if (slash > sizeof(user) - 1)
399 fatal("tilde_expand_filename: ~username too long");
400 memcpy(user, filename, slash);
401 user[slash] = '\0';
402 if ((pw = getpwnam(user)) == NULL)
403 fatal("tilde_expand_filename: No such user %s", user);
404 } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */
405 fatal("tilde_expand_filename: No such uid %d", uid);
406
407 if (strlcpy(ret, pw->pw_dir, sizeof(ret)) >= sizeof(ret))
408 fatal("tilde_expand_filename: Path too long");
409
410 /* Make sure directory has a trailing '/' */
411 len = strlen(pw->pw_dir);
412 if ((len == 0 || pw->pw_dir[len - 1] != '/') &&
413 strlcat(ret, "/", sizeof(ret)) >= sizeof(ret))
414 fatal("tilde_expand_filename: Path too long");
415
416 /* Skip leading '/' from specified path */
417 if (path != NULL)
418 filename = path + 1;
419 if (strlcat(ret, filename, sizeof(ret)) >= sizeof(ret))
420 fatal("tilde_expand_filename: Path too long");
421
422 return (xstrdup(ret));
423}
424
425/*
426 * Expand a string with a set of %[char] escapes. A number of escapes may be
427 * specified as (char *escape_chars, char *replacement) pairs. The list must
428 * be terminated by a NULL escape_char. Returns replaced string in memory
429 * allocated by xmalloc.
430 */
431char *
432percent_expand(const char *string, ...)
433{
434#define EXPAND_MAX_KEYS 16
435 struct {
436 const char *key;
437 const char *repl;
438 } keys[EXPAND_MAX_KEYS];
439 u_int num_keys, i, j;
440 char buf[4096];
441 va_list ap;
442
443 /* Gather keys */
444 va_start(ap, string);
445 for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) {
446 keys[num_keys].key = va_arg(ap, char *);
447 if (keys[num_keys].key == NULL)
448 break;
449 keys[num_keys].repl = va_arg(ap, char *);
450 if (keys[num_keys].repl == NULL)
451 fatal("percent_expand: NULL replacement");
452 }
453 va_end(ap);
454
455 if (num_keys >= EXPAND_MAX_KEYS)
456 fatal("percent_expand: too many keys");
457
458 /* Expand string */
459 *buf = '\0';
460 for (i = 0; *string != '\0'; string++) {
461 if (*string != '%') {
462 append:
463 buf[i++] = *string;
464 if (i >= sizeof(buf))
465 fatal("percent_expand: string too long");
466 buf[i] = '\0';
467 continue;
468 }
469 string++;
470 if (*string == '%')
471 goto append;
472 for (j = 0; j < num_keys; j++) {
473 if (strchr(keys[j].key, *string) != NULL) {
474 i = strlcat(buf, keys[j].repl, sizeof(buf));
475 if (i >= sizeof(buf))
476 fatal("percent_expand: string too long");
477 break;
478 }
479 }
480 if (j >= num_keys)
481 fatal("percent_expand: unknown key %%%c", *string);
482 }
483 return (xstrdup(buf));
484#undef EXPAND_MAX_KEYS
485}
486
487/*
379 * Read an entire line from a public key file into a static buffer, discarding 488 * Read an entire line from a public key file into a static buffer, discarding
380 * lines that exceed the buffer size. Returns 0 on success, -1 on failure. 489 * lines that exceed the buffer size. Returns 0 on success, -1 on failure.
381 */ 490 */
@@ -397,3 +506,20 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
397 } 506 }
398 return -1; 507 return -1;
399} 508}
509
510char *
511tohex(const u_char *d, u_int l)
512{
513 char b[3], *r;
514 u_int i, hl;
515
516 hl = l * 2 + 1;
517 r = xmalloc(hl);
518 *r = '\0';
519 for (i = 0; i < l; i++) {
520 snprintf(b, sizeof(b), "%02x", d[i]);
521 strlcat(r, b, hl);
522 }
523 return (r);
524}
525