misc.c revision 6f8d59d8fcaf391990ca04c7bdcf65ab23320fe0
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include "includes.h"
#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') {
*t = '\0';
return s;
}
t++;
}
return s;
}
void
set_nonblock(int fd)
{
int val;
if (val < 0) {
return;
}
if (val & O_NONBLOCK) {
return;
}
val |= O_NONBLOCK;
debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
}
void
unset_nonblock(int fd)
{
int val;
if (val < 0) {
return;
}
if (!(val & O_NONBLOCK)) {
return;
}
val &= ~O_NONBLOCK;
debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
}
/* disable nagle on socket */
void
set_nodelay(int fd)
{
int opt;
return;
}
if (opt == 1) {
return;
}
opt = 1;
}
/* Characters considered whitespace in strsep calls. */
#define WHITESPACE " \t\r\n"
/*
* Function returns a pointer to the 1st token on the line. Such a token can
* be an empty string in the case of '*s' equal to " value". It changes the
* first whitespace token or '=' character after the 1st token to '\0'. Upon
* return it changes '*s' to point to the first character of the next token.
* That token may be an empty string if the 1st token was followed only by
* whitespace or it could be a NULL pointer if the line contained one token
* only.
*/
char *
strdelim(char **s)
{
char *old;
int wspace = 0;
if (*s == NULL)
return NULL;
old = *s;
if (*s == NULL)
return (old);
/* Allow only one '=' to be skipped */
if (*s[0] == '=')
wspace = 1;
*s[0] = '\0';
if (*s[0] == '=' && !wspace)
return (old);
}
struct passwd *
{
#ifdef HAVE_PW_EXPIRE_IN_PASSWD
#endif
#ifdef HAVE_PW_CHANGE_IN_PASSWD
#endif
#ifdef HAVE_PW_CLASS_IN_PASSWD
#endif
return copy;
}
void
{
struct passwd *p;
return;
p = *pw;
#ifdef HAVE_PW_CLASS_IN_PASSWD
#endif
xfree(p);
}
/*
* Port must be >0 and <=65535.
* Return 0 if invalid.
*/
int
a2port(const char *s)
{
long port;
char *endp;
errno = 0;
return 0;
return port;
}
#define SECONDS 1
/*
* 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)
{
const char *p;
char *endp;
errno = 0;
total = 0;
p = s;
if (p == NULL || *p == '\0')
return -1;
while (*p) {
if (p == endp ||
secs < 0)
return -1;
switch (*endp++) {
case '\0':
endp--;
break;
case 's':
case 'S':
break;
case 'm':
case 'M':
break;
case 'h':
case 'H':
break;
case 'd':
case 'D':
break;
case 'w':
case 'W':
break;
default:
return -1;
}
if (total < 0)
return -1;
p = endp;
}
return total;
}
/*
* Argument may be modified (for termination).
* Returns *cp if parsing succeeds.
* *cp is set to the start of the next delimiter, if one was found.
* If this is the last field, *cp is set to NULL.
*/
char *
{
char *s, *old;
return NULL;
if (*s == '[') {
return NULL;
else
s++;
switch (*s) {
case '\0':
break;
case ':':
case '/':
*s = '\0'; /* terminate */
*cp = s + 1;
break;
default:
return NULL;
}
return old;
}
char *
cleanhostname(char *host)
{
return (host + 1);
} else
return host;
}
char *
{
int flag = 0;
return (0);
if (*cp == '[')
flag = 1;
flag = 1;
return (cp+1);
return (cp);
if (*cp == '/')
return (0);
}
return (0);
}
/* function to assist building execv() arguments */
/* PRINTFLIKE2 */
void
{
char buf[1024];
}
void
{
char *cp;
int r;
if (r == -1)
fatal("replacearg: argument too long");
fatal("replacearg: tried to replace invalid arg %d >= %d",
}
void
{
u_int i;
}
}
/*
* Expand a string with a set of %[char] escapes. A number of escapes may be
* specified as (char *escape_chars, char *replacement) pairs. The list must
* be terminated by a NULL escape_char. Returns replaced string in memory
* allocated by xmalloc.
*/
char *
percent_expand(const char *string, ...)
{
#define EXPAND_MAX_KEYS 16
struct {
const char *key;
const char *repl;
} keys[EXPAND_MAX_KEYS];
char buf[4096];
/* Gather keys */
break;
fatal("percent_expand: NULL replacement");
}
if (num_keys >= EXPAND_MAX_KEYS)
fatal("percent_expand: too many keys");
/* Expand string */
*buf = '\0';
if (*string != '%') {
if (i >= sizeof(buf))
fatal("percent_expand: string too long");
buf[i] = '\0';
continue;
}
string++;
if (*string == '%')
goto append;
for (j = 0; j < num_keys; j++) {
if (i >= sizeof(buf))
fatal("percent_expand: string too long");
break;
}
}
if (j >= num_keys)
}
}
/*
* do not touch those that are already open.
*/
void
sanitise_stdfd(void)
{
exit(1);
}
while (++dupfd <= 2) {
/* Only clobber closed fds */
continue;
exit(1);
}
}
if (nullfd > 2)
}
char *
{
char b[3], *r;
if (l > 65536)
return xstrdup("tohex: length > 65536");
for (i = 0; i < l; i++) {
snprintf(b, sizeof(b), "%02x", p[i]);
}
return (r);
}
{
u_int64_t v;
v = (u_int64_t)p[0] << 56;
v |= (u_int64_t)p[7];
return (v);
}
{
u_int32_t v;
v = (u_int32_t)p[0] << 24;
v |= (u_int32_t)p[3];
return (v);
}
{
u_int16_t v;
v = (u_int16_t)p[0] << 8;
v |= (u_int16_t)p[1];
return (v);
}
void
{
}
void
{
}
void
{
}
{
#ifdef HAVE_SIGACTION
return (mysig_t) -1;
#if defined(SA_INTERRUPT)
#endif
return (mysig_t) -1;
}
return (osa.sa_handler);
#else
#endif
}
/*
* Return true if argument is one of "yes", "true", "no" or "false". If
* 'active' is 0 than we are in a non-matching Host section of the
* configuration file so we check the syntax but will not set the value of
* '*option'. Otherwise we set its value if not already set.
*/
int
int active)
{
int value = -1;
value = 1;
value = 0;
return (value != -1);
}
/*
* Convert a string to lowercase. The string returned is an internally allocated
* one so the consumer of this function is not expected to change it or free it.
*/
char *
tolowercase(const char *s)
{
int i, len;
static int lenret = 0;
/* allocate a new string if the old one it not long enough to store s */
}
/* process the string including the ending '\0' */
for (i = 0; i < len; ++i)
return (ret);
}