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.
*/
* 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
#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. */
}
#endif /* def DEBUG */
+
+/*
+ * Determine whether or not a Config structure represents a session
+ * which can sensibly be launched right now.
+ */
+int cfg_launchable(const Config *cfg)
+{
+ if (cfg->protocol == PROT_SERIAL)
+ return cfg->serline[0] != 0;
+ else
+ return cfg->host[0] != 0;
+}
+
+char const *cfg_dest(const Config *cfg)
+{
+ if (cfg->protocol == PROT_SERIAL)
+ return cfg->serline;
+ else
+ return cfg->host;
+}