2 Unix SMB/Netbios implementation.
4 SMB wrapper stat functions
5 Copyright (C) Andrew Tridgell 1998
6 Copyright (C) Derrell Lipman 2003-2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 static int timezone_diff
= -1;
27 #define TM_YEAR_BASE 1900
29 /*******************************************************************
30 yield the difference between *A and *B, in seconds, ignoring leap seconds
31 ********************************************************************/
32 static int tm_diff(struct tm
*a
, struct tm
*b
)
34 int ay
= a
->tm_year
+ (TM_YEAR_BASE
- 1);
35 int by
= b
->tm_year
+ (TM_YEAR_BASE
- 1);
36 int intervening_leap_days
=
37 (ay
/4 - by
/4) - (ay
/100 - by
/100) + (ay
/400 - by
/400);
39 int days
= 365*years
+ intervening_leap_days
+ (a
->tm_yday
- b
->tm_yday
);
40 int hours
= 24*days
+ (a
->tm_hour
- b
->tm_hour
);
41 int minutes
= 60*hours
+ (a
->tm_min
- b
->tm_min
);
42 int seconds
= 60*minutes
+ (a
->tm_sec
- b
->tm_sec
);
47 /*******************************************************************
48 return the UTC offset in seconds west of UTC, or 0 if it cannot be determined
49 ******************************************************************/
50 static int TimeZone(time_t t
)
52 struct tm
*tm
= gmtime(&t
);
60 return tm_diff(&tm_utc
,tm
);
65 static void copy_stat(struct SMBW_stat
*external
, struct stat
*internal
)
67 if (timezone_diff
< 0)
69 timezone_diff
= TimeZone(time(NULL
));
72 external
->s_dev
= internal
->st_dev
;
73 external
->s_ino
= internal
->st_ino
;
74 external
->s_mode
= internal
->st_mode
;
75 external
->s_nlink
= internal
->st_nlink
;
76 external
->s_uid
= internal
->st_uid
;
77 external
->s_gid
= internal
->st_gid
;
78 external
->s_rdev
= internal
->st_rdev
;
79 external
->s_size
= internal
->st_size
;
80 external
->s_blksize
= internal
->st_blksize
;
81 external
->s_blocks
= internal
->st_blocks
;
82 external
->s_atime
= internal
->st_atime
+ timezone_diff
;
83 external
->s_mtime
= internal
->st_mtime
+ timezone_diff
;
84 external
->s_ctime
= internal
->st_ctime
+ timezone_diff
;
88 /*****************************************************
90 *******************************************************/
91 int smbw_fstat(int fd_smbw
, struct SMBW_stat
*st
)
93 int fd_client
= smbw_fd_map
[fd_smbw
];
96 if (smbc_fstat(fd_client
, &statbuf
) < 0) {
100 copy_stat(st
, &statbuf
);
106 /*****************************************************
108 *******************************************************/
109 int smbw_stat(const char *fname
, struct SMBW_stat
*st
)
118 smbw_fix_path(fname
, path
);
120 p
= path
+ 6; /* look just past smb:// */
121 simulate
= (strchr(p
, '/') == NULL
);
123 /* special case for full-network scan, workgroups, and servers */
127 statbuf
.st_mode
= 0040777;
128 statbuf
.st_nlink
= 1;
133 statbuf
.st_blksize
= 1024;
134 statbuf
.st_blocks
= 1;
135 statbuf
.st_atime
= 0; /* beginning of epoch */
136 statbuf
.st_mtime
= 0; /* beginning of epoch */
137 statbuf
.st_ctime
= 0; /* beginning of epoch */
139 } else if (smbc_stat(path
, &statbuf
) < 0) {
143 copy_stat(st
, &statbuf
);