diff --git a/include/iscsi.h b/include/iscsi.h index 85695cb..4257a05 100644 --- a/include/iscsi.h +++ b/include/iscsi.h @@ -18,6 +18,15 @@ struct iscsi_context; struct sockaddr; +struct iscsi_url { + const char *portal; + const char *target; + int lun; +}; + +struct iscsi_url *iscsi_parse_full_url(struct iscsi_context *iscsi, const char *url); +void iscsi_destroy_url(struct iscsi_url *iscsi_url); + const char *iscsi_get_error(struct iscsi_context *iscsi); diff --git a/lib/init.c b/lib/init.c index 242f786..ac4e53d 100644 --- a/lib/init.c +++ b/lib/init.c @@ -206,4 +206,79 @@ iscsi_is_logged_in(struct iscsi_context *iscsi) return iscsi->is_loggedin; } +struct iscsi_url * +iscsi_parse_full_url(struct iscsi_context *iscsi, const char *url) +{ + struct iscsi_url *iscsi_url; + char *portal; + char *target; + char *lun; + if (strncmp(url, "iscsi://", 8)) { + iscsi_set_error(iscsi, "Invalid URL %s\niSCSI URL must be of the form \"iscsi://[:]//\"\n", url); + return NULL; + } + + portal = strdup(url + 8); + if (portal == NULL) { + iscsi_set_error(iscsi, "Out-of-memory: Failed to strdup url %s\n", url); + return NULL; + } + + target = index(portal, '/'); + if (target == NULL) { + iscsi_set_error(iscsi, "Invalid URL %s\niSCSI URL must be of the form \"iscsi://[:]//\"\n", url); + free(portal); + return NULL; + } + *target++ = 0; + + lun = index(target, '/'); + if (lun == NULL) { + iscsi_set_error(iscsi, "Invalid URL %s\niSCSI URL must be of the form \"iscsi://[:]//\"\n", url); + free(portal); + return NULL; + } + *lun++ = 0; + + + iscsi_url = malloc(sizeof(struct iscsi_url)); + if (iscsi_url == NULL) { + iscsi_set_error(iscsi, "Out-of-memory: Failed to allocate iscsi_url structure\n"); + free(portal); + 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\n"); + iscsi_destroy_url(iscsi_url); + free(portal); + return NULL; + } + + iscsi_url->target = strdup(target); + if (iscsi_url->target == NULL) { + iscsi_set_error(iscsi, "Out-of-memory: Failed to strdup target string\n"); + iscsi_destroy_url(iscsi_url); + free(portal); + return NULL; + } + + iscsi_url->lun = atoi(lun); + free(portal); + return iscsi_url; +} + +void +iscsi_destroy_url(struct iscsi_url *iscsi_url) +{ + if (iscsi_url == NULL) { + return; + } + + free(discard_const(iscsi_url->portal)); + free(discard_const(iscsi_url->target)); + free(iscsi_url); +} diff --git a/src/iscsi-inq.c b/src/iscsi-inq.c index 33c7fad..e866268 100644 --- a/src/iscsi-inq.c +++ b/src/iscsi-inq.c @@ -157,9 +157,8 @@ int main(int argc, const char *argv[]) struct iscsi_context *iscsi; const char **extra_argv; int extra_argc = 0; - char *portal = NULL; - char *target = NULL; - char *lun = NULL; + const char *url = NULL; + struct iscsi_url *iscsi_url = NULL; int evpd = 0, pagecode = 0; int res; @@ -179,7 +178,7 @@ int main(int argc, const char *argv[]) } extra_argv = poptGetArgs(pc); if (extra_argv) { - portal = strdup(*extra_argv); + url = *extra_argv; extra_argv++; while (extra_argv[extra_argc]) { extra_argc++; @@ -187,50 +186,31 @@ int main(int argc, const char *argv[]) } poptFreeContext(pc); - if (portal == NULL) { - fprintf(stderr, "You must specify target portal\n"); - fprintf(stderr, "%s [options] iscsi://[:]//\n", argv[0]); - exit(10); - } - if (strncmp(portal, "iscsi://", 8)) { - fprintf(stderr, "Incorrect portal specified\n"); - fprintf(stderr, "Portal is specified as \"iscsi://[:]//\"\n"); - exit(10); - } - portal += 8; - - target = index(portal, '/'); - if (target == NULL) { - fprintf(stderr, "You must specify target-iqn name\n"); - fprintf(stderr, "Portal is specified as \"iscsi://[:]//\"\n"); - exit(10); - } - *target++ = 0; - - lun = index(target, '/'); - if (lun == NULL) { - fprintf(stderr, "You must specify target-iqn name\n"); - fprintf(stderr, "Portal is specified as \"iscsi://[:]//\"\n"); - exit(10); - } - *lun++ = 0; - iscsi = iscsi_create_context(initiator); if (iscsi == NULL) { fprintf(stderr, "Failed to create context\n"); exit(10); } - iscsi_set_targetname(iscsi, target); - iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL); - iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); - - if (iscsi_full_connect_sync(iscsi, portal, atoi(lun)) != 0) { - fprintf(stderr, "Failed to log in to target %s\n", iscsi_get_error(iscsi)); + iscsi_url = iscsi_parse_full_url(iscsi, url); + if (iscsi_url == NULL) { + fprintf(stderr, "Failed to parse URL : %s\n", url); exit(10); } - do_inquiry(iscsi, atoi(lun), evpd, pagecode); + iscsi_set_targetname(iscsi, iscsi_url->target); + iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL); + iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); + + if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) { + fprintf(stderr, "Failed to log in to target %s\n", iscsi_get_error(iscsi)); + iscsi_destroy_url(iscsi_url); + iscsi_destroy_context(iscsi); + exit(10); + } + + do_inquiry(iscsi, iscsi_url->lun, evpd, pagecode); + iscsi_destroy_url(iscsi_url); iscsi_logout_sync(iscsi); iscsi_destroy_context(iscsi);