lib/time.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    time handling functions
00004 
00005    Copyright (C) Andrew Tridgell                1992-2004
00006    Copyright (C) Stefan (metze) Metzmacher      2002   
00007    Copyright (C) Jeremy Allison                 2007
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2 of the License, or
00012    (at your option) any later version.
00013    
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018    
00019    You should have received a copy of the GNU General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00022 */
00023 
00024 #include "includes.h"
00025 
00026 /**
00027  * @file
00028  * @brief time handling functions
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  External access to time_t_min and time_t_max.
00044 ****************************************************************************/
00045 
00046 time_t get_time_t_max(void)
00047 {
00048         return TIME_T_MAX;
00049 }
00050 
00051 /***************************************************************************
00052  A gettimeofday wrapper.
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  Interpret an 8 byte "filetime" structure to a time_t
00072  It's originally in "100ns units since jan 1st 1601"
00073 
00074  An 8 byte value of 0xffffffffffffffff will be returned as a timespec of
00075 
00076         tv_sec = 0
00077         tv_nsec = 0;
00078 
00079  Returns GMT.
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  Put a 8 byte filetime from a time_t. Uses GMT.
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  Check if it's a null unix time.
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  Check if it's a null NTTIME.
00130 ****************************************************************************/
00131 
00132 BOOL null_nttime(NTTIME t)
00133 {
00134         return t == 0 || t == (NTTIME)-1;
00135 }
00136 
00137 /****************************************************************************
00138  Check if it's a null timespec.
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   create a 16 bit dos packed date
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   create a 16 bit dos packed time
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   create a 32 bit dos packed date/time from some parameters
00172   This takes a GMT time and returns a packed localtime structure
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 put a dos date into a buffer (time/date format)
00198 This takes GMT time and puts local time in the buffer
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 put a dos date into a buffer (date/time format)
00208 This takes GMT time and puts local time in the buffer
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 put a dos 32 bit "unix like" date into a buffer. This routine takes
00220 GMT and converts it to LOCAL time before putting it (most SMBs assume
00221 localtime for this sort of date)
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   interpret a 32 bit dos packed date/time to some parameters
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   create a unix date (int GMT) from a dos date (which is actually in
00251   localtime)
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 like make_unix_date() but the words are reversed
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   create a unix GMT date from a dos date in 32 bit "unix like" format
00290   these generally arrive as localtimes, with corresponding DST
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  Return a HTTP/1.0 time string.
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 /* !HAVE_STRFTIME */
00322                 strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S %Z", tm);
00323 #endif /* !HAVE_STRFTIME */
00324         }
00325         return buf;
00326 }
00327 
00328 
00329 /**
00330  Return the date and time as a string
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         /* some versions of gcc complain about using %c. This is a bug
00347            in the gcc warning, not a bug in this code. See a recent
00348            strftime() manual page for details.
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   return a talloced string representing a NTTIME for human consumption
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   parse a nttime as a large integer in a string and return a NTTIME
00375 */
00376 NTTIME nttime_from_string(const char *s)
00377 {
00378         return strtoull(s, NULL, 0);
00379 }
00380 
00381 /**
00382   return (tv1 - tv2) in microseconds
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   return a zero timeval
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   return True if a timeval is zero
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   return a timeval for the current time
00412 */
00413 struct timeval timeval_current(void)
00414 {
00415         struct timeval tv;
00416         GetTimeOfDay(&tv);
00417         return tv;
00418 }
00419 
00420 /**
00421   return a timeval struct with the given elements
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   return a timeval ofs microseconds after tv
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   return the sum of two timeval structures
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   return a timeval secs/usecs into the future
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   compare two timeval structures. 
00467   Return -1 if tv1 < tv2
00468   Return 0 if tv1 == tv2
00469   Return 1 if tv1 > tv2
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   return True if a timer is in the past
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   return the number of seconds elapsed between two times
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   return the number of seconds elapsed since a given time
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   return the lesser of two timevals
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   return the greater of two timevals
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   return the difference between two timevals as a timeval
00535   if tv1 comes after tv2, then return a zero timeval
00536   (this is *tv2 - *tv1)
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   convert a timeval to a NTTIME
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  Handle conversions between time_t and uint32, taking care to
00567  preserve the "special" values.
00568 **************************************************************/
00569 
00570 uint32 convert_time_t_to_uint32(time_t t)
00571 {
00572 #if (defined(SIZEOF_TIME_T) && (SIZEOF_TIME_T == 8))
00573         /* time_t is 64-bit. */
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         /* time_t is 64-bit. */
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  Yield the difference between *A and *B, in seconds, ignoring leap seconds.
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  Return the UTC offset in seconds west of UTC, or 0 if it cannot be determined.
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  Check if NTTIME is 0.
00636 ****************************************************************************/
00637 
00638 BOOL nt_time_is_zero(const NTTIME *nt)
00639 {
00640         return (*nt == 0);
00641 }
00642 
00643 /****************************************************************************
00644  Convert ASN.1 GeneralizedTime string to unix-time.
00645  Returns 0 on failure; Currently ignores timezone. 
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  Accessor function for the server time zone offset.
00667  set_server_zone_offset() must have been called first.
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  Initialize the server time zone offset. Called when a client connects.
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  Return the date and time as a string
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  Put a dos date into a buffer (time/date format).
00749  This takes GMT time and puts local time in the buffer.
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  Put a dos date into a buffer (date/time format).
00760  This takes GMT time and puts local time in the buffer.
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  Put a dos 32 bit "unix like" date into a buffer. This routine takes
00772  GMT and converts it to LOCAL time before putting it (most SMBs assume
00773  localtime for this sort of date)
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  Server versions of the above functions.
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  Take a Unix time and convert to an NTTIME structure and place in buffer 
00806  pointed to by p.
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  Return the best approximation to a 'create time' under UNIX from a stat
00827  structure.
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;          /* 1/1/1980 */
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          * One of ctime, mtime or atime was zero (probably atime).
00847          * Just return MIN(ctime, mtime).
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  Get/Set all the possible time fields from a stat struct as a timespec.
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         /* Old system - no ns timestamp. */
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         /* Old system - no ns timestamp. */
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         /* Old system - no ns timestamp. */
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         /* Old system - no ns timestamp. */
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         /* Old system - no ns timestamp. */
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         /* Old system - no ns timestamp. */
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  Create a unix date (int GMT) from a dos date (which is actually in
00992  localtime).
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  Like make_unix_date() but the words are reversed.
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  Create a unix GMT date from a dos date in 32 bit "unix like" format
01035  these generally arrive as localtimes, with corresponding DST.
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         /* 1 ns == 1,000,000,000 - one thousand millionths of a second.
01065            increment if it's greater than 500 millionth of a second. */
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  Convert a normalized timeval to a timespec.
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  Convert a normalized timespec to a timeval.
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  Return a timespec for the current time
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  Return the lesser of two timespecs.
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   compare two timespec structures. 
01133   Return -1 if ts1 < ts2
01134   Return 0 if ts1 == ts2
01135   Return 1 if ts1 > ts2
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  Interprets an nt time into a unix struct timespec.
01149  Differs from nt_time_to_unix in that an 8 byte value of 0xffffffffffffffff
01150  will be returned as (time_t)-1, whereas nt_time_to_unix returns 0 in this case.
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  Client versions of the above functions.
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 /* Large integer version. */
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         /* d is now in 100ns units, since jan 1st 1601".
01214            Save off the ns fraction. */
01215 
01216         /*
01217          * Take the last seven decimal digits and multiply by 100.
01218          * to convert from 100ns units to 1ns units.
01219          */
01220         ret.tv_nsec = (long) ((d % (1000 * 1000 * 10)) * 100);
01221 
01222         /* Convert to seconds */
01223         d /= 1000*1000*10;
01224 
01225         /* Now adjust by 369 years to make the secs since 1970 */
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  Check if two NTTIMEs are the same.
01245 ****************************************************************************/
01246 
01247 BOOL nt_time_equals(const NTTIME *nt1, const NTTIME *nt2)
01248 {
01249         return (*nt1 == *nt2);
01250 }
01251 
01252 /*******************************************************************
01253  Re-read the smb serverzone value.
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         /* Save the start time of this process. */
01265         if (start_time_hires.tv_sec == 0 && start_time_hires.tv_usec == 0) {
01266                 GetTimeOfDay(&start_time_hires);
01267         }
01268 }
01269 
01270 /**********************************************************************
01271  Return a timeval struct of the uptime of this process. As TimeInit is
01272  done before a daemon fork then this is the start time from the parent
01273  daemon start. JRA.
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  Convert a NTTIME structure to a time_t.
01292  It's originally in "100ns units".
01293 
01294  This is an absolute version of the one above.
01295  By absolute I mean, it doesn't adjust from 1/1/1601 to 1/1/1970
01296  if the NTTIME was 5 seconds, the time_t is 5 seconds. JFM
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         /* reverse the time */
01316         /* it's a negative value, turn it to positive */
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  Put a 8 byte filetime from a struct timespec. Uses GMT.
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         /* d is now in 100ns units. */
01354         d += (ts.tv_nsec / 100);
01355 
01356         *nt = d;
01357 }
01358 
01359 /****************************************************************************
01360  Convert a time_t to a NTTIME structure
01361 
01362  This is an absolute version of the one above.
01363  By absolute I mean, it doesn't adjust from 1/1/1970 to 1/1/1601
01364  If the time_t was 5 seconds, the NTTIME is 5 seconds. JFM
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                 /* that's what NT uses for infinite */
01383                 *nt = NTTIME_INFINITY;
01384                 return;
01385         }               
01386 
01387         d = (double)(t);
01388         d *= 1.0e7;
01389 
01390         *nt = d;
01391 
01392         /* convert to a negative value */
01393         *nt=~*nt;
01394 }
01395 
01396 
01397 /****************************************************************************
01398  Check if it's a null mtime.
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  Utility function that always returns a const string even if localtime
01410  and asctime fail.
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 }

Sambaに対してSat Aug 29 21:23:00 2009に生成されました。  doxygen 1.4.7