1/* This file is part of Mailfromd. -*- c -*- 2 Copyright (C) 2006-2021 Sergey Poznyakoff 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3, or (at your option) 7 any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17MF_BUILTIN_MODULE 18 19#include <sys/utsname.h> 20#include <mflib/status.h> 21 22MF_DEFUN(system, NUMBER, STRING str) 23{ 24 MF_RETURN(system(str)); 25} 26END 27 28MF_DEFUN(time, NUMBER) 29{ 30 time_t t = time(NULL); 31 MF_RETURN(t); 32} 33END 34 35MF_DEFUN(sleep, VOID, NUMBER seconds, OPTIONAL, NUMBER useconds) 36{ 37 struct timeval tv; 38 39 tv.tv_sec = seconds; 40 tv.tv_usec = MF_OPTVAL(useconds); 41 /* FIXME: signals? */ 42 select(0, NULL, NULL, NULL, &tv); 43} 44END 45 46MF_DEFUN(strftime, STRING, STRING fmt, NUMBER timestamp, OPTIONAL, NUMBER gmt) 47{ 48 char buf[1024]; 49 time_t t = timestamp; 50 struct tm *tm = MF_OPTVAL(gmt) ? gmtime(&t) : localtime(&t); 51 size_t size = strftime(buf, sizeof(buf), fmt, tm); 52 size_t off; 53 char *s = MF_ALLOC_HEAP(off, size + 1); 54 strcpy(s, buf); 55 MF_RETURN(off, size); 56} 57END 58 59MF_DEFUN(umask, NUMBER, NUMBER mask) 60{ 61 mode_t mode = umask(mask); 62 MF_RETURN(mode); 63} 64END 65 66/* Interface to the system uname call. 67 68 Format sequences are: 69 %s sysname 70 %n nodename 71 %r release 72 %v version 73 %m machine 74*/ 75MF_DEFUN(uname, STRING, STRING fmt) 76{ 77 struct utsname ubuf; 78 79 uname(&ubuf); 80 MF_OBSTACK_BEGIN(); 81 while (*fmt) { 82 if (*fmt == '%') { 83 switch (*++fmt) { 84 case 's': 85 MF_OBSTACK_GROW(ubuf.sysname, 86 strlen(ubuf.sysname)); 87 break; 88 case 'n': 89 MF_OBSTACK_GROW(ubuf.nodename, 90 strlen(ubuf.nodename)); 91 break; 92 case 'r': 93 MF_OBSTACK_GROW(ubuf.release, 94 strlen(ubuf.release)); 95 break; 96 case 'v': 97 MF_OBSTACK_GROW(ubuf.version, 98 strlen(ubuf.version)); 99 break; 100 case 'm': 101 MF_OBSTACK_GROW(ubuf.machine, 102 strlen(ubuf.machine)); 103 break; 104 case '%': 105 MF_OBSTACK_1GROW('%'); 106 break; 107 default: 108 MF_OBSTACK_1GROW('%'); 109 MF_OBSTACK_1GROW(*fmt); 110 } 111 fmt++; 112 } else { 113 MF_OBSTACK_1GROW(*fmt); 114 fmt++; 115 } 116 } 117 MF_OBSTACK_1GROW(0); 118 MF_RETURN_OBSTACK(); 119} 120END 121 122static struct builtin_const_trans access_modes[] = { 123 MF_TRANS(R_OK), 124 MF_TRANS(W_OK), 125 MF_TRANS(X_OK), 126 MF_TRANS(F_OK) 127}; 128 129MF_DEFUN(access, NUMBER, STRING pathname, NUMBER mode) 130{ 131 int c_mode; 132 133 MF_ASSERT(_builtin_const_to_c(access_modes, 134 MU_ARRAY_SIZE(access_modes), 135 mode, 136 &c_mode) == 0, 137 mfe_failure, 138 "bad access mode"); 139 MF_RETURN(access(pathname, c_mode) == 0); 140} 141END 142 143MF_DEFUN(getenv, STRING, STRING name) 144{ 145 char *p = getenv(name); 146 MF_ASSERT(p != NULL, 147 mfe_not_found, 148 "%s: environment variable not defined", 149 name); 150 MF_RETURN(p); 151} 152END 153 154MF_DEFUN(unlink, VOID, STRING name) 155{ 156 int rc = unlink(name); 157 MF_ASSERT(rc == 0, 158 mfe_failure, 159 "cannot unlink %s: %s", name, mu_strerror(errno)); 160} 161END 162 163