/*
* Copyright (c) 1998,1999,2000
* Traakan, Inc., Los Altos, CA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Project: NDMJOB
* Ident: $Id: $
*
* Description:
* Handle representation of an NDMP agent.
*
* This provides for a common text for specifying
* an agent host, connection authentication, and
* protocol version. The text specification may
* originate on the command line, in a config file,
* or elsewhere.
*
* A text string representation has the form:
*
* AGENT ::= HOST[:PORT][/FLAGS][,ACCOUNT[,PASSWORD]]
* AGENT ::= .
* FLAGS ::= [23][ntm]
*
* The internal representation is a struct ndmagent.
*/
#include "ndmlib.h"
/* On some solaris distributions INADDR_NONE is not defined,
* so define it here..
*/
#ifndef INADDR_NONE
#define INADDR_NONE ((in_addr_t)-1)
#endif
int
ndmagent_from_str (struct ndmagent *agent, char *str)
{
int have_vers = 0;
int have_auth = 0;
int rc;
char * acct;
char * port;
char * flags;
NDMOS_MACRO_ZEROFILL (agent);
if ((acct = strchr (str, ',')) != 0)
*acct++ = 0; /* stomp */
if ((port = strchr (str, ':')) != 0)
*port++ = 0; /* stomp */
if (port) {
flags = strchr (port, '/');
} else {
flags = strchr (str, '/');
}
if (flags)
*flags++ = 0; /* stomp */
/*
* HOST[:PORT][/FLAGS][,ACCOUNT[,PASSWORD]]
* ^ ^ ^ ^
* str------+ | | |
* port-----------+ | |
* flags-----------------+ |
* acct--------------------------+
*
* The delimiters have been stomped (*p=0).
* If a portion is missing, the respective pointer is NULL (p==0)
* We restore the delimiters (p[-1]=x) as we proceed.
*/
strncpy (agent->host, str, NDMAGENT_HOST_MAX-1);
if (port) {
agent->port = atoi(port);
port[-1] = ':'; /* restore */
} else {
agent->port = NDMPPORT;
}
if (flags) {
char * p;
for (p = flags; *p; p++) {
switch (*p) {
#ifndef NDMOS_OPTION_NO_NDMP2
case '2':
agent->protocol_version = 2;
have_vers++;
break;
#endif /* !NDMOS_OPTION_NO_NDMP2 */
#ifndef NDMOS_OPTION_NO_NDMP3
case '3':
agent->protocol_version = 3;
have_vers++;
break;
#endif /* !NDMOS_OPTION_NO_NDMP3 */
#ifndef NDMOS_OPTION_NO_NDMP4
case '4':
agent->protocol_version = 4;
have_vers++;
break;
#endif /* !NDMOS_OPTION_NO_NDMP4 */
case 'n': /* NDMP_AUTH_NONE */
case 't': /* NDMP_AUTH_TEXT */
case 'm': /* NDMP_AUTH_MD5 */
case 'v': /* void (don't auth) */
agent->auth_type = *p;
have_auth++;
break;
default:
rc = -1;
goto error_out;
}
}
if (have_auth > 1 || have_vers > 1) {
rc = -2;
goto error_out;
}
flags[-1] = '/'; /* restore */
}
if (acct) {
char * pass;
if ((pass = strchr (acct, ',')) != 0)
*pass++ = 0;
strncpy (agent->account, acct, NDMAGENT_ACCOUNT_MAX-1);
if (pass) {
strncpy (agent->password, pass,
NDMAGENT_PASSWORD_MAX-1);
pass[-1] = ',';
}
acct[-1] = ','; /* restore */
if (!have_auth) {
agent->auth_type = 't'; /* NDMP_AUTH_TEXT */
}
}
if (strcmp (agent->host, ".") == 0) {
agent->conn_type = NDMCONN_TYPE_RESIDENT;
strcpy (agent->host, "(resident)");
} else {
agent->conn_type = NDMCONN_TYPE_REMOTE;
}
return 0;
error_out:
if (acct) acct[-1] = ','; /* restore */
if (port) port[-1] = ':'; /* restore */
if (flags) flags[-1] = '/'; /* restore */
return rc;
}
int
ndmhost_lookup (char *hostname, struct sockaddr_in *sin)
{
struct hostent * he;
in_addr_t addr;
NDMOS_MACRO_ZEROFILL (sin);
#ifdef NDMOS_OPTION_HAVE_SIN_LEN
sin->sin_len = sizeof *sin;
#endif
sin->sin_family = AF_INET;
addr = inet_addr (hostname);
if (addr != INADDR_NONE) {
bcopy (&addr, &sin->sin_addr, 4);
} else {
he = gethostbyname (hostname);
if (!he)
return -1;
bcopy (he->h_addr, &sin->sin_addr, 4);
}
return 0;
}
int
ndmagent_to_sockaddr_in (struct ndmagent *agent, struct sockaddr_in *sin)
{
int rc;
rc = ndmhost_lookup (agent->host, sin); /* inits sin */
if (rc) return rc;
sin->sin_port = htons (agent->port);
return 0;
}