#line 1026 "../../src/builtin/snarf.m4"
/* -*- buffer-read-only: t -*- vi: set ro:
   THIS FILE IS GENERATED AUTOMATICALLY.  PLEASE DO NOT EDIT.
*/
#line 1026
#ifdef HAVE_CONFIG_H
#line 1026
# include <config.h>
#line 1026
#endif
#line 1026
#include <sys/types.h>
#line 1026

#line 1026
#include "mailfromd.h"
#line 1026
#include "prog.h"
#line 1026
#include "builtin.h"
#line 1026

#line 1026

#line 1066 "../../src/builtin/snarf.m4"

/* End of snarf.m4 */
#line 1 "gethostname.bi"
/* This file is part of Mailfromd.             -*- c -*-
   Copyright (C) 2009-2025 Sergey Poznyakoff

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */



#ifndef ENAMETOOLONG
# define ENAMETOOLONG 0
#endif

#ifndef INITIAL_HOSTNAME_LENGTH
# define INITIAL_HOSTNAME_LENGTH 34
#endif

#ifndef INITIAL_DOMAINNAME_LENGTH
# define INITIAL_DOMAINNAME_LENGTH 34
#endif

/* string gethostname()

   This implementation is based on xgethostname by Jim Meyering
*/
void
#line 35
bi_gethostname(eval_environ_t env)
#line 35

#line 35

#line 35 "gethostname.bi"
{
#line 35
	
#line 35

#line 35
        long  dns;
#line 35
        
#line 35
        long __bi_argcnt;
#line 35
        get_numeric_arg(env, 0, &__bi_argcnt);
#line 35
        if (__bi_argcnt > 0)
#line 35
                get_numeric_arg(env, 1, &dns);
#line 35
        
#line 35
        adjust_stack(env, __bi_argcnt + 1);
#line 35

#line 35

#line 35
	if (builtin_module_trace(BUILTIN_IDX_gethostname))
#line 35
		prog_trace(env, "gethostname %lu",((__bi_argcnt > 0) ? dns : 0));;
#line 35

{
	size_t size = INITIAL_HOSTNAME_LENGTH;
	
	heap_obstack_begin(env);
	while (1) {
		size_t nsize;
		size_t size_1;
		char *hostname;

		heap_obstack_grow(env, NULL, size);
		hostname = heap_obstack_base(env);

                /* Use SIZE_1 here rather than SIZE to work around the bug in
		   SunOS 5.5's gethostname whereby it NUL-terminates HOSTNAME
		   even when the name is as long as the supplied buffer.  */
		size_1 = size - 1;
		hostname[size_1 - 1] = '\0';
		errno = 0;

		if (gethostname(hostname, size_1) == 0)	{
			if (!hostname[size_1 - 1])
				break;
		} else if (errno != 0
			   && errno != ENAMETOOLONG && errno != EINVAL
			   /* OSX/Darwin does this when the buffer is not
			      large enough */
			   && errno != ENOMEM) {
			int saved_errno = errno;
			heap_obstack_cancel(env);
			(
#line 65
	env_throw_bi(env, mfe_failure, "gethostname", "%s",mu_strerror(saved_errno))
#line 65
);
#line 67
		}

		nsize = size * 2;
		if (nsize <= size) {
			heap_obstack_cancel(env);
			(
#line 72
	env_throw_bi(env, mfe_failure, "gethostname", "%s",mu_strerror(ENOMEM))
#line 72
);
#line 74
		}
		size = nsize;
	}

	if (((__bi_argcnt > 0) ? dns : 0)) {
		struct hostent *hp;
		
		hp = gethostbyname(heap_obstack_base(env));
		if (hp) {
			size_t nlen = strlen(hp->h_name);
			if (nlen >= size)
				heap_obstack_grow(env, NULL, nlen - size + 1);
#line 87
			strcpy(heap_obstack_base(env), hp->h_name);
		}
	}
	
	
#line 91
do {
#line 91
  push(env, (STKVAL) (heap_obstack_finish(env)));
#line 91
  goto endlab;
#line 91
} while (0);
}
endlab:
#line 93
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 93
	return;
#line 93
}

/* string getdomainname()

   This implementation is based on xgetdomainname by Jim Meyering
*/
void
#line 99
bi_getdomainname(eval_environ_t env)
#line 99

#line 99

#line 99 "gethostname.bi"
{
#line 99
	
#line 99

#line 99
        
#line 99

#line 99
        
#line 99
        adjust_stack(env, 0);
#line 99

#line 99

#line 99
	if (builtin_module_trace(BUILTIN_IDX_gethostname))
#line 99
		prog_trace(env, "getdomainname");;
#line 99

{
	size_t size = INITIAL_DOMAINNAME_LENGTH;
	
	heap_obstack_begin(env);
	while (1) {
		size_t nsize;
		size_t size_1;
		char *domainname;
		int rc;
		
		heap_obstack_grow(env, NULL, size);
		domainname = heap_obstack_base(env);

		size_1 = size - 1;
		domainname[size_1 - 1] = '\0';
		errno = 0;

		rc = getdomainname(domainname, size);
		if (rc >= 0 && domainname[size_1] == '\0')
			break;
		else if (rc < 0 && errno != EINVAL) {
			int saved_errno = errno;
			heap_obstack_cancel(env);
			(
#line 123
	env_throw_bi(env, mfe_failure, "getdomainname", "%s",mu_strerror(saved_errno))
#line 123
);
#line 125
		}

		nsize = size * 2;
		if (nsize <= size) {
			heap_obstack_cancel(env);
			(
#line 130
	env_throw_bi(env, mfe_failure, "getdomainname", "%s",mu_strerror(ENOMEM))
#line 130
);
#line 132
		}
		size = nsize;
	}
	
#line 135
do {
#line 135
  push(env, (STKVAL) (heap_obstack_finish(env)));
#line 135
  goto endlab;
#line 135
} while (0);
}
endlab:
#line 137
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 137
	return;
#line 137
}

#line 1026 "../../src/builtin/snarf.m4"

#line 1026

#line 1026

#line 1026
void
#line 1026
gethostname_init_builtin(void)
#line 1026
{
#line 1026
	
#line 1026
	#line 35 "gethostname.bi"
va_builtin_install_ex("gethostname", bi_gethostname, 0, dtype_string, 1, 1, 0|0, dtype_number);
#line 99 "gethostname.bi"
va_builtin_install_ex("getdomainname", bi_getdomainname, 0, dtype_string, 0, 0, 0|0, dtype_unspecified);

#line 1026 "../../src/builtin/snarf.m4"
	
#line 1026
}
#line 1026 "../../src/builtin/snarf.m4"

