#include "exec/types.h"
#include "exec/ports.h"
#include "exec/io.h"
#include "exec/memory.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"
#include <stdio.h>
#define AZTEC 1
#ifdef AZTEC
#include "functions.h"         /* aztec C include */
#endif

#define ACTION_SETDATE_MODE 34L  /* The packet type we will be playing with */
#define DOSTRUE 	    -1L  /* AmigaDos TRUE */
#define MAXARGS              7L  /* limit in packet structure (dosextens.h) */
#define NARGS		     4L  /* Number of args for setdate */

/*---------------------------------------------------------------------*/
/*  sendpkt: generalized send a dos packet.			       */
/*---------------------------------------------------------------------*/

static long sendpkt(pid,action,args,nargs)

struct MsgPort *pid;	/* process indentifier ... (handlers message port ) */
long  action,	       /* number of arguments in list */
      nargs;           /* number of arguments in list  */
ULONG args[];          /* a pointer to a argument list */
{
 
   struct MsgPort        *replyport;
   struct StandardPacket *packet;
 
   long   count, res1; 
   ULONG  *pargs;

   if(nargs > MAXARGS) return NULL; 
 
   replyport = (struct MsgPort *) CreatePort(NULL,NULL); /* make reply port */
   if(!replyport) return NULL;

   packet = (struct StandardPacket *) 
      AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC | MEMF_CLEAR);
   if(!packet) 
     {
       FreeMem((void *)packet,(long)sizeof(struct StandardPacket));
       return(NULL);
     }

   packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt); /* link packet- */
   packet->sp_Pkt.dp_Link         = &(packet->sp_Msg);  /* to message    */
   packet->sp_Pkt.dp_Port         = replyport;         /* set-up reply port */
   packet->sp_Pkt.dp_Type         = action;           /* what to do... */

   /* move all the arguments to the packet */
   pargs = (ULONG *)&(packet->sp_Pkt.dp_Arg1);   /* address of first argument */
   for(count=NULL;count < nargs && count < MAXARGS; ++count) 
     pargs[count]=args[count];

   PutMsg(pid,packet); /* send packet */
   (void)WaitPort(replyport); /* wait for packet to come back */
   (void)GetMsg(replyport);   /* pull message */

   res1 = packet->sp_Pkt.dp_Res1; /* get result */

   /* all done clean up */
   FreeMem((void *)packet,(long)sizeof(*packet)); 
   DeletePort(replyport); 

   return(res1); 
 
}

/*---------------------------------------------------------------------*/
/*  setDate: datestamp the given file with the given date.	       */
/*---------------------------------------------------------------------*/

BOOL setDate( name, date )
char 		 *name;
struct DateStamp *date;
{
   struct MsgPort *task;            /* for process id handler */
   ULONG arg[4];                    /* array of arguments     */
   char *bstr, strcpy();            /* of file to be set      */
   long rc;
   char *strchr();
   int strlen();

   rc = 0;

   if ( !(bstr = (char *)AllocMem(68L, (long)(MEMF_PUBLIC)))) goto exit2;
   if ( !(task = (struct MsgPort *)DeviceProc( name )))       goto exit1;

   /* Dos Packet needs the filename in Bstring format */
 
   (void)strcpy( bstr+1, name );
   *bstr = strlen( name );

   arg[0] = (ULONG)NULL;
   arg[1] = (ULONG)IoErr(); /* lock on parent director set by DeviceProc() */
   arg[2] = (ULONG) bstr >> 2;
   arg[3] = (ULONG) date;
   rc = sendpkt( task, ACTION_SETDATE_MODE, arg, 4L );

exit1: if ( bstr ) FreeMem( (void *)bstr, 68L );
exit2: if ( rc == DOSTRUE )
          return TRUE;
       else
          return FALSE;
}

/*---------------------------------------------------------------------*/
/*  getDate: get the datestamp the given file.			       */
/*---------------------------------------------------------------------*/

BOOL getDate(name, date )
char *name;
register struct DateStamp *date;
{

   struct FileInfoBlock *Fib;
   ULONG		FLock;
   int			result;
   register struct DateStamp	*d;

   if ( (FLock = (ULONG) Lock(name, (long)(ACCESS_READ) )) == NULL)
      return FALSE;

   Fib = (struct FileInfoBlock * )
	AllocMem( (long)sizeof(struct FileInfoBlock), (long)(MEMF_CHIP));

   if (Fib == NULL )
     result = FALSE;
   else
     {
	if ( !Examine( FLock, Fib ))
	   result = FALSE;
	else if ( Fib->fib_DirEntryType > 0 )
	   result = FALSE;  /* It's a directory */
        else
	   {
		d = &Fib->fib_Date;
		date->ds_Days   = d->ds_Days;
		date->ds_Minute = d->ds_Minute;
		date->ds_Tick   = d->ds_Tick;        
		result = TRUE;
	   }
	FreeMem( (void *)Fib, (long)sizeof(struct FileInfoBlock) );
     }

   UnLock( FLock );
   return result;
}
