Beispiel #1
0
/*~f w_io_result_t w_io_read (w_io_t *stream, void *buffer, size_t count)
 *
 * Reads up to `count` bytes from the an input `stream`, placing the data in
 * in memory starting at `buffer`.
 *
 * Passing a `count` of zero always succeeds and has no side effects.
 *
 * If reading succeeds, the amount of bytes read may be smaller than the
 * requested `count`. The reason may be that the end-of-file marker has been
 * reached (and it will be notified at the next attempt of reading data), or
 * because no more data is available for reading at the moment.
 */
w_io_result_t
w_io_read (w_io_t *io, void *buf, size_t len)
{
    w_assert (io);
    w_io_result_t r = W_IO_RESULT (0);

    if (w_unlikely (len == 0))
        return r;

    w_assert (buf);

    /* Handle the putback character... makes things a bit messier */
    if (w_unlikely (io->backch != W_IO_EOF)) {
        *((char*) buf) = io->backch;
        buf = (char*) buf + 1;
        io->backch = W_IO_EOF;

        /* Check whether more characters are to be read */
        if (!--len)
            return W_IO_RESULT (1);
    }

    if (w_likely (io->read != NULL)) {
        r = (*io->read) (io, buf, len);
    } else {
        r = W_IO_RESULT_ERROR (errno = EBADF);
    }
    return r;
}
Beispiel #2
0
static int
_parse_gids (char     *s,
             uidgid_t *u)
{
    char *pos = NULL;
    gid_t gid;

    w_assert (s);
    w_assert (u);

    if (u->ngid >= DMON_GID_COUNT) {
        w_printerr ("more than $L groups given, ignoring additional ones\n",
                    DMON_GID_COUNT);
        return 0;
    }

    pos = strchr (s, ':');
    if (pos != NULL)
        *pos = '\0';

    if (name_to_gid (s, &gid)) {
        if (pos != NULL) *pos = ':';
        return 1;
    }

    if (pos != NULL)
        *pos = ':';

    u->gids[u->ngid++] = gid;

    return (pos == NULL) ? 0 : _parse_gids (pos + 1, u);
}
Beispiel #3
0
int
name_to_gid (const char *str, gid_t *result)
{
    struct group *grp;
    unsigned long num;
    char *dummy;

    w_assert (str);
    w_assert (result);

    num = strtoul (str, &dummy, 0);

    if (num == ULONG_MAX && errno == ERANGE)
        return 1;

    if (!dummy || *dummy == '\0') {
        *result = (gid_t) num;
        return 0;
    }

    if ((grp = getgrnam (str)) == NULL)
        return 1;


    *result = grp->gr_gid;
    return 0;
}
Beispiel #4
0
int
parse_uidgids (char     *s,
               uidgid_t *u)
{
    char *pos = NULL;

    w_assert (s);
    w_assert (u);

    memset (u, 0x00, sizeof (uidgid_t));

    pos = strchr (s, ':');
    if (pos != NULL)
        *pos = '\0';

    if (name_to_uidgid (s, &u->uid, &u->gid)) {
        if (pos != NULL) *pos = ':';
        return 1;
    }

    if (pos != NULL)
        *pos = ':';
    else
        return 0;

    return (pos == NULL) ? 0 : _parse_gids (pos + 1, u);
}
Beispiel #5
0
static bool
_parse_limit_number (const char *sval, long *rval)
{
    w_assert (sval != NULL);
    w_assert (rval != NULL);
    return !(sscanf (sval, "%li", rval) == 1);
}
Beispiel #6
0
bool
w_str_time_period (const char *str, unsigned long long *val)
{
    unsigned long long v = 0;
    char *endpos;

    w_assert (str);
    w_assert (val);

    v = strtoull (str, &endpos, 0);

    if (v == ULLONG_MAX && errno == ERANGE)
        return false;

    if (endpos) {
        switch (*endpos) {
            case 'y': v *= 60 * 60 * 24 * 365; break; /* years   */
            case 'M': v *= 60 * 60 * 24 * 30;  break; /* months  */
            case 'w': v *= 60 * 60 * 24 * 7;   break; /* weeks   */
            case 'd': v *= 60 * 60 * 24;       break; /* days    */
            case 'h': v *= 60 * 60;            break; /* hours   */
            case 'm': v *= 60;                 break; /* minutes */
            case 's': case '\0':               break; /* seconds */
            default : return false;
        }
    }

    return (*val = v, true);
}
Beispiel #7
0
bool
w_str_size_bytes (const char *str, unsigned long long *val)
{
    unsigned long long v = 0;
    char *endpos;

    w_assert (str);
    w_assert (val);

    v = strtoull (str, &endpos, 0);

    if (v == ULLONG_MAX && errno == ERANGE)
        return false;

    if (endpos) {
        switch (*endpos) {
            case 'g': case 'G': v *= 1024 * 1024 * 1024; break; /* gigabytes */
            case 'm': case 'M': v *= 1024 * 1024;        break; /* megabytes */
            case 'k': case 'K': v *= 1024;               break; /* kilobytes */
            case 'b': case 'B': case '\0':               break; /* bytes     */
            default : return false;
        }
    }

    return (*val = v, true);
}
Beispiel #8
0
int
parse_limit_arg (const char *str, int *what, long *value)
{
    unsigned i;

    w_assert (str != NULL);
    w_assert (what != NULL);
    w_assert (value != NULL);

    if (!strcmp (str, "help")) {
        for (i = 0; i < w_lengthof (rlimit_specs); i++) {
            w_print ("$s -- $s\n",
                     rlimit_specs[i].name,
                     rlimit_specs[i].desc);
        }
        return -1;
    }

    for (i = 0; i < w_lengthof (rlimit_specs); i++) {
        unsigned nlen = strlen (rlimit_specs[i].name);
        if (!strncmp (str, rlimit_specs[i].name, nlen) && str[nlen] == '=') {
            *what = rlimit_specs[i].what;
            return ((*rlimit_specs[i].parse) (str + nlen + 1, value));
        }
    }

    return 1;
}
Beispiel #9
0
int
name_to_uidgid (const char *str,
                uid_t      *uresult,
                gid_t      *gresult)
{
    struct passwd *pw;
    unsigned long num;
    char *dummy;

    w_assert (str);
    w_assert (uresult);
    w_assert (gresult);

    num = strtoul (str, &dummy, 0);
    if (num == ULONG_MAX && errno == ERANGE)
        return 1;

    if (!dummy || *dummy == '\0') {
        if ((pw = getpwuid ((uid_t) num)) == NULL)
            return 1;
    }
    else {
        if ((pw = getpwnam (str)) == NULL)
            return 1;
    }

    *uresult = pw->pw_uid;
    *gresult = pw->pw_gid;

    return 0;
}
Beispiel #10
0
static inline const w_opt_t*
_opt_lookup_long (const w_opt_t *opt, const char *str)
{
    w_assert (opt != NULL);
    w_assert (str != NULL);
    for (; opt->string != NULL; opt++)
        if (!strcmp (opt->string, str)) return opt;
    return NULL;
}
Beispiel #11
0
static bool
_parse_limit_bytes (const char *sval, long *rval)
{
    w_assert (sval != NULL);
    w_assert (rval != NULL);

    unsigned long long val;
    bool failed = w_str_size_bytes (sval, &val);
    *rval = val;
    return failed || (val > LONG_MAX);
}
Beispiel #12
0
int
replace_args_string (const char *str,
                     int        *pargc,
                     char     ***pargv)
{
    int ch;
    char *s = NULL;
    int maxarg = REPLACE_ARGS_VCHUNK;
    int numarg = 0;
    int quotes = 0;
    int smax = 0;
    int slen = 0;
    char **argv = w_alloc (char*, maxarg);

    w_assert (str);
    w_assert (pargc);
    w_assert (pargv);

    /* Copy argv[0] pointer */
    argv[numarg++] = (*pargv)[0];

    while ((ch = *str++) != '\0') {
        if (!quotes && isspace (ch)) {
            if (!slen) {
                /*
                 * Got spaces not inside a quote, and the current argument
                 * is empty: skip spaces at the left side of an argument.
                 */
                continue;
            }

            /*
             * Not inside quotes, got space: add '\0', split and reset
             */
            if (numarg >= maxarg) {
                maxarg += REPLACE_ARGS_VCHUNK;
                argv = w_resize (argv, char*, maxarg);
            }

            /* Add terminating "\0" */
            if (slen >= smax) {
                smax += REPLACE_ARGS_SCHUNK;
                s = w_resize (s, char, smax);
            }

            /* Save string in array. */
            s[slen] = '\0';
            argv[numarg++] = s;

            /* Reset stuff */
            smax = slen = 0;
            s = NULL;
            continue;
        }
Beispiel #13
0
w_io_result_t
w_tnetstr_write_buffer (w_io_t *io, const w_buf_t *value)
{
    w_assert (io);
    w_assert (value);

    if (w_unlikely (w_buf_size (value) > _W_TNS_MAX_PAYLOAD))
        return W_IO_RESULT_ERROR (EINVAL);

    return w_io_format (io, "$L:$B,", w_buf_size (value), value);
}
Beispiel #14
0
w_io_result_t
w_tnetstr_write_string (w_io_t *io, const char *value)
{
    w_assert (io);
    w_assert (value);

    size_t len = strlen (value);
    if (w_unlikely ((len) > _W_TNS_MAX_PAYLOAD))
        return W_IO_RESULT_ERROR (EINVAL);

    return w_io_format (io, "$L:$S,", len, len, value);
}
Beispiel #15
0
static w_opt_status_t
_config_option (const w_opt_context_t *ctx)
{
    w_assert (ctx);
    w_assert (ctx->argv);
    w_assert (ctx->argv[0]);

    w_printerr ("$s: Option --config/-C must be the first one specified\n",
                ctx->argv[0]);

    return W_OPT_EXIT_FAIL;
}
Beispiel #16
0
w_opt_status_t
W_OPT_TIME_PERIOD (const w_opt_context_t *ctx)
{
    w_assert (ctx);
    w_assert (ctx->option);
    w_assert (ctx->option->extra);
    w_assert (ctx->option->narg == 1);

    return (!w_str_time_period (ctx->argument[0], ctx->option->extra))
            ? W_OPT_BAD_ARG
            : W_OPT_OK;
}
Beispiel #17
0
w_opt_status_t
W_OPT_DATA_SIZE (const w_opt_context_t *ctx)
{
    w_assert (ctx);
    w_assert (ctx->option);
    w_assert (ctx->option->extra);
    w_assert (ctx->option->narg == 1);

    return (!w_str_size_bytes (ctx->argument[0], ctx->option->extra))
            ? W_OPT_BAD_ARG
            : W_OPT_OK;
}
Beispiel #18
0
/*~f w_io_result_t w_io_format (w_io_t *stream, const char *format, ...)
 *
 * Writes data with a given `format` to an output `stream`.
 * The amount of consumed arguments depends on the `format` string.
 *
 * See :ref:`formatted-output` for more information.
 */
w_io_result_t
w_io_format (w_io_t *io, const char *fmt, ...)
{
    w_assert (io);
    w_assert (fmt);

    va_list args;
    va_start (args, fmt);
    w_io_result_t r = w_io_formatv (io, fmt, args);
    va_end (args);
    return r;
}
Beispiel #19
0
static w_opt_status_t
_store_uidgids_option (const w_opt_context_t *ctx)
{
    w_assert (ctx);
    w_assert (ctx->userdata);
    w_assert (ctx->argument);
    w_assert (ctx->argument[0]);

    return (parse_uidgids (ctx->argument[0], ctx->option->extra))
            ? W_OPT_BAD_ARG
            : W_OPT_OK;
}
Beispiel #20
0
w_io_result_t
w_tnetstr_dump_string (w_buf_t *buffer, const char *value)
{
    w_assert (buffer);
    w_assert (value);

    size_t len = strlen (value);
    if (w_unlikely (len > _W_TNS_MAX_PAYLOAD))
        return W_IO_RESULT_ERROR (EINVAL);

    return w_buf_format (buffer, "$L:$S,", len, len, value);
}
Beispiel #21
0
bool
w_str_float(const char *str, float *val)
{
	float v;
	char *chkstr;
	w_assert(str != NULL);
	w_assert(val != NULL);

	v = strtof(str, &chkstr);
	if (((v == HUGE_VALF) || (v == -HUGE_VALF)) && (errno == ERANGE))
		return false;

	return (*val = v, true);
}
Beispiel #22
0
w_io_result_t
w_tnetstr_dump_list (w_buf_t *buffer, const w_list_t *value)
{
    w_assert (buffer);
    w_assert (value);

    w_buf_t buf = W_BUF;
    w_io_result_t r;

    w_list_foreach (item, value) {
        r = w_tnetstr_dump (&buf, (w_variant_t*) *item);
        if (w_unlikely (w_io_failed (r)))
            break;
    }
Beispiel #23
0
bool
w_str_double(const char *str, double *val)
{
	double v;
	char *chkstr;
	w_assert(str != NULL);
	w_assert(val != NULL);

	v = strtod(str, &chkstr);
	if (((v == HUGE_VAL) || (v == -HUGE_VAL)) && (errno == ERANGE))
		return false;

	return (*val = v, true);
}
Beispiel #24
0
/*
 * This one goes for simple string assignment. Note that memory may be
 * leaked, as a copy of the arguments is made. It's up to the programmer
 * taking care of freeing that.
 */
w_opt_status_t
W_OPT_STRING (const w_opt_context_t *context)
{
    unsigned i;
    w_assert (context != NULL);
    w_assert (context->option != NULL);
    w_assert (context->option->narg > 0);
    w_assert (context->option->extra != NULL);

    for (i = 0; i < context->option->narg; i++)
        ((char**) context->option->extra)[i] = w_str_dup (context->argument[i]);

    return W_OPT_OK;
}
Beispiel #25
0
bool
w_str_long(const char *str, long *val)
{
	long v;
	char *chkstr;
	w_assert(str != NULL);
	w_assert(val != NULL);

	v = strtol(str, &chkstr, 0);
	if ((*str != '\0') && (*chkstr == '\0') &&
	        !((v == LONG_MAX || v == LONG_MIN) && (errno == ERANGE)))
		return (*val = v, true);

	return false;
}
Beispiel #26
0
bool
w_str_ulong(const char *str, unsigned long *val)
{
	unsigned long v;
	char *chkstr;
	w_assert(str != NULL);
	w_assert(val != NULL);

	v = strtoul(str, &chkstr, 0);
	if ((*str != '\0') && (*chkstr == '\0') &&
	        !(v == ULONG_MAX && errno == ERANGE))
		return (*val = v, true);

	return false;
}
Beispiel #27
0
/*~f void w_io_mem_init (w_io_mem_t *stream, uint8_t *address, size_t size)
 *
 * Initializes a `stream` object (possibly located in the stack) to be used
 * with a region of memory of a given `size` located at `address`.
 */
void
w_io_mem_init (w_io_mem_t *io, uint8_t *data, size_t size)
{
    w_assert (io);
    w_assert (data);

    w_io_init ((w_io_t*) io);

    io->parent.close = w_io_mem_close;
    io->parent.write = w_io_mem_write;
    io->parent.read  = w_io_mem_read;
    io->data         = data;
    io->size         = size;
    io->pos          = 0;
}
Beispiel #28
0
ssize_t
w_io_fscan (w_io_t *io, const char *fmt, ...)
{
    ssize_t ret;
    va_list args;

    w_assert (io);
    w_assert (fmt);

    va_start (args, fmt);
    ret = w_io_fscanv (io, fmt, args);
    va_end (args);

    return ret;
}
Beispiel #29
0
static inline const w_opt_t*
_opt_lookup_fuzz (const w_opt_t *opt, const char *str, const char *prg)
{
    size_t len;
    const w_opt_t *ret;

    w_assert (opt != NULL);
    w_assert (str != NULL);
    w_assert (prg != NULL);

    len = strlen (str);
    for (; opt->string != NULL; opt++)
        if (!strncmp (opt->string, str, len))
            break;

    if (opt->string == NULL)
        return NULL;

    ret = opt++;

    /* Check wether the option string is not ambiguous. */
    for (; opt->string != NULL; opt++)
        if (!strncmp (opt->string, str, len))
            break;

    /* If we reach the end, no other prefix is equal -> ok. */
    if (opt->string == NULL)
        return ret;

    /* ...otherwise, we are in trouble. */
    W_IO_NORESULT (w_io_format (w_stderr,
                                "$s: option '$s' is ambiguous, possibilities:\n",
                                prg, str));
    for (; ret->string != NULL; ret++) {
        if (!strncmp (ret->string, str, len)) {
            W_IO_NORESULT (w_io_format (w_stderr,
                                        "    --$s\n",
                                        ret->string));
        }
    }
    W_IO_NORESULT (w_io_format (w_stderr,
                                "Hint: try '$s --help'\n",
                                prg));

    exit (EXIT_FAILURE);
    return NULL; /* Never reached -- but keeps compiler happy =) */
}
Beispiel #30
0
/*~f w_io_result_t w_io_putchar (w_io_t *stream, int character)
 *
 * Writes a `character` to an output `stream`.
 */
w_io_result_t
w_io_putchar (w_io_t *io, int ch)
{
    w_assert (io);

    char bch = ch;
    return w_io_write (io, &bch, 1);
}