[RFC] Add getHostname convenience function to kdelibs? (was: Re: [PATCH] Make the default sending domain configurable)

Ingo Klöcker ingo.kloecker at epost.de
Sat Apr 20 12:21:09 BST 2002


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Saturday 20 April 2002 10:32, Marc Mutz wrote:
> Ingo wrote:
> > Furthermore I added a static KMKernel::guessHostname() function.
> > This function tries to determine the hostname via gethostname(2)
> > with 'localhost' as fallback. As this is needed in several places
> > in KMail I thought it would be useful to put this in a common
> > static function. Is KMKernel the right place for this?

FYI, here is the function:
QString KMKernel::guessHostname()
{
  char str[256];
  if ( !gethostname( str, 255 ) )
    // str need not be NUL-terminated if it has full length
    str[255] = 0;
  else
    str[0] = 0;

  return QString::fromLatin1( *str ? str : "localhost" );
}

> What about kdelibs? If we have the problem, others will have, too.

Yes. gethostname(2) is used a lot in kdelibs (see attached file) and in 
kdenetwork (and probably also in most other modules). But not everyone 
uses "localhost" as fallback. And not everyone needs the hostname as 
QString.
But as some of the usages of gethostname(2) seem to be dangerous (they 
forget to always terminate the hostname with '\0') it's probably worth 
putting this somewhere into kdelibs in a convenience function which 
returns the hostname (with the possible "localhost" fallback) as 
QCString.

- From 'man gethostname':
<quote>
BUGS
       According  to the SUSv2, gethostname must return len bytes
       (a truncated hostname, NUL-terminated  or  not)  when  the
       hostname  is longer.  Linux/Alpha (which has a system call
       gethostname) complies with this requirement, but libc  and
       glibc on Linux/i386 only return an error in this case.

NOTES
       The  definition  of success varies. SUSv2 defines gethost­
       name() as `return possibly truncated hostname', and having
       a  small  len does not cause an error return. Of course it
       must be possible to be certain that one has  obtained  the
       full hostname, and to this end SUSv2 guarantees that `Host
       names are limited to 255 bytes'.
</quote>

Because the return value of gethostname is not guaranteed to be 
NUL-terminated (see BUGS) always a hostname[255] = 0; has to be done 
after calling gethostname.
Obviously most people who used gethostname in kdelibs didn't know that. 

Therefore I propose to add the following convenience function to kdelibs 
with a possible QString variant which calls this function:

static QCString <classname>::getHostname( bool = false );

QCString <classname>::getHostname( bool fallback_to_localhost )
{
  char str[256];
  if ( !gethostname( str, 255 ) )
    // str is not guaranteed to be NUL-terminated if it has full length
    str[255] = 0;
  else
    str[0] = 0;

  if( !*str && fallback_to_localhost )
    return QCString( "localhost" );
  else
    return QCString( str );
}

Regards,
Ingo

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE8wU8lGnR+RTDgudgRAqQCAJ0VAI3a1NFY14vhK+SBnuv8Lk2lOQCeIdTv
ufPHGxhFb+yw8PsExp56ztc=
=reS6
-----END PGP SIGNATURE-----
-------------- next part --------------
Usage of gethostname(2) in kdelibs:

========================================

dcop/dcopc.c:
  char        hostName[256];
...
    if (gethostname(hostName, 255))
	    strcpy(hostName, "localhost");

    snprintf(fileName, sizeof(fileName), ".DCOPserver_%s_%s", hostName, displayName);

========================================

dcop/dcopclient.cpp:
   QCString fName = ::getenv("HOME");
...
      char hostName[256];
      if (gethostname(hostName, 255))
         fName += "localhost";
      else
         fName += hostName;

========================================

dcop/KDE-ICE/Xtrans.c:
/*
 * TRANS(GetHostname) - similar to gethostname but allows special processing.
 */

int TRANS(GetHostname) (char *buf, int maxlen)

{
    int len;

#ifdef NEED_UTSNAME
    struct utsname name;

    uname (&name);
    len = strlen (name.nodename);
    if (len >= maxlen) len = maxlen - 1;
    strncpy (buf, name.nodename, len);
    buf[len] = '\0';
#else
    buf[0] = '\0';
    (void) gethostname (buf, maxlen);
    buf [maxlen - 1] = '\0';
    len = strlen(buf);
#endif /* NEED_UTSNAME */
    return len;
}

========================================

kdecore/kstartupinfo.cpp:
    char hostname[ 256 ];
    hostname[ 0 ] = '\0';
    gethostname( hostname, 255 );
    d->id = QString( "%1;%2;%3;%4" ).arg( hostname ).arg( tm.tv_sec )
        .arg( tm.tv_usec ).arg( getpid()).latin1();

..........

        char tmp[ 256 ];
        tmp[ 0 ] = '\0';
        gethostname( tmp, 255 );
        d->hostname = tmp;

Note: d->hostname is a QCString.

========================================

kdecore/kstandarddirs.cpp:
          char hostname[256];
          hostname[0] = 0;
          gethostname(hostname, 255);
          QString dir = QString("%1socket-%2").arg(localkdedir()).arg(hostname);

..........

          char hostname[256];
          hostname[0] = 0;
          gethostname(hostname, 255);
          QString dir = QString("%1tmp-%2").arg(localkdedir()).arg(hostname);

========================================

kded/kded.cpp:
    char buf[1024+1];
    if (gethostname(buf, 1024) != 0)
       return;
...
    QCString newHostname = buf;

========================================

kdeprint/management/kmwsocketutil.cpp:
	char	buf[256];
	gethostname(buf, 255);
	QPtrList<KAddressInfo>	infos = KExtendedSocket::lookup(buf, QString::null);

Note: KExtendedSocket::lookup expects a QString as first parameter.

========================================

kinit/lnusertemp.c:
  char kde_tmp_dir[PATH_MAX+1];
...
  if (gethostname(kde_tmp_dir+strlen(kde_tmp_dir), PATH_MAX - strlen(kde_tmp_dir) - 1) != 0)
  {
     perror("Aborting. Could not determine hostname: ");
     exit(255);
  }

========================================

kinit/wrapper.c:
  char sock_file[MAX_SOCK_FILE];
...
  if (gethostname(sock_file+strlen(sock_file), MAX_SOCK_FILE - strlen(sock_file) - 1) != 0)
  {
     perror("Warning: Could not determine hostname: ");
     return -1;
  }

========================================

kio/misc/kpac/kpac_dhcp_helper.c:
	char hostname[256];
...
	if (gethostname(hostname, 255) == -1 ||
		strlen(hostname) == 0 ||
		(hent = gethostbyname(hostname)) == NULL)
		exit(1);

========================================

kio/misc/kpac/kpac_discovery.cpp:
    char hostname[256];
    if (gethostname(hostname, 255) == 0)
        m_hostname = hostname;

Note: m_hostname is a QCString.

========================================

kio/misc/kpac/kproxybindings.cpp:
                char hostname[256];
                gethostname(hostname, 255);
                UString addr = dnsResolve(hostname);
                if (addr.isNull())
                    result = Undefined();
                else
                    result = String(addr);

Note: const UString KProxyFunc::dnsResolve(const UString &host) const

========================================

kio/misc/ksendbugmail/main.cpp:
    QString fromaddr = emailConfig.getSetting(KEMailSettings::EmailAddress);
...
        char buffer[200];
        gethostname(buffer, 200);
        fromaddr += buffer;



More information about the kde-core-devel mailing list