System time vs. Software time - IBM AS400
This is a discussion on System time vs. Software time - IBM AS400 ; We are an ASP. On our system, we have multiple companies running all
on one partition. There is a piece of software from a third party
that resets the time for a particular user based on what time zone
they ...
-
System time vs. Software time
We are an ASP. On our system, we have multiple companies running all
on one partition. There is a piece of software from a third party
that resets the time for a particular user based on what time zone
they are physically located. This piece of software is failing
because of some bug in the license code, so we were trying to mock up
something that changes the system time for the user and saving us a
support call. The time offset comes from a data area. So, use
gettimeofday(), add to tv_sec the offset and then set with
settimeofday(). This is setting a clock but not the one we want.
Anybody have a guess as to how this third party software is working?
We don't want to set the global system time, obviously.
I'll attach a C program I wrote. It works, but not the way we want.
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SWAP_CHAR( x, y ) {char c; c = x; x = y; y = c;}
typedef struct {
Qwc_Rdtaa_Data_Returned_t q;
_Decimal(6,0) dec;
} my_QWCRDTAA;
typedef struct {
Qus_EC_t ec_fields;
char Exception_Data[100];
} error_code_t;
error_code_t error_code;
void SendMsg(char *usr, char *msg_text);
void SendMsgf(char *usr, char *fmt, ...);
void reverse(char t[])
{
int i,j;
for (i = 0, j = strlen(t) - 1; i < j; i++, j--) {
SWAP_CHAR(t[i], t[j]);
}
}
void SendMsg(char *usr, char *msg_text)
{
int msg_sent, funcreq;
char msgtype[10];
char delivmd[10];
char usrProfiles[1][10];
char display[1];
char msgq[20];
char usrfield[4];
char junk[30];
error_code_t ec;
/*
Variable initialization. The AS/400 APIs are picky about that
sort of thing. :-)
*/
sprintf(junk, "%-10.10s", usr);
strncpy(usrProfiles[0], junk, 10);
display[0] = 'N';
strncpy(usrfield, "*USR", 4);
strncpy(msgtype, "*INFO ", 10);
strncpy(delivmd, "*NORMAL ", 10);
memset(msgq, ' ', 20);
ec.ec_fields.Bytes_Provided = sizeof(error_code_t);
QEZSNDMG(msgtype, delivmd, msg_text, strlen(msg_text),
usrProfiles, 1, &msg_sent, &funcreq, &ec, display, msgq, usrfield);
if (ec.ec_fields.Bytes_Available != 0) {
SendMsgf("QSYSOPR", "sendmsg() LINE %d - QEZSNDMG failed with
code %s", __LINE__, ec.ec_fields.Exception_Id);
}
}
void SendMsgf(char *usr, char *fmt, ...)
{
char string[1000];
va_list arg_ptr;
va_start(arg_ptr, fmt);
vsprintf(string, fmt, arg_ptr);
SendMsg(usr, string);
va_end(arg_ptr);
}
void printit(int it)
{
time_t t, it2;
struct tm *lt;
it2 = (time_t)it;
/*t = time(&it2);*/
lt = localtime(&it2);
printf("Current local time and date: %s", asctime(lt));
}
int main(int argc, char *argv[])
{
int rc, secs_hours, secs_mins, secs, sign, val;
my_QWCRDTAA my;
error_code_t ec;
struct timeval tv;
struct timezone tzp;
char tmp[10], str_hours[3], str_mins[3], str_secs[3];
ec.ec_fields.Bytes_Provided = sizeof(error_code_t);
/*
Retrieve data area contents.
*/
QWCRDTAA(&my, sizeof(my), "OFFSET *LIBL ", -1, 6, &ec);
/*
double-check the type of the DTAARA. If it's not "*DEC" then
forget it.
*/
if (!strncmp(my.q.Type_Value_Returned, "*DEC", 4)) {
/*
Get the time of day from the system. If successful, try
and set the time.
Qp0zGetTimeofDay
*/
if (gettimeofday(&tv, NULL) == 0) {
printit(tv.tv_sec);
printf("%d\n", tv.tv_sec);
sign = 1;
val = (int)my.dec;
if (val < 0) {
sign = -1;
val = -val;
}
/*
Convert decimal value to text
*/
sprintf(tmp, "%06d", val);
sprintf(str_hours, "%-02.2s", tmp);
sprintf(str_mins, "%-02.2s", tmp + 2);
sprintf(str_secs, "%-02.2s", tmp + 4);
secs_hours = atoi(str_hours) * 3600;
secs_mins = atoi(str_mins) * 60;
secs = atoi(str_secs);
/*
Add (or subtract) the time.
*/
tv.tv_sec += sign * (secs_hours + secs_mins + secs);
/*
Qp0zSetTimeofDay
*/
if (settimeofday(&tv, NULL) != 0) {
SendMsgf("QSYSOPR", "chgswdate LINE %d -
settimeofday() failed", __LINE__);
}
printit(tv.tv_sec);
printf("%d\n", tv.tv_sec);
}
}
}
-
Re: System time vs. Software time
"Mr. K.V.B.L." wrote in message
news:1188594339.240236.113190@w3g2000hsg.googlegro ups.com...
> We are an ASP. On our system, we have multiple companies running all
> on one partition. There is a piece of software from a third party
> that resets the time for a particular user based on what time zone
> they are physically located. This piece of software is failing
> because of some bug in the license code, so we were trying to mock up
> something that changes the system time for the user and saving us a
> support call. The time offset comes from a data area. So, use
> gettimeofday(), add to tv_sec the offset and then set with
> settimeofday(). This is setting a clock but not the one we want.
>
> Anybody have a guess as to how this third party software is working?
> We don't want to set the global system time, obviously.
>
> I'll attach a C program I wrote. It works, but not the way we want.
You don't say what release you are running, but before v5r3, settimeofday
set a "software clock" (affecting the value retrieved by gettimeofday) and
didn't change the system clock. Since v5r3, settimeofday sets the system
clock. The v5r3 memo to users
(http://publib.boulder.ibm.com/infoce...zahg/rzaq9.pdf)
discusses alternate APIs (Qp0zSetTimeOfDay, etc.) for clients that still
want support for a software clock (without modifying the system clock).
P.S. Although recent releases have added support for timezone/local time as
a system value, I don't believe the support has (yet?) been extended to
allow each job to have its own timezone/local time. I'm not sure whether
the "software clock" support mentioned above is machine-wide or specific to
one job.
--
George Timms
IBM Rochester
-
Re: System time vs. Software time
Mr. K.V.B.L. wrote:
> We are an ASP. On our system, we have multiple companies running all
> on one partition. There is a piece of software from a third party
> that resets the time for a particular user based on what time zone
> they are physically located. This piece of software is failing
> because of some bug in the license code, so we were trying to mock up
> something that changes the system time for the user and saving us a
> support call. The time offset comes from a data area. So, use
> gettimeofday(), add to tv_sec the offset and then set with
> settimeofday(). This is setting a clock but not the one we want.
>
> Anybody have a guess as to how this third party software is working?
> We don't want to set the global system time, obviously.
>
> I'll attach a C program I wrote. It works, but not the way we want.
>
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
>
>
> #define SWAP_CHAR( x, y ) {char c; c = x; x = y; y = c;}
>
> typedef struct {
> Qwc_Rdtaa_Data_Returned_t q;
> _Decimal(6,0) dec;
> } my_QWCRDTAA;
>
> typedef struct {
> Qus_EC_t ec_fields;
> char Exception_Data[100];
> } error_code_t;
>
> error_code_t error_code;
>
>
> void SendMsg(char *usr, char *msg_text);
> void SendMsgf(char *usr, char *fmt, ...);
>
>
> void reverse(char t[])
> {
> int i,j;
>
>
> for (i = 0, j = strlen(t) - 1; i < j; i++, j--) {
> SWAP_CHAR(t[i], t[j]);
> }
> }
>
>
> void SendMsg(char *usr, char *msg_text)
> {
> int msg_sent, funcreq;
> char msgtype[10];
> char delivmd[10];
> char usrProfiles[1][10];
> char display[1];
> char msgq[20];
> char usrfield[4];
> char junk[30];
> error_code_t ec;
>
>
> /*
> Variable initialization. The AS/400 APIs are picky about that
> sort of thing. :-)
> */
> sprintf(junk, "%-10.10s", usr);
> strncpy(usrProfiles[0], junk, 10);
> display[0] = 'N';
> strncpy(usrfield, "*USR", 4);
> strncpy(msgtype, "*INFO ", 10);
> strncpy(delivmd, "*NORMAL ", 10);
> memset(msgq, ' ', 20);
>
> ec.ec_fields.Bytes_Provided = sizeof(error_code_t);
>
> QEZSNDMG(msgtype, delivmd, msg_text, strlen(msg_text),
> usrProfiles, 1, &msg_sent, &funcreq, &ec, display, msgq, usrfield);
> if (ec.ec_fields.Bytes_Available != 0) {
> SendMsgf("QSYSOPR", "sendmsg() LINE %d - QEZSNDMG failed with
> code %s", __LINE__, ec.ec_fields.Exception_Id);
> }
> }
>
>
> void SendMsgf(char *usr, char *fmt, ...)
> {
> char string[1000];
>
> va_list arg_ptr;
>
> va_start(arg_ptr, fmt);
> vsprintf(string, fmt, arg_ptr);
> SendMsg(usr, string);
> va_end(arg_ptr);
> }
>
>
> void printit(int it)
> {
> time_t t, it2;
> struct tm *lt;
>
> it2 = (time_t)it;
> /*t = time(&it2);*/
> lt = localtime(&it2);
> printf("Current local time and date: %s", asctime(lt));
> }
>
>
> int main(int argc, char *argv[])
> {
> int rc, secs_hours, secs_mins, secs, sign, val;
> my_QWCRDTAA my;
> error_code_t ec;
> struct timeval tv;
> struct timezone tzp;
> char tmp[10], str_hours[3], str_mins[3], str_secs[3];
>
>
> ec.ec_fields.Bytes_Provided = sizeof(error_code_t);
>
> /*
> Retrieve data area contents.
> */
> QWCRDTAA(&my, sizeof(my), "OFFSET *LIBL ", -1, 6, &ec);
>
> /*
> double-check the type of the DTAARA. If it's not "*DEC" then
> forget it.
> */
> if (!strncmp(my.q.Type_Value_Returned, "*DEC", 4)) {
>
> /*
> Get the time of day from the system. If successful, try
> and set the time.
> Qp0zGetTimeofDay
> */
> if (gettimeofday(&tv, NULL) == 0) {
> printit(tv.tv_sec);
> printf("%d\n", tv.tv_sec);
> sign = 1;
> val = (int)my.dec;
> if (val < 0) {
> sign = -1;
> val = -val;
> }
>
> /*
> Convert decimal value to text
> */
> sprintf(tmp, "%06d", val);
>
> sprintf(str_hours, "%-02.2s", tmp);
> sprintf(str_mins, "%-02.2s", tmp + 2);
> sprintf(str_secs, "%-02.2s", tmp + 4);
>
> secs_hours = atoi(str_hours) * 3600;
> secs_mins = atoi(str_mins) * 60;
> secs = atoi(str_secs);
>
> /*
> Add (or subtract) the time.
> */
> tv.tv_sec += sign * (secs_hours + secs_mins + secs);
>
> /*
> Qp0zSetTimeofDay
> */
> if (settimeofday(&tv, NULL) != 0) {
> SendMsgf("QSYSOPR", "chgswdate LINE %d -
> settimeofday() failed", __LINE__);
> }
> printit(tv.tv_sec);
> printf("%d\n", tv.tv_sec);
> }
> }
> }