<div dir="ltr"><div style>Hi,</div><div style><br></div><div style>Minor correction to my previous patch.  This revision corrects a small leak in config_file_path_xdg_config_dirs().</div><div style><br></div><div style>Thanks!</div>
<div style>-Ossama</div><div style><br></div><div style>---</div><div><br></div><br><div class="gmail_extra"><div class="gmail_extra">Search for a given config file in the directories listed in</div><div class="gmail_extra">
$XDG_CONFIG_DIRS if it wasn't found in $XDG_CONFIG_HOME or ~/.config.</div><div class="gmail_extra">This allows packages to install custom config files in</div><div class="gmail_extra">/etc/xdg/weston, for example, thus allowing them to avoid dealing with</div>
<div class="gmail_extra">home directories.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Signed-off-by: Ossama Othman <<a href="mailto:ossama.othman@intel.com">ossama.othman@intel.com</a>></div><div class="gmail_extra">
---</div><div class="gmail_extra"> shared/config-parser.c |  128 +++++++++++++++++++++++++++++++++++++++---------</div><div class="gmail_extra"> 1 file changed, 105 insertions(+), 23 deletions(-)</div><div class="gmail_extra">
<br></div><div class="gmail_extra">diff --git a/shared/config-parser.c b/shared/config-parser.c</div><div class="gmail_extra">index 10ff86a..a781274 100644</div><div class="gmail_extra">--- a/shared/config-parser.c</div><div class="gmail_extra">
+++ b/shared/config-parser.c</div><div class="gmail_extra">@@ -25,6 +25,7 @@</div><div class="gmail_extra"> #include <stdlib.h></div><div class="gmail_extra"> #include <assert.h></div><div class="gmail_extra">
 #include <ctype.h></div><div class="gmail_extra">+#include <unistd.h></div><div class="gmail_extra"> </div><div class="gmail_extra"> #include "config-parser.h"</div><div class="gmail_extra"> </div><div class="gmail_extra">
@@ -95,6 +96,9 @@ parse_config_file(const char *path,</div><div class="gmail_extra"> <span class="" style="white-space:pre">    </span>const struct config_section *current = NULL;</div><div class="gmail_extra"> <span class="" style="white-space:pre">        </span>int i;</div>
<div class="gmail_extra"> </div><div class="gmail_extra">+<span class="" style="white-space:pre">       </span>if (path == NULL)</div><div class="gmail_extra">+<span class="" style="white-space:pre">           </span>return -1;</div><div class="gmail_extra">
+</div><div class="gmail_extra"> <span class="" style="white-space:pre">        </span>fp = fopen(path, "r");</div><div class="gmail_extra"> <span class="" style="white-space:pre">    </span>if (fp == NULL) {</div><div class="gmail_extra">
 <span class="" style="white-space:pre">              </span>fprintf(stderr, "couldn't open %s\n", path);</div><div class="gmail_extra">@@ -151,37 +155,115 @@ parse_config_file(const char *path,</div><div class="gmail_extra">
 <span class="" style="white-space:pre">      </span>return 0;</div><div class="gmail_extra"> }</div><div class="gmail_extra"> </div><div class="gmail_extra">+static char *</div><div class="gmail_extra">+config_file_path_xdg_config_home(const char *name)</div>
<div class="gmail_extra">+{</div><div class="gmail_extra">+<span class="" style="white-space:pre">      </span>const char *config_dir = getenv("XDG_CONFIG_HOME");</div><div class="gmail_extra">+</div><div class="gmail_extra">
+<span class="" style="white-space:pre">      </span>if (config_dir) {</div><div class="gmail_extra">+<span class="" style="white-space:pre">           </span>size_t size = strlen(config_dir) + 1 + strlen(name) + 1;</div><div class="gmail_extra">
+<span class="" style="white-space:pre">              </span>char *path = malloc(size);</div><div class="gmail_extra">+</div><div class="gmail_extra">+<span class="" style="white-space:pre">            </span>/* TOCTOU race here.  Ideally we should open the file</div>
<div class="gmail_extra">+<span class="" style="white-space:pre">             </span> * and return a handle to it. */</div><div class="gmail_extra">+<span class="" style="white-space:pre">            </span>if (path &&</div><div class="gmail_extra">
+<span class="" style="white-space:pre">              </span>    snprintf(path, size, "%s/%s", config_dir, name) > 0 &&</div><div class="gmail_extra">+<span class="" style="white-space:pre">             </span>    access(path, R_OK) == 0)</div>
<div class="gmail_extra">+<span class="" style="white-space:pre">                     </span>return path;</div><div class="gmail_extra">+</div><div class="gmail_extra">+<span class="" style="white-space:pre">          </span>free(path);</div><div class="gmail_extra">
+<span class="" style="white-space:pre">      </span>}</div><div class="gmail_extra">+</div><div class="gmail_extra">+<span class="" style="white-space:pre">     </span>return NULL;</div><div class="gmail_extra">+}</div><div class="gmail_extra">
+</div><div class="gmail_extra">+static char *</div><div class="gmail_extra">+config_file_path_home(const char *name)</div><div class="gmail_extra">+{</div><div class="gmail_extra">+<span class="" style="white-space:pre"> </span>const char *home_dir = getenv("HOME");</div>
<div class="gmail_extra">+</div><div class="gmail_extra">+<span class="" style="white-space:pre">       </span>if (home_dir) {</div><div class="gmail_extra">+<span class="" style="white-space:pre">             </span>const char dotconf[] = "/.config/";</div>
<div class="gmail_extra">+</div><div class="gmail_extra">+<span class="" style="white-space:pre">               </span>size_t size = strlen(home_dir) + sizeof dotconf + strlen(name);</div><div class="gmail_extra">+<span class="" style="white-space:pre">             </span>char *path = malloc(size);</div>
<div class="gmail_extra">+</div><div class="gmail_extra">+<span class="" style="white-space:pre">               </span>if (path &&</div><div class="gmail_extra">+<span class="" style="white-space:pre">         </span>    snprintf(path, size, "%s%s%s",</div>
<div class="gmail_extra">+<span class="" style="white-space:pre">                     </span>     home_dir, dotconf, name) > 0 &&</div><div class="gmail_extra">+<span class="" style="white-space:pre">             </span>    access(path, R_OK) == 0)</div>
<div class="gmail_extra">+<span class="" style="white-space:pre">                     </span>return path;</div><div class="gmail_extra">+</div><div class="gmail_extra">+<span class="" style="white-space:pre">          </span>free(path);</div><div class="gmail_extra">
+<span class="" style="white-space:pre">      </span>}</div><div class="gmail_extra">+</div><div class="gmail_extra">+<span class="" style="white-space:pre">     </span>return NULL;</div><div class="gmail_extra">+}</div><div class="gmail_extra">
+</div><div class="gmail_extra">+static char *</div><div class="gmail_extra">+config_file_path_xdg_config_dirs(const char *name)</div><div class="gmail_extra">+{</div><div class="gmail_extra">+<span class="" style="white-space:pre">      </span>const char *config_dirs = getenv("XDG_CONFIG_DIRS");</div>
<div class="gmail_extra">+</div><div class="gmail_extra">+<span class="" style="white-space:pre">       </span>if (config_dirs) {</div><div class="gmail_extra">+<span class="" style="white-space:pre">          </span>const char weston_dir[] = "/weston/";</div>
<div class="gmail_extra">+<span class="" style="white-space:pre">             </span>char *config_dir, *saveptr, *dirs;</div><div class="gmail_extra">+<span class="" style="white-space:pre">          </span>char *path = NULL;</div><div class="gmail_extra">
+<span class="" style="white-space:pre">              </span>size_t size;</div><div class="gmail_extra">+</div><div class="gmail_extra">+<span class="" style="white-space:pre">          </span>size = strlen(config_dirs) + 1;</div><div class="gmail_extra">
+<span class="" style="white-space:pre">              </span>dirs = malloc(size);</div><div class="gmail_extra">+<span class="" style="white-space:pre">                </span>if (!dirs)</div><div class="gmail_extra">+<span class="" style="white-space:pre">                  </span>return NULL;</div>
<div class="gmail_extra">+</div><div class="gmail_extra">+<span class="" style="white-space:pre">               </span>/* strtok_r() modifies the first argument.  Avoid</div><div class="gmail_extra">+<span class="" style="white-space:pre">           </span> * clobbering the process environment. */</div>
<div class="gmail_extra">+<span class="" style="white-space:pre">             </span>strncpy(dirs, config_dirs, size);</div><div class="gmail_extra">+</div><div class="gmail_extra">+<span class="" style="white-space:pre">             </span>for (config_dir = strtok_r(dirs, ":", &saveptr);</div>
<div class="gmail_extra">+<span class="" style="white-space:pre">             </span>     config_dir != NULL;</div><div class="gmail_extra">+<span class="" style="white-space:pre">            </span>     config_dir = strtok_r(NULL, ":", &saveptr)) {</div>
<div class="gmail_extra">+<span class="" style="white-space:pre">                     </span>size = strlen(config_dir) +</div><div class="gmail_extra">+<span class="" style="white-space:pre">                                 </span>sizeof weston_dir + strlen(name);</div>
<div class="gmail_extra">+<span class="" style="white-space:pre">                     </span>path = realloc(path, size);</div><div class="gmail_extra">+</div><div class="gmail_extra">+<span class="" style="white-space:pre">                   </span>if (path &&</div>
<div class="gmail_extra">+<span class="" style="white-space:pre">                     </span>    snprintf(path, size, "%s%s%s",</div><div class="gmail_extra">+<span class="" style="white-space:pre">                                </span>     config_dir, weston_dir, name) > 0 &&</div>
<div class="gmail_extra">+<span class="" style="white-space:pre">                     </span>    access(path, R_OK) == 0) {</div><div class="gmail_extra">+<span class="" style="white-space:pre">                              </span>free(dirs);</div><div class="gmail_extra">
+<span class="" style="white-space:pre">                              </span>return path;</div><div class="gmail_extra">+<span class="" style="white-space:pre">                        </span>}</div><div class="gmail_extra">+<span class="" style="white-space:pre">           </span>}</div>
<div class="gmail_extra">+</div><div class="gmail_extra">+<span class="" style="white-space:pre">               </span>free(dirs);</div><div class="gmail_extra">+<span class="" style="white-space:pre">         </span>free(path);</div><div class="gmail_extra">
+<span class="" style="white-space:pre">      </span>}</div><div class="gmail_extra">+</div><div class="gmail_extra">+<span class="" style="white-space:pre">     </span>return NULL;</div><div class="gmail_extra">+}</div><div class="gmail_extra">
+</div><div class="gmail_extra"> char *</div><div class="gmail_extra"> config_file_path(const char *name)</div><div class="gmail_extra"> {</div><div class="gmail_extra">-<span class="" style="white-space:pre">     </span>const char dotconf[] = "/.config/";</div>
<div class="gmail_extra">-<span class="" style="white-space:pre">     </span>const char *config_dir;</div><div class="gmail_extra">-<span class="" style="white-space:pre">     </span>const char *home_dir;</div><div class="gmail_extra">
 <span class="" style="white-space:pre">      </span>char *path;</div><div class="gmail_extra">-<span class="" style="white-space:pre"> </span>size_t size;</div><div class="gmail_extra">-</div><div class="gmail_extra">-<span class="" style="white-space:pre">  </span>config_dir = getenv("XDG_CONFIG_HOME");</div>
<div class="gmail_extra">-<span class="" style="white-space:pre">     </span>if (!config_dir) {</div><div class="gmail_extra">-<span class="" style="white-space:pre">          </span>home_dir = getenv("HOME");</div><div class="gmail_extra">
-<span class="" style="white-space:pre">              </span>if (!home_dir) {</div><div class="gmail_extra">-<span class="" style="white-space:pre">                    </span>fprintf(stderr, "HOME is not set, using cwd.\n");</div><div class="gmail_extra">
-<span class="" style="white-space:pre">                      </span>return strdup(name);</div><div class="gmail_extra">-<span class="" style="white-space:pre">                </span>}</div><div class="gmail_extra"> </div><div class="gmail_extra">-<span class="" style="white-space:pre">             </span>size = strlen(home_dir) + sizeof dotconf + strlen(name);</div>
<div class="gmail_extra">-<span class="" style="white-space:pre">             </span>path = malloc(size);</div><div class="gmail_extra">-<span class="" style="white-space:pre">                </span>if (!path)</div><div class="gmail_extra">-<span class="" style="white-space:pre">                  </span>return NULL;</div>
<div class="gmail_extra">+<span class="" style="white-space:pre">     </span>/* Precedence is given to config files in the home directory,</div><div class="gmail_extra">+<span class="" style="white-space:pre">       </span> * and then to directories listed in XDG_CONFIG_DIRS. */</div>
<div class="gmail_extra"> </div><div class="gmail_extra">-<span class="" style="white-space:pre">               </span>snprintf(path, size, "%s%s%s", home_dir, dotconf, name);</div><div class="gmail_extra">-<span class="" style="white-space:pre">          </span>return path;</div>
<div class="gmail_extra">-<span class="" style="white-space:pre">     </span>}</div><div class="gmail_extra">+<span class="" style="white-space:pre">   </span>path = config_file_path_xdg_config_home(name);</div><div class="gmail_extra">
+</div><div class="gmail_extra">+<span class="" style="white-space:pre">        </span>if (!path)</div><div class="gmail_extra">+<span class="" style="white-space:pre">          </span>path = config_file_path_home(name);</div><div class="gmail_extra">
+</div><div class="gmail_extra">+<span class="" style="white-space:pre">        </span>if (!path)</div><div class="gmail_extra">+<span class="" style="white-space:pre">          </span>path = config_file_path_xdg_config_dirs(name);</div>
<div class="gmail_extra"> </div><div class="gmail_extra">-<span class="" style="white-space:pre">       </span>size = strlen(config_dir) + 1 + strlen(name) + 1;</div><div class="gmail_extra">-<span class="" style="white-space:pre">   </span>path = malloc(size);</div>
<div class="gmail_extra"> <span class="" style="white-space:pre">     </span>if (!path)</div><div class="gmail_extra">-<span class="" style="white-space:pre">          </span>return NULL;</div><div class="gmail_extra">+<span class="" style="white-space:pre">                </span>fprintf(stderr,</div>
<div class="gmail_extra">+<span class="" style="white-space:pre">                     </span>"config file \"%s\" not found in "</div><div class="gmail_extra">+<span class="" style="white-space:pre">                      </span>"$XDG_CONFIG_{HOME,DIRS} or ~/.config\n",</div>
<div class="gmail_extra">+<span class="" style="white-space:pre">                     </span>name);</div><div class="gmail_extra"> </div><div class="gmail_extra">-<span class="" style="white-space:pre">        </span>snprintf(path, size, "%s/%s", config_dir, name);</div>
<div class="gmail_extra"> <span class="" style="white-space:pre">     </span>return path;</div><div class="gmail_extra"> }</div><div class="gmail_extra">-- </div><div class="gmail_extra">1.7.10.4</div></div></div>