+ return file;
+
+errmalloc:
+ free(desc);
+ fclose(file);
+ debug(DBG_ERR, "malloc failed");
+ return NULL;
+}
+
+FILE *pushgconfpath(struct gconffile **cf, const char *path) {
+ FILE *f;
+
+ f = fopen(path, "r");
+ return pushgconffile(cf, f, path);
+}
+
+FILE *pushgconfpaths(struct gconffile **cf, const char *cfgpath) {
+ int i;
+ FILE *f = NULL;
+ glob_t globbuf;
+ char *path, *curfile = NULL, *dir;
+
+ /* if cfgpath is relative, make it relative to current config */
+ if (*cfgpath == '/')
+ path = (char *)cfgpath;
+ else {
+ /* dirname may modify its argument */
+ curfile = stringcopy((*cf)->path, 0);
+ if (!curfile) {
+ debug(DBG_ERR, "malloc failed");
+ goto exit;
+ }
+ dir = dirname(curfile);
+ path = malloc(strlen(dir) + strlen(cfgpath) + 2);
+ if (!path) {
+ debug(DBG_ERR, "malloc failed");
+ goto exit;
+ }
+ strcpy(path, dir);
+ path[strlen(dir)] = '/';
+ strcpy(path + strlen(dir) + 1, cfgpath);
+ }
+ memset(&globbuf, 0, sizeof(glob_t));
+ if (glob(path, 0, NULL, &globbuf)) {
+ debug(DBG_WARN, "could not glob %s", path);
+ goto exit;
+ }
+
+ for (i = globbuf.gl_pathc - 1; i >= 0; i--) {
+ f = pushgconfpath(cf, globbuf.gl_pathv[i]);
+ if (!f)
+ break;
+ }
+ globfree(&globbuf);
+
+exit:
+ if (curfile) {
+ free(curfile);
+ free(path);
+ }