GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/cvs/log.c Lines: 46 63 73.0 %
Date: 2017-11-07 Branches: 29 58 50.0 %

Line Branch Exec Source
1
/*	$OpenBSD: log.c,v 1.47 2015/11/05 09:48:21 nicm Exp $	*/
2
/*
3
 * Copyright (c) 2006 Joris Vink <joris@openbsd.org>
4
 * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 *
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. The name of the author may not be used to endorse or promote products
14
 *    derived from this software without specific prior written permission.
15
 *
16
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
19
 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20
 * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 */
27
28
#include <errno.h>
29
#include <stdlib.h>
30
#include <string.h>
31
32
#include "cvs.h"
33
34
extern char *__progname;
35
36
/*
37
 * cvs_log()
38
 *
39
 * Log the format-string message
40
 * The <fmt> argument should not have a terminating newline, as this is taken
41
 * care of by the logging facility.
42
 */
43
void
44
cvs_log(u_int level, const char *fmt, ...)
45
{
46
2462
	va_list vap;
47
48
1231
	va_start(vap, fmt);
49
1231
	cvs_vlog(level, fmt, vap);
50
1231
	va_end(vap);
51
1231
}
52
53
/*
54
 * cvs_vlog()
55
 *
56
 * The <fmt> argument should not have a terminating newline, as this is taken
57
 * care of by the logging facility.
58
 */
59
void
60
cvs_vlog(u_int level, const char *fmt, va_list vap)
61
{
62
	int ecp;
63
	FILE *out;
64
	char *cmdname;
65
66
2464
	if (cvs_trace != 1 && level == LP_TRACE)
67
1215
		return;
68
69
17
	if (level == LP_ERRNO)
70
		ecp = errno;
71
	else
72
		ecp = 0;
73
74
17
	if (level == LP_NOTICE)
75
11
		out = stdout;
76
	else
77
		out = stderr;
78
79
17
	if (cvs_server_active) {
80
		if (out == stdout)
81
			putc('M', out);
82
		else {
83
			out = stdout;
84
			putc('E', out);
85
		}
86
87
		putc(' ', out);
88
	}
89
90
17
	cmdname = (cmdp != NULL) ? cmdp->cmd_name : __progname;
91
92
	/* The cvs program appends the command name to the program name */
93
17
	if (level == LP_TRACE) {
94
		if (cvs_server_active)
95
			putc('S', out);
96
		else
97
			putc('C', out);
98
		(void)fputs("-> ", out);
99
17
	} else if (level != LP_RCS) {
100
13
		(void)fputs(__progname, out);
101
26
		putc(' ', out);
102
13
		if (level == LP_ABORT)
103
1
			(void)fprintf(out,
104
			    "[%s aborted]", cmdname);
105
		else
106
12
			(void)fputs(cmdname, out);
107
13
		(void)fputs(": ", out);
108
13
	}
109
110
17
	(void)vfprintf(out, fmt, vap);
111
17
	if (level == LP_ERRNO) {
112
		(void)fprintf(out, ": %s\n", strerror(ecp));
113
114
		/* preserve it just in case we changed it? */
115
		errno = ecp;
116
	} else
117
17
		fputc('\n', out);
118
1249
}
119
120
/*
121
 * cvs_printf()
122
 *
123
 * Wrapper function around printf() that prepends a 'M' command when
124
 * the program is acting as server.
125
 */
126
int
127
cvs_printf(const char *fmt, ...)
128
{
129
	static int send_m = 1;
130
	int ret;
131
706
	char *nstr, *dp, *sp;
132
353
	va_list vap;
133
134
353
	va_start(vap, fmt);
135
136
353
	ret = vasprintf(&nstr, fmt, vap);
137
353
	if (ret == -1)
138
		fatal("cvs_printf: could not allocate memory");
139
140
1236
	for (dp = nstr; *dp != '\0';) {
141
408
		sp = strchr(dp, '\n');
142
408
		if (sp == NULL)
143
4450
			for (sp = dp; *sp != '\0'; sp++)
144
				;
145
146
408
		if (cvs_server_active && send_m) {
147
			send_m = 0;
148
			putc('M', stdout);
149
			putc(' ', stdout);
150
		}
151
152

511
		if (dp != nstr && dp != sp &&
153
48
		    !strncmp(dp, LOG_REVSEP, sp - dp))
154
			putc('>', stdout);
155
156
408
		fwrite(dp, sizeof(char), (size_t)(sp - dp), stdout);
157
158
408
		if (*sp != '\n')
159
			break;
160
161
530
		putc('\n', stdout);
162
265
		send_m = 1;
163
265
		dp = sp + 1;
164
	}
165
166
353
	free(nstr);
167
353
	va_end(vap);
168
169
353
	return (ret);
170
353
}