/*
 *  OpenVPN -- An application to securely tunnel IP networks
 *             over a single TCP/UDP port, with support for SSL/TLS-based
 *             session authentication and key exchange,
 *             packet encryption, packet authentication, and
 *             packet compression.
 *
 *  Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2
 *  as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *
 *  A printf-like function (that only recognizes a subset of standard printf
 *  format operators) that prints arguments to an argv list instead
 *  of a standard string.  This is used to build up argv arrays for passing
 *  to execve.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#elif defined(_MSC_VER)
#include "config-msvc.h"
#endif

#include "syshead.h"

#include "argv.h"
#include "integer.h"
#include "options.h"

static void
argv_init(struct argv *a)
{
    a->capacity = 0;
    a->argc = 0;
    a->argv = NULL;
}

struct argv
argv_new(void)
{
    struct argv ret;
    argv_init(&ret);
    return ret;
}

void
argv_reset(struct argv *a)
{
    size_t i;
    for (i = 0; i < a->argc; ++i)
    {
        free(a->argv[i]);
    }
    free(a->argv);
    argv_init(a);
}

static void
argv_extend(struct argv *a, const size_t newcap)
{
    if (newcap > a->capacity)
    {
        char **newargv;
        size_t i;
        ALLOC_ARRAY_CLEAR(newargv, char *, newcap);
        for (i = 0; i < a->argc; ++i)
        {
            newargv[i] = a->argv[i];
        }
        free(a->argv);
        a->argv = newargv;
        a->capacity = newcap;
    }
}

static void
argv_grow(struct argv *a, const size_t add)
{
    const size_t newargc = a->argc + add + 1;
    ASSERT(newargc > a->argc);
    argv_extend(a, adjust_power_of_2(newargc));
}

static void
argv_append(struct argv *a, char *str)  /* str must have been malloced or be NULL */
{
    argv_grow(a, 1);
    a->argv[a->argc++] = str;
}

static struct argv
argv_clone(const struct argv *a, const size_t headroom)
{
    struct argv r;
    size_t i;

    argv_init(&r);
    for (i = 0; i < headroom; ++i)
    {
        argv_append(&r, NULL);
    }
    if (a)
    {
        for (i = 0; i < a->argc; ++i)
        {
            argv_append(&r, string_alloc(a->argv[i], NULL));
        }
    }
    return r;
}

struct argv
argv_insert_head(const struct argv *a, const char *head)
{
    struct argv r;
    r = argv_clone(a, 1);
    r.argv[0] = string_alloc(head, NULL);
    return r;
}

static char *
argv_term(const char **f)
{
    const char *p = *f;
    const char *term = NULL;
    size_t termlen = 0;

    if (*p == '\0')
    {
        return NULL;
    }

    while (true)
    {
        const int c = *p;
        if (c == '\0')
        {
            break;
        }
        if (term)
        {
            if (!isspace(c))
            {
                ++termlen;
            }
            else
            {
                break;
            }
        }
        else
        {
            if (!isspace(c))
            {
                term = p;
                termlen = 1;
            }
        }
        ++p;
    }
    *f = p;

    if (term)
    {
        char *ret;
        ASSERT(termlen > 0);
        ret = malloc(termlen + 1);
        check_malloc_return(ret);
        memcpy(ret, term, termlen);
        ret[termlen] = '\0';
        return ret;
    }
    else
    {
        return NULL;
    }
}

const char *
argv_str(const struct argv *a, struct gc_arena *gc, const unsigned int flags)
{
    if (a->argv)
    {
        return print_argv((const char **)a->argv, gc, flags);
    }
    else
    {
        return "";
    }
}

void
argv_msg(const int msglev, const struct argv *a)
{
    struct gc_arena gc = gc_new();
    msg(msglev, "%s", argv_str(a, &gc, 0));
    gc_free(&gc);
}

void
argv_msg_prefix(const int msglev, const struct argv *a, const char *prefix)
{
    struct gc_arena gc = gc_new();
    msg(msglev, "%s: %s", prefix, argv_str(a, &gc, 0));
    gc_free(&gc);
}

static void
argv_printf_arglist(struct argv *a, const char *format, va_list arglist)
{
    char *term;
    const char *f = format;

    argv_extend(a, 1); /* ensure trailing NULL */

    while ((term = argv_term(&f)) != NULL)
    {
        if (term[0] == '%')
        {
            if (!strcmp(term, "%s"))
            {
                char *s = va_arg(arglist, char *);
                if (!s)
                {
                    s = "";
                }
                argv_append(a, string_alloc(s, NULL));
            }
            else if (!strcmp(term, "%d"))
            {
                char numstr[64];
                openvpn_snprintf(numstr, sizeof(numstr), "%d", va_arg(arglist, int));
                argv_append(a, string_alloc(numstr, NULL));
            }
            else if (!strcmp(term, "%u"))
            {
                char numstr[64];
                openvpn_snprintf(numstr, sizeof(numstr), "%u", va_arg(arglist, unsigned int));
                argv_append(a, string_alloc(numstr, NULL));
            }
            else if (!strcmp(term, "%lu"))
            {
                char numstr[64];
                openvpn_snprintf(numstr, sizeof(numstr), "%lu",
                                 va_arg(arglist, unsigned long));
                argv_append(a, string_alloc(numstr, NULL));
            }
            else if (!strcmp(term, "%s/%d"))
            {
                char numstr[64];
                char *s = va_arg(arglist, char *);

                if (!s)
                {
                    s = "";
                }

                openvpn_snprintf(numstr, sizeof(numstr), "%d", va_arg(arglist, int));

                {
                    const size_t len = strlen(s) + strlen(numstr) + 2;
                    char *combined = (char *) malloc(len);
                    check_malloc_return(combined);

                    strcpy(combined, s);
                    strcat(combined, "/");
                    strcat(combined, numstr);
                    argv_append(a, combined);
                }
            }
            else if (!strcmp(term, "%s%sc"))
            {
                char *s1 = va_arg(arglist, char *);
                char *s2 = va_arg(arglist, char *);
                char *combined;

                if (!s1)
                {
                    s1 = "";
                }
                if (!s2)
                {
                    s2 = "";
                }
                combined = (char *) malloc(strlen(s1) + strlen(s2) + 1);
                check_malloc_return(combined);
                strcpy(combined, s1);
                strcat(combined, s2);
                argv_append(a, combined);
            }
            else
            {
                ASSERT(0);
            }
            free(term);
        }
        else
        {
            argv_append(a, term);
        }
    }
}

void
argv_printf(struct argv *a, const char *format, ...)
{
    va_list arglist;
    argv_reset(a);
    va_start(arglist, format);
    argv_printf_arglist(a, format, arglist);
    va_end(arglist);
}

void
argv_printf_cat(struct argv *a, const char *format, ...)
{
    va_list arglist;
    va_start(arglist, format);
    argv_printf_arglist(a, format, arglist);
    va_end(arglist);
}

void
argv_parse_cmd(struct argv *a, const char *s)
{
    int nparms;
    char *parms[MAX_PARMS + 1];
    struct gc_arena gc = gc_new();

    argv_reset(a);
    argv_extend(a, 1); /* ensure trailing NULL */

    nparms = parse_line(s, parms, MAX_PARMS, "SCRIPT-ARGV", 0, D_ARGV_PARSE_CMD, &gc);
    if (nparms)
    {
        int i;
        for (i = 0; i < nparms; ++i)
        {
            argv_append(a, string_alloc(parms[i], NULL));
        }
    }
    else
    {
        argv_append(a, string_alloc(s, NULL));
    }

    gc_free(&gc);
}
