Michael,
I had a similar problem on my Dec alpha running Redhat 5.1. I think the
fundamental problem is the use of size_t as unsigned long instead of unsigned
int. Due to some of these type mismatches etc. (Alphas are 64 bit processors,
not 32 bit, so longs are 8 bytes and not 4!), the libht.a is not being created,
so you have the problem you encountered. There may have been something else in
there that I corrected. But these should hopefully give you a jumpstart. I'm
including a Connection.cc, and Connection.h from the htlib directory from my
setup. Also, note that one of the network address comparisons, the ~0L is
replaced by ~0 This statement change was fundamentally necessary to make htdig
operate - compiled fairly clean - but wouldn't work.
Paul
On Sep 23, 3:43pm, Michael Boer wrote:
> Subject: htdig: making ht://Dig 3.1.0b1 in Digital Unix 4.0D
> There have been a few questions on making ht://Dig in Digital Unix
> recently, but no answers. Since I'm now in the position of wanting to
> do this, I will share a few observations, hoping that someone will find
> sense and a solution in what is a mystery to me.
>
> I have fresh installations of gcc 2.8.1, gmake 3.77, libstdc++ 2.8.1
> (with the libg++ 2.8.1.1a compatibility thing), and I have compiled c++
> in what I believe is the recommended fashion.
>
> Since the normal ht://Dig make process fails, I've tried to approach it
> a step at a time.
> ........
> -L../rx-1.5/rx -L/usr/lib Document.o HTML.o Images.o Parsable.o
> Plaintext.o Postscript.o Retriever.o SGMLEntities.o Server.o URLRef.o
> main.o ExternalParser.o PDF.o -lcommon -lht -ldb -lrx
> collect2: ld returned 1 exit status
> /usr/bin/ld:
> Can't locate file for: -lht
> gmake: *** [htdig] Error 1
>
> This is the essential failure, I think. So, friends, what's up with
> ld's errors here? (Is it an issue that it uses Digital's /usr/bin/ld
> rather than the gnu ld which located elsewhere? Or is it something
> more fundamental than an ld problem?)
>
End of excerpt from Michael Boer
--
__
Paul J. Meyer
Global Hydrology and Climate Center
NASA/MSFC code HR20 | [EMAIL PROTECTED] (SMTP)
Huntsville, AL 35812 | [EMAIL PROTECTED] (X.500)
Voice: (256) 922-5892 Fax: (256) 922-5723
http://wwwghcc.msfc.nasa.gov/
//
// Connection.cc
//
// (c) Copyright 1993, San Diego State University -- College of Sciences
// (See the COPYRIGHT file for more Copyright information)
//
// Implementation of the Connection class
//
// $Log: Connection.cc,v $
// Revision 1.7 1998/06/22 04:33:20 turtle
// New Berkeley database stuff
//
// Revision 1.6 1998/05/26 03:58:06 turtle
// Got rid of compiler warnings.
//
// Revision 1.5 1998/01/05 05:18:18 turtle
// Fix by Pontus Borg for AIX. Changed 'size_t' to 'unsigned long' for
// the length parameter for getpeername()
//
// Revision 1.4 1997/10/23 18:01:10 turtle
// Fix by Pontus Borg for AIX. Changed 'size_t' to 'unsigned long' for
// the length parameter for getpeername()
//
// Revision 1.3 1997/03/24 04:33:19 turtle
// Renamed the String.h file to htString.h to help compiling under win32
//
// Revision 1.2 1997/02/10 17:32:47 turtle
// Applied AIX specific patches supplied by Lars-Owe Ivarsson
// <[EMAIL PROTECTED]>
//
// Revision 1.1.1.1 1997/02/03 17:11:04 turtle
// Initial CVS
//
//
#include "Connection.h"
#include "Object.h"
#include "htString.h"
#include "List.h"
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <sys/file.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdlib.h>
extern "C" {
int rresvport(int *);
}
List all_connections;
Connection::Connection()
{
sock = -1;
connected = 0;
peer = 0;
server_name = 0;
all_connections.Add(this);
}
//*************************************************************************
// Connection::Connection(int socket)
// PURPOSE:
// Create a connection from just a socket.
// PARAMETERS:
// int socket: obvious!!!!
//
Connection::Connection(int socket)
{
sock = socket;
connected = 0;
unsigned int length = sizeof(server);
if (getpeername(socket, (struct sockaddr *)&server, &length) < 0)
{
perror("getpeername");
}
peer = 0;
server_name = 0;
all_connections.Add(this);
}
//*****************************************************************************
// Connection::~Connection()
//
Connection::~Connection()
{
all_connections.Remove(this);
this->close();
delete peer;
delete server_name;
}
//*****************************************************************************
// int Connection::open(int priv)
//
int Connection::open(int priv)
{
if (priv)
{
int aport = IPPORT_RESERVED - 1;
sock = rresvport(&aport);
}
else
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == NOTOK)
return NOTOK;
int on = 1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on));
server.sin_family = AF_INET;
return OK;
}
//*****************************************************************************
// int Connection::ndelay()
//
int Connection::ndelay()
{
return fcntl(sock, F_SETFL, FNDELAY);
}
//*****************************************************************************
// int Connection::nondelay()
//
int Connection::nondelay()
{
return fcntl(sock, F_SETFL, 0);
}
//*****************************************************************************
// int Connection::close()
//
int Connection::close()
{
connected = 0;
if (sock >= 0)
{
int ret = ::close(sock);
sock = -1;
return ret;
}
return NOTOK;
}
//*****************************************************************************
// int Connection::assign_port(int port)
//
int Connection::assign_port(int port)
{
server.sin_port = htons(port);
return OK;
}
//*****************************************************************************
// int Connection::assign_port(char *service)
//
int Connection::assign_port(char *service)
{
struct servent *sp;
sp = getservbyname(service, "tcp");
if (sp == NULL)
{
return NOTOK;
}
server.sin_port = sp->s_port;
return OK;
}
//*****************************************************************************
// int Connection::assign_server(unsigned int addr)
//
int Connection::assign_server(unsigned int addr)
{
server.sin_addr.s_addr = addr;
return OK;
}
extern "C" unsigned int inet_addr(char *);
//*****************************************************************************
// int Connection::assign_server(char *name)
//
int Connection::assign_server(char *name)
{
struct hostent *hp;
unsigned int addr;
addr = inet_addr(name);
if (addr == ~0/*L*/) /* PJM MOD */
{
hp = gethostbyname(name);
if (hp == NULL)
{
return NOTOK;
}
memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
}
else
{
memcpy((char *)&server.sin_addr, (char *)&addr, sizeof(addr));
}
delete server_name;
server_name = strdup(name);
return OK;
}
//*****************************************************************************
// int Connection::connect(int allow_EINTR)
//
int Connection::connect(int allow_EINTR)
{
int status;
for (;;)
{
status = ::connect(sock, (struct sockaddr *)&server, sizeof(server));
if (status < 0 && errno == EINTR && !allow_EINTR)
{
::close(sock);
open();
continue;
}
break;
}
if (status == 0 || errno == EALREADY || errno == EISCONN)
{
connected = 1;
return OK;
}
#if 0
if (status == ECONNREFUSED)
{
//
// For the case where the connection attempt is refused, we need
// to close the socket and create a new one in order to do any
// more with it.
//
::close(sock);
open();
}
#else
::close(sock);
open(0);
#endif
connected = 0;
return NOTOK;
}
//*****************************************************************************
// int Connection::bind()
//
int Connection::bind()
{
if (::bind(sock, (struct sockaddr *)&server, sizeof(server)) == NOTOK)
{
return NOTOK;
}
return OK;
}
//*****************************************************************************
// int Connection::get_port()
//
int Connection::get_port()
{
unsigned int length = sizeof(server);
if (getsockname(sock, (struct sockaddr *)&server, &length) == NOTOK)
{
return NOTOK;
}
return ntohs(server.sin_port);
}
//*****************************************************************************
// int Connection::listen(int n)
//
int Connection::listen(int n)
{
return ::listen(sock, n);
}
//*****************************************************************************
// Connection *Connection::accept(int priv)
//
Connection *Connection::accept(int priv)
{
int newsock;
while (1)
{
newsock = ::accept(sock, (struct sockaddr *)0, (unsigned int *)0);
if (newsock == NOTOK && errno == EINTR)
continue;
break;
}
if (newsock == NOTOK)
return (Connection *)0;
Connection *newconnect = new Connection;
newconnect->sock = newsock;
unsigned int length = sizeof(newconnect->server);
getpeername(newsock, (struct sockaddr *)&newconnect->server, &length);
if (priv && newconnect->server.sin_port >= IPPORT_RESERVED)
{
delete newconnect;
return (Connection *)0;
}
return newconnect;
}
//*************************************************************************
// Connection *Connection::accept_privileged()
// PURPOSE:
// Accept in incoming connection but only if it is from a
// privileged port
//
Connection * Connection::accept_privileged()
{
return accept(1);
}
//*************************************************************************
// int Connection::read_partial(char *buffer, int maxlength)
// PURPOSE:
// Read at most <maxlength> from the current TCP connection.
// This is equivalent to the workings of the standard read()
// system call
// PARAMETERS:
// char *buffer: Buffer to read the data into
// int maxlength: Maximum number of bytes to read into the buffer
// RETURN VALUE:
// The actual number of bytes read in.
// ASSUMPTIONS:
// The connection has been previously established.
// FUNCTIONS USED:
// read()
//
int Connection::read_partial(char *buffer, int maxlength)
{
int count;
do
{
count = ::read(sock, buffer, maxlength);
}
while (count < 0 && errno == EINTR && !need_io_stop);
need_io_stop = 0;
return count;
}
//*************************************************************************
// int Connection::write_partial(char *buffer, int maxlength)
//
int Connection::write_partial(char *buffer, int maxlength)
{
int count;
do
{
count = ::write(sock, buffer, maxlength);
}
while (count < 0 && errno == EINTR && !need_io_stop);
need_io_stop = 0;
return count;
}
//*************************************************************************
// char * Connection::socket_as_string()
// PURPOSE:
// Return the numeric ASCII equivalent of the socket number.
// This is needed to pass the socket to another program
//
char * Connection::socket_as_string()
{
char *buffer = new char[20];
sprintf(buffer, "%d", sock);
return buffer;
}
extern "C" char *inet_ntoa(struct in_addr);
//*************************************************************************
// char *Connection::get_peername()
//
char *Connection::get_peername()
{
if (!peer)
{
struct sockaddr_in p;
unsigned int length = sizeof(p);
struct hostent *hp;
if (getpeername(sock, (struct sockaddr *) &p, &length) < 0)
{
return 0;
}
length = sizeof(p.sin_addr);
hp = gethostbyaddr((const char *) &p.sin_addr, length, AF_INET);
if (hp)
peer = strdup((char *) hp->h_name);
else
peer = strdup((char *) inet_ntoa(p.sin_addr));
}
return peer;
}
//*************************************************************************
// char *Connection::get_peerip()
//
char *Connection::get_peerip()
{
struct sockaddr_in peer;
unsigned int length = sizeof(peer);
if (getpeername(sock, (struct sockaddr *) &peer, &length) < 0)
{
return 0;
}
return inet_ntoa(peer.sin_addr);
}
#if defined(__sun__)
extern "C" int gethostname(char *name, int namelen);
#endif
//*************************************************************************
// unsigned int gethostip(char *ip, int length)
//
unsigned int gethostip(char *ip, int length)
{
char hostname[100];
if (gethostname(hostname, sizeof(hostname)) == NOTOK)
return 0;
struct hostent *ent = gethostbyname(hostname);
if (!ent)
return 0;
struct in_addr addr;
memcpy((char *) &addr.s_addr, ent->h_addr, sizeof(addr));
if (ip)
strncpy(ip, inet_ntoa(addr), length);
return addr.s_addr;
}
//
// Connection.h
//
// (c) Copyright 1993, San Diego State University -- College of Sciences
// (See the COPYRIGHT file for more Copyright information)
//
// This class forms a easy to use interface to the berkeley tcp socket library.
// All the calls are basically the same, but the parameters do not have any
// stray _addr or _in mixed in...
//
// $Id: Connection.h,v 1.1.1.1 1997/02/03 17:11:04 turtle Exp $
//
// $Log: Connection.h,v $
// Revision 1.1.1.1 1997/02/03 17:11:04 turtle
// Initial CVS
//
//
#if !defined(_Connection_h_)
# define _Connection_h_
#include "io.h"
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
class String;
class Connection : public io
{
public:
// Constructors & Destructors
Connection();
Connection(int socket);
~Connection();
// (De)initialization
int open(int priv = 0);
int close();
int ndelay();
int nondelay();
// Port stuff
int assign_port(int port = 0);
int assign_port(char *service);
int get_port();
int is_privileged();
// Host stuff
int assign_server(char *name);
int assign_server(unsigned int addr = INADDR_ANY);
char *get_server() {return server_name;}
// Connection establishment
int connect(int allow_EINTR = 0);
Connection *accept(int priv = 0);
Connection *accept_privileged();
// Registration things
int bind();
int listen(int n = 5);
// IO
int read_partial(char *buffer, int maxlength);
int write_partial(char *buffer, int maxlength);
void stop_io() {need_io_stop = 1;}
// Access to socket number
char *socket_as_string();
int get_socket() {return sock;}
int isopen() {return sock >= 0;}
int isconnected() {return connected;}
// Access to info about remote socket
char *get_peerip();
char *get_peername();
private:
int sock;
struct sockaddr_in server;
int connected;
char *peer;
char *server_name;
int need_io_stop;
};
//*************************************************************************
// inline int Connection::is_privileged()
// PURPOSE:
// Return whether the port is priveleged or not.
//
inline int Connection::is_privileged()
{
return server.sin_port < 1023;
}
//
// Get arround the lack of gethostip() library call... There is a gethostname()
// call but we want the IP address, not the name!
// The call will put the ASCII string representing the IP address in the supplied
// buffer and it will also return the 4 byte unsigned long equivalent of it.
// The ip buffer can be null...
//
unsigned int gethostip(char *ip = 0, int length = 0);
#endif