diff options
Diffstat (limited to 'misc.c')
-rw-r--r-- | misc.c | 128 |
1 files changed, 127 insertions, 1 deletions
@@ -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" |
26 | RCSID("$OpenBSD: misc.c,v 1.29 2005/03/10 22:01:05 deraadt Exp $"); | 27 | RCSID("$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 | */ | ||
383 | char * | ||
384 | tilde_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 | */ | ||
431 | char * | ||
432 | percent_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 | |||
510 | char * | ||
511 | tohex(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 | |||