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

Reply via email to