xref: /openbsd-src/usr.bin/rsync/log.c (revision 4b70baf6e17fc8b27fc1f7fa7929335753fa94c3)
1 /*	$Id: log.c,v 1.6 2019/02/18 22:47:34 benno Exp $ */
2 /*
3  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 #include <errno.h>
18 #include <stdarg.h>
19 #include <stdint.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "extern.h"
25 
26 /*
27  * Log a message at level "level", starting at zero, which corresponds
28  * to the current verbosity level opts->verbose (whose verbosity starts
29  * at one).
30  */
31 void
32 rsync_log(struct sess *sess, const char *fname,
33 	size_t line, int level, const char *fmt, ...)
34 {
35 	char	*buf = NULL;
36 	va_list	 ap;
37 
38 	if (sess->opts->verbose < level + 1)
39 		return;
40 
41 	if (fmt != NULL) {
42 		va_start(ap, fmt);
43 		if (vasprintf(&buf, fmt, ap) < 0) {
44 			va_end(ap);
45 			return;
46 		}
47 		va_end(ap);
48 	}
49 
50 	if (level <= 0 && buf != NULL)
51 		fprintf(stderr, "%s\n", buf);
52 	else if (level > 0)
53 		fprintf(stderr, "%s:%zu%s%s\n", fname, line,
54 		    (buf != NULL) ? ": " : "",
55 		    (buf != NULL) ? buf : "");
56 	free(buf);
57 }
58 
59 /*
60  * This reports an error---not a warning.
61  * However, it is not like errx(3) in that it does not exit.
62  */
63 void
64 rsync_errx(struct sess *sess, const char *fname,
65 	size_t line, const char *fmt, ...)
66 {
67 	char	*buf = NULL;
68 	va_list	 ap;
69 
70 	if (fmt != NULL) {
71 		va_start(ap, fmt);
72 		if (vasprintf(&buf, fmt, ap) < 0) {
73 			va_end(ap);
74 			return;
75 		}
76 		va_end(ap);
77 	}
78 
79 	fprintf(stderr, "%s:%zu: error%s%s\n", fname, line,
80 	   (buf != NULL) ? ": " : "",
81 	   (buf != NULL) ? buf : "");
82 	free(buf);
83 }
84 
85 /*
86  * This reports an error---not a warning.
87  * However, it is not like err(3) in that it does not exit.
88  */
89 void
90 rsync_err(struct sess *sess, const char *fname,
91 	size_t line, const char *fmt, ...)
92 {
93 	char	*buf = NULL;
94 	va_list	 ap;
95 	int	 er = errno;
96 
97 	if (fmt != NULL) {
98 		va_start(ap, fmt);
99 		if (vasprintf(&buf, fmt, ap) < 0) {
100 			va_end(ap);
101 			return;
102 		}
103 		va_end(ap);
104 	}
105 
106 	fprintf(stderr, "%s:%zu: error%s%s: %s\n", fname, line,
107 	   (buf != NULL) ? ": " : "",
108 	   (buf != NULL) ? buf : "", strerror(er));
109 	free(buf);
110 }
111 
112 /*
113  * Prints a non-terminal error message, that is, when reporting on the
114  * chain of functions from which the actual warning occurred.
115  */
116 void
117 rsync_errx1(struct sess *sess, const char *fname,
118 	size_t line, const char *fmt, ...)
119 {
120 	char	*buf = NULL;
121 	va_list	 ap;
122 
123 	if (sess->opts->verbose < 1)
124 		return;
125 
126 	if (fmt != NULL) {
127 		va_start(ap, fmt);
128 		if (vasprintf(&buf, fmt, ap) < 0) {
129 			va_end(ap);
130 			return;
131 		}
132 		va_end(ap);
133 	}
134 
135 	fprintf(stderr, "%s:%zu: error%s%s\n", fname, line,
136 	   (buf != NULL) ? ": " : "",
137 	   (buf != NULL) ? buf : "");
138 	free(buf);
139 }
140 
141 /*
142  * Prints a warning message.
143  */
144 void
145 rsync_warnx(struct sess *sess, const char *fname,
146 	size_t line, const char *fmt, ...)
147 {
148 	char	*buf = NULL;
149 	va_list	 ap;
150 
151 	if (fmt != NULL) {
152 		va_start(ap, fmt);
153 		if (vasprintf(&buf, fmt, ap) < 0) {
154 			va_end(ap);
155 			return;
156 		}
157 		va_end(ap);
158 	}
159 
160 	fprintf(stderr, "%s:%zu: warning%s%s\n", fname, line,
161 	   (buf != NULL) ? ": " : "",
162 	   (buf != NULL) ? buf : "");
163 	free(buf);
164 }
165 
166 /*
167  * Prints a warning with an errno.
168  * It uses a level detector for when to inhibit printing.
169  */
170 void
171 rsync_warn(struct sess *sess, int level,
172 	const char *fname, size_t line, const char *fmt, ...)
173 {
174 	char	*buf = NULL;
175 	va_list	 ap;
176 	int	 er = errno;
177 
178 	if (sess->opts->verbose < level)
179 		return;
180 
181 	if (fmt != NULL) {
182 		va_start(ap, fmt);
183 		if (vasprintf(&buf, fmt, ap) < 0) {
184 			va_end(ap);
185 			return;
186 		}
187 		va_end(ap);
188 	}
189 
190 	fprintf(stderr, "%s:%zu: warning%s%s: %s\n", fname, line,
191 	   (buf != NULL) ? ": " : "",
192 	   (buf != NULL) ? buf : "", strerror(er));
193 	free(buf);
194 }
195