summaryrefslogtreecommitdiff
path: root/source3/smbd/dosmode.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2002-07-29 11:14:05 +0000
committerAndrew Tridgell <tridge@samba.org>2002-07-29 11:14:05 +0000
commit1ea873e0a07ed146ccfa61acd746de85df9ffb97 (patch)
treeaeac011a0b2be5a0b47b359d59e4a0c3bfd3293d /source3/smbd/dosmode.c
parent8c85675b075404a333c8cc3d653b949e33ddc6a8 (diff)
downloadsamba-1ea873e0a07ed146ccfa61acd746de85df9ffb97.tar.gz
samba-1ea873e0a07ed146ccfa61acd746de85df9ffb97.tar.bz2
samba-1ea873e0a07ed146ccfa61acd746de85df9ffb97.zip
an initial fix for handling sparse files in smbd
This gets my test code working, where we previously failed with files above 20G in size. I'm still not completely happy with this. There are just too many fields in trans2.c that we don't fill in. (This used to be commit 7dfdb456d4c9bcf6ecb1f7e5c5e79989f95e5627)
Diffstat (limited to 'source3/smbd/dosmode.c')
-rw-r--r--source3/smbd/dosmode.c92
1 files changed, 47 insertions, 45 deletions
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index dcffe3aa90..77d8c9cc92 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -115,65 +115,67 @@ mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname)
/****************************************************************************
change a unix mode to a dos mode
****************************************************************************/
-int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf)
+uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf)
{
- int result = 0;
+ int result = 0;
- DEBUG(8,("dos_mode: %s\n", path));
+ DEBUG(8,("dos_mode: %s\n", path));
- if ((sbuf->st_mode & S_IWUSR) == 0)
- result |= aRONLY;
+ if ((sbuf->st_mode & S_IWUSR) == 0)
+ result |= aRONLY;
+
+ if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0))
+ result |= aARCH;
- if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0))
- result |= aARCH;
-
- if (MAP_SYSTEM(conn) && ((sbuf->st_mode & S_IXGRP) != 0))
- result |= aSYSTEM;
-
- if (MAP_HIDDEN(conn) && ((sbuf->st_mode & S_IXOTH) != 0))
- result |= aHIDDEN;
+ if (MAP_SYSTEM(conn) && ((sbuf->st_mode & S_IXGRP) != 0))
+ result |= aSYSTEM;
+
+ if (MAP_HIDDEN(conn) && ((sbuf->st_mode & S_IXOTH) != 0))
+ result |= aHIDDEN;
- if (S_ISDIR(sbuf->st_mode))
- result = aDIR | (result & aRONLY);
+ if (S_ISDIR(sbuf->st_mode))
+ result = aDIR | (result & aRONLY);
+
+ if (sbuf->st_size > sbuf->st_blocks * (SMB_OFF_T)sbuf->st_blksize) {
+ result |= FILE_ATTRIBUTE_SPARSE;
+ }
#ifdef S_ISLNK
#if LINKS_READ_ONLY
- if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
- result |= aRONLY;
+ if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
+ result |= aRONLY;
#endif
#endif
- /* hide files with a name starting with a . */
- if (lp_hide_dot_files(SNUM(conn)))
- {
- char *p = strrchr_m(path,'/');
- if (p)
- p++;
- else
- p = path;
-
- if (p[0] == '.' && p[1] != '.' && p[1] != 0)
- result |= aHIDDEN;
- }
-
- /* Optimization : Only call is_hidden_path if it's not already
- hidden. */
- if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path))
- {
- result |= aHIDDEN;
- }
-
- DEBUG(8,("dos_mode returning "));
+ /* hide files with a name starting with a . */
+ if (lp_hide_dot_files(SNUM(conn))) {
+ char *p = strrchr_m(path,'/');
+ if (p)
+ p++;
+ else
+ p = path;
+
+ if (p[0] == '.' && p[1] != '.' && p[1] != 0)
+ result |= aHIDDEN;
+ }
+
+ /* Optimization : Only call is_hidden_path if it's not already
+ hidden. */
+ if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) {
+ result |= aHIDDEN;
+ }
- if (result & aHIDDEN) DEBUG(8, ("h"));
- if (result & aRONLY ) DEBUG(8, ("r"));
- if (result & aSYSTEM) DEBUG(8, ("s"));
- if (result & aDIR ) DEBUG(8, ("d"));
- if (result & aARCH ) DEBUG(8, ("a"));
+ DEBUG(8,("dos_mode returning "));
- DEBUG(8,("\n"));
+ if (result & aHIDDEN) DEBUG(8, ("h"));
+ if (result & aRONLY ) DEBUG(8, ("r"));
+ if (result & aSYSTEM) DEBUG(8, ("s"));
+ if (result & aDIR ) DEBUG(8, ("d"));
+ if (result & aARCH ) DEBUG(8, ("a"));
+
+ DEBUG(8,("\n"));
- return(result);
+ return(result);
}
/*******************************************************************