diff --git a/.clang-format b/.clang-format
index 6ba67db58dcae48b7df410b5f441f625a8809aec..f292a0f219069123dea60222d9fc5c4b6e9e7efd 100644
--- a/.clang-format
+++ b/.clang-format
@@ -62,6 +62,7 @@ ForEachMacros:
   - 'FOR_EVER'
   - 'FOR_EVER_IF'
   - 'FOR_EVER_UNTIL'
+  - 'FOR_EACH_FLAT_LIST_ITEM'
 
 IncludeCategories:
   - Regex: '.*'
diff --git a/inc/lektor/cmd.h b/inc/lektor/cmd.h
index 39f27694f79ec856f4f4156c786c21713b7a7526..b37d64fe9720ebfff20526feffa2dd831d11114b 100644
--- a/inc/lektor/cmd.h
+++ b/inc/lektor/cmd.h
@@ -15,29 +15,69 @@ extern "C" {
     {                                                                                                                  \
         .name = NULL, .call = func                                                                                     \
     }
+#define CMD_ENV_NULL                                                                                                   \
+    {                                                                                                                  \
+        .name = NULL, .value = NULL, .handler = NULL,                                                                  \
+    }
+#define CMD_ENV(n, hndl)                                                                                               \
+    {                                                                                                                  \
+        .name = n, .handler = hndl                                                                                     \
+    }
+#define CMD_ENV_DEFAULT(n, v, hndl)                                                                                    \
+    {                                                                                                                  \
+        .name = n, .value = v, .handler = hndl                                                                         \
+    }
 
+/* The arguments passed to a command */
 struct cmd_args {
     int argc;          /* The number of arguments passed.  */
     const char **argv; /* An array of argument passed.     */
 };
 
+/* Callback to call on command, takes the arguments */
 typedef void (*cmd_callback)(struct cmd_args *);
 
+/* Callback for the 'apply_env' function. */
+typedef void (*cmd_env_callback)(const char *name, const char *value, void *user);
+
+/* The 'option' command struct, this is how a new command is registered for the
+ * cmd_parse command. The list must end with the CMD_OPT_NULL or
+ * CMD_OPT_DEFAULT macros (set the NULL at the end of a list with no
+ * length...). The command names MUST NOT include the = or : characters! They
+ * also must be distinguishable, i.e. one command name must not be simply
+ * included in another name:
+ * - play, playlist => bad, because play is included in playlist
+ * - status, start  => good, no inclusion between the names */
 struct cmd_opt {
     const char *name;
     cmd_callback call;
 };
 
+/* Options or env of the command. Don't depend on the POSIX env variables for
+ * now and do it ourself. */
+struct cmd_env {
+    const char *name;
+    const char *value;
+    cmd_env_callback handler;
+};
+
+/* Parse the 'env' of the command, i.e. the options before the command, like:
+ * ./a.out opt1=foo opt2=bar sub-command com1
+ * The cmd_apply function is here to do the handle stuff for the options to be
+ * registered in a user specific way (callback + user pointer). */
+void cmd_parse_env(struct cmd_env *env, int *argc, const char ***argv);
+void cmd_apply_env(struct cmd_env *env, void *user);
+
 /* Parse the command line with the list of options. No parameter may be NULL.
-   Does not return. */
+ * Does not return. */
 EXIT_FUNCTION cmd_parse(struct cmd_opt *opts, int argc, const char **argv);
 
 /* Must be setted for the lkt_cmd_parse function to display the correct help
-   in case of errors. */
+ * in case of errors. */
 void cmd_set_executable_name(const char *);
 const char *cmd_get_executable_name(void);
 
-/* Prints the help and exit */
+/* Prints the help if possible and exit. */
 EXIT_FUNCTION print_help(void);
 
 #if defined(__cplusplus)
diff --git a/inc/lektor/common.h b/inc/lektor/common.h
index 0c3914611297ef358e0863ead361ae5079b6cb86..36e007e73b248adead994bcba72b54fa9017454b 100644
--- a/inc/lektor/common.h
+++ b/inc/lektor/common.h
@@ -58,8 +58,11 @@ extern EXIT_FUNCTION ___not_implemented(const char *func, char *file, int line);
         err_flag = errno != 0 || endptr == str;                                                                        \
     })
 
+/* Get a generic function pointer from any function pointer. */
 #define FUNCTION_POINTER(func) ((void (*)(void))(func))
-#define FOR_EVER               for (;;)
+
+/* Forever macros */
+#define FOR_EVER for (;;)
 #define FOR_EVER_IF(expr)                                                                                              \
     FOR_EVER {                                                                                                         \
         if (!(expr))                                                                                                   \
@@ -67,6 +70,9 @@ extern EXIT_FUNCTION ___not_implemented(const char *func, char *file, int line);
     }
 #define FOR_EVER_UNTIL(expr) FOR_EVER_IF (!(expr))
 
+/* For each, for flat-list. Need to be null terminated on the normally non-null field. */
+#define FOR_EACH_FLAT_LIST_ITEM(it, nnull_field) for (; (it)->nnull_field != NULL; it++)
+
 /* Custom defined assert. */
 extern void (*___lkt_assert)(const char *file, int line, const char *func, const char *msg);
 #ifdef assert
diff --git a/src/base/cmd.c b/src/base/cmd.c
index 25715fea4eb46520dae098c60026af56838cbd9d..2b3fae4e36adee6b277385c853f5b60f3b72d810 100644
--- a/src/base/cmd.c
+++ b/src/base/cmd.c
@@ -59,6 +59,63 @@ print_help(void)
     }
 }
 
+PRIVATE_FUNCTION size_t
+___get_max_options(struct cmd_env *env)
+{
+    struct cmd_env *it = env;
+    size_t ret         = 0;
+
+    FOR_EACH_FLAT_LIST_ITEM (it, name) {
+        ret++;
+    }
+
+    return ret;
+}
+
+PRIVATE_FUNCTION bool
+___find_and_set_option(struct cmd_env *env, const char *name, size_t name_len, const char *value)
+{
+    struct cmd_env *it = env;
+
+    FOR_EACH_FLAT_LIST_ITEM (it, name) {
+        if (STR_NMATCH(it->name, name, name_len)) {
+            it->value = value;
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void
+cmd_apply_env(struct cmd_env *env, void *user)
+{
+    struct cmd_env *it = env;
+
+    FOR_EACH_FLAT_LIST_ITEM (it, name) {
+        it->handler(it->name, it->value, user);
+    }
+}
+
+void
+cmd_parse_env(struct cmd_env *env, int *argc, const char ***argv)
+{
+    assert((*argv) >= 0);
+
+    size_t max_options = ___get_max_options(env);
+    size_t len         = 0;
+    int got            = 0;
+
+    for (size_t i = 1; i < (size_t)(*argc) && i < max_options; ++i) {
+        len = strcspn((*argv)[i], "=:");
+        got += ___find_and_set_option(env, (*argv)[i], len, (*argv)[i] + len + 1);
+    }
+
+    /* Skip the gotten options from the command line. */
+    *argv = &(*argv)[got + 1];
+    *argc = (*argc) - (got + 1);
+}
+
 EXIT_FUNCTION
 cmd_parse(struct cmd_opt *opts, int argc, const char **argv)
 {
diff --git a/src/main/lkt.c b/src/main/lkt.c
index b3fb82ff06546c1c7a4bc6ff263585ee3676b919..b30af8bc447a1c62171b4ea125c572af122a5509 100644
--- a/src/main/lkt.c
+++ b/src/main/lkt.c
@@ -45,7 +45,7 @@ row_printer row_print = NULL;
 #define LKT_MAX_OPTIONS 4 /* Number of options that can be passed to lkt before the commands. */
 static const char *host;
 static const char *port;
-static const char *password;
+static const char *pwd;
 static const char *row_format;
 
 /* Default queue length to query */
@@ -54,7 +54,7 @@ static const char *LKT_QUEUE_DEFAULT[] = { "10" };
 /* Small screen column count, to autoset the 'pretty' printer. The standard
  * 80x25 terminal is small! */
 #define LKT_SMALL_SCREEN_THRESHOLD 82
-#define IS_SMALL_SCREEN (___column_count <= LKT_SMALL_SCREEN_THRESHOLD)
+#define IS_SMALL_SCREEN            (___column_count <= LKT_SMALL_SCREEN_THRESHOLD)
 static unsigned ___column_count = 0;
 CONSTRUCTOR_FUNCTION
 setup_column_count(void)
@@ -108,7 +108,7 @@ ___row_printer_pretty(char *line)
 
     /* Get the author */
     char *author = strstr(title, " [");
-    *author = '\0';
+    *author      = '\0';
     author += strlen(" [");
     FAIL_IF(author == NULL, "Invalid row, faild to find the author");
     last = strstr(author, "]");
@@ -410,10 +410,10 @@ just_send(queue_flatten__, "__flat\n");
 EXIT_FUNCTION
 simple_send_with_password__(const char *cmd)
 {
-    FAIL_UNLESS(password, "Password not provided");
+    FAIL_UNLESS(pwd, "Password not provided");
     FILE *sock = lkt_connect();
     write_socket(sock, "command_list_begin\n");
-    write_socket(sock, "password %s\n", password);
+    write_socket(sock, "password %s\n", pwd);
     write_socket(sock, "%s\n", cmd);
     write_socket(sock, "command_list_end\n");
     exit(EXIT_SUCCESS);
@@ -436,13 +436,13 @@ kill__(struct cmd_args *args)
 EXIT_FUNCTION
 rescan_or_update__(struct cmd_args *args, const char *cmd)
 {
-    FAIL_UNLESS(password, "Password not provided");
+    FAIL_UNLESS(pwd, "Password not provided");
     FILE *sock = lkt_connect();
 
     /* All the db */
     if (args->argc == 0) {
         write_socket(sock, "command_list_begin\n");
-        write_socket(sock, "password %s\n", password);
+        write_socket(sock, "password %s\n", pwd);
         write_socket(sock, "%s\n", cmd);
         write_socket(sock, "command_list_end\n");
     }
@@ -453,7 +453,7 @@ rescan_or_update__(struct cmd_args *args, const char *cmd)
         memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char));
         FAIL_IF(lkt_get_query_type(args, buff, LKT_MESSAGE_MAX), "Query is not valid");
         write_socket(sock, "command_list_begin\n");
-        write_socket(sock, "password %s\n", password);
+        write_socket(sock, "password %s\n", pwd);
         write_socket(sock, "%s %s\n", cmd, buff);
         write_socket(sock, "command_list_end\n");
     }
@@ -1314,33 +1314,38 @@ sigpipe__(int sig)
     exit(EXIT_FAILURE);
 }
 
-/* Functions declarations. */
+/* Handle the options switches */
 
-PRIVATE_FUNCTION void
-parse_args(args_t *args, int argc, const char **argv)
-{
-    int i, got = 0;
-    size_t len;
-
-    for (i = 1; i < argc && i < LKT_MAX_OPTIONS; ++i) {
-        len = strcspn(argv[i], "=:");
-
-#define ___get_args(name)                                                                                              \
-    if (STR_NMATCH(#name, argv[i], len)) {                                                                             \
-        args->name = (argv[i] + len + 1);                                                                              \
-        ++got;                                                                                                         \
-    }
-        ___get_args(host);
-        ___get_args(port);
-        ___get_args(pwd);
-        ___get_args(row_format);
-#undef ___get_args
+#define ___DEFINE_SETTER(what)                                                                                         \
+    PRIVATE_FUNCTION void ___USE_SETTER(what)(const char UNUSED *name, const char *value, void UNUSED *user)           \
+    {                                                                                                                  \
+        what = value;                                                                                                  \
     }
+#define ___USE_SETTER(what) ___set_env_##what
+
+___DEFINE_SETTER(host);
+___DEFINE_SETTER(port);
+___DEFINE_SETTER(pwd);
 
-    args->argv = &argv[got + 1];
-    args->argc = argc - (got + 1);
+PRIVATE_FUNCTION void ___USE_SETTER(row_format)(const char UNUSED *name, const char *value, void UNUSED *user)
+{
+    row_format = value;
+    setup_row_printer();
 }
 
+// clang-format off
+static struct cmd_env env_[] = {
+    CMD_ENV_DEFAULT("host", "localhost", ___USE_SETTER(host)),
+    CMD_ENV_DEFAULT("port", "6600",      ___USE_SETTER(port)),
+    CMD_ENV("pwd",                       ___USE_SETTER(pwd)),
+    CMD_ENV("row_format",                ___USE_SETTER(row_format)),
+    CMD_ENV_NULL,
+};
+// clang-format on
+
+#undef ___USE_SETTER
+#undef ___DEFINE_SETTER
+
 int
 main(int argc, const char **argv)
 {
@@ -1352,20 +1357,8 @@ main(int argc, const char **argv)
     if (signal(SIGPIPE, sigpipe__))
         LOG_ERROR("SYS", "Failed to install handler for SIGPIPE signal (you may be using php...)");
 
-    args_t args = {
-        .host = "localhost",
-        .port = "6600",
-    };
-
-    parse_args(&args, argc, argv);
-
-    host       = args.host;
-    port       = args.port;
-    password   = args.pwd;
-    row_format = args.row_format;
-
-    setup_row_printer();
-
-    /* Communication with lektor. */
-    cmd_parse(options_, args.argc, args.argv);
+    /* Parse */
+    cmd_parse_env(env_, &argc, &argv);
+    cmd_apply_env(env_, NULL);
+    cmd_parse(options_, argc, argv);
 }