#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 "system.bi"
/* This file is part of Mailfromd.             -*- c -*-
   Copyright (C) 2006-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/>. */



#include <sys/utsname.h>
#include <mflib/status.h>

void
#line 22
bi_system(eval_environ_t env)
#line 22

#line 22

#line 22 "system.bi"
{
#line 22
	
#line 22

#line 22
        char *  str;
#line 22
        
#line 22

#line 22
        get_string_arg(env, 0, &str);
#line 22
        
#line 22
        adjust_stack(env, 1);
#line 22

#line 22

#line 22
	if (builtin_module_trace(BUILTIN_IDX_system))
#line 22
		prog_trace(env, "system %s",str);;
#line 22

{
	
#line 24
do {
#line 24
  push(env, (STKVAL)(mft_number)(system(str)));
#line 24
  goto endlab;
#line 24
} while (0);
}
endlab:
#line 26
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 26
	return;
#line 26
}

void
#line 28
bi_time(eval_environ_t env)
#line 28

#line 28

#line 28 "system.bi"
{
#line 28
	
#line 28

#line 28
        
#line 28

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

#line 28

#line 28
	if (builtin_module_trace(BUILTIN_IDX_system))
#line 28
		prog_trace(env, "time");;
#line 28

{
	time_t t = time(NULL);
	
#line 31
do {
#line 31
  push(env, (STKVAL)(mft_number)(t));
#line 31
  goto endlab;
#line 31
} while (0);
}
endlab:
#line 33
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 33
	return;
#line 33
}

void
#line 35
bi_sleep(eval_environ_t env)
#line 35

#line 35

#line 35 "system.bi"
{
#line 35
	
#line 35

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

#line 35

#line 35
	if (builtin_module_trace(BUILTIN_IDX_system))
#line 35
		prog_trace(env, "sleep %lu %lu",seconds, ((__bi_argcnt > 1) ? useconds : 0));;
#line 35

{
	struct timeval tv;
	
	tv.tv_sec = seconds;
	tv.tv_usec = ((__bi_argcnt > 1) ? useconds : 0);
	/* FIXME: signals? */
	select(0, NULL, NULL, NULL, &tv);
}

#line 44
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 44
	return;
#line 44
}

void
#line 46
bi_strftime(eval_environ_t env)
#line 46

#line 46

#line 46 "system.bi"
{
#line 46
	
#line 46

#line 46
        char * MFL_DATASEG fmt;
#line 46
        long  timestamp;
#line 46
        long  gmt;
#line 46
        
#line 46
        long __bi_argcnt;
#line 46
        get_numeric_arg(env, 0, &__bi_argcnt);
#line 46
        get_string_arg(env, 1, &fmt);
#line 46
        get_numeric_arg(env, 2, &timestamp);
#line 46
        if (__bi_argcnt > 2)
#line 46
                get_numeric_arg(env, 3, &gmt);
#line 46
        
#line 46
        adjust_stack(env, __bi_argcnt + 1);
#line 46

#line 46

#line 46
	if (builtin_module_trace(BUILTIN_IDX_system))
#line 46
		prog_trace(env, "strftime %s %lu %lu",fmt, timestamp, ((__bi_argcnt > 2) ? gmt : 0));;
#line 46

{
	time_t t = timestamp;
	struct tm *tm = ((__bi_argcnt > 2) ? gmt : 0) ? gmtime(&t) : localtime(&t);
	size_t size = strlen(fmt);

	if (size == 0)
		
#line 53
do {
#line 53
  pushs(env, "");
#line 53
  goto endlab;
#line 53
} while (0);

	heap_obstack_begin(env);
	heap_obstack_grow(env, NULL, size);

	for (;;) {
		size_t n;

		n = strftime(heap_obstack_base(env), size, fmt, tm);
		if (n > 0) {
			heap_obstack_truncate(env, n + 1);
			break;
		}

		n = (size + 1) / 2;
		heap_obstack_grow(env, NULL, n);
		size += n;

	}
	
#line 72
do {
#line 72
  push(env, (STKVAL) (heap_obstack_finish(env)));
#line 72
  goto endlab;
#line 72
} while (0);
}
endlab:
#line 74
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 74
	return;
#line 74
}

void
#line 76
bi_umask(eval_environ_t env)
#line 76

#line 76

#line 76 "system.bi"
{
#line 76
	
#line 76

#line 76
        long  mask;
#line 76
        
#line 76

#line 76
        get_numeric_arg(env, 0, &mask);
#line 76
        
#line 76
        adjust_stack(env, 1);
#line 76

#line 76

#line 76
	if (builtin_module_trace(BUILTIN_IDX_system))
#line 76
		prog_trace(env, "umask %lu",mask);;
#line 76

{
	mode_t mode = umask(mask);
	
#line 79
do {
#line 79
  push(env, (STKVAL)(mft_number)(mode));
#line 79
  goto endlab;
#line 79
} while (0);
}
endlab:
#line 81
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 81
	return;
#line 81
}

/* Interface to the system uname call.
   
   Format sequences are:
   %s   sysname
   %n   nodename
   %r   release
   %v   version
   %m   machine
*/
void
#line 92
bi_uname(eval_environ_t env)
#line 92

#line 92

#line 92 "system.bi"
{
#line 92
	
#line 92

#line 92
        char * MFL_DATASEG fmt;
#line 92
        
#line 92

#line 92
        get_string_arg(env, 0, &fmt);
#line 92
        
#line 92
        adjust_stack(env, 1);
#line 92

#line 92

#line 92
	if (builtin_module_trace(BUILTIN_IDX_system))
#line 92
		prog_trace(env, "uname %s",fmt);;
#line 92

{
	struct utsname ubuf;

	uname(&ubuf);
	heap_obstack_begin(env);
	while (*fmt) {
		if (*fmt == '%') {
			switch (*++fmt) {
			case 's':
				heap_obstack_grow(env, ubuf.sysname, strlen(ubuf.sysname));
#line 104
				break;
			case 'n':
				heap_obstack_grow(env, ubuf.nodename, strlen(ubuf.nodename));
#line 108
				break;
			case 'r':
				heap_obstack_grow(env, ubuf.release, strlen(ubuf.release));
#line 112
				break;
			case 'v':
				heap_obstack_grow(env, ubuf.version, strlen(ubuf.version));
#line 116
				break;
			case 'm':
				heap_obstack_grow(env, ubuf.machine, strlen(ubuf.machine));
#line 120
				break;
			case '%':
				do { char __c = '%'; heap_obstack_grow(env, &__c, 1); } while(0);
				break;
			default:
				do { char __c = '%'; heap_obstack_grow(env, &__c, 1); } while(0);
				do { char __c = *fmt; heap_obstack_grow(env, &__c, 1); } while(0);
			}
			fmt++;
		} else {
			do { char __c = *fmt; heap_obstack_grow(env, &__c, 1); } while(0);
			fmt++;
		}
	}
	do { char __c = 0; heap_obstack_grow(env, &__c, 1); } while(0);
	
#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
}

static struct builtin_const_trans access_modes[] = {
	{ _MFL_R_OK, R_OK },
	{ _MFL_W_OK, W_OK },
	{ _MFL_X_OK, X_OK },
	{ _MFL_F_OK, F_OK }
};

void
#line 146
bi_access(eval_environ_t env)
#line 146

#line 146

#line 146 "system.bi"
{
#line 146
	
#line 146

#line 146
        char *  pathname;
#line 146
        long  mode;
#line 146
        
#line 146

#line 146
        get_string_arg(env, 0, &pathname);
#line 146
        get_numeric_arg(env, 1, &mode);
#line 146
        
#line 146
        adjust_stack(env, 2);
#line 146

#line 146

#line 146
	if (builtin_module_trace(BUILTIN_IDX_system))
#line 146
		prog_trace(env, "access %s %lu",pathname, mode);;
#line 146

{
	int c_mode;
	
		if (!(_builtin_const_to_c(access_modes,
#line 150
				      MU_ARRAY_SIZE(access_modes),
#line 150
				      mode,
#line 150
				      &c_mode) == 0))
#line 150
		(
#line 150
	env_throw_bi(env, mfe_failure, "access", "bad access mode")
#line 150
)
#line 155
;
	
#line 156
do {
#line 156
  push(env, (STKVAL)(mft_number)(access(pathname, c_mode) == 0));
#line 156
  goto endlab;
#line 156
} while (0);
}
endlab:
#line 158
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 158
	return;
#line 158
}

void
#line 160
bi_getenv(eval_environ_t env)
#line 160

#line 160

#line 160 "system.bi"
{
#line 160
	
#line 160

#line 160
        char * MFL_DATASEG name;
#line 160
        
#line 160

#line 160
        get_string_arg(env, 0, &name);
#line 160
        
#line 160
        adjust_stack(env, 1);
#line 160

#line 160

#line 160
	if (builtin_module_trace(BUILTIN_IDX_system))
#line 160
		prog_trace(env, "getenv %s",name);;
#line 160

{
	char *p = getenv(name);
		if (!(p != NULL))
#line 163
		(
#line 163
	env_throw_bi(env, mfe_not_found, "getenv", "%s: environment variable not defined",name)
#line 163
)
#line 166
;
	
#line 167
do {
#line 167
  pushs(env, p);
#line 167
  goto endlab;
#line 167
} while (0);
}
endlab:
#line 169
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 169
	return;
#line 169
}

void
#line 171
bi_unlink(eval_environ_t env)
#line 171

#line 171

#line 171 "system.bi"
{
#line 171
	
#line 171

#line 171
        char *  name;
#line 171
        
#line 171

#line 171
        get_string_arg(env, 0, &name);
#line 171
        
#line 171
        adjust_stack(env, 1);
#line 171

#line 171

#line 171
	if (builtin_module_trace(BUILTIN_IDX_system))
#line 171
		prog_trace(env, "unlink %s",name);;
#line 171

{
	int rc = unlink(name);
		if (!(rc == 0))
#line 174
		(
#line 174
	env_throw_bi(env, mfe_failure, "unlink", "cannot unlink %s: %s",name,mu_strerror(errno))
#line 174
)
#line 176
;
}

#line 178
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 178
	return;
#line 178
}
		  
#line 1026 "../../src/builtin/snarf.m4"

#line 1026

#line 1026

#line 1026
void
#line 1026
system_init_builtin(void)
#line 1026
{
#line 1026
	
#line 1026
	#line 22 "system.bi"
va_builtin_install_ex("system", bi_system, 0, dtype_number, 1, 0, 0|0, dtype_string);
#line 28 "system.bi"
va_builtin_install_ex("time", bi_time, 0, dtype_number, 0, 0, 0|0, dtype_unspecified);
#line 35 "system.bi"
va_builtin_install_ex("sleep", bi_sleep, 0, dtype_unspecified, 2, 1, 0|0, dtype_number, dtype_number);
#line 46 "system.bi"
va_builtin_install_ex("strftime", bi_strftime, 0, dtype_string, 3, 1, 0|0, dtype_string, dtype_number, dtype_number);
#line 76 "system.bi"
va_builtin_install_ex("umask", bi_umask, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 92 "system.bi"
va_builtin_install_ex("uname", bi_uname, 0, dtype_string, 1, 0, 0|0, dtype_string);
#line 146 "system.bi"
va_builtin_install_ex("access", bi_access, 0, dtype_number, 2, 0, 0|0, dtype_string, dtype_number);
#line 160 "system.bi"
va_builtin_install_ex("getenv", bi_getenv, 0, dtype_string, 1, 0, 0|0, dtype_string);
#line 171 "system.bi"
va_builtin_install_ex("unlink", bi_unlink, 0, dtype_unspecified, 1, 0, 0|0, dtype_string);

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

