blob: b971ebb0c3519c7a21b39bf79cf2bf536cda4dbf [file] [log] [blame]
/*
* Copyright (c) 2005, 2006 by KoanLogic s.r.l. - All rights reserved.
*/
static const char rcsid[] =
"$Id: misc.c,v 1.16 2006/01/09 12:38:38 tat Exp $";
#ifdef HAVE_CONFIG_H
#include <wsman_config.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <ctype.h>
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#include <u/os.h>
#include <u/misc.h>
#include <u/carpal.h>
#include <u/memory.h>
#ifndef HAVE_STRSEP
extern char *strsep( char **, const char *);
#endif
/**
* \defgroup misc Miscellaneous
* \{
*/
/** \brief Returns \c 0 if \p c is neither a space or a tab, not-zero otherwise.
*/
__INLINE__ int u_isblank(int c)
{
return c == ' ' || c == '\t';
}
/** \brief Returns \c 0 if \p c is not a quote, not-zero otherwise.
*/
__INLINE__ int u_isquote(int c)
{
return c == '"';
}
void u_trim_quotes(char *s)
{
char *p;
if(!s)
return;
/* trim trailing blanks */
p = s + strlen(s) -1;
while(s < p && u_isquote(*p))
--p;
p[1] = 0;
/* trim leading blanks */
p = s;
while(*p && u_isquote(*p))
++p;
if(p > s)
memmove(s, p, 1 + strlen(p));
}
/** \brief Removes leading and trailing blanks (spaces and tabs) from \p s
*/
void u_trim(char *s)
{
char *p;
if(!s)
return;
/* trim trailing blanks */
p = s + strlen(s) -1;
while(s < p && u_isblank(*p))
--p;
p[1] = 0;
/* trim leading blanks */
p = s;
while(*p && u_isblank(*p))
++p;
if(p > s)
memmove(s, p, 1 + strlen(p));
}
/** \brief Returns \c 1 if \p ln is a blank string i.e. a string formed by
ONLY spaces and/or tabs characters.
*/
__INLINE__ int u_isblank_str(const char *ln)
{
for(; *ln; ++ln)
if(!u_isblank(*ln))
return 0;
return 1;
}
/** \brief Returns \c 0 if \p c is neither a CR (\\r) or a LF (\\n),
not-zero otherwise.
*/
__INLINE__ int u_isnl(int c)
{
return c == '\n' || c == '\r';
}
/** \brief Dups the first \p len chars of \p s.
Returns the dupped zero terminated string or \c NULL on error.
*/
char *u_strndup(const char *s, size_t len)
{
char *cp;
if ((cp = (char*) u_malloc(len + 1)) == NULL)
return NULL;
memcpy(cp, s, len);
cp[len] = 0;
return cp;
}
/** \brief Dups the supplied string \p s */
char *u_strdup(const char *s)
{
return u_strndup(s, strlen(s));
}
/** \brief Save the PID of the calling process to a file named \p pf
(that should be a fully qualified path).
Returns \c 0 on success, not-zero on error.
*/
int u_savepid (const char *pf)
{
FILE *pfp;
dbg_return_if ((pfp = fopen(pf, "w")) == NULL, ~0);
fprintf(pfp, "%ld\n", (long) getpid());
fclose(pfp);
return 0;
}
/** \brief Safe string copy, see also the U_SSTRNCPY define
Safe string copy which null-terminates the destination string \a dst before
copying the source string \a src for no more than \a size bytes.
Returns a pointer to the destination string \a dst.
*/
char *u_sstrncpy (char *dst, const char *src, size_t size)
{
dst[size] = '\0';
return strncpy(dst, src, size);
}
/** \brief Dups the memory block \c src of size \c size.
Returns the pointer of the dup'd block on success, \c NULL on error.
*/
void* u_memdup(const void *src, size_t size)
{
void *p;
p = u_malloc(size);
if(p)
memcpy(p, src, size);
return p;
}
/**
* \brief tokenize the supplied \p wlist string
*
* Tokenize the \p delim separated string \p wlist and place its
* pieces (at most \p tokv_sz - 1) into \p tokv.
*
* \param wlist list of strings possibily separated by chars in \p delim
* \param delim set of token separators
* \param tokv pre-allocated string array
* \param tokv_sz number of cells in \p tokv array
*
*/
int u_tokenize (char *wlist, const char *delim, char **tokv, size_t tokv_sz)
{
char **ap;
dbg_return_if (wlist == NULL, ~0);
dbg_return_if (delim == NULL, ~0);
dbg_return_if (tokv == NULL, ~0);
dbg_return_if (tokv_sz == 0, ~0);
ap = tokv;
for ( ; (*ap = strsep(&wlist, delim)) != NULL; )
{
/* skip empty field */
if (**ap == '\0')
continue;
/* check bounds */
if (++ap >= &tokv[tokv_sz - 1])
break;
}
/* put an explicit stopper to tokv */
*ap = NULL;
return 0;
}
size_t
u_tokenize1(char **result, size_t reslen, char *str, char delim)
{
char *p, *n;
size_t i = 0;
if (!str)
return 0;
for (n = str; *n == ' '; n++);
p = n;
for (i = 0; *n != '\0';) {
if (i == reslen)
return i;
if (*n == delim) {
*n = '\0';
if (*p)
result[i++] = p;
p = ++n;
} else
n++;
}
if (*p)
result[i++] = p;
return i; /* number of tokens */
}
/**
* \brief snprintf-like function that returns 0 on success and ~0 on error
*
* snprintf-like function that returns 0 on success and ~0 on error
*
* \param str destination buffer
* \param size size of \p str
* \param fmt snprintf format string
*
* Returns \c 0 on success, not-zero on error.
*/
int u_snprintf(char *str, size_t size, const char *fmt, ...)
{
va_list ap;
int wr;
va_start(ap, fmt);
wr = vsnprintf(str, size, fmt, ap);
va_end(ap);
dbg_err_if(wr < 0 || wr >= (int)size);
return 0;
err:
return ~0;
}
/**
* \brief snprintf-like function that handle path separator issues
*
* Calls snprintf with the provided arguments and remove consecutive
* path separators from the resulting string.
*
* \param buf destination buffer
* \param sz size of \p str
* \param sep path separator to use ('/' or '\')
* \param fmt snprintf format string
*
* Returns \c 0 on success, not-zero on error.
*/
int u_path_snprintf(char *buf, size_t sz, char sep, const char *fmt, ...)
{
va_list ap;
int wr;
size_t i, len;
va_start(ap, fmt);
wr = vsnprintf(buf, sz, fmt, ap);
va_end(ap);
dbg_err_if(wr < 0 || wr >= (int)sz);
/* remove multiple consecutive '/' */
for(len = i = strlen(buf); i > 0; --i)
if(buf[i] == sep && buf[i-1] == sep)
memmove(buf + i, buf + i + 1, len--);
return 0;
err:
return ~0;
}
__INLINE__ void u_use_unused_args(char *dummy, ...)
{
dummy = 0;
return;
}
/** \brief Return \c 1 if the supplied buffer \p data has non-ascii bytes */
int u_data_is_bin (char *data, size_t sz)
{
size_t i;
for (i = 0; i < sz; i++)
{
if (!isascii(data[i]))
return 1;
}
return 0;
}
/* Added for openwsman */
int isstrdigit(char *str)
{
if (str == NULL || *str == '\0')
return 0;
while (*str != '\0') {
if (!isdigit(*str))
return 0;
str++;
}
return 1;
}
int u_path_is_absolute (const char *filename)
{
int ret = 0;
#ifdef WIN32
if (filename[1] == ':') ret = 1;
#endif
/* we'll count as absolute paths specified using "." */
if (*filename == '.' || *filename == '/') {
ret = 1;
}
return ret;
}
/**
* \}
*/