version 1.1.1.2, 2012/05/29 12:26:49
|
version 1.1.1.6, 2014/06/15 16:12:54
|
Line 1
|
Line 1
|
/* |
/* |
* Copyright (c) 2007-2011 Todd C. Miller <Todd.Miller@courtesan.com> | * Copyright (c) 2007-2013 Todd C. Miller <Todd.Miller@courtesan.com> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
* purpose with or without fee is hereby granted, provided that the above |
* purpose with or without fee is hereby granted, provided that the above |
Line 19
|
Line 19
|
#include <config.h> |
#include <config.h> |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/param.h> |
|
#include <stdio.h> |
#include <stdio.h> |
#ifdef STDC_HEADERS |
#ifdef STDC_HEADERS |
# include <stdlib.h> |
# include <stdlib.h> |
Line 45
|
Line 44
|
|
|
#include "missing.h" |
#include "missing.h" |
#include "alloc.h" |
#include "alloc.h" |
#include "error.h" | #include "fatal.h" |
#include "lbuf.h" |
#include "lbuf.h" |
#include "sudo_debug.h" |
#include "sudo_debug.h" |
|
|
Line 77 lbuf_destroy(struct lbuf *lbuf)
|
Line 76 lbuf_destroy(struct lbuf *lbuf)
|
debug_return; |
debug_return; |
} |
} |
|
|
|
static void |
|
lbuf_expand(struct lbuf *lbuf, int extra) |
|
{ |
|
if (lbuf->len + extra + 1 >= lbuf->size) { |
|
do { |
|
lbuf->size += 256; |
|
} while (lbuf->len + extra + 1 >= lbuf->size); |
|
lbuf->buf = erealloc(lbuf->buf, lbuf->size); |
|
} |
|
} |
|
|
/* |
/* |
* Parse the format and append strings, only %s and %% escapes are supported. |
* Parse the format and append strings, only %s and %% escapes are supported. |
* Any characters in set are quoted with a backslash. |
* Any characters in set are quoted with a backslash. |
Line 86 lbuf_append_quoted(struct lbuf *lbuf, const char *set,
|
Line 96 lbuf_append_quoted(struct lbuf *lbuf, const char *set,
|
{ |
{ |
va_list ap; |
va_list ap; |
int len; |
int len; |
char *cp, *s = NULL; | char *cp, *s; |
debug_decl(lbuf_append_quoted, SUDO_DEBUG_UTIL) |
debug_decl(lbuf_append_quoted, SUDO_DEBUG_UTIL) |
|
|
va_start(ap, fmt); |
va_start(ap, fmt); |
while (*fmt != '\0') { |
while (*fmt != '\0') { |
len = 1; |
|
if (fmt[0] == '%' && fmt[1] == 's') { |
if (fmt[0] == '%' && fmt[1] == 's') { |
s = va_arg(ap, char *); | if ((s = va_arg(ap, char *)) == NULL) |
len = strlen(s); | goto done; |
} | while ((cp = strpbrk(s, set)) != NULL) { |
/* Assume worst case that all chars must be escaped. */ | len = (int)(cp - s); |
if (lbuf->len + (len * 2) + 1 >= lbuf->size) { | lbuf_expand(lbuf, len + 2); |
do { | memcpy(lbuf->buf + lbuf->len, s, len); |
lbuf->size += 256; | lbuf->len += len; |
} while (lbuf->len + len + 1 >= lbuf->size); | lbuf->buf[lbuf->len++] = '\\'; |
lbuf->buf = erealloc(lbuf->buf, lbuf->size); | lbuf->buf[lbuf->len++] = *cp; |
} | s = cp + 1; |
if (*fmt == '%') { | |
if (*(++fmt) == 's') { | |
while ((cp = strpbrk(s, set)) != NULL) { | |
len = (int)(cp - s); | |
memcpy(lbuf->buf + lbuf->len, s, len); | |
lbuf->len += len; | |
lbuf->buf[lbuf->len++] = '\\'; | |
lbuf->buf[lbuf->len++] = *cp; | |
s = cp + 1; | |
} | |
if (*s != '\0') { | |
len = strlen(s); | |
memcpy(lbuf->buf + lbuf->len, s, len); | |
lbuf->len += len; | |
} | |
fmt++; | |
continue; | |
} |
} |
|
if (*s != '\0') { |
|
len = strlen(s); |
|
lbuf_expand(lbuf, len); |
|
memcpy(lbuf->buf + lbuf->len, s, len); |
|
lbuf->len += len; |
|
} |
|
fmt += 2; |
|
continue; |
} |
} |
|
lbuf_expand(lbuf, 2); |
if (strchr(set, *fmt) != NULL) |
if (strchr(set, *fmt) != NULL) |
lbuf->buf[lbuf->len++] = '\\'; |
lbuf->buf[lbuf->len++] = '\\'; |
lbuf->buf[lbuf->len++] = *fmt++; |
lbuf->buf[lbuf->len++] = *fmt++; |
} |
} |
lbuf->buf[lbuf->len] = '\0'; | done: |
| if (lbuf->size != 0) |
| lbuf->buf[lbuf->len] = '\0'; |
va_end(ap); |
va_end(ap); |
|
|
debug_return; |
debug_return; |
Line 140 lbuf_append(struct lbuf *lbuf, const char *fmt, ...)
|
Line 143 lbuf_append(struct lbuf *lbuf, const char *fmt, ...)
|
{ |
{ |
va_list ap; |
va_list ap; |
int len; |
int len; |
char *s = NULL; | char *s; |
debug_decl(lbuf_append, SUDO_DEBUG_UTIL) |
debug_decl(lbuf_append, SUDO_DEBUG_UTIL) |
|
|
va_start(ap, fmt); |
va_start(ap, fmt); |
while (*fmt != '\0') { |
while (*fmt != '\0') { |
len = 1; |
|
if (fmt[0] == '%' && fmt[1] == 's') { |
if (fmt[0] == '%' && fmt[1] == 's') { |
s = va_arg(ap, char *); | if ((s = va_arg(ap, char *)) == NULL) |
| goto done; |
len = strlen(s); |
len = strlen(s); |
|
lbuf_expand(lbuf, len); |
|
memcpy(lbuf->buf + lbuf->len, s, len); |
|
lbuf->len += len; |
|
fmt += 2; |
|
continue; |
} |
} |
if (lbuf->len + len + 1 >= lbuf->size) { | lbuf_expand(lbuf, 1); |
do { | |
lbuf->size += 256; | |
} while (lbuf->len + len + 1 >= lbuf->size); | |
lbuf->buf = erealloc(lbuf->buf, lbuf->size); | |
} | |
if (*fmt == '%') { | |
if (*(++fmt) == 's') { | |
memcpy(lbuf->buf + lbuf->len, s, len); | |
lbuf->len += len; | |
fmt++; | |
continue; | |
} | |
} | |
lbuf->buf[lbuf->len++] = *fmt++; |
lbuf->buf[lbuf->len++] = *fmt++; |
} |
} |
lbuf->buf[lbuf->len] = '\0'; | done: |
| if (lbuf->size != 0) |
| lbuf->buf[lbuf->len] = '\0'; |
va_end(ap); |
va_end(ap); |
|
|
debug_return; |
debug_return; |
Line 247 lbuf_print(struct lbuf *lbuf)
|
Line 244 lbuf_print(struct lbuf *lbuf)
|
/* For very small widths just give up... */ |
/* For very small widths just give up... */ |
len = lbuf->continuation ? strlen(lbuf->continuation) : 0; |
len = lbuf->continuation ? strlen(lbuf->continuation) : 0; |
if (lbuf->cols <= lbuf->indent + len + 20) { |
if (lbuf->cols <= lbuf->indent + len + 20) { |
lbuf->buf[lbuf->len] = '\0'; | if (lbuf->len > 0) { |
lbuf->output(lbuf->buf); | lbuf->buf[lbuf->len] = '\0'; |
| lbuf->output(lbuf->buf); |
| if (lbuf->buf[lbuf->len - 1] != '\n') |
| lbuf->output("\n"); |
| } |
goto done; |
goto done; |
} |
} |
|
|