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