options.c 5.81 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
    Copyright (C) 2016  Jeremy White <jwhite@codeweavers.com>
    All rights reserved.

    This file is part of x11spice

    x11spice is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    x11spice 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 x11spice.  If not, see <http://www.gnu.org/licenses/>.
*/


22
#include <glib.h>
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
#include <getopt.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "options.h"
#include "x11spice.h"

void options_init(options_t *options)
{
    memset(options, 0, sizeof(*options));
}

void options_free(options_t *options)
{
    if (options->display)
    {
        free(options->display);
        options->display = NULL;
    }
43 44 45 46 47 48

    g_free(options->spice_addr);
    options->spice_addr = NULL;

    g_free(options->spice_password);
    options->spice_password = NULL;
49 50 51 52

    if (options->autouri)
        free(options->autouri);
    options->autouri = NULL;
53 54 55 56 57 58 59 60 61 62 63 64
}


static gchar * string_option(GKeyFile *u, GKeyFile *s, const gchar *section, const gchar *key)
{
    gchar *ret = NULL;
    GError *error = NULL;

    if (u)
        ret = g_key_file_get_string(u, section, key, &error);
    if ((! u || error) && s)
        ret = g_key_file_get_string(s, section, key, NULL);
65 66
    if (error)
        g_error_free(error);
67 68

    return ret;
69 70
}

71 72 73 74 75 76 77 78 79
static gint int_option(GKeyFile *u, GKeyFile *s, const gchar *section, const gchar *key)
{
    gint ret = 0;
    GError *error = NULL;

    if (u)
        ret = g_key_file_get_integer(u, section, key, &error);
    if ((! u || error) && s)
        ret = g_key_file_get_integer(s, section, key, NULL);
80 81
    if (error)
        g_error_free(error);
82 83 84 85 86 87 88 89 90 91 92 93 94

    return ret;
}

static gboolean bool_option(GKeyFile *u, GKeyFile *s, const gchar *section, const gchar *key)
{
    gboolean ret = FALSE;
    GError *error = NULL;

    if (u)
        ret = g_key_file_get_boolean(u, section, key, &error);
    if ((! u || error) && s)
        ret = g_key_file_get_boolean(s, section, key, NULL);
95 96
    if (error)
        g_error_free(error);
97 98 99

    return ret;
}
100 101 102 103 104 105 106 107 108 109 110
static void usage(char *argv0)
{
    fprintf(stderr, "%s: \n", argv0);
    // FIXME - write usage
}

int options_parse_arguments(int argc, char *argv[], options_t *options)
{
    int rc;
    int longindex = 0;

111
    enum option_types {  OPTION_VIEWONLY, OPTION_TIMEOUT, OPTION_AUTO, OPTION_HIDE,
112 113
                         OPTION_GENERATE_PASSCODE, OPTION_DISPLAY, OPTION_MINIMIZE,
                         OPTION_HELP
114 115 116 117 118 119
    };

    static struct option long_options[] =
    {
        {"viewonly",                 0, 0,       OPTION_VIEWONLY },
        {"timeout",                  1, 0,       OPTION_TIMEOUT  },
120
        {"auto",                     1, 0,       OPTION_AUTO },
121
        {"hide",                     0, 0,       OPTION_HIDE },
122 123
        {"generate-passcode",        0, 0,       OPTION_GENERATE_PASSCODE},
        {"display",                  1, 0,       OPTION_DISPLAY },
124
        {"minimize",                 0, 0,       OPTION_MINIMIZE },
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
        {"help",                     0, 0,       OPTION_HELP},
        {0, 0, 0, 0}
    };

    while (1)
    {
        rc = getopt_long_only(argc, argv, "", long_options, &longindex);
        if (rc == -1)
        {
            rc = 0;
            break;
        }

        switch (rc)
        {
            case OPTION_TIMEOUT:
                options->timeout = atol(optarg);
                break;

            case OPTION_DISPLAY:
                options->display = strdup(optarg);
                break;

148 149 150 151
            case OPTION_HIDE:
                options->hide = 1;
                break;

152 153 154 155
            case OPTION_AUTO:
                options->autouri = strdup(optarg);
                break;

156 157 158 159
            case OPTION_MINIMIZE:
                options->minimize = 1;
                break;

160 161
            default:
                usage(argv[0]);
162
                return X11SPICE_ERR_BADARGS;
163 164 165 166 167
        }
    }

    return rc;
}
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194

void options_from_config(options_t *options)
{
    GKeyFile * userkey = g_key_file_new();
    GKeyFile * systemkey = g_key_file_new();

    char * user_config_file = g_build_filename(g_get_user_config_dir(), "x11spice", NULL);

    if(!g_key_file_load_from_file(userkey, user_config_file, G_KEY_FILE_NONE, NULL))
    {
        g_key_file_free(userkey);
        userkey = NULL;
    }

    if (!g_key_file_load_from_dirs(systemkey, "x11spice", (const char**)g_get_system_config_dirs(),
            NULL, G_KEY_FILE_NONE, NULL))
    {
        g_key_file_free(systemkey);
        systemkey = NULL;
    }

    options->spice_addr = string_option(userkey, systemkey, "spice", "addr");
    options->spice_password = string_option(userkey, systemkey, "spice", "password");
    options->spice_port = int_option(userkey, systemkey, "spice", "port");
    options->disable_ticketing = bool_option(userkey, systemkey, "spice", "disable_ticketing");
    options->exit_on_disconnect = bool_option(userkey, systemkey, "spice", "exit_on_disconnect");

195
    g_free(user_config_file);
196 197 198 199
    if (systemkey)
        g_key_file_free(systemkey);
    if (userkey)
        g_key_file_free(userkey);
200

201 202
    g_debug("options addr '%s', disable_ticketing %d, port %d", options->spice_addr, options->disable_ticketing, options->spice_port);
}
203 204 205 206 207 208 209 210 211 212 213 214 215

#if defined(OPTIONS_MAIN)
int main(int argc, char *argv[])
{
    options_t options;

    options_init(&options);
    options_parse_arguments(argc, argv, &options);
    g_message("Options parsed");
    options_from_config(&options);
    options_free(&options);
}
#endif