00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "includes.h"
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef TIME_T_MIN
00033 #define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
00034 : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
00035 #endif
00036 #ifndef TIME_T_MAX
00037 #define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
00038 #endif
00039
00040 #define NTTIME_INFINITY (NTTIME)0x8000000000000000LL
00041
00042
00043
00044
00045
00046 time_t get_time_t_max(void)
00047 {
00048 return TIME_T_MAX;
00049 }
00050
00051
00052
00053
00054
00055 void GetTimeOfDay(struct timeval *tval)
00056 {
00057 #ifdef HAVE_GETTIMEOFDAY_TZ
00058 gettimeofday(tval,NULL);
00059 #else
00060 gettimeofday(tval);
00061 #endif
00062 }
00063
00064 #if (SIZEOF_LONG == 8)
00065 #define TIME_FIXUP_CONSTANT_INT 11644473600L
00066 #elif (SIZEOF_LONG_LONG == 8)
00067 #define TIME_FIXUP_CONSTANT_INT 11644473600LL
00068 #endif
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 time_t nt_time_to_unix(NTTIME nt)
00083 {
00084 return convert_timespec_to_time_t(nt_time_to_unix_timespec(&nt));
00085 }
00086
00087
00088
00089
00090
00091 void unix_to_nt_time(NTTIME *nt, time_t t)
00092 {
00093 uint64_t t2;
00094
00095 if (t == (time_t)-1) {
00096 *nt = (NTTIME)-1LL;
00097 return;
00098 }
00099
00100 if (t == TIME_T_MAX) {
00101 *nt = 0x7fffffffffffffffLL;
00102 return;
00103 }
00104
00105 if (t == 0) {
00106 *nt = 0;
00107 return;
00108 }
00109
00110 t2 = t;
00111 t2 += TIME_FIXUP_CONSTANT_INT;
00112 t2 *= 1000*1000*10;
00113
00114 *nt = t2;
00115 }
00116
00117
00118
00119
00120
00121 BOOL null_time(time_t t)
00122 {
00123 return t == 0 ||
00124 t == (time_t)0xFFFFFFFF ||
00125 t == (time_t)-1;
00126 }
00127
00128
00129
00130
00131
00132 BOOL null_nttime(NTTIME t)
00133 {
00134 return t == 0 || t == (NTTIME)-1;
00135 }
00136
00137
00138
00139
00140
00141 BOOL null_timespec(struct timespec ts)
00142 {
00143 return ts.tv_sec == 0 ||
00144 ts.tv_sec == (time_t)0xFFFFFFFF ||
00145 ts.tv_sec == (time_t)-1;
00146 }
00147
00148
00149
00150
00151 static uint16_t make_dos_date1(struct tm *t)
00152 {
00153 uint16_t ret=0;
00154 ret = (((unsigned int)(t->tm_mon+1)) >> 3) | ((t->tm_year-80) << 1);
00155 ret = ((ret&0xFF)<<8) | (t->tm_mday | (((t->tm_mon+1) & 0x7) << 5));
00156 return ret;
00157 }
00158
00159
00160
00161
00162 static uint16_t make_dos_time1(struct tm *t)
00163 {
00164 uint16_t ret=0;
00165 ret = ((((unsigned int)t->tm_min >> 3)&0x7) | (((unsigned int)t->tm_hour) << 3));
00166 ret = ((ret&0xFF)<<8) | ((t->tm_sec/2) | ((t->tm_min & 0x7) << 5));
00167 return ret;
00168 }
00169
00170
00171
00172
00173
00174 static uint32_t make_dos_date(time_t unixdate, int zone_offset)
00175 {
00176 struct tm *t;
00177 uint32_t ret=0;
00178
00179 if (unixdate == 0) {
00180 return 0;
00181 }
00182
00183 unixdate -= zone_offset;
00184
00185 t = gmtime(&unixdate);
00186 if (!t) {
00187 return 0xFFFFFFFF;
00188 }
00189
00190 ret = make_dos_date1(t);
00191 ret = ((ret&0xFFFF)<<16) | make_dos_time1(t);
00192
00193 return ret;
00194 }
00195
00196
00197
00198
00199
00200 void push_dos_date(uint8_t *buf, int offset, time_t unixdate, int zone_offset)
00201 {
00202 uint32_t x = make_dos_date(unixdate, zone_offset);
00203 SIVAL(buf,offset,x);
00204 }
00205
00206
00207
00208
00209
00210 void push_dos_date2(uint8_t *buf,int offset,time_t unixdate, int zone_offset)
00211 {
00212 uint32_t x;
00213 x = make_dos_date(unixdate, zone_offset);
00214 x = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
00215 SIVAL(buf,offset,x);
00216 }
00217
00218
00219
00220
00221
00222
00223 void push_dos_date3(uint8_t *buf,int offset,time_t unixdate, int zone_offset)
00224 {
00225 if (!null_time(unixdate)) {
00226 unixdate -= zone_offset;
00227 }
00228 SIVAL(buf,offset,unixdate);
00229 }
00230
00231
00232
00233
00234 static void interpret_dos_date(uint32_t date,int *year,int *month,int *day,int *hour,int *minute,int *second)
00235 {
00236 uint32_t p0,p1,p2,p3;
00237
00238 p0=date&0xFF; p1=((date&0xFF00)>>8)&0xFF;
00239 p2=((date&0xFF0000)>>16)&0xFF; p3=((date&0xFF000000)>>24)&0xFF;
00240
00241 *second = 2*(p0 & 0x1F);
00242 *minute = ((p0>>5)&0xFF) + ((p1&0x7)<<3);
00243 *hour = (p1>>3)&0xFF;
00244 *day = (p2&0x1F);
00245 *month = ((p2>>5)&0xFF) + ((p3&0x1)<<3) - 1;
00246 *year = ((p3>>1)&0xFF) + 80;
00247 }
00248
00249
00250
00251
00252
00253 time_t pull_dos_date(const uint8_t *date_ptr, int zone_offset)
00254 {
00255 uint32_t dos_date=0;
00256 struct tm t;
00257 time_t ret;
00258
00259 dos_date = IVAL(date_ptr,0);
00260
00261 if (dos_date == 0) return (time_t)0;
00262
00263 interpret_dos_date(dos_date,&t.tm_year,&t.tm_mon,
00264 &t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec);
00265 t.tm_isdst = -1;
00266
00267 ret = timegm(&t);
00268
00269 ret += zone_offset;
00270
00271 return ret;
00272 }
00273
00274
00275
00276
00277 time_t pull_dos_date2(const uint8_t *date_ptr, int zone_offset)
00278 {
00279 uint32_t x,x2;
00280
00281 x = IVAL(date_ptr,0);
00282 x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
00283 SIVAL(&x,0,x2);
00284
00285 return pull_dos_date((const uint8_t *)&x, zone_offset);
00286 }
00287
00288
00289
00290
00291
00292 time_t pull_dos_date3(const uint8_t *date_ptr, int zone_offset)
00293 {
00294 time_t t = (time_t)IVAL(date_ptr,0);
00295 if (!null_time(t)) {
00296 t += zone_offset;
00297 }
00298 return t;
00299 }
00300
00301
00302
00303
00304
00305 char *http_timestring(time_t t)
00306 {
00307 static fstring buf;
00308 struct tm *tm = localtime(&t);
00309
00310 if (t == TIME_T_MAX) {
00311 slprintf(buf,sizeof(buf)-1,"never");
00312 } else if (!tm) {
00313 slprintf(buf,sizeof(buf)-1,"%ld seconds since the Epoch",(long)t);
00314 } else {
00315 #ifndef HAVE_STRFTIME
00316 const char *asct = asctime(tm);
00317 fstrcpy(buf, asct ? asct : "unknown");
00318 }
00319 if(buf[strlen(buf)-1] == '\n') {
00320 buf[strlen(buf)-1] = 0;
00321 #else
00322 strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S %Z", tm);
00323 #endif
00324 }
00325 return buf;
00326 }
00327
00328
00329
00330
00331
00332 char *timestring(TALLOC_CTX *mem_ctx, time_t t)
00333 {
00334 char *TimeBuf;
00335 char tempTime[80];
00336 struct tm *tm;
00337
00338 tm = localtime(&t);
00339 if (!tm) {
00340 return talloc_asprintf(mem_ctx,
00341 "%ld seconds since the Epoch",
00342 (long)t);
00343 }
00344
00345 #ifdef HAVE_STRFTIME
00346
00347
00348
00349
00350 strftime(tempTime,sizeof(tempTime)-1,"%c %Z",tm);
00351 TimeBuf = talloc_strdup(mem_ctx, tempTime);
00352 #else
00353 TimeBuf = talloc_strdup(mem_ctx, asctime(tm));
00354 #endif
00355
00356 return TimeBuf;
00357 }
00358
00359
00360
00361
00362 const char *nt_time_string(TALLOC_CTX *mem_ctx, NTTIME nt)
00363 {
00364 time_t t;
00365 if (nt == 0) {
00366 return "NTTIME(0)";
00367 }
00368 t = nt_time_to_unix(nt);
00369 return timestring(mem_ctx, t);
00370 }
00371
00372
00373
00374
00375
00376 NTTIME nttime_from_string(const char *s)
00377 {
00378 return strtoull(s, NULL, 0);
00379 }
00380
00381
00382
00383
00384 int64_t usec_time_diff(struct timeval *tv1, struct timeval *tv2)
00385 {
00386 int64_t sec_diff = tv1->tv_sec - tv2->tv_sec;
00387 return (sec_diff * 1000000) + (int64_t)(tv1->tv_usec - tv2->tv_usec);
00388 }
00389
00390
00391
00392
00393
00394 struct timeval timeval_zero(void)
00395 {
00396 struct timeval tv;
00397 tv.tv_sec = 0;
00398 tv.tv_usec = 0;
00399 return tv;
00400 }
00401
00402
00403
00404
00405 BOOL timeval_is_zero(const struct timeval *tv)
00406 {
00407 return tv->tv_sec == 0 && tv->tv_usec == 0;
00408 }
00409
00410
00411
00412
00413 struct timeval timeval_current(void)
00414 {
00415 struct timeval tv;
00416 GetTimeOfDay(&tv);
00417 return tv;
00418 }
00419
00420
00421
00422
00423 struct timeval timeval_set(uint32_t secs, uint32_t usecs)
00424 {
00425 struct timeval tv;
00426 tv.tv_sec = secs;
00427 tv.tv_usec = usecs;
00428 return tv;
00429 }
00430
00431
00432
00433
00434
00435 struct timeval timeval_add(const struct timeval *tv,
00436 uint32_t secs, uint32_t usecs)
00437 {
00438 struct timeval tv2 = *tv;
00439 const unsigned int million = 1000000;
00440 tv2.tv_sec += secs;
00441 tv2.tv_usec += usecs;
00442 tv2.tv_sec += tv2.tv_usec / million;
00443 tv2.tv_usec = tv2.tv_usec % million;
00444 return tv2;
00445 }
00446
00447
00448
00449
00450 struct timeval timeval_sum(const struct timeval *tv1,
00451 const struct timeval *tv2)
00452 {
00453 return timeval_add(tv1, tv2->tv_sec, tv2->tv_usec);
00454 }
00455
00456
00457
00458
00459 struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs)
00460 {
00461 struct timeval tv = timeval_current();
00462 return timeval_add(&tv, secs, usecs);
00463 }
00464
00465
00466
00467
00468
00469
00470
00471 int timeval_compare(const struct timeval *tv1, const struct timeval *tv2)
00472 {
00473 if (tv1->tv_sec > tv2->tv_sec) return 1;
00474 if (tv1->tv_sec < tv2->tv_sec) return -1;
00475 if (tv1->tv_usec > tv2->tv_usec) return 1;
00476 if (tv1->tv_usec < tv2->tv_usec) return -1;
00477 return 0;
00478 }
00479
00480
00481
00482
00483 BOOL timeval_expired(const struct timeval *tv)
00484 {
00485 struct timeval tv2 = timeval_current();
00486 if (tv2.tv_sec > tv->tv_sec) return True;
00487 if (tv2.tv_sec < tv->tv_sec) return False;
00488 return (tv2.tv_usec >= tv->tv_usec);
00489 }
00490
00491
00492
00493
00494 double timeval_elapsed2(const struct timeval *tv1, const struct timeval *tv2)
00495 {
00496 return (tv2->tv_sec - tv1->tv_sec) +
00497 (tv2->tv_usec - tv1->tv_usec)*1.0e-6;
00498 }
00499
00500
00501
00502
00503 double timeval_elapsed(const struct timeval *tv)
00504 {
00505 struct timeval tv2 = timeval_current();
00506 return timeval_elapsed2(tv, &tv2);
00507 }
00508
00509
00510
00511
00512 struct timeval timeval_min(const struct timeval *tv1,
00513 const struct timeval *tv2)
00514 {
00515 if (tv1->tv_sec < tv2->tv_sec) return *tv1;
00516 if (tv1->tv_sec > tv2->tv_sec) return *tv2;
00517 if (tv1->tv_usec < tv2->tv_usec) return *tv1;
00518 return *tv2;
00519 }
00520
00521
00522
00523
00524 struct timeval timeval_max(const struct timeval *tv1,
00525 const struct timeval *tv2)
00526 {
00527 if (tv1->tv_sec > tv2->tv_sec) return *tv1;
00528 if (tv1->tv_sec < tv2->tv_sec) return *tv2;
00529 if (tv1->tv_usec > tv2->tv_usec) return *tv1;
00530 return *tv2;
00531 }
00532
00533
00534
00535
00536
00537
00538 struct timeval timeval_until(const struct timeval *tv1,
00539 const struct timeval *tv2)
00540 {
00541 struct timeval t;
00542 if (timeval_compare(tv1, tv2) >= 0) {
00543 return timeval_zero();
00544 }
00545 t.tv_sec = tv2->tv_sec - tv1->tv_sec;
00546 if (tv1->tv_usec > tv2->tv_usec) {
00547 t.tv_sec--;
00548 t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec);
00549 } else {
00550 t.tv_usec = tv2->tv_usec - tv1->tv_usec;
00551 }
00552 return t;
00553 }
00554
00555
00556
00557
00558
00559 NTTIME timeval_to_nttime(const struct timeval *tv)
00560 {
00561 return 10*(tv->tv_usec +
00562 ((TIME_FIXUP_CONSTANT_INT + (uint64_t)tv->tv_sec) * 1000000));
00563 }
00564
00565
00566
00567
00568
00569
00570 uint32 convert_time_t_to_uint32(time_t t)
00571 {
00572 #if (defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T == 8))
00573
00574 if (t == 0x8000000000000000LL) {
00575 return 0x80000000;
00576 } else if (t == 0x7FFFFFFFFFFFFFFFLL) {
00577 return 0x7FFFFFFF;
00578 }
00579 #endif
00580 return (uint32)t;
00581 }
00582
00583 time_t convert_uint32_to_time_t(uint32 u)
00584 {
00585 #if (defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T == 8))
00586
00587 if (u == 0x80000000) {
00588 return (time_t)0x8000000000000000LL;
00589 } else if (u == 0x7FFFFFFF) {
00590 return (time_t)0x7FFFFFFFFFFFFFFFLL;
00591 }
00592 #endif
00593 return (time_t)u;
00594 }
00595
00596
00597
00598
00599
00600 static int tm_diff(struct tm *a, struct tm *b)
00601 {
00602 int ay = a->tm_year + (1900 - 1);
00603 int by = b->tm_year + (1900 - 1);
00604 int intervening_leap_days =
00605 (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
00606 int years = ay - by;
00607 int days = 365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
00608 int hours = 24*days + (a->tm_hour - b->tm_hour);
00609 int minutes = 60*hours + (a->tm_min - b->tm_min);
00610 int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
00611
00612 return seconds;
00613 }
00614
00615 int extra_time_offset=0;
00616
00617
00618
00619
00620
00621 int get_time_zone(time_t t)
00622 {
00623 struct tm *tm = gmtime(&t);
00624 struct tm tm_utc;
00625 if (!tm)
00626 return 0;
00627 tm_utc = *tm;
00628 tm = localtime(&t);
00629 if (!tm)
00630 return 0;
00631 return tm_diff(&tm_utc,tm)+60*extra_time_offset;
00632 }
00633
00634
00635
00636
00637
00638 BOOL nt_time_is_zero(const NTTIME *nt)
00639 {
00640 return (*nt == 0);
00641 }
00642
00643
00644
00645
00646
00647
00648 time_t generalized_to_unix_time(const char *str)
00649 {
00650 struct tm tm;
00651
00652 ZERO_STRUCT(tm);
00653
00654 if (sscanf(str, "%4d%2d%2d%2d%2d%2d",
00655 &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
00656 &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
00657 return 0;
00658 }
00659 tm.tm_year -= 1900;
00660 tm.tm_mon -= 1;
00661
00662 return timegm(&tm);
00663 }
00664
00665
00666
00667
00668
00669
00670 static int server_zone_offset;
00671
00672 int get_server_zone_offset(void)
00673 {
00674 return server_zone_offset;
00675 }
00676
00677
00678
00679
00680
00681 int set_server_zone_offset(time_t t)
00682 {
00683 server_zone_offset = get_time_zone(t);
00684 return server_zone_offset;
00685 }
00686
00687
00688
00689
00690
00691 char *current_timestring(BOOL hires)
00692 {
00693 static fstring TimeBuf;
00694 struct timeval tp;
00695 time_t t;
00696 struct tm *tm;
00697
00698 if (hires) {
00699 GetTimeOfDay(&tp);
00700 t = (time_t)tp.tv_sec;
00701 } else {
00702 t = time(NULL);
00703 }
00704 tm = localtime(&t);
00705 if (!tm) {
00706 if (hires) {
00707 slprintf(TimeBuf,
00708 sizeof(TimeBuf)-1,
00709 "%ld.%06ld seconds since the Epoch",
00710 (long)tp.tv_sec,
00711 (long)tp.tv_usec);
00712 } else {
00713 slprintf(TimeBuf,
00714 sizeof(TimeBuf)-1,
00715 "%ld seconds since the Epoch",
00716 (long)t);
00717 }
00718 } else {
00719 #ifdef HAVE_STRFTIME
00720 if (hires) {
00721 strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %H:%M:%S",tm);
00722 slprintf(TimeBuf+strlen(TimeBuf),
00723 sizeof(TimeBuf)-1 - strlen(TimeBuf),
00724 ".%06ld",
00725 (long)tp.tv_usec);
00726 } else {
00727 strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %H:%M:%S",tm);
00728 }
00729 #else
00730 if (hires) {
00731 const char *asct = asctime(tm);
00732 slprintf(TimeBuf,
00733 sizeof(TimeBuf)-1,
00734 "%s.%06ld",
00735 asct ? asct : "unknown",
00736 (long)tp.tv_usec);
00737 } else {
00738 const char *asct = asctime(tm);
00739 fstrcpy(TimeBuf, asct ? asct : "unknown");
00740 }
00741 #endif
00742 }
00743 return(TimeBuf);
00744 }
00745
00746
00747
00748
00749
00750
00751
00752 static void put_dos_date(char *buf,int offset,time_t unixdate, int zone_offset)
00753 {
00754 uint32 x = make_dos_date(unixdate, zone_offset);
00755 SIVAL(buf,offset,x);
00756 }
00757
00758
00759
00760
00761
00762
00763 static void put_dos_date2(char *buf,int offset,time_t unixdate, int zone_offset)
00764 {
00765 uint32 x = make_dos_date(unixdate, zone_offset);
00766 x = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
00767 SIVAL(buf,offset,x);
00768 }
00769
00770
00771
00772
00773
00774
00775
00776 static void put_dos_date3(char *buf,int offset,time_t unixdate, int zone_offset)
00777 {
00778 if (!null_mtime(unixdate)) {
00779 unixdate -= zone_offset;
00780 }
00781 SIVAL(buf,offset,unixdate);
00782 }
00783
00784
00785
00786
00787
00788
00789 void srv_put_dos_date(char *buf,int offset,time_t unixdate)
00790 {
00791 put_dos_date(buf, offset, unixdate, server_zone_offset);
00792 }
00793
00794 void srv_put_dos_date2(char *buf,int offset, time_t unixdate)
00795 {
00796 put_dos_date2(buf, offset, unixdate, server_zone_offset);
00797 }
00798
00799 void srv_put_dos_date3(char *buf,int offset,time_t unixdate)
00800 {
00801 put_dos_date3(buf, offset, unixdate, server_zone_offset);
00802 }
00803
00804
00805
00806
00807
00808
00809 void put_long_date_timespec(char *p, struct timespec ts)
00810 {
00811 NTTIME nt;
00812 unix_timespec_to_nt_time(&nt, ts);
00813 SIVAL(p, 0, nt & 0xFFFFFFFF);
00814 SIVAL(p, 4, nt >> 32);
00815 }
00816
00817 void put_long_date(char *p, time_t t)
00818 {
00819 struct timespec ts;
00820 ts.tv_sec = t;
00821 ts.tv_nsec = 0;
00822 put_long_date_timespec(p, ts);
00823 }
00824
00825
00826
00827
00828
00829
00830 time_t get_create_time(const SMB_STRUCT_STAT *st,BOOL fake_dirs)
00831 {
00832 time_t ret, ret1;
00833
00834 if(S_ISDIR(st->st_mode) && fake_dirs) {
00835 return (time_t)315493200L;
00836 }
00837
00838 ret = MIN(st->st_ctime, st->st_mtime);
00839 ret1 = MIN(ret, st->st_atime);
00840
00841 if(ret1 != (time_t)0) {
00842 return ret1;
00843 }
00844
00845
00846
00847
00848
00849 return ret;
00850 }
00851
00852 struct timespec get_create_timespec(const SMB_STRUCT_STAT *st,BOOL fake_dirs)
00853 {
00854 struct timespec ts;
00855 ts.tv_sec = get_create_time(st, fake_dirs);
00856 ts.tv_nsec = 0;
00857 return ts;
00858 }
00859
00860
00861
00862
00863
00864 struct timespec get_atimespec(const SMB_STRUCT_STAT *pst)
00865 {
00866 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
00867 struct timespec ret;
00868
00869
00870 ret.tv_sec = pst->st_atime;
00871 ret.tv_nsec = 0;
00872 return ret;
00873 #else
00874 #if defined(HAVE_STAT_ST_ATIM)
00875 return pst->st_atim;
00876 #elif defined(HAVE_STAT_ST_ATIMENSEC)
00877 struct timespec ret;
00878 ret.tv_sec = pst->st_atime;
00879 ret.tv_nsec = pst->st_atimensec;
00880 return ret;
00881 #else
00882 #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
00883 #endif
00884 #endif
00885 }
00886
00887 void set_atimespec(SMB_STRUCT_STAT *pst, struct timespec ts)
00888 {
00889 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
00890
00891 pst->st_atime = ts.tv_sec;
00892 #else
00893 #if defined(HAVE_STAT_ST_ATIM)
00894 pst->st_atim = ts;
00895 #elif defined(HAVE_STAT_ST_ATIMENSEC)
00896 pst->st_atime = ts.tv_sec;
00897 pst->st_atimensec = ts.tv_nsec
00898 #else
00899 #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
00900 #endif
00901 #endif
00902 }
00903
00904 struct timespec get_mtimespec(const SMB_STRUCT_STAT *pst)
00905 {
00906 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
00907 struct timespec ret;
00908
00909
00910 ret.tv_sec = pst->st_mtime;
00911 ret.tv_nsec = 0;
00912 return ret;
00913 #else
00914 #if defined(HAVE_STAT_ST_MTIM)
00915 return pst->st_mtim;
00916 #elif defined(HAVE_STAT_ST_MTIMENSEC)
00917 struct timespec ret;
00918 ret.tv_sec = pst->st_mtime;
00919 ret.tv_nsec = pst->st_mtimensec;
00920 return ret;
00921 #else
00922 #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
00923 #endif
00924 #endif
00925 }
00926
00927 void set_mtimespec(SMB_STRUCT_STAT *pst, struct timespec ts)
00928 {
00929 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
00930
00931 pst->st_mtime = ts.tv_sec;
00932 #else
00933 #if defined(HAVE_STAT_ST_MTIM)
00934 pst->st_mtim = ts;
00935 #elif defined(HAVE_STAT_ST_MTIMENSEC)
00936 pst->st_mtime = ts.tv_sec;
00937 pst->st_mtimensec = ts.tv_nsec
00938 #else
00939 #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
00940 #endif
00941 #endif
00942 }
00943
00944 struct timespec get_ctimespec(const SMB_STRUCT_STAT *pst)
00945 {
00946 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
00947 struct timespec ret;
00948
00949
00950 ret.tv_sec = pst->st_ctime;
00951 ret.tv_nsec = 0;
00952 return ret;
00953 #else
00954 #if defined(HAVE_STAT_ST_CTIM)
00955 return pst->st_ctim;
00956 #elif defined(HAVE_STAT_ST_CTIMENSEC)
00957 struct timespec ret;
00958 ret.tv_sec = pst->st_ctime;
00959 ret.tv_nsec = pst->st_ctimensec;
00960 return ret;
00961 #else
00962 #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
00963 #endif
00964 #endif
00965 }
00966
00967 void set_ctimespec(SMB_STRUCT_STAT *pst, struct timespec ts)
00968 {
00969 #if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
00970
00971 pst->st_ctime = ts.tv_sec;
00972 #else
00973 #if defined(HAVE_STAT_ST_CTIM)
00974 pst->st_ctim = ts;
00975 #elif defined(HAVE_STAT_ST_CTIMENSEC)
00976 pst->st_ctime = ts.tv_sec;
00977 pst->st_ctimensec = ts.tv_nsec
00978 #else
00979 #error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
00980 #endif
00981 #endif
00982 }
00983
00984 void dos_filetime_timespec(struct timespec *tsp)
00985 {
00986 tsp->tv_sec &= ~1;
00987 tsp->tv_nsec = 0;
00988 }
00989
00990
00991
00992
00993
00994
00995 static time_t make_unix_date(const void *date_ptr, int zone_offset)
00996 {
00997 uint32 dos_date=0;
00998 struct tm t;
00999 time_t ret;
01000
01001 dos_date = IVAL(date_ptr,0);
01002
01003 if (dos_date == 0) {
01004 return 0;
01005 }
01006
01007 interpret_dos_date(dos_date,&t.tm_year,&t.tm_mon,
01008 &t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec);
01009 t.tm_isdst = -1;
01010
01011 ret = timegm(&t);
01012
01013 ret += zone_offset;
01014
01015 return(ret);
01016 }
01017
01018
01019
01020
01021
01022 static time_t make_unix_date2(const void *date_ptr, int zone_offset)
01023 {
01024 uint32 x,x2;
01025
01026 x = IVAL(date_ptr,0);
01027 x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
01028 SIVAL(&x,0,x2);
01029
01030 return(make_unix_date((const void *)&x, zone_offset));
01031 }
01032
01033
01034
01035
01036
01037
01038 static time_t make_unix_date3(const void *date_ptr, int zone_offset)
01039 {
01040 time_t t = (time_t)IVAL(date_ptr,0);
01041 if (!null_mtime(t)) {
01042 t += zone_offset;
01043 }
01044 return(t);
01045 }
01046
01047 time_t srv_make_unix_date(const void *date_ptr)
01048 {
01049 return make_unix_date(date_ptr, server_zone_offset);
01050 }
01051
01052 time_t srv_make_unix_date2(const void *date_ptr)
01053 {
01054 return make_unix_date2(date_ptr, server_zone_offset);
01055 }
01056
01057 time_t srv_make_unix_date3(const void *date_ptr)
01058 {
01059 return make_unix_date3(date_ptr, server_zone_offset);
01060 }
01061
01062 time_t convert_timespec_to_time_t(struct timespec ts)
01063 {
01064
01065
01066 if (ts.tv_nsec > 500000000) {
01067 return ts.tv_sec + 1;
01068 }
01069 return ts.tv_sec;
01070 }
01071
01072 struct timespec convert_time_t_to_timespec(time_t t)
01073 {
01074 struct timespec ts;
01075 ts.tv_sec = t;
01076 ts.tv_nsec = 0;
01077 return ts;
01078 }
01079
01080
01081
01082
01083
01084 struct timespec convert_timeval_to_timespec(const struct timeval tv)
01085 {
01086 struct timespec ts;
01087 ts.tv_sec = tv.tv_sec;
01088 ts.tv_nsec = tv.tv_usec * 1000;
01089 return ts;
01090 }
01091
01092
01093
01094
01095
01096 struct timeval convert_timespec_to_timeval(const struct timespec ts)
01097 {
01098 struct timeval tv;
01099 tv.tv_sec = ts.tv_sec;
01100 tv.tv_usec = ts.tv_nsec / 1000;
01101 return tv;
01102 }
01103
01104
01105
01106
01107
01108 struct timespec timespec_current(void)
01109 {
01110 struct timeval tv;
01111 struct timespec ts;
01112 GetTimeOfDay(&tv);
01113 ts.tv_sec = tv.tv_sec;
01114 ts.tv_nsec = tv.tv_usec * 1000;
01115 return ts;
01116 }
01117
01118
01119
01120
01121
01122 struct timespec timespec_min(const struct timespec *ts1,
01123 const struct timespec *ts2)
01124 {
01125 if (ts1->tv_sec < ts2->tv_sec) return *ts1;
01126 if (ts1->tv_sec > ts2->tv_sec) return *ts2;
01127 if (ts1->tv_nsec < ts2->tv_nsec) return *ts1;
01128 return *ts2;
01129 }
01130
01131
01132
01133
01134
01135
01136
01137
01138 int timespec_compare(const struct timespec *ts1, const struct timespec *ts2)
01139 {
01140 if (ts1->tv_sec > ts2->tv_sec) return 1;
01141 if (ts1->tv_sec < ts2->tv_sec) return -1;
01142 if (ts1->tv_nsec > ts2->tv_nsec) return 1;
01143 if (ts1->tv_nsec < ts2->tv_nsec) return -1;
01144 return 0;
01145 }
01146
01147
01148
01149
01150
01151
01152
01153 struct timespec interpret_long_date(const char *p)
01154 {
01155 NTTIME nt;
01156 nt = IVAL(p,0) + ((uint64_t)IVAL(p,4) << 32);
01157 if (nt == (uint64_t)-1) {
01158 struct timespec ret;
01159 ret.tv_sec = (time_t)-1;
01160 ret.tv_nsec = 0;
01161 return ret;
01162 }
01163 return nt_time_to_unix_timespec(&nt);
01164 }
01165
01166
01167
01168
01169
01170 void cli_put_dos_date(struct cli_state *cli, char *buf, int offset, time_t unixdate)
01171 {
01172 put_dos_date(buf, offset, unixdate, cli->serverzone);
01173 }
01174
01175 void cli_put_dos_date2(struct cli_state *cli, char *buf, int offset, time_t unixdate)
01176 {
01177 put_dos_date2(buf, offset, unixdate, cli->serverzone);
01178 }
01179
01180 void cli_put_dos_date3(struct cli_state *cli, char *buf, int offset, time_t unixdate)
01181 {
01182 put_dos_date3(buf, offset, unixdate, cli->serverzone);
01183 }
01184
01185 time_t cli_make_unix_date(struct cli_state *cli, void *date_ptr)
01186 {
01187 return make_unix_date(date_ptr, cli->serverzone);
01188 }
01189
01190 time_t cli_make_unix_date2(struct cli_state *cli, void *date_ptr)
01191 {
01192 return make_unix_date2(date_ptr, cli->serverzone);
01193 }
01194
01195 time_t cli_make_unix_date3(struct cli_state *cli, void *date_ptr)
01196 {
01197 return make_unix_date3(date_ptr, cli->serverzone);
01198 }
01199
01200
01201 struct timespec nt_time_to_unix_timespec(NTTIME *nt)
01202 {
01203 int64 d;
01204 struct timespec ret;
01205
01206 if (*nt == 0 || *nt == (int64)-1) {
01207 ret.tv_sec = 0;
01208 ret.tv_nsec = 0;
01209 return ret;
01210 }
01211
01212 d = (int64)*nt;
01213
01214
01215
01216
01217
01218
01219
01220 ret.tv_nsec = (long) ((d % (1000 * 1000 * 10)) * 100);
01221
01222
01223 d /= 1000*1000*10;
01224
01225
01226 d -= TIME_FIXUP_CONSTANT_INT;
01227
01228 if (d <= (int64)TIME_T_MIN) {
01229 ret.tv_sec = TIME_T_MIN;
01230 ret.tv_nsec = 0;
01231 return ret;
01232 }
01233
01234 if (d >= (int64)TIME_T_MAX) {
01235 ret.tv_sec = TIME_T_MAX;
01236 ret.tv_nsec = 0;
01237 return ret;
01238 }
01239
01240 ret.tv_sec = (time_t)d;
01241 return ret;
01242 }
01243
01244
01245
01246
01247 BOOL nt_time_equals(const NTTIME *nt1, const NTTIME *nt2)
01248 {
01249 return (*nt1 == *nt2);
01250 }
01251
01252
01253
01254
01255
01256 static struct timeval start_time_hires;
01257
01258 void TimeInit(void)
01259 {
01260 set_server_zone_offset(time(NULL));
01261
01262 DEBUG(4,("TimeInit: Serverzone is %d\n", server_zone_offset));
01263
01264
01265 if (start_time_hires.tv_sec == 0 && start_time_hires.tv_usec == 0) {
01266 GetTimeOfDay(&start_time_hires);
01267 }
01268 }
01269
01270
01271
01272
01273
01274
01275
01276 void get_process_uptime(struct timeval *ret_time)
01277 {
01278 struct timeval time_now_hires;
01279
01280 GetTimeOfDay(&time_now_hires);
01281 ret_time->tv_sec = time_now_hires.tv_sec - start_time_hires.tv_sec;
01282 if (time_now_hires.tv_usec < start_time_hires.tv_usec) {
01283 ret_time->tv_sec -= 1;
01284 ret_time->tv_usec = 1000000 + (time_now_hires.tv_usec - start_time_hires.tv_usec);
01285 } else {
01286 ret_time->tv_usec = time_now_hires.tv_usec - start_time_hires.tv_usec;
01287 }
01288 }
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299 time_t nt_time_to_unix_abs(const NTTIME *nt)
01300 {
01301 uint64 d;
01302
01303 if (*nt == 0) {
01304 return (time_t)0;
01305 }
01306
01307 if (*nt == (uint64)-1) {
01308 return (time_t)-1;
01309 }
01310
01311 if (*nt == NTTIME_INFINITY) {
01312 return (time_t)-1;
01313 }
01314
01315
01316
01317 d=~*nt;
01318
01319 d += 1000*1000*10/2;
01320 d /= 1000*1000*10;
01321
01322 if (!(TIME_T_MIN <= ((time_t)d) && ((time_t)d) <= TIME_T_MAX)) {
01323 return (time_t)0;
01324 }
01325
01326 return (time_t)d;
01327 }
01328
01329
01330
01331
01332
01333 void unix_timespec_to_nt_time(NTTIME *nt, struct timespec ts)
01334 {
01335 uint64 d;
01336
01337 if (ts.tv_sec ==0 && ts.tv_nsec == 0) {
01338 *nt = 0;
01339 return;
01340 }
01341 if (ts.tv_sec == TIME_T_MAX) {
01342 *nt = 0x7fffffffffffffffLL;
01343 return;
01344 }
01345 if (ts.tv_sec == (time_t)-1) {
01346 *nt = (uint64)-1;
01347 return;
01348 }
01349
01350 d = ts.tv_sec;
01351 d += TIME_FIXUP_CONSTANT_INT;
01352 d *= 1000*1000*10;
01353
01354 d += (ts.tv_nsec / 100);
01355
01356 *nt = d;
01357 }
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367 void unix_to_nt_time_abs(NTTIME *nt, time_t t)
01368 {
01369 double d;
01370
01371 if (t==0) {
01372 *nt = 0;
01373 return;
01374 }
01375
01376 if (t == TIME_T_MAX) {
01377 *nt = 0x7fffffffffffffffLL;
01378 return;
01379 }
01380
01381 if (t == (time_t)-1) {
01382
01383 *nt = NTTIME_INFINITY;
01384 return;
01385 }
01386
01387 d = (double)(t);
01388 d *= 1.0e7;
01389
01390 *nt = d;
01391
01392
01393 *nt=~*nt;
01394 }
01395
01396
01397
01398
01399
01400
01401 BOOL null_mtime(time_t mtime)
01402 {
01403 if (mtime == 0 || mtime == (time_t)0xFFFFFFFF || mtime == (time_t)-1)
01404 return(True);
01405 return(False);
01406 }
01407
01408
01409
01410
01411
01412
01413 const char *time_to_asc(const time_t t)
01414 {
01415 const char *asct;
01416 struct tm *lt = localtime(&t);
01417
01418 if (!lt) {
01419 return "unknown time";
01420 }
01421
01422 asct = asctime(lt);
01423 if (!asct) {
01424 return "unknown time";
01425 }
01426 return asct;
01427 }
01428
01429 const char *display_time(NTTIME nttime)
01430 {
01431 static fstring string;
01432
01433 float high;
01434 float low;
01435 int sec;
01436 int days, hours, mins, secs;
01437
01438 if (nttime==0)
01439 return "Now";
01440
01441 if (nttime==NTTIME_INFINITY)
01442 return "Never";
01443
01444 high = 65536;
01445 high = high/10000;
01446 high = high*65536;
01447 high = high/1000;
01448 high = high * (~(nttime >> 32));
01449
01450 low = ~(nttime & 0xFFFFFFFF);
01451 low = low/(1000*1000*10);
01452
01453 sec=high+low;
01454
01455 days=sec/(60*60*24);
01456 hours=(sec - (days*60*60*24)) / (60*60);
01457 mins=(sec - (days*60*60*24) - (hours*60*60) ) / 60;
01458 secs=sec - (days*60*60*24) - (hours*60*60) - (mins*60);
01459
01460 fstr_sprintf(string, "%u days, %u hours, %u minutes, %u seconds", days, hours, mins, secs);
01461 return (string);
01462 }
01463
01464 BOOL nt_time_is_set(const NTTIME *nt)
01465 {
01466 if (*nt == 0x7FFFFFFFFFFFFFFFLL) {
01467 return False;
01468 }
01469
01470 if (*nt == NTTIME_INFINITY) {
01471 return False;
01472 }
01473
01474 return True;
01475 }