1 /******************************************************************************
5 * Description: Central utility functions that may be frequently needed
6 * accross the application.
8 * Copyright (c) 1997-2000 Messaging Direct Ltd.
11 * Portions Copyright (c) 2003 Jeremy Rumpf
12 * jrumpf@heavyload.net
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
23 * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
27 * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
30 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
32 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
33 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
40 * This source file created using 8 space tabs.
42 *****************************************************************************/
48 #include <sys/types.h>
55 /****************************************
56 * flags global from saslauthd-main.c
57 *****************************************/
59 /*************************************************************
60 * Variadic logging function to simplify printing of log
62 **************************************************************/
63 void logger(int priority, const char *function, const char *format, ...) {
66 static int have_syslog = 0;
68 va_start(arg_list, format);
69 vsnprintf(buffer, 1023, format, arg_list);
74 if (flags & LOG_USE_STDERR)
75 fprintf(stderr, L_STDERR_FORMAT, getpid(), function, buffer);
77 if (flags & LOG_USE_SYSLOG) {
79 openlog("saslauthd", LOG_PID|LOG_NDELAY, LOG_AUTH);
83 syslog(priority, "%-16s: %s", function, buffer);
88 /**************************************************************
89 * I/O wrapper to attempt to ensure a full record gets
90 * transmitted. If the function returns anything less than
91 * bytesrequested, it should be considered a failure.
92 **************************************************************/
93 ssize_t tx_rec(int filefd, void *prebuff, size_t bytesrequested) {
99 bytesleft = bytesrequested;
102 while (bytesleft > 0) {
103 bytesio = write(filefd, buff, bytesleft);
107 logger(L_ERR, L_FUNC, "write failure");
108 logger(L_ERR, L_FUNC, "write: %s", strerror(rc));
112 if (bytesio == 0 && errno != EINTR)
113 return(bytesrequested - bytesleft);
115 bytesleft -= bytesio;
116 buff = (void *)((char *)buff + bytesio);
120 return(bytesrequested);
124 /**************************************************************
125 * I/O wrapper to attempt to read in the specified amount of
126 * data, without any guarantees. If the function returns
127 * anything less than bytesrequested, it should be considered
129 **************************************************************/
130 ssize_t rx_rec(int filefd, void *prebuff, size_t bytesrequested) {
133 size_t bytesleft = 0;
136 bytesleft = bytesrequested;
139 while (bytesleft > 0) {
140 bytesio = read(filefd, buff, bytesleft);
144 logger(L_ERR, L_FUNC, "read failure");
145 logger(L_ERR, L_FUNC, "read: %s", strerror(rc));
149 if (bytesio == 0 && errno != EINTR)
150 return(bytesrequested - bytesleft);
152 bytesleft -= bytesio;
153 buff = (void *)((char *)buff + bytesio);
157 return(bytesrequested);
161 /**************************************************************
162 * I/O wrapper to attempt to write out the specified vector.
163 * data, without any guarantees. If the function returns
164 * -1, the vector wasn't completely written.
165 **************************************************************/
166 int retry_writev(int fd, struct iovec *iov, int iovcnt) {
167 int n; /* return value from writev() */
168 int i; /* loop counter */
169 int written; /* bytes written so far */
170 static int iov_max; /* max number of iovec entries */
186 while (iovcnt && iov[0].iov_len == 0) {
195 n = writev(fd, iov, iovcnt > iov_max ? iov_max : iovcnt);
198 if (errno == EINVAL && iov_max > 10) {
203 if (errno == EINTR) {
213 for (i = 0; i < iovcnt; i++) {
214 if ((int) iov[i].iov_len > n) {
215 iov[i].iov_base = (char *)iov[i].iov_base + n;
231 /* strlcpy -- copy string smartly.
233 * i believe/hope this is compatible with the BSD strlcpy().
235 size_t saslauthd_strlcpy(char *dst, const char *src, size_t len)
240 /* we can't do anything ! */
244 /* assert(len >= 1); */
245 for (n = 0; n < len-1; n++) {
246 if ((dst[n] = src[n]) == '\0') break;
249 /* ran out of space */
258 size_t saslauthd_strlcat(char *dst, const char *src, size_t len)
264 return o + strlen(src);
266 for (i = 0, j = o; i < len; i++, j++) {
267 if ((dst[j] = src[i]) == '\0') break;
270 if (src[i] == '\0') {
273 return j + strlen(src + i);