Browse Source

Client klish uses config file

Serj Kalichev 1 year ago
parent
commit
98aaef49b5
7 changed files with 83 additions and 18 deletions
  1. 11 0
      bin/klish/klish.c
  2. 54 10
      bin/klish/opts.c
  3. 6 0
      bin/klish/private.h
  4. 7 7
      bin/klishd/opts.c
  5. 1 1
      bin/klishd/private.h
  6. 2 0
      klish.conf
  7. 2 0
      klishd.conf

+ 11 - 0
bin/klish/klish.c

@@ -63,6 +63,17 @@ int main(int argc, char **argv)
 		goto err;
 	}
 
+	// Parse config file
+	if (!access(opts->cfgfile, R_OK)) {
+		if (!config_parse(opts->cfgfile, opts))
+			goto err;
+	} else if (opts->cfgfile_userdefined) {
+		// User defined config must be found
+		fprintf(stderr, "Error: Can't find config file %s\n",
+			opts->cfgfile);
+		goto err;
+	}
+
 	// Connect to server
 	unix_sock = ktp_connect_unix(opts->unix_socket_path);
 	if (unix_sock < 0) {

+ 54 - 10
bin/klish/opts.c

@@ -13,6 +13,7 @@
 #include <faux/faux.h>
 #include <faux/str.h>
 #include <faux/list.h>
+#include <faux/ini.h>
 
 #include <klish/ktp_session.h>
 
@@ -33,7 +34,10 @@ struct options *opts_init(void)
 	opts->stop_on_error = BOOL_FALSE;
 	opts->dry_run = BOOL_FALSE;
 	opts->quiet = BOOL_FALSE;
+	opts->cfgfile = faux_str_dup(DEFAULT_CFGFILE);
+	opts->cfgfile_userdefined = BOOL_FALSE;
 	opts->unix_socket_path = faux_str_dup(KLISH_DEFAULT_UNIX_SOCKET_PATH);
+	opts->pager = faux_str_dup(DEFAULT_PAGER);
 
 	// Don't free command list because elements are the pointers to
 	// command line options and don't need to be freed().
@@ -52,7 +56,9 @@ void opts_free(struct options *opts)
 {
 	if (!opts)
 		return;
+	faux_str_free(opts->cfgfile);
 	faux_str_free(opts->unix_socket_path);
+	faux_str_free(opts->pager);
 	faux_list_free(opts->commands);
 	faux_list_free(opts->files);
 
@@ -64,14 +70,14 @@ void opts_free(struct options *opts)
  */
 int opts_parse(int argc, char *argv[], struct options *opts)
 {
-	static const char *shortopts = "hvS:c:edq";
+	static const char *shortopts = "hvf:c:erq";
 	static const struct option longopts[] = {
-		{"socket",		1, NULL, 'S'},
+		{"conf",		1, NULL, 'f'},
 		{"help",		0, NULL, 'h'},
 		{"verbose",		0, NULL, 'v'},
 		{"command",		1, NULL, 'c'},
 		{"stop-on-error",	0, NULL, 'e'},
-		{"dry-run",		0, NULL, 'd'},
+		{"dry-run",		0, NULL, 'r'},
 		{"quiet",		0, NULL, 'q'},
 		{NULL,			0, NULL, 0}
 	};
@@ -84,17 +90,13 @@ int opts_parse(int argc, char *argv[], struct options *opts)
 		if (-1 == opt)
 			break;
 		switch (opt) {
-		case 'S':
-			faux_str_free(opts->unix_socket_path);
-			opts->unix_socket_path = faux_str_dup(optarg);
-			break;
 		case 'v':
 			opts->verbose = BOOL_TRUE;
 			break;
 		case 'e':
 			opts->stop_on_error = BOOL_TRUE;
 			break;
-		case 'd':
+		case 'r':
 			opts->dry_run = BOOL_TRUE;
 			break;
 		case 'q':
@@ -107,6 +109,11 @@ int opts_parse(int argc, char *argv[], struct options *opts)
 		case 'c':
 			faux_list_add(opts->commands, optarg);
 			break;
+		case 'f':
+			faux_str_free(opts->cfgfile);
+			opts->cfgfile = faux_str_dup(optarg);
+			opts->cfgfile_userdefined = BOOL_TRUE;
+			break;
 		default:
 			help(-1, argv[0]);
 			_exit(-1);
@@ -158,13 +165,50 @@ void help(int status, const char *argv0)
 		printf("Usage   : %s [options] [filename] ... [filename]\n", name);
 		printf("Klish client\n");
 		printf("Options :\n");
-		printf("\t-S <path>, --socket=<path> UNIX socket path.\n");
 		printf("\t-h, --help Print this help.\n");
 		printf("\t-v, --verbose Be verbose.\n");
 		printf("\t-c <line>, --command=<line> Command to execute.\n"
 			"\t\tMultiple options are allowed.\n");
 		printf("\t-e, --stop-on-error Stop script execution on error.\n");
 		printf("\t-q, --quiet Disable echo while executing commands\n\t\tfrom the file stream.\n");
-		printf("\t-d, --dry-run Don't actually execute ACTION scripts.\n");
+		printf("\t-r, --dry-run Don't actually execute ACTION scripts.\n");
+		printf("\t-f <path>, --conf=<path> Config file ("
+			DEFAULT_CFGFILE ").\n");
+	}
+}
+
+
+/** @brief Parse config file
+ *
+ */
+bool_t config_parse(const char *cfgfile, struct options *opts)
+{
+	faux_ini_t *ini = NULL;
+	const char *tmp = NULL;
+
+	ini = faux_ini_new();
+	assert(ini);
+	if (!ini)
+		NULL;
+	if (!faux_ini_parse_file(ini, cfgfile)) {
+		fprintf(stderr, "Error: Can't parse config file \"%s\"\n", cfgfile);
+		faux_ini_free(ini);
+		return BOOL_FALSE;
+	}
+
+	// UnixSocketPath
+	if ((tmp = faux_ini_find(ini, "UnixSocketPath"))) {
+		faux_str_free(opts->unix_socket_path);
+		opts->unix_socket_path = faux_str_dup(tmp);
 	}
+
+	// DBs
+	if ((tmp = faux_ini_find(ini, "Pager"))) {
+		faux_str_free(opts->pager);
+		opts->pager = faux_str_dup(tmp);
+	}
+
+	faux_ini_free(ini);
+
+	return BOOL_TRUE;
 }

+ 6 - 0
bin/klish/private.h

@@ -6,12 +6,17 @@
 #define VERSION "1.0.0"
 #endif
 
+#define DEFAULT_CFGFILE "/etc/klish/klish.conf"
+#define DEFAULT_PAGER "/usr/bin/less -I -F -e -X -K -d"
 
 /** @brief Command line and config file options
  */
 struct options {
 	bool_t verbose;
+	char *cfgfile;
+	bool_t cfgfile_userdefined;
 	char *unix_socket_path;
+	char *pager;
 	bool_t stop_on_error;
 	bool_t dry_run;
 	bool_t quiet;
@@ -24,6 +29,7 @@ void help(int status, const char *argv0);
 struct options *opts_init(void);
 void opts_free(struct options *opts);
 int opts_parse(int argc, char *argv[], struct options *opts);
+bool_t config_parse(const char *cfgfile, struct options *opts);
 
 // Interactive shell
 int klish_interactive_shell(ktp_session_t *ktp, struct options *opts);

+ 7 - 7
bin/klishd/opts.c

@@ -63,12 +63,12 @@ void opts_free(struct options *opts)
  */
 int opts_parse(int argc, char *argv[], struct options *opts)
 {
-	static const char *shortopts = "hp:c:fl:v";
+	static const char *shortopts = "hp:f:dl:v";
 	static const struct option longopts[] = {
 		{"help",		0, NULL, 'h'},
 		{"pid",			1, NULL, 'p'},
-		{"conf",		1, NULL, 'c'},
-		{"foreground",		0, NULL, 'f'},
+		{"conf",		1, NULL, 'f'},
+		{"foreground",		0, NULL, 'd'},
 		{"verbose",		0, NULL, 'v'},
 		{"facility",		1, NULL, 'l'},
 		{NULL,			0, NULL, 0}
@@ -86,12 +86,12 @@ int opts_parse(int argc, char *argv[], struct options *opts)
 			faux_str_free(opts->pidfile);
 			opts->pidfile = faux_str_dup(optarg);
 			break;
-		case 'c':
+		case 'f':
 			faux_str_free(opts->cfgfile);
 			opts->cfgfile = faux_str_dup(optarg);
 			opts->cfgfile_userdefined = BOOL_TRUE;
 			break;
-		case 'f':
+		case 'd':
 			opts->foreground = BOOL_TRUE;
 			break;
 		case 'v':
@@ -142,11 +142,11 @@ void help(int status, const char *argv0)
 		printf("Klish daemon\n");
 		printf("Options :\n");
 		printf("\t-h, --help Print this help.\n");
-		printf("\t-f, --foreground Don't daemonize.\n");
+		printf("\t-d, --foreground Don't daemonize.\n");
 		printf("\t-v, --verbose Be verbose.\n");
 		printf("\t-p <path>, --pid=<path> File to save daemon's PID to ("
 			DEFAULT_PIDFILE ").\n");
-		printf("\t-c <path>, --conf=<path> Config file ("
+		printf("\t-f <path>, --conf=<path> Config file ("
 			DEFAULT_CFGFILE ").\n");
 		printf("\t-l, --facility Syslog facility (DAEMON).\n");
 	}

+ 1 - 1
bin/klishd/private.h

@@ -16,9 +16,9 @@
 struct options {
 	char *pidfile;
 	char *cfgfile;
+	bool_t cfgfile_userdefined;
 	char *unix_socket_path;
 	char *dbs;
-	bool_t cfgfile_userdefined;
 	bool_t foreground; // Don't daemonize
 	bool_t verbose;
 	int log_facility;

+ 2 - 0
klish.conf

@@ -0,0 +1,2 @@
+UnixSocketPath=/tmp/klish-unix-socket
+#Pager=/usr/bin/more

+ 2 - 0
klishd.conf

@@ -0,0 +1,2 @@
+UnixSocketPath=/tmp/klish-unix-socket
+DBs=libxml2