diff --git a/lib/package_alternatives.c b/lib/package_alternatives.c
index b2867cdd..145d1ba7 100644
--- a/lib/package_alternatives.c
+++ b/lib/package_alternatives.c
@@ -79,7 +79,6 @@ normpath(char *path)
 	return path;
 }
 
-
 static char *
 relpath(char *from, char *to)
 {
@@ -145,103 +144,85 @@ remove_symlinks(struct xbps_handle *xhp, xbps_array_t a, const char *grname)
 static int
 create_symlinks(struct xbps_handle *xhp, xbps_array_t a, const char *grname)
 {
-	unsigned int i, cnt;
+	int rv;
+	unsigned int i, n;
+	char *alternative, *tok1, *tok2, *linkpath, *target, *dir, *p;
 
-	cnt = xbps_array_count(a);
-	for (i = 0; i < cnt; i++) {
-		xbps_string_t str;
-		char *tgt_dup, *tgt_dir, *tgt_dir_dup, *lnk_dup, *lnk_dir;
-		char *l, *lnk, *tgt = NULL;
-		const char *tgt0;
-		int rv;
+	n = xbps_array_count(a);
 
-		str = xbps_array_get(a, i);
-		l = left(xbps_string_cstring_nocopy(str));
-		assert(l);
-		tgt0 = right(xbps_string_cstring_nocopy(str));
-		assert(tgt0);
-		/* always create target dir, for dangling symlinks */
-		tgt_dup = strdup(tgt0);
-		assert(tgt_dup);
-		tgt_dir = dirname(tgt_dup);
-		tgt_dir_dup = strdup(tgt_dir);
-		if (strcmp(tgt_dir, ".")) {
-			tgt = xbps_xasprintf("%s%s", xhp->rootdir, tgt_dir);
-			if (xbps_mkpath(tgt, 0755) != 0) {
-				if (errno != EEXIST) {
-					rv = errno;
-					xbps_dbg_printf(xhp, "failed to create "
-					    "target dir '%s' for group '%s': %s\n",
-					    tgt, grname, strerror(errno));
-					free(tgt_dir_dup);
-					free(tgt_dup);
-					free(tgt);
-					free(l);
-					return rv;
-				}
-			}
-			free(tgt);
-		}
-		/* always create link dir, for dangling symlinks */
-		lnk_dup = strdup(l);
-		assert(lnk_dup);
-		lnk_dir = dirname(lnk_dup);
-		if (strcmp(lnk_dir, ".")) {
-			lnk = xbps_xasprintf("%s%s", xhp->rootdir, lnk_dir);
-			if (xbps_mkpath(lnk, 0755) != 0) {
-				if (errno != EEXIST) {
-					rv = errno;
-					xbps_dbg_printf(xhp, "failed to create symlink"
-					    "dir '%s' for group '%s': %s\n",
-					    lnk, grname, strerror(errno));
-					free(tgt_dir_dup);
-					free(tgt_dup);
-					free(lnk_dup);
-					free(lnk);
-					free(l);
-					return rv;
-				}
-			}
-			free(lnk);
-		}
-		free(lnk_dup);
+	for (i = 0; i < n; i++) {
+		alternative = xbps_string_cstring(xbps_array_get(a, i));
 
-		if (l[0] != '/') {
-			lnk = xbps_xasprintf("%s%s/%s", xhp->rootdir, tgt_dir_dup, l);
-			free(tgt_dup);
-			tgt_dup = strdup(tgt0);
-			assert(tgt_dup);
-			tgt = strdup(basename(tgt_dup));
-			free(tgt_dup);
-		} else {
-			free(tgt_dup);
-			tgt = strdup(tgt0);
-			lnk = xbps_xasprintf("%s%s", xhp->rootdir, l);
+		if (!(tok1 = strtok(alternative, ":")) ||
+		    !(tok2 = strtok(NULL, ":"))) {
+			free(alternative);
+			return -1;
 		}
-		free(tgt_dir_dup);
+
+		target = strdup(tok2);
+		dir = dirname(tok2);
+
+		/* add target dir to relative links */
+		if (tok1[0] != '/')
+			linkpath = xbps_xasprintf("%s/%s/%s", xhp->rootdir, dir, tok1);
+		else
+			linkpath = xbps_xasprintf("%s/%s", xhp->rootdir, tok1);
+
+		/* create target directory, necessary for dangling symlinks */
+		dir = xbps_xasprintf("%s/%s", xhp->rootdir, dir);
+		if (strcmp(dir, ".") && xbps_mkpath(dir, 0755) && errno != EEXIST) {
+			rv = errno;
+			xbps_dbg_printf(xhp,
+			    "failed to create target dir '%s' for group '%s': %s\n",
+			    dir, grname, strerror(errno));
+			free(dir);
+			goto err;
+		}
+		free(dir);
+
+		/* create link directory, necessary for dangling symlinks */
+		p = strdup(linkpath);
+		dir = dirname(p);
+		if (strcmp(dir, ".") && xbps_mkpath(dir, 0755) && errno != EEXIST) {
+			rv = errno;
+			xbps_dbg_printf(xhp,
+			    "failed to create symlink dir '%s' for group '%s': %s\n",
+			    dir, grname, strerror(errno));
+			free(p);
+			goto err;
+		}
+		free(p);
+
 		xbps_set_cb_state(xhp, XBPS_STATE_ALTGROUP_LINK_ADDED, 0, NULL,
-		    "Creating '%s' alternatives group symlink: %s -> %s", grname, l, tgt);
-		unlink(lnk);
-		if (tgt[0] == '/') {
-			tgt_dup = relpath(lnk + strlen(xhp->rootdir), tgt);
-			free(tgt);
-			tgt = tgt_dup;
+		    "Creating '%s' alternatives group symlink: %s -> %s",
+		    grname, tok1, target);
+
+		if (target[0] == '/') {
+			p = relpath(linkpath + strlen(xhp->rootdir), target);
+			free(target);
+			target = p;
 		}
-		if ((rv = symlink(tgt, lnk)) != 0) {
-			xbps_dbg_printf(xhp, "failed to create alt symlink '%s'"
-			    "for group '%s': %s\n", lnk, grname,
-			    strerror(errno));
-			free(tgt);
-			free(lnk);
-			free(l);
-			return rv;
+
+		unlink(linkpath);
+		if ((rv = symlink(target, linkpath)) != 0) {
+			xbps_dbg_printf(xhp,
+			    "failed to create alt symlink '%s' for group '%s': %s\n",
+			    linkpath, grname,  strerror(errno));
+			goto err;
 		}
-		free(tgt);
-		free(lnk);
-		free(l);
+
+		free(alternative);
+		free(target);
+		free(linkpath);
 	}
 
 	return 0;
+
+err:
+	free(alternative);
+	free(target);
+	free(linkpath);
+	return rv;
 }
 
 int