1*397ddb8aSnicm /* $OpenBSD: log.c,v 1.47 2015/11/05 09:48:21 nicm Exp $ */
26c121f58Sjfb /*
33ad3fb45Sjoris * Copyright (c) 2006 Joris Vink <joris@openbsd.org>
44743a7c5Sjfb * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
56c121f58Sjfb * All rights reserved.
66c121f58Sjfb *
76c121f58Sjfb * Redistribution and use in source and binary forms, with or without
86c121f58Sjfb * modification, are permitted provided that the following conditions
96c121f58Sjfb * are met:
106c121f58Sjfb *
116c121f58Sjfb * 1. Redistributions of source code must retain the above copyright
126c121f58Sjfb * notice, this list of conditions and the following disclaimer.
136c121f58Sjfb * 2. The name of the author may not be used to endorse or promote products
146c121f58Sjfb * derived from this software without specific prior written permission.
156c121f58Sjfb *
166c121f58Sjfb * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
176c121f58Sjfb * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
186c121f58Sjfb * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
196c121f58Sjfb * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
206c121f58Sjfb * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
216c121f58Sjfb * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
226c121f58Sjfb * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
236c121f58Sjfb * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
246c121f58Sjfb * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
256c121f58Sjfb * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
266c121f58Sjfb */
276c121f58Sjfb
281f8531bdSotto #include <errno.h>
29*397ddb8aSnicm #include <stdlib.h>
301f8531bdSotto #include <string.h>
316c121f58Sjfb
32d2aab16aSjfb #include "cvs.h"
336c121f58Sjfb
346c121f58Sjfb extern char *__progname;
356c121f58Sjfb
366c121f58Sjfb /*
376c121f58Sjfb * cvs_log()
386c121f58Sjfb *
396c121f58Sjfb * Log the format-string message
406c121f58Sjfb * The <fmt> argument should not have a terminating newline, as this is taken
416c121f58Sjfb * care of by the logging facility.
426c121f58Sjfb */
43cc3db800Sxsa void
cvs_log(u_int level,const char * fmt,...)446c121f58Sjfb cvs_log(u_int level, const char *fmt, ...)
456c121f58Sjfb {
466c121f58Sjfb va_list vap;
476c121f58Sjfb
486c121f58Sjfb va_start(vap, fmt);
49cc3db800Sxsa cvs_vlog(level, fmt, vap);
506c121f58Sjfb va_end(vap);
516c121f58Sjfb }
526c121f58Sjfb
536c121f58Sjfb /*
546c121f58Sjfb * cvs_vlog()
556c121f58Sjfb *
566c121f58Sjfb * The <fmt> argument should not have a terminating newline, as this is taken
576c121f58Sjfb * care of by the logging facility.
586c121f58Sjfb */
59cc3db800Sxsa void
cvs_vlog(u_int level,const char * fmt,va_list vap)606c121f58Sjfb cvs_vlog(u_int level, const char *fmt, va_list vap)
616c121f58Sjfb {
626c121f58Sjfb int ecp;
636c121f58Sjfb FILE *out;
64c9e36cf3Sjoris char *cmdname;
656c121f58Sjfb
663ad3fb45Sjoris if (cvs_trace != 1 && level == LP_TRACE)
67cc3db800Sxsa return;
686c121f58Sjfb
696c121f58Sjfb if (level == LP_ERRNO)
706c121f58Sjfb ecp = errno;
71de708f0cSjfb else
72de708f0cSjfb ecp = 0;
736c121f58Sjfb
743ad3fb45Sjoris if (level == LP_NOTICE)
756c121f58Sjfb out = stdout;
766c121f58Sjfb else
776c121f58Sjfb out = stderr;
786c121f58Sjfb
799fac60a5Sjoris if (cvs_server_active) {
80d2aab16aSjfb if (out == stdout)
81d2aab16aSjfb putc('M', out);
828da655f9Sjfb else {
838da655f9Sjfb out = stdout;
84d2aab16aSjfb putc('E', out);
858da655f9Sjfb }
863ad3fb45Sjoris
87d2aab16aSjfb putc(' ', out);
88d2aab16aSjfb }
89d2aab16aSjfb
90c9e36cf3Sjoris cmdname = (cmdp != NULL) ? cmdp->cmd_name : __progname;
91c9e36cf3Sjoris
9222a5d0f6Sxsa /* The cvs program appends the command name to the program name */
9322a5d0f6Sxsa if (level == LP_TRACE) {
9422a5d0f6Sxsa if (cvs_server_active)
9522a5d0f6Sxsa putc('S', out);
9622a5d0f6Sxsa else
9722a5d0f6Sxsa putc('C', out);
9822a5d0f6Sxsa (void)fputs("-> ", out);
99e8755a22Stobias } else if (level != LP_RCS) {
10022a5d0f6Sxsa (void)fputs(__progname, out);
10122a5d0f6Sxsa putc(' ', out);
10222a5d0f6Sxsa if (level == LP_ABORT)
10322a5d0f6Sxsa (void)fprintf(out,
104c9e36cf3Sjoris "[%s aborted]", cmdname);
10522a5d0f6Sxsa else
106c9e36cf3Sjoris (void)fputs(cmdname, out);
10722a5d0f6Sxsa (void)fputs(": ", out);
10822a5d0f6Sxsa }
10922a5d0f6Sxsa
11022a5d0f6Sxsa (void)vfprintf(out, fmt, vap);
11122a5d0f6Sxsa if (level == LP_ERRNO) {
11222a5d0f6Sxsa (void)fprintf(out, ": %s\n", strerror(ecp));
1136c121f58Sjfb
1146c121f58Sjfb /* preserve it just in case we changed it? */
1156c121f58Sjfb errno = ecp;
11622a5d0f6Sxsa } else
11722a5d0f6Sxsa fputc('\n', out);
1186c121f58Sjfb }
1194743a7c5Sjfb
1204743a7c5Sjfb /*
1214743a7c5Sjfb * cvs_printf()
1224743a7c5Sjfb *
123b5e8f568Sjfb * Wrapper function around printf() that prepends a 'M' command when
1244743a7c5Sjfb * the program is acting as server.
1254743a7c5Sjfb */
1264743a7c5Sjfb int
cvs_printf(const char * fmt,...)1274743a7c5Sjfb cvs_printf(const char *fmt, ...)
1284743a7c5Sjfb {
12963c546bcSnicm static int send_m = 1;
1304743a7c5Sjfb int ret;
131b5e8f568Sjfb char *nstr, *dp, *sp;
1324743a7c5Sjfb va_list vap;
1334743a7c5Sjfb
1344743a7c5Sjfb va_start(vap, fmt);
1354743a7c5Sjfb
136b5e8f568Sjfb ret = vasprintf(&nstr, fmt, vap);
1377599b6c6Sray if (ret == -1)
1389a0ecc80Stobias fatal("cvs_printf: could not allocate memory");
1397c650248Sjoris
140b5e8f568Sjfb for (dp = nstr; *dp != '\0';) {
141b5e8f568Sjfb sp = strchr(dp, '\n');
142b5e8f568Sjfb if (sp == NULL)
143b5e8f568Sjfb for (sp = dp; *sp != '\0'; sp++)
144b5e8f568Sjfb ;
145b5e8f568Sjfb
146449bca81Sniallo if (cvs_server_active && send_m) {
1474ec26eccSjoris send_m = 0;
148b5e8f568Sjfb putc('M', stdout);
149b5e8f568Sjfb putc(' ', stdout);
1504ec26eccSjoris }
1514ec26eccSjoris
152449bca81Sniallo if (dp != nstr && dp != sp &&
153449bca81Sniallo !strncmp(dp, LOG_REVSEP, sp - dp))
154449bca81Sniallo putc('>', stdout);
155449bca81Sniallo
1567599b6c6Sray fwrite(dp, sizeof(char), (size_t)(sp - dp), stdout);
157b5e8f568Sjfb
158b5e8f568Sjfb if (*sp != '\n')
159b5e8f568Sjfb break;
160b5e8f568Sjfb
161b5e8f568Sjfb putc('\n', stdout);
1624ec26eccSjoris send_m = 1;
163b5e8f568Sjfb dp = sp + 1;
164b5e8f568Sjfb }
165b5e8f568Sjfb
166*397ddb8aSnicm free(nstr);
167b5e8f568Sjfb va_end(vap);
1687c650248Sjoris
1694743a7c5Sjfb return (ret);
1704743a7c5Sjfb }
171