Annotation of src/usr.bin/cvs/log.c, Revision 1.37
1.37 ! xsa 1: /* $OpenBSD: log.c,v 1.36 2006/07/07 17:37:17 joris Exp $ */
1.1 jfb 2: /*
1.35 joris 3: * Copyright (c) 2006 Joris Vink <joris@openbsd.org>
1.2 jfb 4: * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
1.1 jfb 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:
1.29 xsa 28: #include "includes.h"
1.1 jfb 29:
1.16 xsa 30: #include "cvs.h"
1.1 jfb 31: #include "log.h"
32:
33: extern char *__progname;
1.19 joris 34: static int send_m = 1;
1.1 jfb 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: */
1.34 xsa 43: void
1.1 jfb 44: cvs_log(u_int level, const char *fmt, ...)
45: {
46: va_list vap;
47:
48: va_start(vap, fmt);
1.34 xsa 49: cvs_vlog(level, fmt, vap);
1.1 jfb 50: va_end(vap);
51: }
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: */
1.34 xsa 59: void
1.1 jfb 60: cvs_vlog(u_int level, const char *fmt, va_list vap)
61: {
62: int ecp;
1.25 xsa 63: char prefix[64], buf[1024], ebuf[255];
1.1 jfb 64: FILE *out;
1.27 joris 65: char *cmdname;
1.20 joris 66: struct cvs_cmd *cmdp;
1.1 jfb 67:
1.35 joris 68: if (cvs_trace != 1 && level == LP_TRACE)
1.34 xsa 69: return;
1.1 jfb 70:
71: if (level == LP_ERRNO)
72: ecp = errno;
1.4 jfb 73: else
74: ecp = 0;
1.1 jfb 75:
1.17 xsa 76: /* always use the command name in error messages, not aliases */
1.27 joris 77: if (cvs_command == NULL)
78: cmdname = " ";
79: else {
80: cmdp = cvs_findcmd(cvs_command);
81: cmdname = cmdp->cmd_name;
82: }
1.17 xsa 83:
1.3 jfb 84: /* The cvs program appends the command name to the program name */
1.8 jfb 85: if (level == LP_TRACE) {
86: strlcpy(prefix, " -> ", sizeof(prefix));
1.36 joris 87: if (cvs_server_active)
1.8 jfb 88: prefix[0] = 'S';
1.36 joris 89: else
90: prefix[0] = 'C';
1.8 jfb 91: } else if (cvs_command != NULL) {
1.4 jfb 92: if (level == LP_ABORT)
1.37 ! xsa 93: (void)xsnprintf(prefix, sizeof(prefix),
! 94: "%s [%s aborted]", __progname, cmdname);
! 95: else
! 96: (void)xsnprintf(prefix, sizeof(prefix), "%s %s",
1.27 joris 97: __progname, cmdname);
1.6 deraadt 98: } else /* just use the standard strlcpy */
1.3 jfb 99: strlcpy(prefix, __progname, sizeof(prefix));
100:
1.1 jfb 101: vsnprintf(buf, sizeof(buf), fmt, vap);
102: if (level == LP_ERRNO) {
1.37 ! xsa 103: (void)xsnprintf(ebuf, sizeof(ebuf), ": %s", strerror(errno));
1.1 jfb 104: strlcat(buf, ebuf, sizeof(buf));
105: }
106:
1.35 joris 107: if (level == LP_NOTICE)
108: out = stdout;
109: else
110: out = stderr;
111:
1.36 joris 112: if (cvs_server_active) {
1.35 joris 113: if (out == stdout)
114: putc('M', out);
115: else {
1.1 jfb 116: out = stdout;
1.35 joris 117: putc('E', out);
1.3 jfb 118: }
1.1 jfb 119:
1.35 joris 120: putc(' ', out);
1.1 jfb 121: }
122:
1.35 joris 123: fputs(prefix, out);
124: if (level != LP_TRACE)
125: fputs(": ", out);
126: fputs(buf, out);
127: fputc('\n', out);
1.1 jfb 128:
129: /* preserve it just in case we changed it? */
130: if (level == LP_ERRNO)
131: errno = ecp;
1.2 jfb 132: }
133:
134: /*
135: * cvs_printf()
136: *
1.14 jfb 137: * Wrapper function around printf() that prepends a 'M' command when
1.2 jfb 138: * the program is acting as server.
139: */
140: int
141: cvs_printf(const char *fmt, ...)
142: {
143: int ret;
1.14 jfb 144: char *nstr, *dp, *sp;
1.2 jfb 145: va_list vap;
146:
147: va_start(vap, fmt);
1.14 jfb 148:
1.36 joris 149: if (cvs_server_active) {
1.14 jfb 150: ret = vasprintf(&nstr, fmt, vap);
1.32 ray 151: if (ret == -1)
152: fatal("cvs_printf: %s", strerror(errno));
153: for (dp = nstr; *dp != '\0';) {
154: sp = strchr(dp, '\n');
155: if (sp == NULL)
156: for (sp = dp; *sp != '\0'; sp++)
157: ;
158:
159: if (send_m) {
160: send_m = 0;
161: putc('M', stdout);
162: putc(' ', stdout);
1.14 jfb 163: }
1.32 ray 164:
165: fwrite(dp, sizeof(char), (size_t)(sp - dp), stdout);
166:
167: if (*sp != '\n')
168: break;
169:
170: putc('\n', stdout);
171: send_m = 1;
172: dp = sp + 1;
1.14 jfb 173: }
1.32 ray 174: xfree(nstr);
1.14 jfb 175: } else
176: ret = vprintf(fmt, vap);
177:
1.2 jfb 178: va_end(vap);
179: return (ret);
1.19 joris 180: }