/* utime.c
   utime() - set a file's datestamp (strictly, the modification time).
   Based on hints in a library of Darren Salt.
   Adapted for Norcroft C/C++ 01.03.2009 Thomas Milius using some code from my crmlconv program. */
#ifndef utime_h
#define utime_h

/* !!!!!!!!!! libraries !!!!!!!!!! */
/* ---------- RISC OS ---------- */
#include <kernel.h>
#include <swis.h>

/* !!!!!!!!!!! definitions !!!!!!!!!! */
#define HAVE_STRUCT_UTIMBUF 1

/* !!!!!!!!!! data structures !!!!!!!!!! */
struct utimbuf
{
  time_t actime;
  time_t modtime;
};

/* !!!!!!!!!! support functions !!!!!!!!!! */

/* !!!!!!!!!! functions !!!!!!!!!! */

/* Set a file's modification time.
   If the file is untyped, set its type to Text. */
int utime (const char *file_name,
           const struct utimbuf *time)
{
unsigned long long ros_time;
unsigned long risc_os_file_type;
unsigned long risc_os_attributes;
unsigned long risc_os_timestamp[2];
_kernel_oserror *os_error;
_kernel_swi_regs regs;

errno = 0;
/* Time to RISC OS time. UNIX starts at 1.1.1970.
   RISC OS is in Centiseconds from 1.1.1900 */
ros_time=24*60*60;
ros_time*=(70*365 + 17);
ros_time-=60*60;
ros_time+=(unsigned long long) time->modtime;
ros_time*=100;
/* Note old RISC OS attributes */
regs.r[0]=23;
regs.r[1]=(int) file_name;
if (_kernel_swi(OS_File, &regs, &regs) != NULL) {
  errno = 1;
  return 1;
  }
risc_os_file_type=regs.r[6] & 0x00000FFF;
regs.r[0]=17;
regs.r[1]=(int) file_name;
if ((os_error=_kernel_swi(OS_File, &regs, &regs)) != NULL) {
  errno = 1;
  return 1;
  }
if (regs.r[0] == 0)
  {
  errno = 1;
  return 1;
  }
risc_os_attributes=regs.r[5];
/* existing info and new date merged */
risc_os_timestamp[0]=((unsigned long) regs.r[2] & 0xFFFFFF00) | ((unsigned long) ((unsigned long long) (ros_time>>32) & 0x00000000000000FF));
risc_os_timestamp[1]=ros_time & 0x00000000FFFFFFFF;
regs.r[0]=1;
regs.r[1]=(int) file_name;
regs.r[2]=(risc_os_timestamp[0] & 0xFFF000FF) | risc_os_file_type<<8;
regs.r[3]=risc_os_timestamp[1];
regs.r[5]=risc_os_attributes;
if ((os_error=_kernel_swi(OS_File, &regs, &regs)) != NULL) {
  errno = 1;
  return 1;
  }
return 0;
}

#endif
