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

Last change on this file since 4001 was 4001, checked in by Jean-Yves Lamoureux, 10 years ago
  • Fixed most of Clang Static Checker warnings. And rand() is ok to me, thank you.
  • Property svn:keywords set to Id
File size: 13.1 KB
Line 
1/*
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 *
7 *  $Id: configuration.c 4001 2009-11-22 15:01:24Z jylam $
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
28struct config_line *get_config(const char *name);
29int set_window_manager(const char *argv, struct screen_list *screen_list);
30int set_cube_duration(const char *argv, struct screen_list *screen_list);
31int set_thumbnails(const char *argv, struct screen_list *screen_list);
32int set_status_bar(const char *argv, struct screen_list *screen_list);
33int set_screensaver_timeout(const char *argv, struct screen_list *screen_list);
34int set_autolock_timeout(const char *argv, struct screen_list *screen_list);
35int set_lock_on_detach(const char *argv, struct screen_list *screen_list);
36int set_socket_dir(const char *argv, struct screen_list *screen_list);
37int set_delay(const char *argv, struct screen_list *screen_list);
38int set_eyecandy(const char *argv, struct screen_list *screen_list);
39char*  get_window_manager(struct screen_list *screen_list);
40char*  get_cube_duration(struct screen_list *screen_list);
41char*  get_thumbnails(struct screen_list *screen_list);
42char*  get_status_bar(struct screen_list *screen_list);
43char*  get_screensaver_timeout(struct screen_list *screen_list);
44char*  get_autolock_timeout(struct screen_list *screen_list);
45char*  get_lock_on_detach(struct screen_list *screen_list);
46char*  get_socket_dir(struct screen_list *screen_list);
47char*  get_delay(struct screen_list *screen_list);
48char*  get_eyecandy(struct screen_list *screen_list);
49
50/* Options definition and associated function pointer */
51struct config_line config_option[] = {
52    {.name = "window_manager",.set = set_window_manager, .get = get_window_manager},
53    {.name = "eyecandy",.set = set_eyecandy, .get = get_eyecandy},
54    {.name = "cube_duration",.set = set_cube_duration, .get = get_window_manager},
55    {.name = "thumbnails",.set = set_thumbnails, .get = get_window_manager},
56    {.name = "status_bar",.set = set_status_bar, .get = get_window_manager},
57    {.name = "screensaver_timeout",.set = set_screensaver_timeout, .get = get_window_manager},
58    {.name = "autolock_timeout",.set = set_autolock_timeout, .get = get_window_manager},
59    {.name = "lock_on_detach",.set = set_lock_on_detach, .get = get_window_manager},
60    {.name = "socket_dir",.set = set_socket_dir, .get = get_window_manager},
61    {.name = "delay",.set = set_delay, .get = NULL},
62   
63    {.name = "last",.set = NULL},
64};
65
66
67
68int read_configuration_file(char *filename, struct screen_list *screen_list)
69{
70    FILE *fp;
71    struct stat st;
72    int size = 0, i = 0, total = 0, offset = 0, l = 1;
73    char *buffer = NULL;
74
75    screen_list->config = NULL;
76
77    /* Check if file exist */
78    if (stat(filename, &st) < 0)
79    {
80        return -1;
81    }
82    /* Get its size */
83    size = st.st_size;
84    if (!size)
85    {
86        fprintf(stderr, "File too short\n");
87        return -1;
88    }
89
90    /* Open it */
91    fp = fopen(filename, "r");
92    if (!fp)
93    {
94        return -1;
95    }
96
97    buffer = malloc(size + 1);
98    if (!buffer)
99    {
100        fclose(fp);
101        fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
102                __LINE__);
103        return -1;
104    }
105    /* Read it */
106    while ((i = fread(buffer + total, 1, size, fp)) > 0)
107    {
108        total += i;
109    }
110    buffer[total] = '\n';
111
112    fclose(fp);
113
114    /* Parse it */
115    while ((i =
116            parse_conf_line(buffer + offset, total - offset, screen_list)) > 0)
117    {
118        offset += i;
119        l++;
120    }
121
122    free(buffer);
123
124    /* Fill neercs configuration with it */
125    fill_config(screen_list);
126
127    return 1;
128}
129
130
131int parse_conf_line(char *buf, int size, struct screen_list *screen_list)
132{
133    int i, s = 0, c = 0;
134    char *line = NULL;
135    int l = 0;
136    int in_quote = 0, end_spaces = 0;
137    static struct option *prev = NULL;
138
139    if (size <= 0)
140        return -1;
141
142    /* Find EOL */
143    for (i = 0; i < size; i++)
144    {
145        if (buf[i] == '\n')
146        {
147            s = i + 1;
148            break;
149        }
150    }
151
152    /* Strip comments and trailing spaces */
153    for (i = 0; i < s; i++)
154    {
155        if (buf[i] == ';' && !in_quote)
156        {
157            break;
158        }
159        else if (buf[i] == '\n')
160        {
161            break;
162        }
163        else if (buf[i] == ' ' && !c)
164        {
165        }
166        else
167        {
168            if (line == NULL)
169            {
170                line = malloc(2);
171                if (!line)
172                {
173                    fprintf(stderr, "Can't allocate memory at %s:%d\n",
174                            __FUNCTION__, __LINE__);
175                    return -1;
176                }
177            }
178            else
179            {
180                line = realloc(line, l + 2);
181                if (!line)
182                {
183                    fprintf(stderr, "Can't allocate memory at %s:%d\n",
184                            __FUNCTION__, __LINE__);
185                    return -1;
186                }
187            }
188            if (buf[i] == '"')
189                in_quote = !in_quote;
190            if (buf[i] == ' ')
191                end_spaces++;
192            else
193                end_spaces = 0;
194
195            line[l] = buf[i];
196            line[l + 1] = 0;
197            l++;
198            c = 1;
199        }
200    }
201
202    if (c == 0)
203    {
204        /* This line is empty, do nothing */
205    }
206    else
207    {
208        struct option *option = malloc(sizeof(struct option));
209        if (!option)
210        {
211            fprintf(stderr, "Can't allocate memory at %s:%d\n",
212                    __FUNCTION__, __LINE__);
213            return -1;
214        }
215        option->next = NULL;
216        l -= end_spaces;
217        line = realloc(line, l + 1);
218        line[l] = 0;
219
220        get_key_value(line, option);
221
222        if (!screen_list->config)
223            screen_list->config = option;
224
225        if (prev)
226            prev->next = option;
227
228        prev = option;
229    }
230    free(line);
231    return s;
232}
233
234int get_key_value(char *line, struct option *option)
235{
236    unsigned int i, o = 0, b = 0, end_spaces = 0;
237    char *cur = NULL;
238    option->value = NULL;
239    option->key = NULL;
240
241    /* Line is a section delimiter */
242    if (line[0] == '[')
243    {
244        option->value = malloc(strlen(line) - 1);
245        if (!option->value)
246        {
247            fprintf(stderr, "Can't allocate memory at %s:%d\n",
248                    __FUNCTION__, __LINE__);
249            return -1;
250        }
251        memcpy(option->value, line + 1, strlen(line) - 1);
252        option->value[strlen(line) - 2] = 0;
253        return 0;
254    }
255
256    cur = malloc(1);
257    if (!cur)
258    {
259        fprintf(stderr, "Can't allocate memory at %s:%d\n",
260                __FUNCTION__, __LINE__);
261        return -1;
262    }
263    cur[0] = 0;
264
265    for (i = 0; i < strlen(line); i++)
266    {
267        if (line[i] == ' ' && !b)
268            continue;
269
270
271        if (line[i] == '=')
272        {
273            b = 0;
274            cur[o - end_spaces] = 0;
275            cur = realloc(cur, (o - end_spaces) + 1);
276            if (!cur)
277            {
278                fprintf(stderr, "Can't allocate memory at %s:%d\n",
279                        __FUNCTION__, __LINE__);
280                return -1;
281            }
282            o = 0;
283            option->key = cur;
284            cur = malloc(1);
285        }
286        else
287        {
288            if (line[i] == ' ')
289                end_spaces++;
290            else
291                end_spaces = 0;
292
293            cur = realloc(cur, o + 2);
294            if (!cur)
295            {
296                fprintf(stderr, "Can't allocate memory at %s:%d\n",
297                        __FUNCTION__, __LINE__);
298                return -1;
299            }
300            cur[o] = line[i];
301            o++;
302            b = 1;
303
304        }
305    }
306    cur[o] = 0;
307    option->value = cur;
308    return 0;
309}
310
311
312
313struct config_line *get_config(const char *name)
314{
315    int i = 0;
316    while (strncmp(config_option[i].name, "last", strlen("last")))
317    {
318        if (!strncmp(name, config_option[i].name, strlen(name)))
319        {
320            debug("Found\n");
321            return &config_option[i];
322        }
323        i++;
324    }
325    return NULL;
326}
327
328
329
330int fill_config(struct screen_list *screen_list)
331{
332    int i = 0;
333    struct option *option = screen_list->config;
334
335    while (option)
336    {
337        if (option->key == NULL)
338        {
339            option = option->next;
340            continue;
341        }
342
343        struct config_line *c = get_config(option->key);
344        if (c)
345        {
346            c->set((const char*)option->value, screen_list);
347        }
348        option = option->next;
349    }
350
351    return i;
352}
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
372    {
373        fprintf(stderr, "Unknown window manager '%s'\n", argv);
374        return -1;
375    }
376    return 0;
377}
378
379int set_cube_duration(const char *argv, struct screen_list *screen_list)
380{
381    screen_list->cube.duration = atoi(argv) * 1000000;
382    return 0;
383}
384
385int set_thumbnails(const char *argv, struct screen_list *screen_list)
386{
387    if (IS_OPTION("true") || IS_OPTION("1"))
388        screen_list->mini = 1;
389    else
390        screen_list->mini = 0;
391    return 0;
392   
393}
394
395int set_status_bar(const char *argv, struct screen_list *screen_list)
396{
397    if (IS_OPTION("true") || IS_OPTION("1"))
398        screen_list->status = 1;
399    else
400        screen_list->status = 0;
401    return 0;
402}
403
404int set_screensaver_timeout(const char *argv, struct screen_list *screen_list)
405{
406    screen_list->screensaver_timeout = atoi(argv) * 1000000;
407    /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
408    if (!screen_list->screensaver_timeout)
409        screen_list->screensaver_timeout -= 1;
410    return 0;
411}
412
413int set_autolock_timeout(const char *argv, struct screen_list *screen_list)
414{
415    if (screen_list->autolock_timeout == 0 ||
416        screen_list->autolock_timeout ==
417        ((long long unsigned int)0) - 1)
418    {
419        screen_list->autolock_timeout = atoi(argv) * 1000000;
420        /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
421        if (!screen_list->autolock_timeout)
422            screen_list->autolock_timeout -= 1;
423    }
424    return 0;
425}
426
427int set_lock_on_detach(const char *argv, struct screen_list *screen_list)
428{
429    if (IS_OPTION("true") || IS_OPTION("1"))
430        screen_list->lock_on_detach = 1;
431    else
432        screen_list->lock_on_detach = 0;
433    return 0;
434}
435
436int set_eyecandy(const char *argv, struct screen_list *screen_list)
437{
438    if (IS_OPTION("true") || IS_OPTION("1"))
439        screen_list->eyecandy = 1;
440    else
441        screen_list->eyecandy = 0;
442    return 0;
443}
444
445int set_socket_dir(const char *argv, struct screen_list *screen_list)
446{
447    screen_list->socket_dir = strdup(argv);
448        return 0;
449}
450
451int set_delay(const char *argv, struct screen_list *screen_list)
452{
453    screen_list->requested_delay = atoi(argv);
454    screen_list->delay = atoi(argv);
455        return 0;
456}
457
458char* get_window_manager(struct screen_list *screen_list)
459{
460    switch(screen_list->wm_type)
461    {
462        case WM_FULL:
463            return "full";
464        case WM_CARD:
465            return "card";
466        case WM_VSPLIT:
467            return "vsplit";
468        case WM_HSPLIT:
469            return "hsplit";
470        default:
471            return "invalid";
472    }
473    return NULL; /* Not reached */
474}
475
476char*  get_cube_duration(struct screen_list *screen_list)
477{
478    char *r = malloc(100);
479    sprintf(r, "%f", (float)screen_list->cube.duration/1000000.0f);
480    return r;
481}
482
483char*  get_thumbnails(struct screen_list *screen_list)
484{
485    if(screen_list->mini) return "yes";
486    return "no";
487}
488
489char*  get_status_bar(struct screen_list *screen_list)
490{
491    if(screen_list->status) return "yes";
492    return "no";
493}
494
495char*  get_eyecandy(struct screen_list *screen_list)
496{
497    if(screen_list->eyecandy) return "yes";
498    return "no";
499}
500
501char*  get_screensaver_timeout(struct screen_list *screen_list)
502{
503    char *r = malloc(100);
504    sprintf(r, "%f", (float)screen_list->screensaver_timeout/1000000.0f);
505    return r;
506}
507
508char*  get_autolock_timeout(struct screen_list *screen_list)
509{
510    char *r = malloc(100);
511    sprintf(r, "%f", (float)screen_list->autolock_timeout/1000000.0f);
512    return r;
513}
514
515char*  get_lock_on_detach(struct screen_list *screen_list)
516{
517    if(screen_list->lock_on_detach) return "yes";
518    else return "no";
519}
520
521char*  get_socket_dir(struct screen_list *screen_list)
522{
523    return screen_list->socket_dir;
524}
525
526char*  get_delay(struct screen_list *screen_list)
527{
528    char *r = malloc(100);
529    sprintf(r, "%d", screen_list->requested_delay);
530    return r;
531}
532
533
534
Note: See TracBrowser for help on using the repository browser.