2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1999 University of Maryland at College Park
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of U.M. not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. U.M. makes no representations about the
13 * suitability of this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
16 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Authors: the Amanda Development Team. Its members are listed in a
24 * file named AUTHORS, in the root directory of this distribution.
27 * $Id: util.c,v 1.2.2.2.4.3.2.1 2002/03/31 21:01:33 jrjackson Exp $
34 * Keep calling read() until we've read buflen's worth of data, or EOF,
37 * Returns the number of bytes read, 0 on EOF, or negative on error.
40 fullread(fd, vbuf, buflen)
45 ssize_t nread, tot = 0;
46 char *buf = vbuf; /* cast to char so we can ++ it */
49 nread = read(fd, buf, buflen);
62 * Keep calling write() until we've written buflen's worth of data,
65 * Returns the number of bytes written, or negative on error.
68 fullwrite(fd, vbuf, buflen)
73 ssize_t nwritten, tot = 0;
74 const char *buf = vbuf; /* cast to char so we can ++ it */
77 nwritten = write(fd, buf, buflen);
88 * Bind to a port in the given range. Takes a begin,end pair of port numbers.
90 * Returns negative on error (EGAIN if all ports are in use). Returns 0
94 bind_portrange(s, addrp, first_port, last_port)
96 struct sockaddr_in *addrp;
97 int first_port, last_port;
100 const int num_ports = last_port - first_port + 1;
103 assert(first_port > 0 && first_port <= last_port && last_port < 65536);
106 * We pick a different starting port based on our pid and the current
107 * time to avoid always picking the same reserved port twice.
109 port = ((getpid() + time(0)) % num_ports) + first_port;
112 * Scan through the range, trying all available ports. Wrap around
113 * if we don't happen to start at the beginning.
115 for (cnt = 0; cnt < num_ports; cnt++) {
116 addrp->sin_port = htons(port);
117 if (bind(s, (struct sockaddr *)addrp, sizeof(*addrp)) >= 0)
120 * If the error was something other then port in use, stop.
122 if (errno != EADDRINUSE)
124 if (++port > last_port)
127 if (cnt == num_ports) {
128 dbprintf(("%s: bind_portrange: all ports between %d and %d busy\n",
129 debug_prefix_time(NULL),
133 } else if (last_port < IPPORT_RESERVED
135 && errno == EACCES) {
137 * Do not bother with an error message in this case because it
142 dbprintf(("%s: bind_portrange: port %d: %s\n",
143 debug_prefix_time(NULL),
152 * Construct a datestamp (YYYYMMDD) from a time_t.
155 construct_datestamp(t)
159 char datestamp[3*NUM_STR_SIZE];
163 when = time((time_t *)NULL);
167 tm = localtime(&when);
168 ap_snprintf(datestamp, sizeof(datestamp),
169 "%04d%02d%02d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
170 return stralloc(datestamp);
174 * Construct a timestamp (YYYYMMDDHHMMSS) from a time_t.
177 construct_timestamp(t)
181 char timestamp[6*NUM_STR_SIZE];
185 when = time((time_t *)NULL);
189 tm = localtime(&when);
190 ap_snprintf(timestamp, sizeof(timestamp),
191 "%04d%02d%02d%02d%02d%02d",
192 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
193 tm->tm_hour, tm->tm_min, tm->tm_sec);
194 return stralloc(timestamp);