⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 time.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/CIFS implementation.   time handling functions   Copyright (C) Andrew Tridgell 		1992-1998   Copyright (C) Stefan (metze) Metzmacher	2002      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "includes.h"/*  This stuff was largely rewritten by Paul Eggert <eggert@twinsun.com>  in May 1996   */int extra_time_offset = 0;#ifndef CHAR_BIT#define CHAR_BIT 8#endif#ifndef TIME_T_MIN#define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \		    : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))#endif#ifndef TIME_T_MAX#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)#endifvoid get_nttime_max(NTTIME *t){	/* FIXME: This is incorrect */	unix_to_nt_time(t, get_time_t_max());}/******************************************************************* External access to time_t_min and time_t_max.********************************************************************/time_t get_time_t_max(void){	return TIME_T_MAX;}/******************************************************************* A gettimeofday wrapper.********************************************************************/void GetTimeOfDay(struct timeval *tval){#ifdef HAVE_GETTIMEOFDAY_TZ	gettimeofday(tval,NULL);#else	gettimeofday(tval);#endif}#define TM_YEAR_BASE 1900/******************************************************************* Yield the difference between *A and *B, in seconds, ignoring leap seconds.********************************************************************/static int tm_diff(struct tm *a, struct tm *b){	int ay = a->tm_year + (TM_YEAR_BASE - 1);	int by = b->tm_year + (TM_YEAR_BASE - 1);	int intervening_leap_days = (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);	int years = ay - by;	int days = 365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);	int hours = 24*days + (a->tm_hour - b->tm_hour);	int minutes = 60*hours + (a->tm_min - b->tm_min);	int seconds = 60*minutes + (a->tm_sec - b->tm_sec);	return seconds;}/******************************************************************* Return the UTC offset in seconds west of UTC, or 0 if it cannot be determined.******************************************************************/int get_time_zone(time_t t){	struct tm *tm = gmtime(&t);	struct tm tm_utc;	if (!tm) {		return 0;	}	tm_utc = *tm;	tm = localtime(&t);	if (!tm) {		return 0;	}	return tm_diff(&tm_utc,tm) + 60*extra_time_offset;}/******************************************************************* Accessor function for the server time zone offset. set_server_zone_offset() must have been called first.******************************************************************/static int server_zone_offset;int get_server_zone_offset(void){	return server_zone_offset;}/******************************************************************* Initialize the server time zone offset. Called when a client connects.******************************************************************/int set_server_zone_offset(time_t t){	server_zone_offset = get_time_zone(t);	return server_zone_offset;}/******************************************************************* Re-read the smb serverzone value.******************************************************************/static struct timeval start_time_hires;void TimeInit(void){	set_server_zone_offset(time(NULL));	DEBUG(4,("TimeInit: Serverzone is %d\n", server_zone_offset));	/* Save the start time of this process. */	if (start_time_hires.tv_sec == 0 && start_time_hires.tv_usec == 0) {		GetTimeOfDay(&start_time_hires);	}}/********************************************************************** Return a timeval struct of the uptime of this process. As TimeInit is done before a daemon fork then this is the start time from the parent daemon start. JRA.***********************************************************************/void get_process_uptime(struct timeval *ret_time){	struct timeval time_now_hires;	GetTimeOfDay(&time_now_hires);	ret_time->tv_sec = time_now_hires.tv_sec - start_time_hires.tv_sec;	ret_time->tv_usec = time_now_hires.tv_usec - start_time_hires.tv_usec;	if (time_now_hires.tv_usec < start_time_hires.tv_usec) {		ret_time->tv_sec -= 1;		ret_time->tv_usec = 1000000 + (time_now_hires.tv_usec - start_time_hires.tv_usec);	} else {		ret_time->tv_usec = time_now_hires.tv_usec - start_time_hires.tv_usec;	}}#if 0/**************************************************************************** Return the UTC offset in seconds west of UTC, adjusted for extra time offset.**************************************************************************/int TimeDiff(time_t t){	return get_time_zone(t);}#endif#define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))/**************************************************************************** Interpret an 8 byte "filetime" structure to a time_t It's originally in "100ns units since jan 1st 1601" An 8 byte value of 0xffffffffffffffff will be returned as (time_t)0. Returns GMT.****************************************************************************/time_t nt_time_to_unix(NTTIME *nt){	double d;	time_t ret;	/* The next two lines are a fix needed for the 		broken SCO compiler. JRA. */	time_t l_time_min = TIME_T_MIN;	time_t l_time_max = TIME_T_MAX;	if (nt->high == 0 || (nt->high == 0xffffffff && nt->low == 0xffffffff)) {		return(0);	}	d = ((double)nt->high)*4.0*(double)(1<<30);	d += (nt->low&0xFFF00000);	d *= 1.0e-7; 	/* now adjust by 369 years to make the secs since 1970 */	d -= TIME_FIXUP_CONSTANT;	if (d <= l_time_min) {		return (l_time_min);	}	if (d >= l_time_max) {		return (l_time_max);	}	ret = (time_t)(d+0.5);	return(ret);}/**************************************************************************** Convert a NTTIME structure to a time_t. It's originally in "100ns units". This is an absolute version of the one above. By absolute I mean, it doesn't adjust from 1/1/1601 to 1/1/1970 if the NTTIME was 5 seconds, the time_t is 5 seconds. JFM****************************************************************************/time_t nt_time_to_unix_abs(NTTIME *nt){	double d;	time_t ret;	/* The next two lines are a fix needed for the 	   broken SCO compiler. JRA. */	time_t l_time_min = TIME_T_MIN;	time_t l_time_max = TIME_T_MAX;	if (nt->high == 0) {		return(0);	}	if (nt->high==0x80000000 && nt->low==0) {		return (time_t)-1;	}	/* reverse the time */	/* it's a negative value, turn it to positive */	nt->high=~nt->high;	nt->low=~nt->low;	d = ((double)nt->high)*4.0*(double)(1<<30);	d += (nt->low&0xFFF00000);	d *= 1.0e-7;  	if (!(l_time_min <= d && d <= l_time_max)) {		return(0);	}	ret = (time_t)(d+0.5);	return(ret);}/**************************************************************************** Interprets an nt time into a unix time_t. Differs from nt_time_to_unix in that an 8 byte value of 0xffffffffffffffff will be returned as (time_t)-1, whereas nt_time_to_unix returns 0 in this case.****************************************************************************/time_t interpret_long_date(char *p){	NTTIME nt;	nt.low = IVAL(p,0);	nt.high = IVAL(p,4);	if (nt.low == 0xFFFFFFFF && nt.high == 0xFFFFFFFF) {		return (time_t)-1;	}	return nt_time_to_unix(&nt);}/**************************************************************************** Put a 8 byte filetime from a time_t. Uses GMT.****************************************************************************/void unix_to_nt_time(NTTIME *nt, time_t t){	double d;	if (t==0) {		nt->low = 0;		nt->high = 0;		return;	}	if (t == TIME_T_MAX) {		nt->low = 0xffffffff;		nt->high = 0x7fffffff;		return;	}			if (t == (time_t)-1) {		nt->low = 0xffffffff;		nt->high = 0xffffffff;		return;	}			d = (double)(t);	d += TIME_FIXUP_CONSTANT;	d *= 1.0e7;	nt->high = (uint32)(d * (1.0/(4.0*(double)(1<<30))));	nt->low  = (uint32)(d - ((double)nt->high)*4.0*(double)(1<<30));}/**************************************************************************** Convert a time_t to a NTTIME structure This is an absolute version of the one above. By absolute I mean, it doesn't adjust from 1/1/1970 to 1/1/1601 If the nttime_t was 5 seconds, the NTTIME is 5 seconds. JFM****************************************************************************/void unix_to_nt_time_abs(NTTIME *nt, time_t t){	double d;	if (t==0) {		nt->low = 0;		nt->high = 0;		return;	}	if (t == TIME_T_MAX) {		nt->low = 0xffffffff;		nt->high = 0x7fffffff;		return;	}			if (t == (time_t)-1) {		/* that's what NT uses for infinite */		nt->low = 0x0;		nt->high = 0x80000000;		return;	}			d = (double)(t);	d *= 1.0e7;	nt->high = (uint32)(d * (1.0/(4.0*(double)(1<<30))));	nt->low  = (uint32)(d - ((double)nt->high)*4.0*(double)(1<<30));	/* convert to a negative value */	nt->high=~nt->high;	nt->low=~nt->low;}/**************************************************************************** Take a Unix time and convert to an NTTIME structure and place in buffer  pointed to by p.****************************************************************************/void put_long_date(char *p, time_t t){	NTTIME nt;	unix_to_nt_time(&nt, t);	SIVAL(p, 0, nt.low);	SIVAL(p, 4, nt.high);}/**************************************************************************** Check if it's a null mtime.****************************************************************************/BOOL null_mtime(time_t mtime){	if (mtime == 0 || mtime == (time_t)0xFFFFFFFF || mtime == (time_t)-1)		return(True);	return(False);}/******************************************************************* Create a 16 bit dos packed date.********************************************************************/static uint16 make_dos_date1(struct tm *t){	uint16 ret=0;	ret = (((unsigned)(t->tm_mon+1)) >> 3) | ((t->tm_year-80) << 1);	ret = ((ret&0xFF)<<8) | (t->tm_mday | (((t->tm_mon+1) & 0x7) << 5));	return(ret);}/******************************************************************* Create a 16 bit dos packed time.********************************************************************/static uint16 make_dos_time1(struct tm *t){	uint16 ret=0;	ret = ((((unsigned)t->tm_min >> 3)&0x7) | (((unsigned)t->tm_hour) << 3));	ret = ((ret&0xFF)<<8) | ((t->tm_sec/2) | ((t->tm_min & 0x7) << 5));	return(ret);}/******************************************************************* Create a 32 bit dos packed date/time from some parameters. This takes a GMT time and returns a packed localtime structure.********************************************************************/static uint32 make_dos_date(time_t unixdate, int zone_offset){	struct tm *t;	uint32 ret=0;	if (unixdate == 0) {		return 0;	}	unixdate -= zone_offset;	t = gmtime(&unixdate);	if (!t) {		return 0xFFFFFFFF;	}	ret = make_dos_date1(t);	ret = ((ret&0xFFFF)<<16) | make_dos_time1(t);	return(ret);}/******************************************************************* Put a dos date into a buffer (time/date format). This takes GMT time and puts local time in the buffer.********************************************************************/static void put_dos_date(char *buf,int offset,time_t unixdate, int zone_offset){	uint32 x = make_dos_date(unixdate, zone_offset);	SIVAL(buf,offset,x);}/******************************************************************* Put a dos date into a buffer (date/time format). This takes GMT time and puts local time in the buffer.********************************************************************/static void put_dos_date2(char *buf,int offset,time_t unixdate, int zone_offset){	uint32 x = make_dos_date(unixdate, zone_offset);	x = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);	SIVAL(buf,offset,x);}/******************************************************************* Put a dos 32 bit "unix like" date into a buffer. This routine takes GMT and converts it to LOCAL time before putting it (most SMBs assume localtime for this sort of date)********************************************************************/static void put_dos_date3(char *buf,int offset,time_t unixdate, int zone_offset){	if (!null_mtime(unixdate)) {		unixdate -= zone_offset;	}	SIVAL(buf,offset,unixdate);}/******************************************************************* Interpret a 32 bit dos packed date/time to some parameters.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -