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