X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=misc.c;h=ed6290f52eee9eb81af4ea5bbf65021fe039f929;hb=19aefec3e8b33f12e6edbead1028c07b5f486ce0;hp=d40f99017e74284ccacccb930ebb4dab9d750e73;hpb=cac650b8a56a362b5fc8f6309ad83734bf6a71e5;p=PuTTY.git diff --git a/misc.c b/misc.c index d40f9901..ed6290f5 100644 --- a/misc.c +++ b/misc.c @@ -9,6 +9,7 @@ #include #include #include "putty.h" +#include "misc.h" /* * Parse a string block size specification. This is approximately a @@ -174,7 +175,7 @@ int main(void) return fails != 0 ? 1 : 0; } /* Stubs to stop the rest of this module causing compile failures. */ -void modalfatalbox(char *fmt, ...) {} +void modalfatalbox(const char *fmt, ...) {} int conf_get_int(Conf *conf, int primary) { return 0; } char *conf_get_str(Conf *conf, int primary) { return NULL; } #endif /* TEST_HOST_STRFOO */ @@ -393,25 +394,19 @@ int toint(unsigned u) * directive we don't know about, we should panic and die rather * than run any risk. */ -char *dupprintf(const char *fmt, ...) -{ - char *ret; - va_list ap; - va_start(ap, fmt); - ret = dupvprintf(fmt, ap); - va_end(ap); - return ret; -} -char *dupvprintf(const char *fmt, va_list ap) +static char *dupvprintf_inner(char *buf, int oldlen, int oldsize, + const char *fmt, va_list ap) { - char *buf; int len, size; - buf = snewn(512, char); - size = 512; + size = oldsize - oldlen; + if (size == 0) { + size = 512; + buf = sresize(buf, oldlen + size, char); + } while (1) { -#ifdef _WINDOWS +#if defined _WINDOWS && _MSC_VER < 1900 /* 1900 == VS2015 has real snprintf */ #define vsnprintf _vsnprintf #endif #ifdef va_copy @@ -419,7 +414,7 @@ char *dupvprintf(const char *fmt, va_list ap) * XXX some environments may have this as __va_copy() */ va_list aq; va_copy(aq, ap); - len = vsnprintf(buf, size, fmt, aq); + len = vsnprintf(buf + oldlen, size, fmt, aq); va_end(aq); #else /* Ugh. No va_copy macro, so do something nasty. @@ -430,7 +425,7 @@ char *dupvprintf(const char *fmt, va_list ap) * (indeed, it has been observed to). * XXX the autoconf manual suggests that using memcpy() will give * "maximum portability". */ - len = vsnprintf(buf, size, fmt, ap); + len = vsnprintf(buf + oldlen, size, fmt, ap); #endif if (len >= 0 && len < size) { /* This is the C99-specified criterion for snprintf to have @@ -445,10 +440,65 @@ char *dupvprintf(const char *fmt, va_list ap) * buffer wasn't big enough, so we enlarge it a bit and hope. */ size += 512; } - buf = sresize(buf, size, char); + buf = sresize(buf, oldlen + size, char); } } +char *dupvprintf(const char *fmt, va_list ap) +{ + return dupvprintf_inner(NULL, 0, 0, fmt, ap); +} +char *dupprintf(const char *fmt, ...) +{ + char *ret; + va_list ap; + va_start(ap, fmt); + ret = dupvprintf(fmt, ap); + va_end(ap); + return ret; +} + +struct strbuf { + char *s; + int len, size; +}; +strbuf *strbuf_new(void) +{ + strbuf *buf = snew(strbuf); + buf->len = 0; + buf->size = 512; + buf->s = snewn(buf->size, char); + *buf->s = '\0'; + return buf; +} +void strbuf_free(strbuf *buf) +{ + sfree(buf->s); + sfree(buf); +} +char *strbuf_str(strbuf *buf) +{ + return buf->s; +} +char *strbuf_to_str(strbuf *buf) +{ + char *ret = buf->s; + sfree(buf); + return ret; +} +void strbuf_catfv(strbuf *buf, const char *fmt, va_list ap) +{ + buf->s = dupvprintf_inner(buf->s, buf->len, buf->size, fmt, ap); + buf->len += strlen(buf->s + buf->len); +} +void strbuf_catf(strbuf *buf, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + strbuf_catfv(buf, fmt, ap); + va_end(ap); +} + /* * Read an entire line of text from a file. Return a buffer * malloced to be as big as necessary (caller must free). @@ -472,11 +522,29 @@ char *fgetline(FILE *fp) return ret; } +/* + * Perl-style 'chomp', for a line we just read with fgetline. Unlike + * Perl chomp, however, we're deliberately forgiving of strange + * line-ending conventions. Also we forgive NULL on input, so you can + * just write 'line = chomp(fgetline(fp));' and not bother checking + * for NULL until afterwards. + */ +char *chomp(char *str) +{ + if (str) { + int len = strlen(str); + while (len > 0 && (str[len-1] == '\r' || str[len-1] == '\n')) + len--; + str[len] = '\0'; + } + return str; +} + /* ---------------------------------------------------------------------- * Core base64 encoding and decoding routines. */ -void base64_encode_atom(unsigned char *data, int n, char *out) +void base64_encode_atom(const unsigned char *data, int n, char *out) { static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -500,7 +568,7 @@ void base64_encode_atom(unsigned char *data, int n, char *out) out[3] = '='; } -int base64_decode_atom(char *atom, unsigned char *out) +int base64_decode_atom(const char *atom, unsigned char *out) { int vals[4]; int i, v, len; @@ -811,9 +879,9 @@ void safefree(void *ptr) */ #ifdef DEBUG -extern void dputs(char *); /* defined in per-platform *misc.c */ +extern void dputs(const char *); /* defined in per-platform *misc.c */ -void debug_printf(char *fmt, ...) +void debug_printf(const char *fmt, ...) { char *buf; va_list ap; @@ -826,15 +894,15 @@ void debug_printf(char *fmt, ...) } -void debug_memdump(void *buf, int len, int L) +void debug_memdump(const void *buf, int len, int L) { int i; - unsigned char *p = buf; + const unsigned char *p = buf; char foo[17]; if (L) { int delta; debug_printf("\t%d (0x%x) bytes:\n", len, len); - delta = 15 & (unsigned long int) p; + delta = 15 & (uintptr_t)p; p -= delta; len += delta; } @@ -1036,6 +1104,39 @@ int smemeq(const void *av, const void *bv, size_t len) return (0x100 - val) >> 8; } +int match_ssh_id(int stringlen, const void *string, const char *id) +{ + int idlen = strlen(id); + return (idlen == stringlen && !memcmp(string, id, idlen)); +} + +void *get_ssh_string(int *datalen, const void **data, int *stringlen) +{ + void *ret; + unsigned int len; + + if (*datalen < 4) + return NULL; + len = GET_32BIT_MSB_FIRST((const unsigned char *)*data); + if (*datalen < len+4) + return NULL; + ret = (void *)((const char *)*data + 4); + *datalen -= len + 4; + *data = (const char *)*data + len + 4; + *stringlen = len; + return ret; +} + +int get_ssh_uint32(int *datalen, const void **data, unsigned *ret) +{ + if (*datalen < 4) + return FALSE; + *ret = GET_32BIT_MSB_FIRST((const unsigned char *)*data); + *datalen -= 4; + *data = (const char *)*data + 4; + return TRUE; +} + int strstartswith(const char *s, const char *t) { return !memcmp(s, t, strlen(t)); @@ -1046,3 +1147,68 @@ int strendswith(const char *s, const char *t) size_t slen = strlen(s), tlen = strlen(t); return slen >= tlen && !strcmp(s + (slen - tlen), t); } + +char *buildinfo(const char *newline) +{ + strbuf *buf = strbuf_new(); + extern const char commitid[]; /* in commitid.c */ + + strbuf_catf(buf, "Build platform: %d-bit %s", + (int)(CHAR_BIT * sizeof(void *)), + BUILDINFO_PLATFORM); + +#ifdef __clang_version__ + strbuf_catf(buf, "%sCompiler: clang %s", newline, __clang_version__); +#elif defined __GNUC__ && defined __VERSION__ + strbuf_catf(buf, "%sCompiler: gcc %s", newline, __VERSION__); +#elif defined _MSC_VER + strbuf_catf(buf, "%sCompiler: Visual Studio", newline); +#if _MSC_VER == 1900 + strbuf_catf(buf, " 2015 / MSVC++ 14.0"); +#elif _MSC_VER == 1800 + strbuf_catf(buf, " 2013 / MSVC++ 12.0"); +#elif _MSC_VER == 1700 + strbuf_catf(buf, " 2012 / MSVC++ 11.0"); +#elif _MSC_VER == 1600 + strbuf_catf(buf, " 2010 / MSVC++ 10.0"); +#elif _MSC_VER == 1500 + strbuf_catf(buf, " 2008 / MSVC++ 9.0"); +#elif _MSC_VER == 1400 + strbuf_catf(buf, " 2005 / MSVC++ 8.0"); +#elif _MSC_VER == 1310 + strbuf_catf(buf, " 2003 / MSVC++ 7.1"); +#else + strbuf_catf(buf, ", unrecognised version"); +#endif + strbuf_catf(buf, " (_MSC_VER=%d)", (int)_MSC_VER); +#endif + +#ifdef NO_SECURITY + strbuf_catf(buf, "%sBuild option: NO_SECURITY", newline); +#endif +#ifdef NO_SECUREZEROMEMORY + strbuf_catf(buf, "%sBuild option: NO_SECUREZEROMEMORY", newline); +#endif +#ifdef NO_IPV6 + strbuf_catf(buf, "%sBuild option: NO_IPV6", newline); +#endif +#ifdef NO_GSSAPI + strbuf_catf(buf, "%sBuild option: NO_GSSAPI", newline); +#endif +#ifdef STATIC_GSSAPI + strbuf_catf(buf, "%sBuild option: STATIC_GSSAPI", newline); +#endif +#ifdef UNPROTECT + strbuf_catf(buf, "%sBuild option: UNPROTECT", newline); +#endif +#ifdef FUZZING + strbuf_catf(buf, "%sBuild option: FUZZING", newline); +#endif +#ifdef DEBUG + strbuf_catf(buf, "%sBuild option: DEBUG", newline); +#endif + + strbuf_catf(buf, "%sSource commit: %s", newline, commitid); + + return strbuf_to_str(buf); +}