home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************/
- /* THE FOLLOWING PROGRAM IS THE SOLE PROPERTY OF */
- /* RONALD Q. SMITH */
- /* CONTAINING HIS PROPRIETARY CONFIDENTIAL INFORMATION */
- /* COPYRIGHT RONALD Q. SMITH 1992 */
- /*****************************************************************************/
-
- /* Global data definitions */
-
- #include <dos.h>
- #include <fcntl.h>
- #include <sys\types.h>
- #include <sys\stat.h>
- #include <io.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ioctl.h>
-
- /* Function prototypes */
-
- static int ioctl_write(void * data, int length);
- static int ioctl_read(void * data, int length);
- static int open_clock(void);
-
- /* Global static variables */
-
- static unsigned int handle = 0;
- static unsigned char password[8] = "";
-
- /*
- PROCEDURE: connec
-
- connec changes the value of the CONNECTED flag in CLOCK.SYS. Values supported
- are:
- 0 = disconnected
- 1 = connected for writes only (default)
- 2 = connected for writes and periodic reads
- 3 = connected for all operations
-
- INTERFACE:
- status = connec(&connected);
-
- "connected" is the new value of the connected flag.
-
- "status" is zero if the operation succeeds. It is the DOS
- error code if the operation fails. Likely values are:
- 1 = Not CLOCK.SYS
- 5 = Incorrect password
- 6 = Unable to obtain handle for CLOCK$
- 0xD = Illegal value for connected
- -1 = Internal error
-
- */
-
- extern int pascal far connec(int *connect)
- {
- auto struct {
- int function;
- int connect;
- } connect_data;
- auto int status;
-
- /* Copy data to be sent to local storage. */
-
- connect_data.function = 1; /* Set CONNECT */
- connect_data.connect = *connect;
-
- /* Check for legal values. */
-
- if (connect_data.connect > 3)
- return(0xD);
-
- /* Write new value. */
-
- status = ioctl_write(&connect_data, sizeof connect_data);
-
- return ((status == sizeof connect_data) ? 0 : ((status < 0) ?
- -status : -1));
-
- }
-
- /*
- PROCEDURE: stzone
-
- stzone sets the time zone offsets and the time zone name.
-
- INTERFACE:
- status = stzone(&hour, &minute, &second, zone);
-
- "hour:minute:second" is the difference in time between UTC and
- local time. The values are positive West of Greenwich and
- negative East.
-
- "zone" is a character string containing the local time zone name.
- It must be LJSF (Left Justified, Space Filled) or LJNT (Left
- Justified, NULL Terminated). It must be no more than 32
- characters in length.
-
- "status" is zero if the operation succeeds. It is the DOS
- error code if the operation fails. Likely values are:
- 1 = Not CLOCK.SYS
- 5 = Incorrect password
- 6 = Unable to obtain handle for CLOCK$
- 0xD = Illegal value for offset
- -1 = Internal error
- */
-
- extern int pascal far stzone(int *std_hour, int *std_minute, int *std_second,
- unsigned char std_name[32], int *day_hour, int *day_minute,
- int *day_second, unsigned char day_name[32])
-
- {
- auto struct {
- int function;
- struct time_zone standard;
- struct time_zone daylight;
- } zone_data;
- auto int status;
- auto char *zone_loc;
-
- /* Copy values to local storage. LJSF zones. */
-
- zone_data.function = 2;
-
- zone_data.standard.offs.hour = *std_hour;
- zone_data.standard.offs.minute = *std_minute;
- zone_data.standard.offs.second = *std_second;
- memcpy(zone_data.standard.zone, std_name, sizeof zone_data.standard.zone);
-
- zone_data.daylight.offs.hour = *day_hour;
- zone_data.daylight.offs.minute = *day_minute;
- zone_data.daylight.offs.second = *day_second;
- memcpy(zone_data.daylight.zone, day_name, sizeof zone_data.daylight.zone);
-
- /* Check for legal offset values. */
-
- if ((abs(zone_data.standard.offs.hour) > 23) ||
- (abs(zone_data.standard.offs.minute) > 59) ||
- (abs(zone_data.standard.offs.second) > 59) ||
- (abs(zone_data.daylight.offs.hour) > 23) ||
- (abs(zone_data.daylight.offs.minute) > 59) ||
- (abs(zone_data.daylight.offs.second) > 59))
- {
- return(0xD);
- }
-
- /* Write new values to CLOCK.SYS */
-
- status = ioctl_write(&zone_data, sizeof zone_data);
-
- return ((status == sizeof zone_data) ? 0 : ((status < 0) ?
- -status : -1));
-
- }
-
- /*
- PROCEDURE: stmode
-
- stmode sets a new value for the mode flag.
-
- INTERFACE:
- status = stmode(&mode);
-
- "mode" is the new value for the mode flag. The "mode" flag
- contains a set of bits which may be set in any combination.
-
- "status" is zero if the operation succeeds. It is the DOS
- error code if the operation fails. Likely values are:
- 1 = Not CLOCK.SYS
- 5 = Incorrect password
- 6 = Unable to obtain handle for CLOCK$
- 0xD = Illegal value for mode
- -1 = Internal error
- */
-
- extern int pascal far stmode(struct modes *mode)
-
- {
- auto struct {
- int function;
- struct modes mode;
- } mode_data;
- auto int status;
-
- /* Copy values to local storage. */
-
- mode_data.function = 3;
- mode_data.mode = *mode;
-
- /* Write new value to CLOCK.SYS */
-
- status = ioctl_write(&mode_data, sizeof mode_data);
-
- return ((status == sizeof mode_data) ? 0 : ((status < 0) ?
- -status : -1));
-
- }
-
- /*
- PROCEDURE: rstrct
-
- rstrct sets the time restriction limit values.
-
- INTERFACE:
- status = rstrct(&back_hour, &back_minute, &back_second, &forward_hour,
- &forward_minute, &forward_second);
-
- "back_hour:back_minute:back_second" is the new limit on backward
- time changes. All values must be positive and less than or
- equal to 23:59:59.
-
- "forward_hour:forward_minute:forward_second" is the new limit on
- forward time changes. All values must be positive and less than
- or equal to 23:59:59.
-
- "status" is zero if the operation succeeds. It is the DOS
- error code if the operation fails. Likely values are:
- 1 = Not CLOCK.SYS
- 5 = Incorrect password
- 6 = Unable to obtain handle for CLOCK$
- 0xD = Illegal value for limits
- -1 = Internal error
- */
-
- extern int pascal far rstrct(int *back_hour, int *back_minute,
- int *back_second, int *forward_hour, int *forward_minute,
- int *forward_second)
-
- {
- auto struct {
- int function;
- int back_hour;
- int back_minute;
- int back_second;
- int forward_hour;
- int forward_minute;
- int forward_second;
- } rstrct_data;
- auto int status;
-
- /* Copy values to local storage. */
-
- rstrct_data.function = 4;
- rstrct_data.back_hour = *back_hour;
- rstrct_data.back_minute = *back_minute;
- rstrct_data.back_second = *back_second;
- rstrct_data.forward_hour = *forward_hour;
- rstrct_data.forward_minute = *forward_minute;
- rstrct_data.forward_second = *forward_second;
-
- /* Check values for legal limits. */
-
- if ((rstrct_data.back_hour < 0) || (rstrct_data.back_hour > 23) ||
- (rstrct_data.back_minute < 0) || (rstrct_data.back_minute > 59) ||
- (rstrct_data.back_second < 0) || (rstrct_data.back_second > 59) ||
- (rstrct_data.forward_hour < 0) || (rstrct_data.forward_hour > 23) ||
- (rstrct_data.forward_minute < 0) || (rstrct_data.forward_minute > 59)
- || (rstrct_data.forward_second < 0) ||
- (rstrct_data.forward_second > 59))
- {
- return(0xD);
- }
-
- /* Write new values to CLOCK.SYS */
-
- status = ioctl_write(&rstrct_data, sizeof rstrct_data);
-
- return ((status == sizeof rstrct_data) ? 0 : ((status < 0) ?
- -status : -1));
-
- }
-
- /*
- PROCEDURE: tdisp
-
- tdisp sets the time display cursor location. The mode to enable the display
- must be set separately with stmode.
-
- INTERFACE:
- status = tdisp(&disp_x, &disp_y, &attribute);
-
- "disp_x" is the screen x coordinate in character positions of
- the left-most character of the time display. The value must be
- positive and less than 256.
-
- "disp_y" is the screen y coordinate in lines of the time display.
- The value must be positive and less than 256.
-
- "attribute" is the screen attribute to be used for the display.
- The value must be less than 256 and the low-order three bits of
- each nybble must not be equal.
-
- "status" is zero if the operation succeeds. It is the DOS
- error code if the operation fails. Likely values are:
- 1 = Not CLOCK.SYS
- 5 = Incorrect password
- 6 = Unable to obtain handle for CLOCK$
- 0xD = Illegal value for tdisp
- -1 = Internal error
- */
- extern int pascal far tdisp(int *disp_x, int *disp_y, int *attribute)
-
- {
-
- auto struct {
- int function;
- int disp_x;
- int disp_y;
- int attribute;
- } tdisp_data;
- auto int status;
-
- /* Copy values to local storage. */
-
- tdisp_data.function = 5;
- tdisp_data.disp_x = *disp_x;
- tdisp_data.disp_y = *disp_y;
- tdisp_data.attribute = *attribute;
-
- /* Check values for ranges. */
-
- if ((tdisp_data.disp_x < 0) || (tdisp_data.disp_x > 255) ||
- (tdisp_data.disp_y < 0) || (tdisp_data.disp_y > 255) ||
- (tdisp_data.attribute < 0) || (tdisp_data.attribute > 255) ||
- ((tdisp_data.attribute & 7) == ((tdisp_data.attribute >> 4) & 7)))
- {
- return(0xD);
- }
-
- /* Write new values to CLOCK.SYS */
-
- status = ioctl_write(&tdisp_data, sizeof tdisp_data);
-
- return ((status == sizeof tdisp_data) ? 0 : ((status < 0) ?
- -status : -1));
-
- }
-
- /*
- PROCEDURE: setpw
-
- setpw sets the password to be used on all future operations to change the
- CLOCK.SYS values. setpw must be called with the correct password prior to
- any operation after password checking is enabled. If password checking is
- not enabled, setpw is not required.
-
- INTERFACE:
-
- setpw(pword);
-
- "pword" is an 8-character array containing the password to
- be used. It must be LJSF or LJNF (Left Justified, NULL Filled).
-
- */
-
- extern void pascal far setpw(unsigned char *pword)
-
- {
-
- /* Copy the password to local storage for use on later calls. */
-
- memcpy(password, pword, sizeof password);
-
- }
-
- /*
- PROCEDURE: newpw
-
- newpw sets a new password into CLOCK.SYS. This new password is immediately
- effective. newpw also copies the new password to local storage as the current
- password if the operation of setting it in CLOCK.SYS is successful.
-
- INTERFACE:
-
- status = newpw(pword);
-
- "pword" is the new password. It must be exactly 8 characters in
- length. It may be LJSF or LJNF.
-
- "status" is zero if the operation succeeds. It is the DOS
- error code if the operation fails. Likely values are:
- 1 = Not CLOCK.SYS
- 5 = Incorrect password
- 6 = Unable to obtain handle for CLOCK$
- -1 = Internal error
- */
-
- extern int pascal far newpw(unsigned char *pword)
-
- {
-
- auto struct {
- int function;
- unsigned char pword[sizeof password];
- } newpw_data;
- auto int status;
-
- /* Copy the values to local storage. */
-
- newpw_data.function = 6;
- memcpy(newpw_data.pword, pword, sizeof password);
-
- /* Set the new password in CLOCK.SYS */
-
- status = ioctl_write(&newpw_data, sizeof newpw_data);
-
- /* If everything OK, copy the new password to the current password. */
-
- if (status == sizeof newpw_data)
- {
- memcpy(password, pword, sizeof password);
- return(0);
- }
-
- return ((status < 0) ? -status : -1);
-
- }
-
-
- /*
- PROCEDURE: clksta
-
- clksta gets the current state of CLOCK.SYS.
-
- INTERFACE:
- status = clksta(&data);
-
- "data" is a structure that will contain the returned information.
-
- "status" is the number of bytes read or the negative of the DOS
- error status if an error occurs.
-
- */
-
- extern int pascal far clksta(struct CLOCK_DATA *data)
-
- {
-
- return(ioctl_read(data, sizeof (struct CLOCK_DATA)));
-
- }
-
- /****************************************************************************/
- /* INTERNAL FUNCTIONS */
- /****************************************************************************/
-
- /*
- PROCEDURE: ioctl_write
-
- ioctl_write performs a "Send Control Data to Character Device" function.
-
- INTERFACE:
- status = ioctl_write(data, length);
-
- "data" is an array of "length" bytes.
-
- "length" is the number of bytes to be sent.
-
- "status" is the number of bytes accepted by the device or the negative
- of _doserrno if an error occurs.
-
- */
-
- static int ioctl_write(void * data, int length)
-
- {
- auto union REGS regs;
- auto unsigned char send_data[200]; /* Leave room for growth */
-
- /* If file for CLOCK$ not open, open it. */
-
- if (!handle)
- {
- if (open_clock() <= 0)
- return(-_doserrno);
- }
-
- /* Copy password and caller's data to same area to send. */
-
- memcpy(send_data, password, sizeof password);
- memcpy(&send_data[sizeof password], data, length);
-
- regs.x.ax = 0x4403; /* IOCTL Send Control Data */
- regs.x.bx = handle;
- regs.x.cx = length + sizeof password;
- regs.x.dx = (int) send_data; /* Send data bytes */
-
- intdos(®s, ®s);
-
- return(regs.x.cflag ? -_doserrno : regs.x.ax - sizeof password);
- }
-
-
- /*
- PROCEDURE: ioctl_read
-
- ioctl_read performs a "Read Control Data from Character Device" function.
-
- INTERFACE:
- status = ioctl_read(data, length);
-
- "data" is an array of "length" bytes to receive the information.
-
- "length" is the number of bytes to be read.
-
- "status" is the number of bytes returned by the device or
- is the negative of the DOS error status if an error occurs.
-
- */
-
- static int ioctl_read(void * data, int length)
-
- {
- auto union REGS regs;
-
- /* If file for CLOCK$ not open, open it. */
-
- if (!handle)
- {
- if (open_clock() <= 0)
- return(-_doserrno);
- }
-
- regs.x.ax = 0x4402; /* IOCTL Read Control Data */
- regs.x.bx = handle;
- regs.x.cx = length;
- regs.x.dx = (int) data; /* Read data bytes */
-
- intdos(®s, ®s);
-
- return(regs.x.cflag ? -_doserrno : regs.x.ax);
-
- }
-
- /*
- PROCEDURE: open_clock
-
- "open_clock" opens a file handle for the CLOCK$ device.
-
- INTERFACE:
- open_clock();
-
- open_clock returns the file handle or the value -1 if
- unable to establish a handle.
- */
-
- static int open_clock(void)
-
- {
- return(handle = open("CLOCK$",O_RDWR));
- }
-
- /*****************************************************************************/
- /* THE PRECEDING PROGRAM IS THE SOLE PROPERTY OF */
- /* RONALD Q. SMITH */
- /* CONTAINING HIS PROPRIETARY CONFIDENTIAL INFORMATION */
- /* COPYRIGHT RONALD Q. SMITH 1992 */
- /*****************************************************************************/
-