xref: /openbsd-src/usr.bin/cvs/log.c (revision 397ddb8a3f80a7c0fc96b9834bf9a6841845ed3c)
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