daemon: debug segv correct use of dereferencing NULL.
[libguestfs.git] / fish / config.c
1 /* libguestfs - guestfish and guestmount shared option parsing
2  * Copyright (C) 2011 Red Hat Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #include <config.h>
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #ifdef HAVE_LIBCONFIG
26 #include <libconfig.h>
27 #endif
28
29 #include "guestfs.h"
30
31 #include "options.h"
32
33 static const char *home_filename = /* $HOME/ */ ".libguestfs-tools.rc";
34 static const char *etc_filename = "/etc/libguestfs-tools.conf";
35
36 #ifdef HAVE_LIBCONFIG
37
38 /* Note that parse_config is called very early, before command line
39  * parsing and before the verbose flag has been set.
40  */
41
42 void
43 parse_config (void)
44 {
45   const char *home;
46   size_t len;
47   char *path;
48   FILE *fp;
49   config_t conf;
50
51   config_init (&conf);
52
53   /* Try $HOME first. */
54   home = getenv ("HOME");
55   if (home != NULL) {
56     len = strlen (home) + 1 + strlen (home_filename) + 1;
57     path = malloc (len);
58     if (path == NULL) {
59       perror ("malloc");
60       exit (EXIT_FAILURE);
61     }
62     snprintf (path, len, "%s/%s", home, home_filename);
63
64     fp = fopen (path, "r");
65     if (fp != NULL) {
66       /*
67       if (verbose)
68         fprintf (stderr, "%s: reading configuration from %s\n",
69                  program_name, path);
70       */
71
72       if (config_read (&conf, fp) == CONFIG_FALSE) {
73         fprintf (stderr,
74                  _("%s: %s: line %d: error parsing configuration file: %s\n"),
75                  program_name, path, config_error_line (&conf),
76                  config_error_text (&conf));
77         exit (EXIT_FAILURE);
78       }
79
80       if (fclose (fp) == -1) {
81         perror (path);
82         exit (EXIT_FAILURE);
83       }
84
85       /* Notes:
86        *
87        * (1) It's not obvious from the documentation, that config_read
88        * completely resets the 'conf' structure.  This means we cannot
89        * call config_read twice on the two possible configuration
90        * files, but instead have to copy out settings into our
91        * variables between calls.
92        *
93        * (2) If the next call fails then 'read_only' variable is not
94        * updated.  Failure could happen just because the setting is
95        * missing from the configuration file, so we ignore it here.
96        */
97       config_lookup_bool (&conf, "read_only", &read_only);
98     }
99
100     free (path);
101   }
102
103   fp = fopen (etc_filename, "r");
104   if (fp != NULL) {
105     /*
106     if (verbose)
107       fprintf (stderr, "%s: reading configuration from %s\n",
108                program_name, etc_filename);
109     */
110
111     if (config_read (&conf, fp) == CONFIG_FALSE) {
112       fprintf (stderr,
113                _("%s: %s: line %d: error parsing configuration file: %s\n"),
114                program_name, etc_filename, config_error_line (&conf),
115                config_error_text (&conf));
116       exit (EXIT_FAILURE);
117     }
118
119     if (fclose (fp) == -1) {
120       perror (etc_filename);
121       exit (EXIT_FAILURE);
122     }
123
124     config_lookup_bool (&conf, "read_only", &read_only);
125   }
126
127   config_destroy (&conf);
128 }
129
130 #else /* !HAVE_LIBCONFIG */
131
132 void
133 parse_config (void)
134 {
135   /*
136   if (verbose)
137     fprintf (stderr,
138              _("%s: compiled without libconfig, guestfish configuration file ignored\n"),
139              program_name);
140   */
141 }
142
143 #endif /* !HAVE_LIBCONFIG */