]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/subversion/subversion/svnserve/logger.c
MFC r275385 (by bapt):
[FreeBSD/stable/10.git] / contrib / subversion / subversion / svnserve / logger.c
1 /*
2  * logger.c : Implementation of the SvnServe logger API
3  *
4  * ====================================================================
5  *    Licensed to the Apache Software Foundation (ASF) under one
6  *    or more contributor license agreements.  See the NOTICE file
7  *    distributed with this work for additional information
8  *    regarding copyright ownership.  The ASF licenses this file
9  *    to you under the Apache License, Version 2.0 (the
10  *    "License"); you may not use this file except in compliance
11  *    with the License.  You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  *    Unless required by applicable law or agreed to in writing,
16  *    software distributed under the License is distributed on an
17  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18  *    KIND, either express or implied.  See the License for the
19  *    specific language governing permissions and limitations
20  *    under the License.
21  * ====================================================================
22  */
23
24
25 \f
26 #define APR_WANT_STRFUNC
27 #include <apr_want.h>
28
29 #include "svn_error.h"
30 #include "svn_io.h"
31 #include "svn_pools.h"
32 #include "svn_time.h"
33
34 #include "private/svn_mutex.h"
35
36 #include "svn_private_config.h"
37 #include "logger.h"
38
39 #ifdef HAVE_UNISTD_H
40 #include <unistd.h>   /* For getpid() */
41 #endif
42
43 struct logger_t
44 {
45   /* actual log file / stream object */
46   svn_stream_t *stream;
47
48   /* mutex used to serialize access to this structure */
49   svn_mutex__t *mutex;
50
51   /* private pool used for temporary allocations */
52   apr_pool_t *pool;
53 };
54
55 svn_error_t *
56 logger__create_for_stderr(logger_t **logger,
57                           apr_pool_t *pool)
58 {
59   logger_t *result = apr_pcalloc(pool, sizeof(*result));
60   result->pool = svn_pool_create(pool);
61
62   SVN_ERR(svn_stream_for_stderr(&result->stream, pool));
63   SVN_ERR(svn_mutex__init(&result->mutex, TRUE, pool));
64
65   *logger = result;
66
67   return SVN_NO_ERROR;
68 }
69
70 svn_error_t *
71 logger__create(logger_t **logger,
72                const char *filename,
73                apr_pool_t *pool)
74 {
75   logger_t *result = apr_pcalloc(pool, sizeof(*result));
76   apr_file_t *file;
77
78   SVN_ERR(svn_io_file_open(&file, filename,
79                            APR_WRITE | APR_CREATE | APR_APPEND,
80                            APR_OS_DEFAULT, pool));
81   SVN_ERR(svn_mutex__init(&result->mutex, TRUE, pool));
82
83   result->stream = svn_stream_from_aprfile2(file, FALSE,  pool);
84   result->pool = svn_pool_create(pool);
85
86   *logger = result;
87
88   return SVN_NO_ERROR;
89 }
90
91 void
92 logger__log_error(logger_t *logger,
93                   svn_error_t *err,
94                   repository_t *repository,
95                   client_info_t *client_info)
96 {
97   if (logger && err)
98     {
99       const char *timestr, *continuation;
100       const char *user, *repos, *remote_host;
101       char errbuf[256];
102       /* 8192 from MAX_STRING_LEN in from httpd-2.2.4/include/httpd.h */
103       char errstr[8192];
104
105       svn_error_clear(svn_mutex__lock(logger->mutex));
106
107       timestr = svn_time_to_cstring(apr_time_now(), logger->pool);
108       remote_host = client_info && client_info->remote_host
109                   ? client_info->remote_host
110                   : "-";
111       user = client_info && client_info->user
112            ? client_info->user
113            : "-";
114       repos = repository && repository->repos_name
115             ? repository->repos_name
116              : "-";
117
118       continuation = "";
119       while (err)
120         {
121           const char *message = svn_err_best_message(err, errbuf, sizeof(errbuf));
122           /* based on httpd-2.2.4/server/log.c:log_error_core */
123           apr_size_t len = apr_snprintf(errstr, sizeof(errstr),
124                                         "%" APR_PID_T_FMT
125                                         " %s %s %s %s ERR%s %s %ld %d ",
126                                         getpid(), timestr, remote_host, user,
127                                         repos, continuation,
128                                         err->file ? err->file : "-", err->line,
129                                         err->apr_err);
130
131           len += escape_errorlog_item(errstr + len, message,
132                                       sizeof(errstr) - len);
133           /* Truncate for the terminator (as apr_snprintf does) */
134           if (len > sizeof(errstr) - sizeof(APR_EOL_STR)) {
135             len = sizeof(errstr) - sizeof(APR_EOL_STR);
136           }
137
138           memcpy(errstr + len, APR_EOL_STR, sizeof(APR_EOL_STR));
139           len += sizeof(APR_EOL_STR) -1;  /* add NL, ex terminating NUL */
140
141           svn_error_clear(svn_stream_write(logger->stream, errstr, &len));
142
143           continuation = "-";
144           err = err->child;
145         }
146
147       svn_pool_clear(logger->pool);
148
149       svn_error_clear(svn_mutex__unlock(logger->mutex, SVN_NO_ERROR));
150     }
151 }
152
153 svn_error_t *
154 logger__write(logger_t *logger,
155               const char *errstr,
156               apr_size_t len)
157 {
158   SVN_MUTEX__WITH_LOCK(logger->mutex,
159                        svn_stream_write(logger->stream, errstr, &len));
160   return SVN_NO_ERROR;
161 }