util  findconf.c at [e02ae59ffd]

File clib/findconf.c artifact a59d30e6d7 part of check-in e02ae59ffd


/* [ʞ] findconf.c
 *  ~ lexi hale <lexi@hale.su>
 *  $ cc -c findconf.c
 *  🄯 GNU AGPL v3
 *	# include <stdlib.h>
 *	  include "compose.c"
 */

#include <stdlib.h>
#define sz(x) (sizeof x / sizeof x[0])

#define _k_conf(name,s) findconf((name ".cf"), ("ʞ_" name "_conf"), (s))
bool findconf(char* filename,char* env,safestr* s) {
	say("attempting to locate config file",0);
	var(filename);

	if (filename != NULL) {
		char* conf = getenv(env);
		if (conf != NULL) {
			say("config file specified by " _hlvar("%s") ": " _hlpath, env, conf);
			s->heap=false; s->ptr = conf;
			s->len=strlen(conf); return true;
		} else {
			say("no config file specified by " _hlvar("%s") ", constructing XDG path",env);
		}
	}

	char* xdg, *home, *path = NULL;
	size_t len;
	if (xdg  = getenv("XDG_CONFIG_HOME")) {
		say("config dir " _hlpath " specified by " _hlvar("XDG_CONFIG_HOME"), xdg);
		pstr xdg_path[] = { {0, xdg}, _p("/"), {0, filename} } ;
		path = compose(xdg_path, sz(xdg_path), &(s->len));
	} else if (home = getenv("HOME")) {
		say(_hlvar("XDG_CONFIG_HOME") " undefined, constructing default from " _hlvar("HOME"),home);
		var(home);
		pstr home_path[] = { {0, home}, _p("/.config/"), {0, filename} };
		path = compose(home_path, sz(home_path), &(s->len));
	} else {
		say("no " _hlvar("HOME") " variable, assuming /home/$USER",0);
		char* user = getenv("USER");
		if (user == NULL) { /* uh oh */ user = getlogin();
			say("no " _hlvar("USER") " variable, but " _hl(3, "getlogin","","()") " reports %s",user); }
		if (user != NULL) {
			pstr user_path[] = { _p("/home/"), {0, user}, _p("/.config/"), {0, filename} };
			path = compose(user_path, sz(user_path), &(s->len));
		} else {
			// UH OH
			say("no " _hlvar("USER") " and " _hl(3, "getlogin","","()") " did not return a sane value - bailing the fuck out",0);
			return false;
		}
	}

	var(path);
	if (path) {
		s->ptr = path;
		s->heap = true;
		return true;
	} else return false;
}
#undef sz