home *** CD-ROM | disk | FTP | other *** search
- /*
- ** This file is in the public domain.
- **
- ** This is a hacked-over and reformatted version of the public domain
- ** utime routine written by Larry Jones <scjones@sdrc.uu.net> for which
- ** I am very grateful.
- */
- /*#include <iodef.h>*/
- #include <unixio.h>
- #include <descrip.h>
- #include <fibdef.h>
- #include <atrdef.h>
- #include <stsdef.h>
-
- /*
- ** Change the modification time (VMS doesn't keep access time); to
- ** change the creation time, use ATR$C_CREDATE in the Attributes
- ** definition, below.
- */
- int
- utime(file, time)
- char *file;
- time_t time[2];
- {
- static struct fibdef Fib;
- static unsigned long TheTime[2];
- static const long TicksPerSeck = 10000000;
- static const long Zero = 0;
- static const unsigned long Epoch[2] = {
- 0x4beb4000, 0x007c9567
- };
- static struct dsc$descriptor D = {
- 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL
- };
- static const struct dsc$descriptor F = {
- sizeof Fib, DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *)&Fib
- };
- static const struct atrdef Attributes[] = {
- { sizeof TheTime, ATR$C_REVDATE, (unsigned long)TheTime },
- { 0, 0, 0 }
- };
- struct stat Sbuf;
- unsigned short Channel;
- unsigned short IOBlock[4];
- unsigned long status;
-
- /* Get the current statistics on the file. */
- if (stat(file, &Sbuf) < 0)
- return -1;
-
- /* Convert to clock ticks, and add in base ignoring overflow. */
- LIB$EMUL(&time[1], &TicksPerSeck, &Zero, TheTime);
- LIB$ADDX(Epoch, TheTime, TheTime);
-
- /* Build up a channel pointing to that file. */
- D.dsc$w_length = strlen(Sbuf.st_dev);
- D.dsc$a_pointer = Sbuf.st_dev;
- status = SYS$ASSIGN(&D, &Channel, 0, 0);
- if ((status & STS$M_SUCCESS) == 0)
- return -1;
- Fib.fib$r_fid_overlay.fib$w_fid[0] = Sbuf.st_ino[0];
- Fib.fib$r_fid_overlay.fib$w_fid[1] = Sbuf.st_ino[1];
- Fib.fib$r_fid_overlay.fib$w_fid[2] = Sbuf.st_ino[2];
-
- /* Modify the attributes to have the new timestamp. */
- status = SYS$QIOW(0, Channel, IO$_MODIFY, IOBlock, 0, 0,
- &F, 0, 0, 0, Attributes, 0);
- if ((status & STS$M_SUCCESS) == 0)
- return -1;
- if ((IOBlock[0] & STS$M_SUCCESS) == 0)
- return -1;
-
- /* Close the channel. */
- status = SYS$DASSGN(Channel);
- if ((status & STS$M_SUCCESS) == 0)
- return -1;
- return 0;
- }
-