diff --git a/src/commands.c b/src/commands.c
index 2c8fc902008875e605bf27be68e8de5c4bf5824d..7f5a765524ca86682d00c368b792810d7c258ebb 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -177,18 +177,16 @@ bool
 command_play(volatile sqlite3 *db, struct lkt_win *win, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
 {
     *watch_mask_ptr |= MPD_IDLE_PLAYER;
-    char *endptr;
-    long pos = 0;
+    char *endptr, err;
+    long pos = 1;
 
     /* Argument handle. */
-
-    pos = args[0] == NULL ? 1 : strtol(args[0], &endptr, 10);
-    RETURN_IF((errno == ERANGE && (pos == LONG_MAX || pos == LONG_MIN)) || (errno != 0 && pos == 0),
-              "Failed: strtol", false);
-    RETURN_IF(endptr == args[0], "No digit found", false);
+    if (!args[0]) {
+        STRTOL(pos, args[0], endptr, err);
+        RETURN_IF(err, "STRTOL failed", false);
+    }
 
     /* Do the actual job here. */
-
     database_queue_stop(db);
     RETURN_UNLESS(win->new (win), "Can't create window", false);
     return __play_that_file(db, win, pos);
@@ -198,20 +196,16 @@ bool
 command_playid(volatile sqlite3 *db, struct lkt_win *win, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
 {
     *watch_mask_ptr |= MPD_IDLE_PLAYER;
-    char *endptr;
+    char *endptr, err;
     int pos = 0;
     long id;
 
     /* Argument handle. */
-
     RETURN_IF(args[0] == NULL, "Invalid argument", false);
-    id = strtol(args[0], &endptr, 10);
-    RETURN_IF((errno == ERANGE && (id == LONG_MAX || id == LONG_MIN)) || (errno != 0 && id == 0),
-              "Failed: strtol", false);
-    RETURN_IF(endptr == args[0], "No digit found", false);
+    STRTOL(id, args[0], endptr, err);
+    RETURN_IF(err, "STRTOL failed", false);
 
     /* Do the work. */
-
     database_queue_stop(db);
     RETURN_UNLESS(win->new (win), "Can't create window", false);
     database_queue_seekid(db, (int) id, &pos);
@@ -249,14 +243,12 @@ command_addid(volatile sqlite3 *db, struct lkt_win *win, char *args[LKT_MESSAGE_
     UNUSED(win);
     RETURN_UNLESS(args, "Invalid argument", false);
     long id;
-    char *endptr, *id_str = args[0];
+    char *endptr = NULL, err = 0;
     struct lkt_uri uri = { .type = uri_id };
-    errno = 0;
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
-    id = strtol(id_str, &endptr, 10);
-    RETURN_IF((errno == ERANGE && (id == LONG_MAX || id == LONG_MIN)) || (errno != 0 && id == 0), "Failed: strtol", false);
+    STRTOL(id, args[0], endptr, err);
+    RETURN_IF(err, "STRTOL failed", false);
     uri.value = (void *) (size_t) id;
-    RETURN_IF(endptr == args[0], "No digit found", false);
     return database_queue_add_uri(db, &uri, 1);
 }
 
@@ -279,15 +271,12 @@ command_delid(volatile sqlite3 *db, struct lkt_win *win, char *id_str, mpd_idle_
 {
     UNUSED(win);
     long id;
-    char *endptr;
+    char *endptr = NULL, err = 0;
     int uri = 0;
 
-    errno = 0;
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
-    id = strtol(id_str, &endptr, 10);
-    RETURN_IF((errno == ERANGE && (id == LONG_MAX || id == LONG_MIN)) || (errno != 0 && id == 0),
-              "Failed: strtol", false);
-    RETURN_IF(endptr == id_str, "No digit found", false);
+    STRTOL(id, id_str, endptr, err);
+    RETURN_IF(err, "STRTOL failed", false);
 
     /* If one day we allow suppression of the current kara, will need the `win`
        pointer to reload the kara in the same position (but the kara won't be
@@ -301,25 +290,18 @@ bool
 command_move(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
 {
     long from, to;
-    char *endptr;
+    char *endptr, err;
 
     RETURN_UNLESS(args && args[0] && args[1], "Invalid argument", false);
-    errno = 0;
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
 
     /* First argument: from */
-
-    from = strtol(args[0], &endptr, 10);
-    RETURN_IF((errno == ERANGE && (from == LONG_MAX || from == LONG_MIN)) || (errno != 0 && from == 0),
-              "Failed: strtol", false);
-    RETURN_IF(endptr == args[0], "No digit found", false);
+    STRTOL(from, args[0], endptr, err);
+    RETURN_IF(err, "STRTOL failed", false);
 
     /* Second argument: to */
-
-    to = strtol(args[1], &endptr, 10);
-    RETURN_IF((errno == ERANGE && (to == LONG_MAX || to == LONG_MIN)) || (errno != 0 && to == 0),
-              "Failed: strtol", false);
-    RETURN_IF(endptr == args[0], "No digit found", false);
+    STRTOL(to, args[1], endptr, err);
+    RETURN_IF(err, "STRTOL failed", false);
 
     return database_queue_move(db, from, to);
 }
@@ -516,18 +498,15 @@ command_set_playback_option(struct lkt_state *srv, size_t c, enum lkt_playback_o
 {
     RETURN_UNLESS(srv, "Invalid argument", false);
     UNUSED(c);
-    long val, ret = false;
-    char *endptr;
+    long val;
+    char *endptr, ret = false;
     struct lkt_win *win = &srv->win;
 
     if (args == NULL || args[0] == NULL)
         val = 0;
     else {
-        errno = 0;
-        val = strtol(args[0], &endptr, 10);
-        RETURN_IF((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0),
-                  "Failed: strtol", false);
-        RETURN_IF(endptr == args[0], "No digit found", false);
+        STRTOL(val, args[0], endptr, ret);
+        RETURN_IF(ret, "STRTOL failed", false);
 
         // No values can exceed those boundings, no matter the option //
         if (val < 0)
@@ -612,21 +591,17 @@ end_plt_add_uri:
 bool
 command_plt_remove(volatile sqlite3 *db, char *args[LKT_MESSAGE_ARGS_MAX], mpd_idle_flag *watch_mask_ptr)
 {
-    char *endptr;
-    long pos;
-
     RETURN_UNLESS(args && args[0], "Invalid argument", false);
+    char *endptr, err;
+    long pos;
 
     if (args[1] == NULL) {
         *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
         return database_plt_remove(db, args[0]);
     }
 
-    pos = strtol(args[1], &endptr, 10);
-    RETURN_IF((errno == ERANGE && (pos == LONG_MAX || pos == LONG_MIN)) || (errno != 0 && pos == 0),
-              "Failed: strtol", false);
-    RETURN_IF(endptr == args[1], "No digit found", false);
-
+    STRTOL(pos, args[1], endptr, err);
+    RETURN_IF(err, "STRTOL failed", false);
     *watch_mask_ptr |= MPD_IDLE_PLAYLIST;
     return database_plt_remove_pos(db, args[0], pos);
 }
@@ -699,7 +674,7 @@ command_queue_list(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_
 {
     unsigned int from, to, tmp_switch;
     long val;
-    char *endptr, *str;
+    char *endptr, err, *str;
     struct lkt_callback callback = {
         .call = lkt_callback_send_row_v1,
         .srv = srv,
@@ -709,13 +684,8 @@ command_queue_list(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_
     RETURN_UNLESS(args && args[0] && strlen(args[0]), "Invalid argument", false);
 
     /* Convert the first integer. */
-    errno = 0;
-    str = args[0] + strspn(args[0], "-+ "); // Skip not permited chars (NO NEGATIVE!) //
-    val = (unsigned int) strtol(str, &endptr, 0);
-    RETURN_IF((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0),
-              "Invalid argument", false);
-    RETURN_IF(endptr == args[0], "No digit found", false);
-
+    STRTOL(val, args[0], endptr, err);
+    RETURN_IF(err, "STRTOL failed", false);
     from = labs(val);
 
     /* There is nothing after, is is the song pos version. */
@@ -725,12 +695,9 @@ command_queue_list(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_
     /* There is something after, this is the absolute forme of the command. Then
        parse the second value. Skip the supposed ':' character. */
     else {
-        str = endptr + strspn(endptr, "-+: "); // NO NEGATIVE! //
-        val = strtol(str, &endptr, 0);
-        RETURN_IF((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) || (errno != 0 && val == 0),
-                  "Invalid argument", false);
-        RETURN_IF(endptr == args[0], "No digit found", false);
-
+        str = endptr;
+        STRTOL(val, str, endptr, err);
+        RETURN_IF(err, "STRTOL failed", false);
         to = labs(val);
 
         if (to < from) {
@@ -866,14 +833,16 @@ bool
 command_sticker_get(struct lkt_state *srv, size_t c, char *argv[LKT_MESSAGE_ARGS_MAX])
 {
     RETURN_UNLESS(argv[0] && argv[1] && argv[2] && !argv[3], "Invalid argument", false);
-    int uri = atoi(argv[1]); /* FIXME: Use strtol. */
+    int uri, err;
+    char *endptr;
+    STRTOL(uri, argv[1], endptr, err);
+    RETURN_IF(err, "STRTOL failed", false);
     struct sticker_callback cb = {
         .srv = srv,
         .c = c,
         .call = sticker_send_one_value,
     };
-    RETURN_UNLESS(database_sticker_get(srv->db, argv[0], argv[2], uri, &cb), "Failed to get sticker",
-                  false);
+    RETURN_UNLESS(database_sticker_get(srv->db, argv[0], argv[2], uri, &cb), "Failed to get sticker", false);
     return true;
 }
 
@@ -882,8 +851,11 @@ command_sticker_set(struct lkt_state *srv, size_t c, char *argv[LKT_MESSAGE_ARGS
 {
     UNUSED(c);
     RETURN_UNLESS(argv[0] && argv[1] && argv[2] && argv[3] && !argv[4], "Invalid argument", false);
-    int uri = atoi(argv[1]);    /* FIXME: Use strtol. */
-    int value = atoi(argv[4]);  /* FIXME: Use strtol. */
+    int uri, value, err1, err2;
+    char *endptr;
+    STRTOL(uri, argv[1], endptr, err1);
+    STRTOL(value, argv[4], endptr, err2);
+    RETURN_IF(err1 || err2, "STRTOL failed", false);
     RETURN_UNLESS(database_sticker_set(srv->db, argv[0], argv[2], uri, value), "Failed to get sticker", false);
     srv->mpd_idle_events |= MPD_IDLE_STICKER;
     return true;