source: neercs/trunk/src/configuration.c @ 3998

Last change on this file since 3998 was 3998, checked in by Jean-Yves Lamoureux, 13 years ago
  • Moved help code to help.c
  • Fixed bad string handling in configuration
  • Property svn:keywords set to Id
File size: 10.7 KB
RevLine 
[3969]1/*
[2463]2 *  neercs        console-based window manager
3 *  Copyright (c) 2006 Sam Hocevar <sam@zoy.org>
4 *                2008 Jean-Yves Lamoureux <jylam@lnxscene.org>
5 *                All Rights Reserved
6 *
[3551]7 *  $Id: configuration.c 3998 2009-11-22 14:06:26Z jylam $
[2463]8 *
9 *  This program is free software. It comes without any warranty, to
10 *  the extent permitted by applicable law. You can redistribute it
11 *  and/or modify it under the terms of the Do What The Fuck You Want
12 *  To Public License, Version 2, as published by Sam Hocevar. See
13 *  http://sam.zoy.org/wtfpl/COPYING for more details.
14 */
15
16#include <fcntl.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <unistd.h>
22#include <errno.h>
23#include <string.h>
24
25#include "neercs.h"
26
27
[3997]28struct config_line
29{
30    const char name[32];
31    int (*func_ptr) (const char *argv, struct screen_list * screen_list);
32};
33
34struct config_line *get_config(const char *name);
35int set_window_manager(const char *argv, struct screen_list *screen_list);
36int set_cube_duration(const char *argv, struct screen_list *screen_list);
37int set_thumbnails(const char *argv, struct screen_list *screen_list);
38int set_status_bar(const char *argv, struct screen_list *screen_list);
39int set_screensaver_timeout(const char *argv, struct screen_list *screen_list);
40int set_autolock_timeout(const char *argv, struct screen_list *screen_list);
41int set_lock_on_detach(const char *argv, struct screen_list *screen_list);
42int set_socket_dir(const char *argv, struct screen_list *screen_list);
43int set_delay(const char *argv, struct screen_list *screen_list);
44
45/* Options definition and associated function pointer */
46struct config_line config_option[] = {
47    {.name = "window_manager",.func_ptr = set_window_manager},
48    {.name = "cube_duration",.func_ptr = set_cube_duration},
49    {.name = "thumbnails",.func_ptr = set_thumbnails},
50    {.name = "status_bar",.func_ptr = set_status_bar},
51    {.name = "screensaver_timeout",.func_ptr = set_screensaver_timeout},
52    {.name = "autolock_timeout",.func_ptr = set_autolock_timeout},
53    {.name = "lock_on_detach",.func_ptr = set_lock_on_detach},
54    {.name = "socket_dir",.func_ptr = set_socket_dir},
55    {.name = "delay",.func_ptr = set_delay},
56   
57    {.name = "last",.func_ptr = NULL},
58};
59
60
61
[2463]62int read_configuration_file(char *filename, struct screen_list *screen_list)
63{
64    FILE *fp;
65    struct stat st;
[2464]66    int size = 0, i = 0, total = 0, offset = 0, l = 1;
[2463]67    char *buffer = NULL;
68
[2587]69    screen_list->config = NULL;
70
[2463]71    /* Check if file exist */
[3969]72    if (stat(filename, &st) < 0)
[2463]73    {
74        return -1;
75    }
[3969]76    /* Get its size */
[2463]77    size = st.st_size;
[3969]78    if (!size)
[2463]79    {
80        fprintf(stderr, "File too short\n");
81        return -1;
82    }
83
84    /* Open it */
85    fp = fopen(filename, "r");
[3969]86    if (!fp)
[2463]87    {
88        return -1;
89    }
90
[2464]91    buffer = malloc(size + 1);
[3969]92    if (!buffer)
[2463]93    {
94        fclose(fp);
[3969]95        fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
96                __LINE__);
[2463]97        return -1;
98    }
99    /* Read it */
[3969]100    while ((i = fread(buffer + total, 1, size, fp)) > 0)
[2463]101    {
[3969]102        total += i;
[2463]103    }
[2464]104    buffer[total] = '\n';
[2463]105
106    fclose(fp);
107
[3969]108    i = 0;
[2463]109
110    /* Parse it */
[3969]111    while ((i =
112            parse_conf_line(buffer + offset, total - offset, screen_list)) > 0)
[2463]113    {
[3969]114        offset += i;
[2464]115        l++;
[2463]116    }
117
118    free(buffer);
119
120    /* Fill neercs configuration with it */
121    fill_config(screen_list);
122
123    return 1;
124}
125
126
127int parse_conf_line(char *buf, int size, struct screen_list *screen_list)
128{
129    int i, s = 0, eol = 0, c = 0;
130    char *line = NULL;
131    int l = 0;
132    int in_quote = 0, end_spaces = 0;
133    static struct option *prev = NULL;
134
[3969]135    if (size <= 0)
136        return -1;
[2463]137
[3969]138    /* Find EOL */
139    for (i = 0; i < size; i++)
[2463]140    {
[3969]141        if (buf[i] == '\n')
[2463]142        {
143            s = i + 1;
144            break;
145        }
146    }
147
148    /* Strip comments and trailing spaces */
[3969]149    for (i = 0; i < s; i++)
[2463]150    {
[3969]151        if (buf[i] == ';' && !in_quote)
[2463]152        {
153            eol = i;
154            break;
155        }
[3969]156        else if (buf[i] == '\n')
[2463]157        {
158            eol = i;
159            break;
160        }
[3969]161        else if (buf[i] == ' ' && !c)
162        {
163        }
[2463]164        else
165        {
[3969]166            if (line == NULL)
[2463]167            {
168                line = malloc(2);
[3969]169                if (!line)
[2463]170                {
[2648]171                    fprintf(stderr, "Can't allocate memory at %s:%d\n",
[3969]172                            __FUNCTION__, __LINE__);
[2463]173                    return -1;
174                }
175            }
176            else
177            {
[3969]178                line = realloc(line, l + 2);
179                if (!line)
[2463]180                {
[2648]181                    fprintf(stderr, "Can't allocate memory at %s:%d\n",
[3969]182                            __FUNCTION__, __LINE__);
[2463]183                    return -1;
184                }
185            }
[3969]186            if (buf[i] == '"')
[2463]187                in_quote = !in_quote;
[3969]188            if (buf[i] == ' ')
[2463]189                end_spaces++;
190            else
191                end_spaces = 0;
192
[3969]193            line[l] = buf[i];
194            line[l + 1] = 0;
[2463]195            l++;
196            c = 1;
197        }
198    }
199
[3969]200    if (c == 0)
[2463]201    {
202        /* This line is empty, do nothing */
203    }
204    else
205    {
206        struct option *option = malloc(sizeof(struct option));
[3969]207        if (!option)
[2648]208        {
209            fprintf(stderr, "Can't allocate memory at %s:%d\n",
[3969]210                    __FUNCTION__, __LINE__);
[2648]211            return -1;
212        }
[2463]213        option->next = NULL;
[3969]214        l -= end_spaces;
215        line = realloc(line, l + 1);
[2463]216        line[l] = 0;
[2464]217
[2463]218        get_key_value(line, option);
219
[3969]220        if (!screen_list->config)
[2463]221            screen_list->config = option;
222
[3969]223        if (prev)
[2463]224            prev->next = option;
225
226        prev = option;
227    }
228    free(line);
229    return s;
230}
231
232int get_key_value(char *line, struct option *option)
233{
[3969]234    unsigned int i, o = 0, b = 0, end_spaces = 0;
[2463]235    char *cur = NULL;
236    option->value = NULL;
237    option->key = NULL;
238
239    /* Line is a section delimiter */
[3969]240    if (line[0] == '[')
[2463]241    {
242        option->value = malloc(strlen(line) - 1);
[3969]243        if (!option->value)
[2648]244        {
245            fprintf(stderr, "Can't allocate memory at %s:%d\n",
246                    __FUNCTION__, __LINE__);
247            return -1;
248        }
[3969]249        memcpy(option->value, line + 1, strlen(line) - 1);
[2463]250        option->value[strlen(line) - 2] = 0;
251        return 0;
252    }
253
254    cur = malloc(1);
[3969]255    if (!cur)
[2649]256    {
257        fprintf(stderr, "Can't allocate memory at %s:%d\n",
258                __FUNCTION__, __LINE__);
259        return -1;
260    }
[2463]261    cur[0] = 0;
262
[3969]263    for (i = 0; i < strlen(line); i++)
[2463]264    {
[3969]265        if (line[i] == ' ' && !b)
266            continue;
[2463]267
[2464]268
[3969]269        if (line[i] == '=')
[2463]270        {
271            b = 0;
[3969]272            cur[o - end_spaces] = 0;
273            cur = realloc(cur, (o - end_spaces) + 1);
274            if (!cur)
[2649]275            {
276                fprintf(stderr, "Can't allocate memory at %s:%d\n",
[3969]277                        __FUNCTION__, __LINE__);
[2649]278                return -1;
279            }
[2463]280            o = 0;
281            option->key = cur;
282            cur = malloc(1);
283        }
284        else
285        {
[3969]286            if (line[i] == ' ')
287                end_spaces++;
288            else
289                end_spaces = 0;
[2464]290
[3969]291            cur = realloc(cur, o + 2);
292            if (!cur)
[2463]293            {
[2649]294                fprintf(stderr, "Can't allocate memory at %s:%d\n",
[3969]295                        __FUNCTION__, __LINE__);
[2649]296                return -1;
[2463]297            }
[3969]298            cur[o] = line[i];
[2463]299            o++;
300            b = 1;
[2464]301
[2463]302        }
303    }
304    cur[o] = 0;
305    option->value = cur;
306    return 0;
307}
308
309
310
[3997]311struct config_line *get_config(const char *name)
312{
313    int i = 0;
314    while (strncmp(config_option[i].name, "last", strlen("last")))
315    {
316        if (!strncmp(name, config_option[i].name, strlen(name)))
317        {
318            debug("Found\n");
319            return &config_option[i];
320        }
321        i++;
322    }
323    return NULL;
324}
[2463]325
[3997]326
327
[2463]328int fill_config(struct screen_list *screen_list)
329{
330    int i = 0;
331    struct option *option = screen_list->config;
332    char *section = NULL;
333
[3969]334    while (option)
[2463]335    {
[3969]336        if (option->key == NULL)
[2463]337        {
338            section = option->key;
339            option = option->next;
340            continue;
341        }
342
[3997]343        struct config_line *c = get_config(option->key);
344        if (c)
[2463]345        {
[3997]346            c->func_ptr(option->value, screen_list);
[3969]347        }
[2463]348        option = option->next;
349    }
350
351    return i;
352}
[3997]353
354
355
356/*
357 * Options setters
358 */
359
360#define IS_OPTION(t) (!strncmp(argv, t, strlen(argv)))
361int set_window_manager(const char *argv, struct screen_list *screen_list)
362{
363    if (IS_OPTION("full"))
364        screen_list->wm_type = WM_FULL;
365    else if (IS_OPTION("hsplit"))
366        screen_list->wm_type = WM_HSPLIT;
367    else if (IS_OPTION("vsplit"))
368        screen_list->wm_type = WM_VSPLIT;
369    else if (IS_OPTION("card"))
370        screen_list->wm_type = WM_CARD;
371    else if (IS_OPTION("cube"))
372        screen_list->wm_type = WM_CUBE;
373    else
374    {
375        fprintf(stderr, "Unknown window manager '%s'\n", argv);
376        return -1;
377    }
378    return 0;
379}
380
381int set_cube_duration(const char *argv, struct screen_list *screen_list)
382{
383    screen_list->cube.duration = atoi(argv) * 1000000;
384    return 0;
385}
386
387int set_thumbnails(const char *argv, struct screen_list *screen_list)
388{
389    if (IS_OPTION("true") || IS_OPTION("1"))
390        screen_list->mini = 1;
391    else
392        screen_list->mini = 0;
393    return 0;
394   
395}
396
397int set_status_bar(const char *argv, struct screen_list *screen_list)
398{
399    if (IS_OPTION("true") || IS_OPTION("1"))
400        screen_list->status = 1;
401    else
402        screen_list->status = 0;
403    return 0;
404}
405
406int set_screensaver_timeout(const char *argv, struct screen_list *screen_list)
407{
408    screen_list->screensaver_timeout = atoi(argv) * 1000000;
409    /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
410    if (!screen_list->screensaver_timeout)
411        screen_list->screensaver_timeout -= 1;
412    return 0;
413}
414
415int set_autolock_timeout(const char *argv, struct screen_list *screen_list)
416{
417    if (screen_list->autolock_timeout == 0 ||
418        screen_list->autolock_timeout ==
419        ((long long unsigned int)0) - 1)
420    {
421        screen_list->autolock_timeout = atoi(argv) * 1000000;
422        /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
423        if (!screen_list->autolock_timeout)
424            screen_list->autolock_timeout -= 1;
425    }
426    return 0;
427}
428
429int set_lock_on_detach(const char *argv, struct screen_list *screen_list)
430{
431    if (IS_OPTION("true") || IS_OPTION("1"))
432        screen_list->lock_on_detach = 1;
433    else
434        screen_list->lock_on_detach = 0;
435    return 0;
436}
437
438int set_socket_dir(const char *argv, struct screen_list *screen_list)
439{
[3998]440    screen_list->socket_dir = strdup(argv);
[3997]441        return 0;
442}
443
444int set_delay(const char *argv, struct screen_list *screen_list)
445{
446    screen_list->requested_delay = atoi(argv);
447    screen_list->delay = atoi(argv);
448        return 0;
449}
Note: See TracBrowser for help on using the repository browser.