169783Smsmith/*
269783Smsmith * Copyright (c) 1995 - 2000 Kungliga Tekniska H��gskolan
369783Smsmith * (Royal Institute of Technology, Stockholm, Sweden).
469783Smsmith * All rights reserved.
569783Smsmith *
669783Smsmith * Redistribution and use in source and binary forms, with or without
769783Smsmith * modification, are permitted provided that the following conditions
869783Smsmith * are met:
969783Smsmith *
1069783Smsmith * 1. Redistributions of source code must retain the above copyright
1169783Smsmith *    notice, this list of conditions and the following disclaimer.
1269783Smsmith *
1369783Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1469783Smsmith *    notice, this list of conditions and the following disclaimer in the
1569783Smsmith *    documentation and/or other materials provided with the distribution.
1669783Smsmith *
1769783Smsmith * 3. Neither the name of the Institute nor the names of its contributors
1869783Smsmith *    may be used to endorse or promote products derived from this software
1969783Smsmith *    without specific prior written permission.
2069783Smsmith *
2169783Smsmith * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2269783Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2369783Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2469783Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2569783Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2669783Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2769783Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2869783Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2969783Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3069783Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31119418Sobrien * SUCH DAMAGE.
32119418Sobrien */
33119418Sobrien
3469783Smsmith#include <config.h>
3569783Smsmith
3669783Smsmith#ifndef HAVE_VSYSLOG
3769783Smsmith
3869783Smsmith#include <stdio.h>
3969783Smsmith#include <syslog.h>
4069783Smsmith#include <stdarg.h>
41129876Sphk
4269783Smsmith#include "roken.h"
43107546Simp
44107546Simp/*
45106844Smdodd * the theory behind this is that we might be trying to call vsyslog
4669783Smsmith * when there's no memory left, and we should try to be as useful as
4769783Smsmith * possible.  And the format string should say something about what's
4869783Smsmith * failing.
49119285Simp */
50119285Simp
51119285Simpstatic void
5269783Smsmithsimple_vsyslog(int pri, const char *fmt, va_list ap)
5369783Smsmith{
5469783Smsmith    syslog (pri, "%s", fmt);
5569783Smsmith}
5669783Smsmith
5769783Smsmith/*
5869783Smsmith * do like syslog but with a `va_list'
5969783Smsmith */
6069783Smsmith
61145661SimpROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
6269783Smsmithvsyslog(int pri, const char *fmt, va_list ap)
6369783Smsmith{
6469783Smsmith    char *fmt2;
6569783Smsmith    const char *p;
6669783Smsmith    char *p2;
6769783Smsmith    int ret;
6869783Smsmith    int saved_errno = errno;
6969783Smsmith    int fmt_len  = strlen (fmt);
7069783Smsmith    int fmt2_len = fmt_len;
7169783Smsmith    char *buf;
7269783Smsmith
7369783Smsmith    fmt2 = malloc (fmt_len + 1);
7469783Smsmith    if (fmt2 == NULL) {
7569783Smsmith	simple_vsyslog (pri, fmt, ap);
7669783Smsmith	return;
7769783Smsmith    }
7869783Smsmith
7969783Smsmith    for (p = fmt, p2 = fmt2; *p != '\0'; ++p) {
8069783Smsmith	if (p[0] == '%' && p[1] == 'm') {
8169783Smsmith	    const char *e = strerror (saved_errno);
82164264Sjhb	    int e_len = strlen (e);
83164264Sjhb	    char *tmp;
84164264Sjhb	    int pos;
85164264Sjhb
86169221Sjhb	    pos = p2 - fmt2;
8769783Smsmith	    fmt2_len += e_len - 2;
8869783Smsmith	    tmp = realloc (fmt2, fmt2_len + 1);
8969783Smsmith	    if (tmp == NULL) {
9069783Smsmith		free (fmt2);
91154079Sjhb		simple_vsyslog (pri, fmt, ap);
9269783Smsmith		return;
93154079Sjhb	    }
9469783Smsmith	    fmt2 = tmp;
9569783Smsmith	    p2   = fmt2 + pos;
9669783Smsmith	    memmove (p2, e, e_len);
97163805Simp	    p2 += e_len;
98163805Simp	    ++p;
99163805Simp	} else
100163805Simp	    *p2++ = *p;
101163805Simp    }
102163805Simp    *p2 = '\0';
103163805Simp
104163805Simp    ret = vasprintf (&buf, fmt2, ap);
105163805Simp    free (fmt2);
106163805Simp    if (ret < 0 || buf == NULL) {
107163805Simp	simple_vsyslog (pri, fmt, ap);
108163805Simp	return;
109163805Simp    }
110163805Simp    syslog (pri, "%s", buf);
111163805Simp    free (buf);
112163805Simp}
113163805Simp#endif
114163805Simp