-/* $OpenBSD: misc.c,v 1.3 2001/02/28 05:34:28 deraadt Exp $ */
+/* $OpenBSD: misc.c,v 1.15 2002/01/24 21:09:25 stevesk Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*/
#include "includes.h"
-RCSID("$OpenBSD: misc.c,v 1.3 2001/02/28 05:34:28 deraadt Exp $");
+RCSID("$OpenBSD: misc.c,v 1.15 2002/01/24 21:09:25 stevesk Exp $");
#include "misc.h"
#include "log.h"
#include "xmalloc.h"
+/* remove newline at end of string */
char *
chop(char *s)
{
char *t = s;
while (*t) {
- if(*t == '\n' || *t == '\r') {
+ if (*t == '\n' || *t == '\r') {
*t = '\0';
return s;
}
}
+/* set/unset filedescriptor to non-blocking */
void
set_nonblock(int fd)
{
int val;
+
val = fcntl(fd, F_GETFL, 0);
if (val < 0) {
error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
return;
}
if (val & O_NONBLOCK) {
- debug("fd %d IS O_NONBLOCK", fd);
+ debug2("fd %d is O_NONBLOCK", fd);
return;
}
debug("fd %d setting O_NONBLOCK", fd);
fd, strerror(errno));
}
+void
+unset_nonblock(int fd)
+{
+ int val;
+
+ val = fcntl(fd, F_GETFL, 0);
+ if (val < 0) {
+ error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
+ return;
+ }
+ if (!(val & O_NONBLOCK)) {
+ debug2("fd %d is not O_NONBLOCK", fd);
+ return;
+ }
+ debug("fd %d clearing O_NONBLOCK", fd);
+ val &= ~O_NONBLOCK;
+ if (fcntl(fd, F_SETFL, val) == -1)
+ if (errno != ENODEV)
+ error("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
+ fd, strerror(errno));
+}
+
+/* disable nagle on socket */
+void
+set_nodelay(int fd)
+{
+ int on = 1;
+
+ debug("fd %d setting TCP_NODELAY", fd);
+ if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on) == -1)
+ error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
+}
+
/* Characters considered whitespace in strsep calls. */
#define WHITESPACE " \t\r\n"
+/* return next token in configuration line */
char *
strdelim(char **s)
{
pwcopy(struct passwd *pw)
{
struct passwd *copy = xmalloc(sizeof(*copy));
+
memset(copy, 0, sizeof(*copy));
copy->pw_name = xstrdup(pw->pw_name);
copy->pw_passwd = xstrdup(pw->pw_passwd);
+ copy->pw_gecos = xstrdup(pw->pw_gecos);
copy->pw_uid = pw->pw_uid;
copy->pw_gid = pw->pw_gid;
+#ifdef HAVE_PW_EXPIRE_IN_PASSWD
+ copy->pw_expire = pw->pw_expire;
+#endif
+#ifdef HAVE_PW_CHANGE_IN_PASSWD
+ copy->pw_change = pw->pw_change;
+#endif
+#ifdef HAVE_PW_CLASS_IN_PASSWD
copy->pw_class = xstrdup(pw->pw_class);
+#endif
copy->pw_dir = xstrdup(pw->pw_dir);
copy->pw_shell = xstrdup(pw->pw_shell);
return copy;
}
+/*
+ * Convert ASCII string to TCP/IP port number.
+ * Port must be >0 and <=65535.
+ * Return 0 if invalid.
+ */
+int
+a2port(const char *s)
+{
+ long port;
+ char *endp;
+
+ errno = 0;
+ port = strtol(s, &endp, 0);
+ if (s == endp || *endp != '\0' ||
+ (errno == ERANGE && (port == LONG_MIN || port == LONG_MAX)) ||
+ port <= 0 || port > 65535)
+ return 0;
+
+ return port;
+}
+
+#define SECONDS 1
+#define MINUTES (SECONDS * 60)
+#define HOURS (MINUTES * 60)
+#define DAYS (HOURS * 24)
+#define WEEKS (DAYS * 7)
+
+/*
+ * Convert a time string into seconds; format is
+ * a sequence of:
+ * time[qualifier]
+ *
+ * Valid time qualifiers are:
+ * <none> seconds
+ * s|S seconds
+ * m|M minutes
+ * h|H hours
+ * d|D days
+ * w|W weeks
+ *
+ * Examples:
+ * 90m 90 minutes
+ * 1h30m 90 minutes
+ * 2d 2 days
+ * 1w 1 week
+ *
+ * Return -1 if time string is invalid.
+ */
+long
+convtime(const char *s)
+{
+ long total, secs;
+ const char *p;
+ char *endp;
+
+ errno = 0;
+ total = 0;
+ p = s;
+
+ if (p == NULL || *p == '\0')
+ return -1;
+
+ while (*p) {
+ secs = strtol(p, &endp, 10);
+ if (p == endp ||
+ (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) ||
+ secs < 0)
+ return -1;
+
+ switch (*endp++) {
+ case '\0':
+ endp--;
+ case 's':
+ case 'S':
+ break;
+ case 'm':
+ case 'M':
+ secs *= MINUTES;
+ break;
+ case 'h':
+ case 'H':
+ secs *= HOURS;
+ break;
+ case 'd':
+ case 'D':
+ secs *= DAYS;
+ break;
+ case 'w':
+ case 'W':
+ secs *= WEEKS;
+ break;
+ default:
+ return -1;
+ }
+ total += secs;
+ if (total < 0)
+ return -1;
+ p = endp;
+ }
+
+ return total;
+}
+
+char *
+cleanhostname(char *host)
+{
+ if (*host == '[' && host[strlen(host) - 1] == ']') {
+ host[strlen(host) - 1] = '\0';
+ return (host + 1);
+ } else
+ return host;
+}
+
+char *
+colon(char *cp)
+{
+ int flag = 0;
+
+ if (*cp == ':') /* Leading colon is part of file name. */
+ return (0);
+ if (*cp == '[')
+ flag = 1;
+
+ for (; *cp; ++cp) {
+ if (*cp == '@' && *(cp+1) == '[')
+ flag = 1;
+ if (*cp == ']' && *(cp+1) == ':' && flag)
+ return (cp+1);
+ if (*cp == ':' && !flag)
+ return (cp);
+ if (*cp == '/')
+ return (0);
+ }
+ return (0);
+}
+
+/* function to assist building execv() arguments */
+void
+addargs(arglist *args, char *fmt, ...)
+{
+ va_list ap;
+ char buf[1024];
+
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+
+ if (args->list == NULL) {
+ args->nalloc = 32;
+ args->num = 0;
+ } else if (args->num+2 >= args->nalloc)
+ args->nalloc *= 2;
+
+ args->list = xrealloc(args->list, args->nalloc * sizeof(char *));
+ args->list[args->num++] = xstrdup(buf);
+ args->list[args->num] = NULL;
+}
+
mysig_t
mysignal(int sig, mysig_t act)
{
memset(&sa, 0, sizeof(sa));
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
-#if defined(SA_RESTART)
- if (sig == SIGCHLD)
- sa.sa_flags |= SA_RESTART;
-#endif
#if defined(SA_INTERRUPT)
if (sig == SIGALRM)
sa.sa_flags |= SA_INTERRUPT;