summaryrefslogtreecommitdiff
path: root/usr/src/cmd/iscsi/iscsitadm/helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/iscsi/iscsitadm/helper.c')
-rw-r--r--usr/src/cmd/iscsi/iscsitadm/helper.c517
1 files changed, 0 insertions, 517 deletions
diff --git a/usr/src/cmd/iscsi/iscsitadm/helper.c b/usr/src/cmd/iscsi/iscsitadm/helper.c
deleted file mode 100644
index e34bd3f8b6..0000000000
--- a/usr/src/cmd/iscsi/iscsitadm/helper.c
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <wchar.h>
-#include <widec.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <libintl.h>
-#include <limits.h>
-#include <string.h>
-#include <strings.h>
-#include <syslog.h>
-#include <errno.h>
-#include <netinet/in.h>
-#include <sys/iscsi_protocol.h>
-#include <door.h>
-#include <sys/scsi/generic/inquiry.h>
-#include <sys/mman.h>
-#include <sys/filio.h>
-#include <libxml/xmlreader.h>
-#include <libscf.h>
-#include <fcntl.h>
-
-#include <iscsitgt_impl.h>
-#include "cmdparse.h"
-#include "utility.h"
-#include "helper.h"
-
-extern char *cmdName;
-
-static stat_delta_t *stat_head;
-
-/*
- * []----
- * | buffer_xml -- buffer incoming XML response until complete
- * |
- * | Incoming data from target may not be a complete XML message. So,
- * | we need to wait until we've got everything otherwise the XML routines
- * | will generate a parsing error for a short buffer.
- * []----
- */
-Boolean_t
-buffer_xml(char *s, char **storage, tgt_node_t **np)
-{
- tgt_node_t *node = NULL;
- xmlTextReaderPtr r;
- char *p,
- *e,
- *end_tag,
- hold_ch;
-
- p = *storage;
- if (s != NULL) {
- if (p == NULL) {
- p = strdup(s);
- } else {
- p = realloc(p, strlen(p) + strlen(s) + 1);
- (void) strcat(p, s);
- }
- }
- if (p == NULL) {
- return (False);
- }
-
- if (*p != '<') {
- return (False);
- }
-
- if ((e = strchr(p, '>')) == NULL) {
- return (False);
- }
-
- /*
- * The +3 is for the slash, closing tag character and null
- * For example if p is pointing at a string which starts with
- * "<foo>...."
- * p will point at '<' and e will point at '>'. e - p is 4, yet
- * the tag length is really 5 characters. We will need to create
- * the end tag which also has a slash and NULL byte.
- */
- if ((end_tag = malloc(e - p + 3)) == NULL) {
- return (False);
- }
-
- end_tag[0] = '<';
- end_tag[1] = '/';
-
- /*
- * Copy in the tag value and the closing tag character '>'.
- */
- bcopy(p + 1, &end_tag[2], e - p);
-
- /*
- * Add the null byte
- */
- end_tag[e - p + 2] = '\0';
-
- /*
- * Do we have the closing string yet? If not, just return
- */
- if ((e = strstr(p, end_tag)) == NULL) {
- *storage = p;
- return (False);
- }
-
- /*
- * Move past the closing tag and free the end_tag memory
- */
- e += strlen(end_tag);
- free(end_tag);
-
- /*
- * NULL terminate the string and remember to save that character
- * so that we can restore it later.
- */
- hold_ch = *e;
- *e = '\0';
-
- if ((r = (xmlTextReaderPtr)xmlReaderForMemory(p, strlen(p), NULL,
- NULL, 0)) == NULL)
- return (False);
-
- while (xmlTextReaderRead(r) == 1) {
- if (tgt_node_process(r, &node) == False)
- break;
- }
-
- *np = node;
-
- xmlFreeTextReader(r);
-
- *e = hold_ch;
- for (; isspace(*e); e++)
- ;
- if (*e != '\0') {
- *storage = strdup(e);
- } else
- *storage = NULL;
- free(p);
- return (True);
-}
-
-/*
- * Retrieve CHAP secret from input
- */
-int
-getSecret(char *secret, int *secretLen, int minSecretLen, int maxSecretLen)
-{
- char *chapSecret;
-
- /* XXX Should we prompt for hex or ascii printable input? */
-
- /* get password */
- chapSecret = getpassphrase(gettext("Enter secret:"));
-
- if (strlen(chapSecret) > maxSecretLen) {
- (void) fprintf(stderr, "%s: %s\n", cmdName,
- gettext("secret too long"));
- *secret = NULL;
- return (1);
- }
-
- if (strlen(chapSecret) < minSecretLen && strlen(chapSecret) != 0) {
- (void) fprintf(stderr, "%s: %s\n", cmdName,
- gettext("secret too short"));
- *secret = NULL;
- return (1);
- }
-
- (void) strcpy(secret, chapSecret);
-
- chapSecret = getpassphrase(gettext("Re-enter secret:"));
- if (strcmp(secret, chapSecret) != 0) {
- (void) fprintf(stderr, "%s: %s\n", cmdName,
- gettext("secret not changed"));
- *secret = NULL;
- return (1);
- }
- *secretLen = strlen(chapSecret);
- return (0);
-}
-
-void
-iSCSINameCheckStatusDisplay(iSCSINameCheckStatusType status)
-{
- switch (status) {
- case iSCSINameLenZero:
- (void) fprintf(stderr, "%s: %s\n",
- cmdName, gettext("empty iSCSI name."));
- break;
- case iSCSINameLenExceededMax:
- (void) fprintf(stderr, "%s: %s\n", cmdName,
- gettext("iSCSI name exceeded maximum length."));
- break;
- case iSCSINameUnknownType:
- (void) fprintf(stderr, "%s: %s\n", cmdName,
- gettext("unknown iSCSI name type."));
- break;
- case iSCSINameIqnFormatError:
- (void) fprintf(stderr, "%s: %s\n", cmdName,
- gettext("iqn formatting error."));
- break;
- case iSCSINameEUIFormatError:
- (void) fprintf(stderr, "%s: %s\n", cmdName,
- gettext("eui formatting error."));
- break;
- }
-}
-
-/*
- * This helper function could go into a utility module for general use.
- */
-int
-parseAddress(char *address_port_str,
- uint16_t defaultPort,
- char *address_str,
- size_t address_str_len,
- uint16_t *port,
- boolean_t *isIpv6)
-{
- char port_str[64];
- int tmp_port;
-
- if (address_port_str[0] == '[') {
- /* IPv6 address */
- char *close_bracket_pos;
- close_bracket_pos = strchr(address_port_str, ']');
- if (!close_bracket_pos) {
- syslog(LOG_USER|LOG_DEBUG,
- "IP address format error: %s\n", address_str);
- return (PARSE_ADDR_MISSING_CLOSING_BRACKET);
- }
-
- *close_bracket_pos = NULL;
- (void) strlcpy(address_str, &address_port_str[1],
- address_str_len);
-
- /* Extract the port number */
- close_bracket_pos++;
- if (*close_bracket_pos == ':') {
- close_bracket_pos++;
- if (*close_bracket_pos != NULL) {
- (void) strlcpy(port_str, close_bracket_pos,
- 64);
- tmp_port = atoi(port_str);
- if (((tmp_port > 0) &&
- (tmp_port > USHRT_MAX)) ||
- (tmp_port < 0)) {
- /* Port number out of range */
- syslog(LOG_USER|LOG_DEBUG,
- "Specified port out of range: %d",
- tmp_port);
- return (PARSE_ADDR_PORT_OUT_OF_RANGE);
- } else {
- *port = (uint16_t)tmp_port;
- }
- } else {
- *port = defaultPort;
- }
- } else {
- *port = defaultPort;
- }
-
- *isIpv6 = B_TRUE;
- } else {
- /* IPv4 address */
- char *colon_pos;
- colon_pos = strchr(address_port_str, ':');
- if (!colon_pos) {
- /* No port number specified. */
- *port = defaultPort;
- (void) strlcpy(address_str, address_port_str,
- address_str_len);
- } else {
- *colon_pos = (char)NULL;
- (void) strlcpy(address_str, address_port_str,
- address_str_len);
-
- /* Extract the port number */
- colon_pos++;
- if (*colon_pos != NULL) {
- (void) strlcpy(port_str, colon_pos, 64);
- tmp_port = atoi(port_str);
- if (((tmp_port > 0) &&
- (tmp_port > USHRT_MAX)) ||
- (tmp_port < 0)) {
- /* Port number out of range */
- syslog(LOG_USER|LOG_DEBUG,
- "Specified port out of range: %d",
- tmp_port);
- return (PARSE_ADDR_PORT_OUT_OF_RANGE);
- } else {
- *port = (uint16_t)tmp_port;
- }
- } else {
- *port = defaultPort;
- }
- }
-
- *isIpv6 = B_FALSE;
- }
-
- return (PARSE_ADDR_OK);
-}
-
-/*
- * []----
- * | Following routine (number_to_scaled_string) is lifted
- * | from usr/src/cmd/fs.d/df.c
- * []----
- */
-/*
- * Convert an unsigned long long to a string representation and place the
- * result in the caller-supplied buffer.
- * The given number is in units of "unit_from" size,
- * this will first be converted to a number in 1024 or 1000 byte size,
- * depending on the scaling factor.
- * Then the number is scaled down until it is small enough to be in a good
- * human readable format i.e. in the range 0 thru scale-1.
- * If it's smaller than 10 there's room enough to provide one decimal place.
- * The value "(unsigned long long)-1" is a special case and is always
- * converted to "-1".
- * Returns a pointer to the caller-supplied buffer.
- */
-char *
-number_to_scaled_string(
- char *buf, /* put the result here */
- unsigned long long number, /* convert this number */
- int unit_from,
- int scale)
-{
- unsigned long long save = 0;
- char *M = "KMGTPE"; /* Measurement: kilo, mega, giga, tera, peta, exa */
- char *uom = M; /* unit of measurement, initially 'K' (=M[0]) */
-
- if ((long long)number == (long long)-1) {
- (void) strcpy(buf, "-1");
- return (buf);
- }
-
- if ((number < scale) && (unit_from == 1)) {
- (void) sprintf(buf, "%4llu", number);
- return (buf);
- }
- /*
- * Convert number from unit_from to given scale (1024 or 1000).
- * This means multiply number by unit_from and divide by scale.
- *
- * Would like to multiply by unit_from and then divide by scale,
- * but if the first multiplication would overflow, then need to
- * divide by scale and then multiply by unit_from.
- */
- if (number > (UINT64_MAX / (unsigned long long)unit_from)) {
- number = (number / (unsigned long long)scale) *
- (unsigned long long)unit_from;
- } else {
- number = (number * (unsigned long long)unit_from) /
- (unsigned long long)scale;
- }
-
- /*
- * Now we have number as a count of scale units.
- * Stop scaling when we reached exa bytes, then something is
- * probably wrong with our number.
- */
-
- while ((number >= scale) && (*uom != 'E')) {
- uom++; /* next unit of measurement */
- save = number;
- number = (number + (scale / 2)) / scale;
- }
- /* check if we should output a decimal place after the point */
- if (save && ((save / scale) < 10)) {
- /* sprintf() will round for us */
- float fnum = (float)save / scale;
- (void) sprintf(buf, "%2.1f%c", fnum, *uom);
- } else {
- (void) sprintf(buf, "%4llu%c", number, *uom);
- }
- return (buf);
-}
-
-void
-stats_load_counts(tgt_node_t *n, stat_delta_t *d)
-{
- tgt_node_t *conn = NULL,
- *lun;
- char *val;
-
- bzero(d, sizeof (*d));
- d->device = n->x_value;
-
- while (conn = tgt_node_next(n, XML_ELEMENT_CONN, conn)) {
- lun = NULL;
- while (lun = tgt_node_next(conn, XML_ELEMENT_LUN, lun)) {
- if (tgt_find_value_str(lun, XML_ELEMENT_READCMDS,
- &val) == True) {
- d->read_cmds += strtoll(val, NULL, 0);
- free(val);
- }
- if (tgt_find_value_str(lun, XML_ELEMENT_WRITECMDS,
- &val) == True) {
- d->write_cmds += strtoll(val, NULL, 0);
- free(val);
- }
- if (tgt_find_value_str(lun, XML_ELEMENT_READBLKS,
- &val) == True) {
- d->read_blks += strtoll(val, NULL, 0);
- free(val);
- }
- if (tgt_find_value_str(lun, XML_ELEMENT_WRITEBLKS,
- &val) == True) {
- d->write_blks += strtoll(val, NULL, 0);
- free(val);
- }
- }
- }
-}
-
-stat_delta_t *
-stats_prev_counts(stat_delta_t *cp)
-{
- stat_delta_t *n;
-
- for (n = stat_head; n; n = n->next) {
- if (strcmp(n->device, cp->device) == 0)
- return (n);
- }
- if ((n = calloc(1, sizeof (*n))) == NULL)
- return (NULL);
- n->device = strdup(cp->device);
- if (stat_head == NULL)
- stat_head = n;
- else {
- n->next = stat_head;
- stat_head = n;
- }
- return (n);
-}
-
-void
-stats_update_counts(stat_delta_t *p, stat_delta_t *c)
-{
- p->read_cmds += c->read_cmds - p->read_cmds;
- p->write_cmds += c->write_cmds - p->write_cmds;
- p->read_blks += c->read_blks - p->read_blks;
- p->write_blks += c->write_blks - p->write_blks;
-}
-
-void
-stats_free()
-{
- stat_delta_t *n;
-
- /* CSTYLED */
- for (;stat_head;) {
- n = stat_head->next;
- free(stat_head->device);
- free(stat_head);
- stat_head = n;
- }
-}
-
-static char spaces[128];
-
-/*
- * []----
- * | dospace -- generate a string which has the appropriate number of spaces
- * |
- * | NOTE: Since this function modifies a static buffer usage of this
- * | function may not be what's expected. For example:
- * | printf("%sfoo%sbar\n", dospace(1), dospace(2)); would produce
- * | ' foo bar'
- * | instead of
- * | ' foo bar'
- * []----
- */
-char *
-dospace(int n)
-{
- (void) memset(spaces, ' ', sizeof (spaces));
- spaces[sizeof (spaces) - 1] = '\0';
-
- if (n < sizeof (spaces))
- spaces[n * 4] = '\0';
- return (spaces);
-}