+ /* Copy known value to the first URI. */
+ tmp_uris[0].dtype = proto->dtype;
+ tmp_uris[0].proto = proto->type;
+
+ if (proto->code == P_FILE) {
+ if (*purl != '/') {
+ ERR("Missing destination full path.");
+ goto free_error;
+ }
+
+ strncpy(tmp_uris[0].dst.path, purl, sizeof(tmp_uris[0].dst.path));
+ tmp_uris[0].dst.path[sizeof(tmp_uris[0].dst.path) - 1] = '\0';
+ DBG3("URI file destination: %s", purl);
+ goto end;
+ }
+
+ /* Assume we are at the beginning of an address or host of some sort. */
+ addr_b = purl;
+
+ /*
+ * Handle IPv6 address inside square brackets as mention by RFC 2732. IPv6
+ * address that does not start AND end with brackets will be rejected even
+ * if valid.
+ *
+ * proto://[<addr>]...
+ * ^
+ */
+ if (*purl == '[') {
+ /* Address begins after '[' */
+ addr_b = purl + 1;
+ addr_e = strchr(addr_b, ']');
+ if (addr_e == NULL || addr_b == addr_e) {
+ ERR("Broken IPv6 address %s", addr_b);
+ goto free_error;
+ }
+
+ /* Moving parsed URL pointer after the final bracket ']' */
+ purl = addr_e + 1;
+
+ /*
+ * The closing bracket must be followed by a seperator or NULL char.
+ */
+ if (strchr(seps, *purl) == NULL) {
+ ERR("Unknown symbol after IPv6 address: %s", purl);
+ goto free_error;
+ }
+ } else {
+ purl = strpbrk_or_eos(purl, seps);
+ addr_e = purl;
+ }
+
+ /* Check if we at least have a char for the addr or hostname. */
+ if (addr_b == addr_e) {
+ ERR("No address or hostname detected.");
+ goto free_error;