diff --git a/include/iscsi.h b/include/iscsi.h index e3cb00d..d806659 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -54,17 +54,41 @@ struct iscsi_url { /* * This function is used to parse an iSCSI URL into a iscsi_url structure. * iSCSI URL format : - * iscsi://[%@][:]// + * iscsi://[[%]@][:]// * * Function will return a pointer to an iscsi url structure if successful, * or it will return NULL and set iscsi_get_error() accrodingly if there was a problem * with the URL. * + * CHAP username/password can also be provided via environment variables + * LIBISCSI_CHAP_USERNAME=ronnie + * LIBISCSI_CHAP_PASSWORD=password + * * The returnes structure is freed by calling iscsi_destroy_url() */ struct iscsi_url *iscsi_parse_full_url(struct iscsi_context *iscsi, const char *url); void iscsi_destroy_url(struct iscsi_url *iscsi_url); +/* + * This function is used to parse an iSCSI Portal URL into a iscsi_url structure. + * iSCSI Portal URL format : + * iscsi://[[%]@][:] + * + * iSCSI Portal URL is used when describing a discovery session, where the target-iqn and the + * lun is not yet known. + * + * Function will return a pointer to an iscsi url structure if successful, + * or it will return NULL and set iscsi_get_error() accrodingly if there was a problem + * with the URL. + * + * CHAP username/password can also be provided via environment variables + * LIBISCSI_CHAP_USERNAME=ronnie + * LIBISCSI_CHAP_PASSWORD=password + * + * The returnes structure is freed by calling iscsi_destroy_url() + */ +struct iscsi_url * +iscsi_parse_portal_url(struct iscsi_context *iscsi, const char *url); /* * This function returns a description of the last encountered error. diff --git a/lib/init.c b/lib/init.c index ec2c28f..f871f9c 100644 --- a/lib/init.c +++ b/lib/init.c @@ -31,6 +31,8 @@ #define ISCSI_URL_SYNTAX "\"iscsi://[[%]@]" \ "[:]//\"" +#define ISCSI_PURL_SYNTAX "\"iscsi://[[%]@]" \ + "[:]\"" struct iscsi_context * iscsi_create_context(const char *initiator_name) @@ -368,6 +370,86 @@ iscsi_parse_full_url(struct iscsi_context *iscsi, const char *url) return iscsi_url; } +struct iscsi_url * +iscsi_parse_portal_url(struct iscsi_context *iscsi, const char *url) +{ + struct iscsi_url *iscsi_url; + char *str; + char *portal; + char *user = NULL; + char *passwd = NULL; + char *tmp; + + if (strncmp(url, "iscsi://", 8)) { + iscsi_set_error(iscsi, "Invalid URL %s\niSCSI Portal URL must be of " + "the form: %s", + url, + ISCSI_PURL_SYNTAX); + return NULL; + } + + str = strdup(url + 8); + if (str == NULL) { + iscsi_set_error(iscsi, "Out-of-memory: Failed to strdup url %s", url); + return NULL; + } + portal = str; + + user = getenv("LIBISCSI_CHAP_USERNAME"); + passwd = getenv("LIBISCSI_CHAP_PASSWORD"); + + tmp = index(portal, '@'); + if (tmp != NULL) { + user = portal; + *tmp++ = 0; + portal = tmp; + + tmp = index(user, '%'); + if (tmp != NULL) { + *tmp++ = 0; + passwd = tmp; + } + } + + + iscsi_url = malloc(sizeof(struct iscsi_url)); + if (iscsi_url == NULL) { + iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate iscsi_url structure"); + free(str); + return NULL; + } + memset(iscsi_url, 0, sizeof(struct iscsi_url)); + + iscsi_url->portal = strdup(portal); + if (iscsi_url->portal == NULL) { + iscsi_set_error(iscsi, "Out-of-memory: Failed to strdup portal string"); + iscsi_destroy_url(iscsi_url); + free(str); + return NULL; + } + + if (user != NULL && passwd != NULL) { + iscsi_url->user = strdup(user); + if (iscsi_url->user == NULL) { + iscsi_set_error(iscsi, "Out-of-memory: Failed to strdup username string"); + iscsi_destroy_url(iscsi_url); + free(str); + return NULL; + } + + iscsi_url->passwd = strdup(passwd); + if (iscsi_url->passwd == NULL) { + iscsi_set_error(iscsi, "Out-of-memory: Failed to strdup password string"); + iscsi_destroy_url(iscsi_url); + free(str); + return NULL; + } + } + + free(str); + return iscsi_url; +} + void iscsi_destroy_url(struct iscsi_url *iscsi_url) {