home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2001 January
/
PCWorld_2001-01_cd.bin
/
Software
/
Topware
/
sambar
/
_SETUP.1
/
netutils.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-07-31
|
13KB
|
587 lines
/*
** NETUTILS
**
** HTTP Wrapper for some basic Network Utilities
** (Not yet ported to UNIX)
**
** Confidential Property of Tod Sambar
** (c) Copyright Tod Sambar 1997
** All rights reserved.
**
**
** Public Functions:
**
** netutils_init
** ipname_lookup
** ipname_scalar
** whois_lookup
** finger_lookup
**
**
** History:
** Chg# Date Description Resp
** ---- ------- ------------------------------------------------------- ----
** 2FEB97 Created sambar
*/
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#ifdef WIN32
#include <winsock.h>
#include <direct.h>
#endif /* WIN32 */
#include <errno.h>
#include <netutils.h>
/*
** WHOIS defines
*/
#define WHOIS_PORT 43
#define WHOIS_SERVER "198.41.0.6" /* rs.internic.net */
/*
** Network Utility RPC Commands
*/
typedef struct netutils__rpcs
{
SA_CHAR *name;
SA_RPCPARAM *params;
SA_INT numparams;
SA_INT auth;
SA_VOID *func;
SA_CHAR *descr;
} NETUTILS__RPCS;
static SA_RPCPARAM ipnamep [] =
{
{ "ipaddr", 1, "IP Address to lookup." }
};
static SA_RPCPARAM whoisp [] =
{
{ "sitename", 1, "Site name to lookup." },
{ "nameserver", 0, "Name server to use (rs.internic.net is default)" }
};
static SA_RPCPARAM fingerp [] =
{
{ "user", 0, "User name to lookup (may be NULL)." },
{ "host", 1, "Site to lookup user on (must have finger daemon)." }
};
static NETUTILS__RPCS netutils_rpcs [] =
{
{ "ipname", ipnamep, sizeof(ipnamep) / sizeof(SA_RPCPARAM),
SA_AUTHORIZATION_SCRIPT, (SA_VOID *)ipname_lookup,
"Lookup the DNS name associated with an IP address." },
{ "whois", whoisp, sizeof(ipnamep) / sizeof(SA_RPCPARAM),
SA_AUTHORIZATION_SCRIPT, (SA_VOID *)whois_lookup,
"Perform a whois lookup given a network domain name." },
{ "finger", fingerp, sizeof(fingerp) / sizeof(SA_RPCPARAM),
SA_AUTHORIZATION_SCRIPT, (SA_VOID *)finger_lookup,
"Perform a finger lookup given a user and host." }
};
/*
** Network Scalar Methods
*/
typedef struct netutils__scalars
{
SA_CHAR *name;
SA_SCALARARG *args;
SA_INT numargs;
SA_VOID *func;
SA_CHAR *descr;
} NETUTILS__SCALARS;
static SA_SCALARARG ipscalarp [] =
{
{ "ipaddr", "IP Address to lookup." }
};
static NETUTILS__SCALARS netutils_scalars [] =
{
{ "ipname", ipscalarp, sizeof(ipscalarp)/sizeof(SA_SCALARARG),
(SA_VOID *)ipname_scalar,
"Lookup the DNS name associated with an IP address." },
};
/*
** NETUTILS_INIT
**
** Initialize the Network Utilities.
**
** Parameters:
** sactx Sambar Server context
**
** Returns:
** SA_SUCCEED | SA_FAIL
*/
SA_RETCODE SA_PUBLIC
netutils_init(sactx)
SA_CTX *sactx;
{
int i;
/* Register the Network Uitlities RPCs with the application */
for (i = 0; i < sizeof(netutils_rpcs) / sizeof(NETUTILS__RPCS); i++)
{
if (sa_cmd_init(sactx, netutils_rpcs[i].name,
netutils_rpcs[i].params, netutils_rpcs[i].numparams,
netutils_rpcs[i].auth, netutils_rpcs[i].descr,
(SA_RPCFUNC)netutils_rpcs[i].func) != SA_SUCCEED)
{
sa_log(sactx, "Unable to initialize Network Utility RPCs");
return (SA_FAIL);
}
}
/* Register the Scalar methods with the server */
for (i = 0; i < sizeof(netutils_scalars) / sizeof(NETUTILS__SCALARS); i++)
{
if (sa_scalar_init(sactx, netutils_scalars[i].name,
netutils_scalars[i].args, netutils_scalars[i].numargs,
netutils_scalars[i].descr, netutils_scalars[i].func) != SA_SUCCEED)
{
sa_log(sactx, "Unable to initialize Network Utility Scalars");
return (SA_FAIL);
}
}
sa_log(sactx, "Network Utilities Initialized");
return (SA_SUCCEED);
}
/*
** IPNAME_LOOKUP
**
** Get the host name associated with an IP address.
**
** Parameters:
** sactx Sambar Server context
** saconn Sambar Server connection
** saparams RPC Parameters
** infop Error parameters
**
** Returns:
** SA_SUCCEED | SA_FAIL
*/
SA_RETCODE SA_PUBLIC
ipname_lookup(sactx, saconn, saparams, infop)
SA_CTX *sactx;
SA_CONN *saconn;
SA_PARAMS *saparams;
SA_INT *infop;
{
#ifndef WIN32
return (SA_FAIL);
#else
unsigned long addr;
SA_INT datalen;
SA_CHAR *data;
struct hostent *hent;
/* Get the ip address to lookup */
if ((sa_param(sactx, saparams, "ipaddr", &data, &datalen) != SA_SUCCEED)
|| (datalen == 0) || (datalen > 255))
{
*infop = SA_E_INVALIDDATA;
return (SA_FAIL);
}
addr = (int)inet_addr((char *)data);
if (addr == -1)
{
*infop = SA_E_INVALIDDATA;
return (SA_FAIL);
}
hent = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
if (hent != NULL)
{
if (sa_conn_send(saconn, hent->h_name, SA_NULLTERM) != SA_SUCCEED)
return (SA_FAIL);
}
else
{
if (sa_conn_send(saconn, "unknown", SA_NULLTERM) != SA_SUCCEED)
return (SA_FAIL);
}
return (SA_SUCCEED);
#endif /* WIN32 */
}
/*
** WHOIS_LOOKUP
**
** Perform a whois search.
**
** Parameters:
** sactx Sambar Server context
** saconn Sambar Server connection
** saparams RPC Parameters
** infop Error parameters
**
** Returns:
** SA_SUCCEED | SA_FAIL
*/
SA_RETCODE SA_PUBLIC
whois_lookup(sactx, saconn, saparams, infop)
SA_CTX *sactx;
SA_CONN *saconn;
SA_PARAMS *saparams;
SA_INT *infop;
{
#ifndef WIN32
return (SA_FAIL);
#else
int timeo;
SA_INT buflen;
SA_INT datalen;
SA_BOOL finished;
SOCKET sock;
unsigned long addr;
SA_CHAR *data;
SA_CHAR *nameserver;
struct sockaddr_in sin;
struct hostent *hent;
SA_CHAR buffer[1024];
/* Get the (optional) name server to use. */
datalen = 0;
(void)sa_param(sactx, saparams, "nameserver", &data, &datalen);
if ((datalen > 0) && (datalen < 255))
nameserver = data;
else
nameserver = WHOIS_SERVER;
/* Get the site name */
if ((sa_param(sactx, saparams, "sitename", &data, &datalen) != SA_SUCCEED)
|| (datalen == 0) || (datalen > 255))
{
*infop = SA_E_INVALIDDATA;
return (SA_FAIL);
}
/* Get the WHOIS server address for the query */
addr = (int)inet_addr(nameserver);
if (addr == -1)
{
/* Try gethostbyname() */
hent = gethostbyname(nameserver);
if (hent == NULL)
{
*infop = SA_E_INVALIDDATA;
return (SA_FAIL);
}
addr = (int)hent->h_addr;
}
hent = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
if (hent == NULL)
{
if (sa_conn_send(saconn, "The WHOIS server is not available.",
SA_NULLTERM) != SA_SUCCEED)
{
return (SA_FAIL);
}
return (SA_SUCCEED);
}
/* Create a socket */
sock = socket(hent->h_addrtype, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
if (sa_conn_send(saconn, "The WHOIS server is not available.",
SA_NULLTERM) != SA_SUCCEED)
{
return (SA_FAIL);
}
return (SA_SUCCEED);
}
/* Connect to the WHOIS server */
sin.sin_family = AF_INET;
sin.sin_port = htons((u_short)WHOIS_PORT);
memcpy(&sin.sin_addr, hent->h_addr, hent->h_length);
/* Now, connect to that WHOIS server */
if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
closesocket(sock);
if (sa_conn_send(saconn, "The WHOIS server is not available.",
SA_NULLTERM) != SA_SUCCEED)
{
return (SA_FAIL);
}
return (SA_SUCCEED);
}
/* Set the socket recv timeout to 10 seconds */
timeo = 10000;
(void)setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeo,
sizeof(int));
/* Send the request. */
sprintf(buffer, "%s\r\n", data);
buflen = strlen(buffer);
if (send(sock, buffer, buflen, 0) != buflen)
{
closesocket(sock);
if (sa_conn_send(saconn, "The WHOIS server is not available.",
SA_NULLTERM) != SA_SUCCEED)
{
return (SA_FAIL);
}
return (SA_SUCCEED);
}
/* Receive the response. */
finished = 0;
while (!finished)
{
buflen = recv(sock, buffer, 1024, 0);
if ((buflen < 0) && (errno == EINTR))
continue;
if (buflen == SOCKET_ERROR)
{
closesocket(sock);
return (SA_FAIL);
}
if (buflen > 0)
{
if (sa_conn_send(saconn, buffer, buflen) != SA_SUCCEED)
{
closesocket(sock);
return (SA_FAIL);
}
}
else
{
finished = 1;
}
}
closesocket(sock);
if (!finished)
{
if (sa_conn_send(saconn, "The WHOIS server is not available.",
SA_NULLTERM) != SA_SUCCEED)
{
return (SA_FAIL);
}
}
return (SA_SUCCEED);
#endif /* WIN32 */
}
/*
** FINGER_LOOKUP
**
** Perform a 'finger' search.
**
** Parameters:
** sactx Sambar Server context
** saconn Sambar Server connection
** saparams RPC Parameters
** infop Error parameters
**
** Returns:
** SA_SUCCEED | SA_FAIL
*/
SA_RETCODE SA_PUBLIC
finger_lookup(sactx, saconn, saparams, infop)
SA_CTX *sactx;
SA_CONN *saconn;
SA_PARAMS *saparams;
SA_INT *infop;
{
#ifndef WIN32
return (SA_FAIL);
#else
int timeo;
SA_INT buflen;
SA_INT userlen;
SA_INT hostlen;
SA_BOOL finished;
SOCKET sock;
SA_CHAR *host;
SA_CHAR *user;
struct sockaddr_in sin;
struct hostent *hent;
SA_CHAR buffer[1024];
/* Get the host where the finger server is running */
if ((sa_param(sactx, saparams, "host", &host, &hostlen) != SA_SUCCEED)
|| (hostlen == 0) || (hostlen > 255))
{
*infop = SA_E_INVALIDDATA;
return (SA_FAIL);
}
(void)sa_param(sactx, saparams, "user", &user, &userlen);
/* Get the finger server address */
hent = gethostbyname(host);
if (hent == NULL)
{
sprintf(buffer, "Unable to locate the specified host: '%s'", host);
if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
return (SA_FAIL);
return (SA_SUCCEED);
}
/* Open a socket */
sock = socket(PF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
if (sa_conn_send(saconn, "Unable to create a new TCP/IP socket.",
SA_NULLTERM) != SA_SUCCEED)
{
return (SA_FAIL);
}
return (SA_SUCCEED);
}
/* Connect to the finger server */
sin.sin_family = AF_INET;
sin.sin_port = htons((u_short)IPPORT_FINGER);
memcpy(&sin.sin_addr, hent->h_addr, hent->h_length);
/* Now, connect to that WHOIS server */
if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
closesocket(sock);
sprintf(buffer, "Unable to connect to the host: '%s'", host);
if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
return (SA_FAIL);
return (SA_SUCCEED);
}
/* Set the socket recv timeout to 10 seconds */
timeo = 10000;
(void)setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeo,
sizeof(int));
/* Send the request. */
sprintf(buffer, "%s\r\n", (userlen > 0 && userlen < 255) ? user : "");
buflen = strlen(buffer);
if (send(sock, buffer, buflen, 0) != buflen)
{
closesocket(sock);
sprintf(buffer, "Failure connecting to finger daemon at: '%s'", host);
if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
return (SA_FAIL);
return (SA_SUCCEED);
}
/* Receive the response. */
finished = 0;
while (!finished)
{
buflen = recv(sock, buffer, 1024, 0);
if ((buflen < 0) && (errno == EINTR))
continue;
if (buflen == SOCKET_ERROR)
{
closesocket(sock);
return (SA_FAIL);
}
if (buflen > 0)
{
if (sa_conn_send(saconn, buffer, buflen) != SA_SUCCEED)
{
closesocket(sock);
return (SA_FAIL);
}
}
else
{
finished = 1;
}
}
closesocket(sock);
if (!finished)
{
sprintf(buffer, "Finger daemon at host '%s' is not available.", host);
if (sa_conn_send(saconn, buffer, SA_NULLTERM) != SA_SUCCEED)
return (SA_FAIL);
}
return (SA_SUCCEED);
#endif /* WIN32 */
}
/*
** IPNAME_SCALAR
**
** Scalar to retrieve the IP address associated with a host name.
**
** Usage: <RC@ipname(host)>
**
** Parameters:
** sactx Sambar Server context
** saconn Sambar Server connection
** saargs Scalar arguments
** value Result buffer (maximum 1000 bytes).
**
** Returns:
** SA_SUCCEED | SA_FAIL
*/
SA_RETCODE SA_PUBLIC
ipname_scalar(sactx, saconn, saargs, value)
SA_CTX *sactx;
SA_CONN *saconn;
SA_ARG *saargs;
SA_CHAR *value;
{
#ifndef WIN32
return (SA_FAIL);
#else
unsigned long addr;
SA_CHAR *data;
struct hostent *hent;
data = saargs->value;
if (data == NULL)
return (SA_FAIL);
addr = (int)inet_addr((char *)data);
if (addr == -1)
return (SA_FAIL);
hent = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
if (hent != NULL)
strcpy(value, hent->h_name);
else
strcpy(value, "unknown");
return (SA_SUCCEED);
#endif /* WIN32 */
}