X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/66ab14c717d6954a7fa5986c02b685271c6b5b64..4a693cfc5c3ee0e639bbee0215345e921715ab04:/misc.c diff --git a/misc.c b/misc.c index 9c8d2039..cf97c049 100644 --- a/misc.c +++ b/misc.c @@ -87,6 +87,46 @@ char ctrlparse(char *s, char **next) return c; } +prompts_t *new_prompts(void *frontend) +{ + prompts_t *p = snew(prompts_t); + p->prompts = NULL; + p->n_prompts = 0; + p->frontend = frontend; + p->data = NULL; + p->to_server = TRUE; /* to be on the safe side */ + p->name = p->instruction = NULL; + p->name_reqd = p->instr_reqd = FALSE; + return p; +} +void add_prompt(prompts_t *p, char *promptstr, int echo, size_t len) +{ + prompt_t *pr = snew(prompt_t); + char *result = snewn(len, char); + pr->prompt = promptstr; + pr->echo = echo; + pr->result = result; + pr->result_len = len; + p->n_prompts++; + p->prompts = sresize(p->prompts, p->n_prompts, prompt_t *); + p->prompts[p->n_prompts-1] = pr; +} +void free_prompts(prompts_t *p) +{ + size_t i; + for (i=0; i < p->n_prompts; i++) { + prompt_t *pr = p->prompts[i]; + memset(pr->result, 0, pr->result_len); /* burn the evidence */ + sfree(pr->result); + sfree(pr->prompt); + sfree(pr); + } + sfree(p->prompts); + sfree(p->name); + sfree(p->instruction); + sfree(p); +} + /* ---------------------------------------------------------------------- * String handling routines. */ @@ -140,20 +180,11 @@ char *dupcat(const char *s1, ...) * Do an sprintf(), but into a custom-allocated buffer. * * Currently I'm doing this via vsnprintf. This has worked so far, - * but it's not good, because: - * - * - vsnprintf is not available on all platforms. There's an ifdef - * to use `_vsnprintf', which seems to be the local name for it - * on Windows. Other platforms may lack it completely, in which - * case it'll be time to rewrite this function in a totally - * different way. - * - * - technically you can't reuse a va_list like this: it is left - * unspecified whether advancing a va_list pointer modifies its - * value or something it points to, so on some platforms calling - * vsnprintf twice on the same va_list might fail hideously. It - * would be better to use the `va_copy' macro mandated by C99, - * but that too is not yet ubiquitous. + * but it's not good, because vsnprintf is not available on all + * platforms. There's an ifdef to use `_vsnprintf', which seems + * to be the local name for it on Windows. Other platforms may + * lack it completely, in which case it'll be time to rewrite + * this function in a totally different way. * * The only `properly' portable solution I can think of is to * implement my own format string scanner, which figures out an @@ -201,7 +232,24 @@ char *dupvprintf(const char *fmt, va_list ap) #ifdef _WINDOWS #define vsnprintf _vsnprintf #endif +#ifdef va_copy + /* Use the `va_copy' macro mandated by C99, if present. + * XXX some environments may have this as __va_copy() */ + va_list aq; + va_copy(aq, ap); + len = vsnprintf(buf, size, fmt, aq); + va_end(aq); +#else + /* Ugh. No va_copy macro, so do something nasty. + * Technically, you can't reuse a va_list like this: it is left + * unspecified whether advancing a va_list pointer modifies its + * value or something it points to, so on some platforms calling + * vsnprintf twice on the same va_list might fail hideously + * (indeed, it has been observed to). + * XXX the autoconf manual suggests that using memcpy() will give + * "maximum portability". */ len = vsnprintf(buf, size, fmt, ap); +#endif if (len >= 0 && len < size) { /* This is the C99-specified criterion for snprintf to have * been completely successful. */ @@ -557,7 +605,7 @@ void debug_memdump(void *buf, int len, int L) if (L) { int delta; debug_printf("\t%d (0x%x) bytes:\n", len, len); - delta = 15 & (int) p; + delta = 15 & (unsigned long int) p; p -= delta; len += delta; } @@ -585,3 +633,23 @@ void debug_memdump(void *buf, int len, int L) } #endif /* def DEBUG */ + +/* + * Determine whether or not a Conf represents a session which can + * sensibly be launched right now. + */ +int conf_launchable(Conf *conf) +{ + if (conf_get_int(conf, CONF_protocol) == PROT_SERIAL) + return conf_get_str(conf, CONF_serline)[0] != 0; + else + return conf_get_str(conf, CONF_host)[0] != 0; +} + +char const *conf_dest(Conf *conf) +{ + if (conf_get_int(conf, CONF_protocol) == PROT_SERIAL) + return conf_get_str(conf, CONF_serline); + else + return conf_get_str(conf, CONF_host); +}