+ char filename[FNLEN];
+ FILE *fp;
+ char *line;
+ tree234 *ret;
+
+ make_filename(filename, INDEX_SESSION, sessionname);
+ fp = fopen(filename, "r");
+ if (!fp)
+ return NULL; /* can't open */
+
+ ret = newtree234(keycmp);
+
+ while ( (line = fgetline(fp)) ) {
+ char *value = strchr(line, '=');
+ struct keyval *kv;
+
+ if (!value)
+ continue;
+ *value++ = '\0';
+ value[strcspn(value, "\r\n")] = '\0'; /* trim trailing NL */
+
+ kv = snew(struct keyval);
+ kv->key = dupstr(line);
+ kv->value = dupstr(value);
+ add234(ret, kv);
+
+ sfree(line);
+ }
+
+ fclose(fp);
+
+ return ret;
+}
+
+char *read_setting_s(void *handle, const char *key, char *buffer, int buflen)
+{
+ tree234 *tree = (tree234 *)handle;
+ const char *val;
+ struct keyval tmp, *kv;
+
+ tmp.key = key;
+ if (tree != NULL &&
+ (kv = find234(tree, &tmp, NULL)) != NULL) {
+ val = kv->value;
+ assert(val != NULL);
+ } else
+ val = get_setting(key);
+
+ if (!val)
+ return NULL;
+ else {
+ strncpy(buffer, val, buflen);
+ buffer[buflen-1] = '\0';
+ return buffer;
+ }
+}
+
+int read_setting_i(void *handle, const char *key, int defvalue)
+{
+ tree234 *tree = (tree234 *)handle;
+ const char *val;
+ struct keyval tmp, *kv;
+
+ tmp.key = key;
+ if (tree != NULL &&
+ (kv = find234(tree, &tmp, NULL)) != NULL) {
+ val = kv->value;
+ assert(val != NULL);
+ } else
+ val = get_setting(key);
+
+ if (!val)
+ return defvalue;
+ else
+ return atoi(val);
+}
+
+int read_setting_fontspec(void *handle, const char *name, FontSpec *result)
+{
+ return !!read_setting_s(handle, name, result->name, sizeof(result->name));
+}
+int read_setting_filename(void *handle, const char *name, Filename *result)
+{
+ return !!read_setting_s(handle, name, result->path, sizeof(result->path));
+}
+
+void write_setting_fontspec(void *handle, const char *name, FontSpec result)
+{
+ write_setting_s(handle, name, result.name);
+}
+void write_setting_filename(void *handle, const char *name, Filename result)
+{
+ write_setting_s(handle, name, result.path);