diff options
Diffstat (limited to 'usr/src/cmd/iscsi/iscsitadm/helper.c')
| -rw-r--r-- | usr/src/cmd/iscsi/iscsitadm/helper.c | 517 | 
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); -} | 
