diff --git a/src/modules/system/configure.in b/src/modules/system/configure.in
index acd86ec33cd23e80f9281e678fd0e5d30bf5e9cd..ff3075cf872739d1680df2f4ac5d5b3d70dc9fff 100644
--- a/src/modules/system/configure.in
+++ b/src/modules/system/configure.in
@@ -1,4 +1,4 @@
-# $Id: configure.in,v 1.32 1999/10/27 14:38:08 grubba Exp $
+# $Id: configure.in,v 1.33 2000/01/16 04:54:24 hubbe Exp $
 AC_INIT(system.c)
 AC_CONFIG_HEADER(system_machine.h)
 
@@ -11,7 +11,7 @@ AC_CHECK_LIB(nsl, gethostbyname)
 AC_HAVE_HEADERS(syslog.h sys/syslog.h sys/types.h errno.h unistd.h pwd.h \
 	sys/conf.h sys/socket.h netinet/in.h arpa/inet.h netdb.h stdarg.h \
 	sys/utsname.h pwd.h passwd.h shadow.h grp.h sys/stat.h winsock.h \
-        sys/systeminfo.h windows.h sys/param.h)
+        sys/systeminfo.h windows.h sys/param.h utime.h)
 
 AC_HAVE_FUNCS(syslog link symlink readlink resolvepath chown \
 	initgroups setgroups getgroups seteuid setresuid setegid setresgid \
@@ -21,7 +21,7 @@ AC_HAVE_FUNCS(syslog link symlink readlink resolvepath chown \
 	chroot fchroot uname sysinfo gethostname gethostbyname \
         getgrnam_r getgrent_r getgrgid_r \
         getpwnam_r getpwent_r getpwuid_r \
-        getspnam_r innetgr)
+        getspnam_r innetgr utime)
 
 
 AC_CHECK_LIB(nsl, gethostbyname)
diff --git a/src/modules/system/system.c b/src/modules/system/system.c
index b9c629cca2f6e4af5f30d58e18fdf449ac85d85e..b412e39c7e6415eb701be108ed6b92eda2c69f85 100644
--- a/src/modules/system/system.c
+++ b/src/modules/system/system.c
@@ -1,5 +1,5 @@
 /*
- * $Id: system.c,v 1.80 1999/12/27 20:56:33 hubbe Exp $
+ * $Id: system.c,v 1.81 2000/01/16 04:54:24 hubbe Exp $
  *
  * System-call module for Pike
  *
@@ -15,7 +15,7 @@
 #include "system_machine.h"
 #include "system.h"
 
-RCSID("$Id: system.c,v 1.80 1999/12/27 20:56:33 hubbe Exp $");
+RCSID("$Id: system.c,v 1.81 2000/01/16 04:54:24 hubbe Exp $");
 #ifdef HAVE_WINSOCK_H
 #include <winsock.h>
 #endif
@@ -79,6 +79,10 @@ RCSID("$Id: system.c,v 1.80 1999/12/27 20:56:33 hubbe Exp $");
 #include <sys/utsname.h>
 #endif
 
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+
 #include "dmalloc.h"
 
 #ifndef NGROUPS_MAX
@@ -394,6 +398,34 @@ void f_chown(INT32 args)
 }
 #endif
 
+#ifdef HAVE_UTIME
+void f_utime(INT32 args)
+{
+  char *path;
+  INT32 atime, mtime;
+  int err;
+  struct utimbuf b;
+
+#ifdef PIKE_SECURITY
+  if(!CHECK_SECURITY(SECURITY_BIT_SECURITY))
+    error("utime: permission denied.\n");
+#endif
+
+  get_all_args("utime", args, "%s%i%i", &path, &atime, &mtime);
+  b.actime=atime;
+  b.modtime=mtime;
+  THREADS_ALLOW_UID();
+  do {
+    err = utime(path, &b);
+  } while((err < 0) && (errno == EINTR));
+  THREADS_DISALLOW_UID();
+  if (err < 0) {
+    report_error("utime");
+  }
+  pop_n_elems(args);
+}
+#endif
+
 #ifdef HAVE_INITGROUPS
 /* void initgroups(string name, int gid) */
 void f_initgroups(INT32 args)
@@ -1302,6 +1334,13 @@ void pike_module_init(void)
 /* function(string, int, int:void) */
   ADD_EFUN("chown", f_chown,tFunc(tStr tInt tInt,tVoid), OPT_SIDE_EFFECT);
 #endif
+
+#ifdef HAVE_UTIME
+  
+/* function(string, int, int:void) */
+  ADD_EFUN("utime", f_utime,tFunc(tStr tInt tInt,tVoid), OPT_SIDE_EFFECT);
+#endif
+
 #ifdef HAVE_INITGROUPS
   
 /* function(string, int:void) */