home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / unzip511.zip / amiga / filedate.c < prev    next >
C/C++ Source or Header  |  1994-01-23  |  7KB  |  241 lines

  1. /***********************/
  2. /* Function filedate() */
  3. /***********************/
  4.  
  5. /*  FileDate() (originally utime.c), by Paul Wells.  Modified by John Bush
  6.  *  and others (see also sendpkt() comments, below); NewtWare SetFileDate()
  7.  *  clone cheaply ripped off from utime().
  8.  */
  9.  
  10. /* HISTORY/CHANGES
  11.  *  2 Sep 92, Greg Roelofs, Original coding.
  12.  *  6 Sep 92, John Bush, Incorporated into UnZip 5.1
  13.  *  6 Sep 92, John Bush, Interlude "FileDate()" defined, which calls or
  14.  *            redefines SetFileDate() depending upon AMIGADOS2 definition.
  15.  * 11 Oct 92, John Bush, Eliminated AMIGADOS2 switch by determining
  16.  *            revision via OpenLibrary() call.  Now only one version of
  17.  *            the program runs on both platforms (1.3.x vs. 2.x)
  18.  * 11 Oct 92, John Bush, Merged with Zip version and changed arg passing
  19.  *            to take time_t input instead of struct DateStamp.
  20.  *            Arg passing made to conform with utime().
  21.  * 22 Nov 92, Paul Kienitz, fixed includes for Aztec and cleaned up some
  22.  *            lint-ish errors; simplified test for AmigaDOS version.
  23.  */
  24.  
  25. /* DESCRIPTION
  26.  * This routine chooses between 2 methods to set the file date on AMIGA.
  27.  * Since AmigaDOS 2.x came out, SetFileDate() was available in ROM (v.36
  28.  * and higher).  Under AmigaDOS 1.3.x (less than v.36 ROM), SetFileDate()
  29.  * must be accomplished by constructing a message packet and sending it
  30.  * to the file system handler of the file to be stamped.
  31.  *
  32.  * The system's ROM version is extracted from the external system Library
  33.  * base.
  34.  *
  35.  * NOTE:  although argument passing conforms with utime(), note the
  36.  *        following differences:  
  37.  *          - Return value is boolean success/failure.
  38.  *          - If a structure or array is passed, only the first value
  39.  *            is used, which *may* correspond to date accessed and not
  40.  *            date modified.
  41.  */
  42.  
  43. #include <string.h>
  44. #include <time.h>
  45. #include <errno.h>
  46. #include <stdio.h>
  47.  
  48. #include <exec/types.h>
  49. #include <exec/memory.h>
  50. #include <exec/libraries.h>
  51. #include <libraries/dos.h>
  52. #include <libraries/dosextens.h>
  53.  
  54. #ifdef AZTEC_C
  55.    extern int timezone;
  56.    void tzset(void);
  57. #  include <clib/exec_protos.h>
  58. #  include <clib/dos_protos.h>
  59. #  include <pragmas/exec_lib.h>
  60. #  include <pragmas/dos_lib.h>
  61. #  define ESRCH ENOENT
  62. #  define EOSERR EIO
  63. #endif
  64.  
  65. #if defined(LATTICE) || defined(__SASC)
  66. #  include <proto/exec.h>
  67. #  include <proto/dos.h>
  68. #endif
  69.  
  70. extern int _OSERR;
  71.  
  72. #ifndef SUCCESS
  73. #  define SUCCESS (-1L)
  74. #  define FAILURE 0L
  75. #endif
  76.  
  77. #define ReqVers 36L  /* required library version for SetFileDate() */
  78.  
  79. extern struct Library *SysBase;
  80.  
  81. LONG FileDate (char *filename, time_t u[]);
  82.  
  83. /* =============================================================== */
  84.  
  85. LONG FileDate(filename, u)
  86.   char *filename;
  87.   time_t u[];
  88. {
  89.   LONG SetFileDate(UBYTE *filename, struct DateStamp *pDate);
  90.   LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs);
  91.   struct MsgPort *taskport;
  92.   struct FileLock *dirlock, *lock;
  93.   struct FileInfoBlock *fib;
  94.   LONG pktargs[4];
  95.   UBYTE *ptr;
  96.   long ret;
  97.  
  98.   struct DateStamp pDate;
  99.   time_t mtime;
  100.  
  101.   tzset();
  102.   mtime=u[0]-timezone;
  103.  
  104. #ifdef DEBUG
  105.   fprintf (stderr,"Entry to FileDate(): mtime=%s\n",ctime(&mtime));
  106. #endif
  107.     
  108. /*  magic number = 2922 = 8 years + 2 leaps between 1970 - 1978 */
  109.  
  110.   pDate.ds_Days = (mtime / 86400L) - 2922L;
  111.   mtime = mtime % 86400L;
  112.   pDate.ds_Minute = mtime / 60L;
  113.   mtime = mtime % 60L;
  114.   pDate.ds_Tick = mtime * TICKS_PER_SECOND;
  115.  
  116. #ifdef DEBUG
  117.   fprintf (stderr,"In FileDate(): Days=%ld Minutes=%ld Ticks=%ld\n",
  118.            pDate.ds_Days,pDate.ds_Minute,pDate.ds_Tick);
  119. #endif
  120.  
  121.   if (SysBase->lib_Version >= ReqVers) {
  122.       return (SetFileDate(filename,&pDate));  /* native routine at 2.0+ */
  123.     }
  124.     else  /* !(SysBase->lib_Version >=ReqVers) */
  125.     { 
  126.       if( !(taskport = (struct MsgPort *)DeviceProc(filename)) )
  127.       {
  128.           errno = ESRCH;          /* no such process */
  129.           _OSERR = IoErr();
  130.           return FAILURE;
  131.       }
  132.  
  133.       if( !(lock = (struct FileLock *)Lock(filename,SHARED_LOCK)) )
  134.       {
  135.           errno = ENOENT;         /* no such file */
  136.           _OSERR = IoErr();
  137.           return FAILURE;
  138.       }
  139.  
  140.       if( !(fib = (struct FileInfoBlock *)AllocMem(
  141.           (long)sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)) )
  142.       {
  143.           errno = ENOMEM;         /* insufficient memory */
  144.           UnLock((BPTR)lock);
  145.           return FAILURE;
  146.       }
  147.  
  148.       if( Examine((BPTR)lock,fib)==FAILURE )
  149.       {
  150.           errno = EOSERR;         /* operating system error */
  151.           _OSERR = IoErr();
  152.           UnLock((BPTR)lock);
  153.           FreeMem((char *)fib,(long)sizeof(*fib));
  154.           return FAILURE;
  155.       }
  156.  
  157.       dirlock = (struct FileLock *)ParentDir((BPTR)lock);
  158.       ptr = (UBYTE *)AllocMem(64L,MEMF_PUBLIC);
  159.       strcpy((ptr+1),fib->fib_FileName);
  160.       *ptr = strlen(fib->fib_FileName);
  161.       FreeMem((char *)fib,(long)sizeof(*fib));
  162.       UnLock((BPTR)lock);
  163.  
  164.       /* now fill in argument array */
  165.  
  166.       pktargs[0] = 0;
  167.       pktargs[1] = (LONG)dirlock;
  168.       pktargs[2] = (LONG)&ptr[0] >> 2;
  169.       pktargs[3] = (LONG)&pDate;
  170.  
  171.       errno = ret = sendpkt(taskport,ACTION_SET_DATE,pktargs,4L);
  172.  
  173.       FreeMem(ptr,64L);
  174.       UnLock((BPTR)dirlock);
  175.  
  176.       return SUCCESS;
  177.     }  /* ?(SysBase->lib_Version >= ReqVers) */
  178. } /* FileDate() */
  179.  
  180. /* LOW LEVEL SUPPORT ROUTINES */
  181.  
  182. /*  sendpkt.c
  183.  *  by A. Finkel, P. Lindsay, C. Sheppner
  184.  *  returns Res1 of the reply packet
  185.  */
  186. /*
  187. #include <exec/types.h>
  188. #include <exec/memory.h>
  189. #include <libraries/dos.h>
  190. #include <libraries/dosextens.h>
  191. #include <proto/exec.h>
  192. #include <proto/dos.h>
  193. */
  194.  
  195. LONG sendpkt(pid,action,args,nargs)
  196. struct MsgPort *pid;           /* process identifier (handler message port) */
  197. LONG action,                   /* packet type (desired action)              */
  198.      *args,                    /* a pointer to argument list                */
  199.      nargs;                    /* number of arguments in list               */
  200. {
  201.  
  202.     struct MsgPort *replyport, *CreatePort(UBYTE *, long);
  203.     void DeletePort(struct MsgPort *);
  204.     struct StandardPacket *packet;
  205.     LONG count, *pargs, res1;
  206.  
  207.     replyport = CreatePort(NULL,0L);
  208.     if( !replyport ) return(0);
  209.  
  210.     packet = (struct StandardPacket *)AllocMem(
  211.             (long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR);
  212.     if( !packet )
  213.     {
  214.         DeletePort(replyport);
  215.         return(0);
  216.     }
  217.  
  218.     packet->sp_Msg.mn_Node.ln_Name  = (char *)&(packet->sp_Pkt);
  219.     packet->sp_Pkt.dp_Link          = &(packet->sp_Msg);
  220.     packet->sp_Pkt.dp_Port          = replyport;
  221.     packet->sp_Pkt.dp_Type          = action;
  222.  
  223.     /* copy the args into the packet */
  224.     pargs = &(packet->sp_Pkt.dp_Arg1);      /* address of 1st argument */
  225.     for( count=0; count<nargs; count++ )
  226.         pargs[count] = args[count];
  227.  
  228.     PutMsg(pid,(struct Message *)packet);   /* send packet */
  229.  
  230.     WaitPort(replyport);
  231.     GetMsg(replyport);
  232.  
  233.     res1 = packet->sp_Pkt.dp_Res1;
  234.  
  235.     FreeMem((char *)packet,(long)sizeof(*packet));
  236.     DeletePort(replyport);
  237.  
  238.     return(res1);
  239.  
  240. } /* sendpkt() */
  241.