1245803Stheraven/* xgethostname.c -- return current hostname with unlimited length 2245803Stheraven 3245803Stheraven Copyright (C) 1992, 1996, 2000, 2001, 2003, 2004, 2005 Free Software 4245803Stheraven Foundation, Inc. 5245803Stheraven 6245803Stheraven This program is free software; you can redistribute it and/or modify 7245803Stheraven it under the terms of the GNU General Public License as published by 8245803Stheraven the Free Software Foundation; either version 2, or (at your option) 9245803Stheraven any later version. 10245803Stheraven 11245803Stheraven This program is distributed in the hope that it will be useful, 12245803Stheraven but WITHOUT ANY WARRANTY; without even the implied warranty of 13245803Stheraven MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14245803Stheraven GNU General Public License for more details. 15245803Stheraven 16245803Stheraven You should have received a copy of the GNU General Public License 17245803Stheraven along with this program; if not, write to the Free Software Foundation, 18245803Stheraven Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 19245803Stheraven#include <sys/cdefs.h> 20245803Stheraven__RCSID("$NetBSD: xgethostname.c,v 1.2 2016/05/17 14:00:09 christos Exp $"); 21245803Stheraven 22245803Stheraven 23245803Stheraven/* written by Jim Meyering */ 24245803Stheraven 25245803Stheraven#ifdef HAVE_CONFIG_H 26245803Stheraven# include <config.h> 27245803Stheraven#endif 28245803Stheraven 29245803Stheraven/* Specification. */ 30245803Stheraven#include "xgethostname.h" 31245803Stheraven 32245803Stheraven#include <stdlib.h> 33245803Stheraven#include <errno.h> 34245839Stheraven 35245803Stheraven#if HAVE_UNISTD_H 36245839Stheraven# include <unistd.h> 37245839Stheraven#endif 38245803Stheraven 39245839Stheraven#include "xalloc.h" 40245803Stheraven 41245803Stheraven#ifndef ENAMETOOLONG 42245803Stheraven# define ENAMETOOLONG 0 43245803Stheraven#endif 44245803Stheraven 45245803Stheraven#ifndef INITIAL_HOSTNAME_LENGTH 46245803Stheraven# define INITIAL_HOSTNAME_LENGTH 34 47289935Stheraven#endif 48245803Stheraven 49289935Stheraven/* Return the current hostname in malloc'd storage. 50245803Stheraven If malloc fails, exit. 51245803Stheraven Upon any other failure, return NULL and set errno. */ 52245803Stheravenchar * 53245803Stheravenxgethostname (void) 54245803Stheraven{ 55245803Stheraven char *hostname = NULL; 56245803Stheraven size_t size = INITIAL_HOSTNAME_LENGTH; 57245803Stheraven 58245803Stheraven while (1) 59245803Stheraven { 60245803Stheraven /* Use SIZE_1 here rather than SIZE to work around the bug in 61245803Stheraven SunOS 5.5's gethostname whereby it NUL-terminates HOSTNAME 62245803Stheraven even when the name is as long as the supplied buffer. */ 63245803Stheraven size_t size_1; 64245803Stheraven 65245803Stheraven hostname = x2realloc (hostname, &size); 66245803Stheraven size_1 = size - 1; 67245803Stheraven hostname[size_1 - 1] = '\0'; 68245803Stheraven errno = 0; 69245803Stheraven 70245803Stheraven if (gethostname (hostname, size_1) == 0) 71245803Stheraven { 72245803Stheraven if (! hostname[size_1 - 1]) 73245803Stheraven break; 74245803Stheraven } 75245803Stheraven else if (errno != 0 && errno != ENAMETOOLONG && errno != EINVAL 76245803Stheraven /* OSX/Darwin does this when the buffer is not large enough */ 77245803Stheraven && errno != ENOMEM) 78245803Stheraven { 79245803Stheraven int saved_errno = errno; 80245803Stheraven free (hostname); 81245803Stheraven errno = saved_errno; 82245803Stheraven return NULL; 83245803Stheraven } 84245803Stheraven } 85245803Stheraven 86245803Stheraven return hostname; 87245803Stheraven} 88245803Stheraven