Install public header files again and include required prototypes.
[ira/wip.git] / source4 / lib / util / dprintf.c
index 62dc2a227a168f13fb04019d04828ca11d3b13a9..e4f02758eb8e0c99c610a2dd4695329c42fa314c 100644 (file)
@@ -2,10 +2,11 @@
    Unix SMB/CIFS implementation.
    display print functions
    Copyright (C) Andrew Tridgell 2001
+   Copyright (C) Jelmer Vernooij 2007
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 
 /*
-  this module provides functions for printing internal strings in the "display charset"
-  This charset may be quite different from the chosen unix charset
+  this module provides functions for printing internal strings in the 
+  "display charset".
+  
+  This charset may be quite different from the chosen unix charset.
 
   Eventually these functions will need to take care of column count constraints
 
 */
 
 #include "includes.h"
+#include "system/locale.h"
+#include "param/param.h"
 
-_PUBLIC_ int d_vfprintf(FILE *f, const char *format, va_list ap) _PRINTF_ATTRIBUTE(2,0)
+static smb_iconv_t display_cd = (smb_iconv_t)-1;
+
+void d_set_iconv(smb_iconv_t cd)
+{
+       display_cd = cd;
+}
+
+_PUBLIC_ int d_vfprintf(FILE *f, const char *format, va_list ap) 
 {
        char *p, *p2;
-       int ret, maxlen, clen;
+       int ret, clen;
        va_list ap2;
 
+       /* If there's nothing to convert, take a shortcut */
+       if (display_cd == (smb_iconv_t)-1) {
+               return vfprintf(f, format, ap);
+       }
+
        /* do any message translations */
        va_copy(ap2, ap);
-
        ret = vasprintf(&p, format, ap2);
+       va_end(ap2);
 
        if (ret <= 0) return ret;
 
-       /* now we have the string in unix format, convert it to the display
-          charset, but beware of it growing */
-       maxlen = ret*2;
-again:
-       p2 = malloc(maxlen);
-       if (!p2) {
+       clen = convert_string_talloc_descriptor(NULL, display_cd, p, ret, (void **)&p2);
+        if (clen == -1) {
+               /* the string can't be converted - do the best we can,
+                  filling in non-printing chars with '?' */
+               int i;
+               for (i=0;i<ret;i++) {
+                       if (isprint(p[i]) || isspace(p[i])) {
+                               fwrite(p+i, 1, 1, f);
+                       } else {
+                               fwrite("?", 1, 1, f);
+                       }
+               }
                SAFE_FREE(p);
-               return -1;
-       }
-       clen = convert_string(CH_UNIX, CH_DISPLAY, p, ret, p2, maxlen);
-
-       if (clen >= maxlen) {
-               /* it didn't fit - try a larger buffer */
-               maxlen *= 2;
-               SAFE_FREE(p2);
-               goto again;
-       }
+               return ret;
+        }
 
        /* good, its converted OK */
        SAFE_FREE(p);
        ret = fwrite(p2, 1, clen, f);
-       SAFE_FREE(p2);
+       talloc_free(p2);
 
        return ret;
 }
 
 
-_PUBLIC_ int d_fprintf(FILE *f, const char *format, ...) _PRINTF_ATTRIBUTE(2,3)
+_PUBLIC_ int d_fprintf(FILE *f, const char *format, ...) 
 {
        int ret;
        va_list ap;
@@ -83,25 +97,15 @@ _PUBLIC_ int d_fprintf(FILE *f, const char *format, ...) _PRINTF_ATTRIBUTE(2,3)
        return ret;
 }
 
-static FILE *outfile;
-
-_PUBLIC_ int d_printf(const char *format, ...) _PRINTF_ATTRIBUTE(1,2)
+_PUBLIC_ int d_printf(const char *format, ...)
 {
        int ret;
        va_list ap;
 
-       if (!outfile) outfile = stdout;
-       
        va_start(ap, format);
-       ret = d_vfprintf(outfile, format, ap);
+       ret = d_vfprintf(stdout, format, ap);
        va_end(ap);
 
        return ret;
 }
 
-/* interactive programs need a way of tell d_*() to write to stderr instead
-   of stdout */
-_PUBLIC_ void display_set_stderr(void)
-{
-       outfile = stderr;
-}