int d_vfprintf(FILE *f, const char *format, va_list ap) { char *p = NULL, *p2 = NULL; int ret, maxlen, clen; const char *msgstr; va_list ap2; va_copy(ap2, ap); /* do any message translations */ msgstr = lang_msg(format); if (!msgstr) { ret = -1; goto out; } ret = vasprintf(&p, msgstr, ap2); lang_msg_free(msgstr); if (ret <= 0) { ret = -1; goto out; } /* now we have the string in unix format, convert it to the display charset, but beware of it growing */ maxlen = ret*2; again: p2 = (char *)SMB_MALLOC(maxlen); if (!p2) { ret = -1; goto out; } clen = convert_string(CH_UNIX, CH_DISPLAY, p, ret, p2, maxlen, True); if (clen == -1) { ret = -1; goto out; } if (clen >= maxlen) { /* it didn't fit - try a larger buffer */ maxlen *= 2; SAFE_FREE(p2); goto again; } /* good, its converted OK */ ret = fwrite(p2, 1, clen, f); out: SAFE_FREE(p); SAFE_FREE(p2); va_end(ap2); return ret; }
/* when the _() translation macro is used there is no obvious place to free the resulting string and there is no easy way to give a static pointer. All we can do is rotate between some static buffers and hope a single d_printf() doesn't have more calls to _() than the number of buffers */ const char *lang_msg_rotate(const char *msgid) { #define NUM_LANG_BUFS 16 char *msgstr; static pstring bufs[NUM_LANG_BUFS]; static int next; msgstr = (char *)lang_msg(msgid); if (!msgstr) return msgid; pstrcpy(bufs[next], msgstr); msgstr = bufs[next]; next = (next+1) % NUM_LANG_BUFS; return msgstr; }