1/* 2 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25#include "includes.h"
|
26RCSID("$OpenBSD: misc.c,v 1.20 2002/12/13 10:03:15 markus Exp $");
|
26RCSID("$OpenBSD: misc.c,v 1.22 2003/09/18 08:49:45 markus Exp $"); |
27 28#include "misc.h" 29#include "log.h" 30#include "xmalloc.h" 31 32/* remove newline at end of string */ 33char * 34chop(char *s) 35{ 36 char *t = s; 37 while (*t) { 38 if (*t == '\n' || *t == '\r') { 39 *t = '\0'; 40 return s; 41 } 42 t++; 43 } 44 return s; 45 46} 47 48/* set/unset filedescriptor to non-blocking */ 49void 50set_nonblock(int fd) 51{ 52 int val; 53 54 val = fcntl(fd, F_GETFL, 0); 55 if (val < 0) { 56 error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); 57 return; 58 } 59 if (val & O_NONBLOCK) { 60 debug2("fd %d is O_NONBLOCK", fd); 61 return; 62 }
|
63 debug("fd %d setting O_NONBLOCK", fd);
|
63 debug2("fd %d setting O_NONBLOCK", fd); |
64 val |= O_NONBLOCK; 65 if (fcntl(fd, F_SETFL, val) == -1) 66 debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", 67 fd, strerror(errno)); 68} 69 70void 71unset_nonblock(int fd) 72{ 73 int val; 74 75 val = fcntl(fd, F_GETFL, 0); 76 if (val < 0) { 77 error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); 78 return; 79 } 80 if (!(val & O_NONBLOCK)) { 81 debug2("fd %d is not O_NONBLOCK", fd); 82 return; 83 } 84 debug("fd %d clearing O_NONBLOCK", fd); 85 val &= ~O_NONBLOCK; 86 if (fcntl(fd, F_SETFL, val) == -1) 87 debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", 88 fd, strerror(errno)); 89} 90 91/* disable nagle on socket */ 92void 93set_nodelay(int fd) 94{ 95 int opt; 96 socklen_t optlen; 97 98 optlen = sizeof opt; 99 if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) { 100 error("getsockopt TCP_NODELAY: %.100s", strerror(errno)); 101 return; 102 } 103 if (opt == 1) { 104 debug2("fd %d is TCP_NODELAY", fd); 105 return; 106 } 107 opt = 1; 108 debug2("fd %d setting TCP_NODELAY", fd); 109 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1) 110 error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); 111} 112 113/* Characters considered whitespace in strsep calls. */ 114#define WHITESPACE " \t\r\n" 115 116/* return next token in configuration line */ 117char * 118strdelim(char **s) 119{ 120 char *old; 121 int wspace = 0; 122 123 if (*s == NULL) 124 return NULL; 125 126 old = *s; 127 128 *s = strpbrk(*s, WHITESPACE "="); 129 if (*s == NULL) 130 return (old); 131 132 /* Allow only one '=' to be skipped */ 133 if (*s[0] == '=') 134 wspace = 1; 135 *s[0] = '\0'; 136 137 *s += strspn(*s + 1, WHITESPACE) + 1; 138 if (*s[0] == '=' && !wspace) 139 *s += strspn(*s + 1, WHITESPACE) + 1; 140 141 return (old); 142} 143 144struct passwd * 145pwcopy(struct passwd *pw) 146{ 147 struct passwd *copy = xmalloc(sizeof(*copy)); 148 149 memset(copy, 0, sizeof(*copy)); 150 copy->pw_name = xstrdup(pw->pw_name); 151 copy->pw_passwd = xstrdup(pw->pw_passwd); 152 copy->pw_gecos = xstrdup(pw->pw_gecos); 153 copy->pw_uid = pw->pw_uid; 154 copy->pw_gid = pw->pw_gid; 155#ifdef HAVE_PW_EXPIRE_IN_PASSWD 156 copy->pw_expire = pw->pw_expire; 157#endif 158#ifdef HAVE_PW_CHANGE_IN_PASSWD 159 copy->pw_change = pw->pw_change; 160#endif 161#ifdef HAVE_PW_CLASS_IN_PASSWD 162 copy->pw_class = xstrdup(pw->pw_class); 163#endif 164 copy->pw_dir = xstrdup(pw->pw_dir); 165 copy->pw_shell = xstrdup(pw->pw_shell); 166 return copy; 167} 168 169/* 170 * Convert ASCII string to TCP/IP port number. 171 * Port must be >0 and <=65535. 172 * Return 0 if invalid. 173 */ 174int 175a2port(const char *s) 176{ 177 long port; 178 char *endp; 179 180 errno = 0; 181 port = strtol(s, &endp, 0); 182 if (s == endp || *endp != '\0' || 183 (errno == ERANGE && (port == LONG_MIN || port == LONG_MAX)) || 184 port <= 0 || port > 65535) 185 return 0; 186 187 return port; 188} 189 190#define SECONDS 1 191#define MINUTES (SECONDS * 60) 192#define HOURS (MINUTES * 60) 193#define DAYS (HOURS * 24) 194#define WEEKS (DAYS * 7) 195 196/* 197 * Convert a time string into seconds; format is 198 * a sequence of: 199 * time[qualifier] 200 * 201 * Valid time qualifiers are: 202 * <none> seconds 203 * s|S seconds 204 * m|M minutes 205 * h|H hours 206 * d|D days 207 * w|W weeks 208 * 209 * Examples: 210 * 90m 90 minutes 211 * 1h30m 90 minutes 212 * 2d 2 days 213 * 1w 1 week 214 * 215 * Return -1 if time string is invalid. 216 */ 217long 218convtime(const char *s) 219{ 220 long total, secs; 221 const char *p; 222 char *endp; 223 224 errno = 0; 225 total = 0; 226 p = s; 227 228 if (p == NULL || *p == '\0') 229 return -1; 230 231 while (*p) { 232 secs = strtol(p, &endp, 10); 233 if (p == endp || 234 (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) || 235 secs < 0) 236 return -1; 237 238 switch (*endp++) { 239 case '\0': 240 endp--; 241 case 's': 242 case 'S': 243 break; 244 case 'm': 245 case 'M': 246 secs *= MINUTES; 247 break; 248 case 'h': 249 case 'H': 250 secs *= HOURS; 251 break; 252 case 'd': 253 case 'D': 254 secs *= DAYS; 255 break; 256 case 'w': 257 case 'W': 258 secs *= WEEKS; 259 break; 260 default: 261 return -1; 262 } 263 total += secs; 264 if (total < 0) 265 return -1; 266 p = endp; 267 } 268 269 return total; 270} 271 272char * 273cleanhostname(char *host) 274{ 275 if (*host == '[' && host[strlen(host) - 1] == ']') { 276 host[strlen(host) - 1] = '\0'; 277 return (host + 1); 278 } else 279 return host; 280} 281 282char * 283colon(char *cp) 284{ 285 int flag = 0; 286 287 if (*cp == ':') /* Leading colon is part of file name. */ 288 return (0); 289 if (*cp == '[') 290 flag = 1; 291 292 for (; *cp; ++cp) { 293 if (*cp == '@' && *(cp+1) == '[') 294 flag = 1; 295 if (*cp == ']' && *(cp+1) == ':' && flag) 296 return (cp+1); 297 if (*cp == ':' && !flag) 298 return (cp); 299 if (*cp == '/') 300 return (0); 301 } 302 return (0); 303} 304 305/* function to assist building execv() arguments */ 306void 307addargs(arglist *args, char *fmt, ...) 308{ 309 va_list ap; 310 char buf[1024]; 311 int nalloc; 312 313 va_start(ap, fmt); 314 vsnprintf(buf, sizeof(buf), fmt, ap); 315 va_end(ap); 316 317 nalloc = args->nalloc; 318 if (args->list == NULL) { 319 nalloc = 32; 320 args->num = 0; 321 } else if (args->num+2 >= nalloc) 322 nalloc *= 2; 323 324 args->list = xrealloc(args->list, nalloc * sizeof(char *)); 325 args->nalloc = nalloc; 326 args->list[args->num++] = xstrdup(buf); 327 args->list[args->num] = NULL; 328}
|
329
330mysig_t
331mysignal(int sig, mysig_t act)
332{
333#ifdef HAVE_SIGACTION
334 struct sigaction sa, osa;
335
336 if (sigaction(sig, NULL, &osa) == -1)
337 return (mysig_t) -1;
338 if (osa.sa_handler != act) {
339 memset(&sa, 0, sizeof(sa));
340 sigemptyset(&sa.sa_mask);
341 sa.sa_flags = 0;
342#if defined(SA_INTERRUPT)
343 if (sig == SIGALRM)
344 sa.sa_flags |= SA_INTERRUPT;
345#endif
346 sa.sa_handler = act;
347 if (sigaction(sig, &sa, NULL) == -1)
348 return (mysig_t) -1;
349 }
350 return (osa.sa_handler);
351#else
352 return (signal(sig, act));
353#endif
354}
|
|