]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Implement Windows reparse points -- similar to directories, but
authorKern Sibbald <kern@sibbald.com>
Sun, 24 Jun 2007 17:27:12 +0000 (17:27 +0000)
committerKern Sibbald <kern@sibbald.com>
Sun, 24 Jun 2007 17:27:12 +0000 (17:27 +0000)
     we do not descend into it. This is a first cut. They seem to
     be backed up, but restore is not yet tested.
kes  Remove restore_blocking in tls code when shutting a socket to leave
     it in blocking mode. Hopefully this will fix the encryption bug
     reported by Frank Sweetser.
kes  When opening a file for backup, tell the OS that we are going to
     read it sequentially -- optimization.
kes  Change variable names in authenticate_director() to not conflict
     with member names in bat. Caused great confusion with compiler,
     but no warnings.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@5077 91ce42f0-d328-0410-95d8-f526ca767f89

15 files changed:
bacula/src/baconfig.h
bacula/src/filed/backup.c
bacula/src/filed/estimate.c
bacula/src/filed/status.c
bacula/src/filed/verify.c
bacula/src/findlib/bfile.c
bacula/src/findlib/bfile.h
bacula/src/findlib/create_file.c
bacula/src/findlib/find.c
bacula/src/findlib/find_one.c
bacula/src/lib/bsock.c
bacula/src/lib/tls.c
bacula/src/version.h
bacula/src/win32/compat/compat.cpp
bacula/technotes-2.1

index 6fa3fd6b2fc795597e784e7c9ac59a1e4b8d7872..ae5bddbf9fda7153c75f02c89fca4958c3c76109 100644 (file)
@@ -267,12 +267,13 @@ void InitWinAPIWrapper();
 #define FT_NOOPEN    15               /* Could not open directory */
 #define FT_RAW       16               /* Raw block device */
 #define FT_FIFO      17               /* Raw fifo device */
-/* This directory packet is sent to the FD file processing routine so
+/* The DIRBEGIN packet is sent to the FD file processing routine so
  * that it can filter packets, but otherwise, it is not used
  * or saved */
 #define FT_DIRBEGIN  18               /* Directory at beginning (not saved) */
 #define FT_INVALIDFS 19               /* File system not allowed for */
 #define FT_INVALIDDT 20               /* Drive type not allowed for */
+#define FT_REPARSE   21               /* Win NTFS reparse point */
 
 /* Definitions for upper part of type word (see above). */
 #define AR_DATA_STREAM (1<<16)        /* Data stream id present */
index e4651c7c1931def805c6a15573cb25b967c8369a..db9193e7161661cc22ff8e24035f96bf2bae9758 100644 (file)
@@ -273,6 +273,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level)
       Jmsg(jcr, M_INFO, 1, _("     Disallowed drive type. Will not descend into %s\n"),
            ff_pkt->fname);
       break;
+   case FT_REPARSE:
    case FT_DIREND:
       Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link);
       break;
@@ -441,6 +442,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level)
       do_read = ff_pkt->statp.st_size > 0;
 #endif
    } else if (ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
+              ff_pkt->type == FT_REPARSE ||
          (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
       do_read = true;
    }
@@ -453,6 +455,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level)
          tid = NULL;
       }
       int noatime = ff_pkt->flags & FO_NOATIME ? O_NOATIME : 0;
+      ff_pkt->bfd.reparse_point = ff_pkt->type == FT_REPARSE;
       if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY | noatime, 0) < 0) {
          ff_pkt->ff_errno = errno;
          berrno be;
@@ -1068,7 +1071,7 @@ static bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_strea
       stat = sd->fsend("%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles,
                ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0,
                attribsEx, 0);
-   } else if (ff_pkt->type == FT_DIREND) {
+   } else if (ff_pkt->type == FT_DIREND || ff_pkt->type == FT_REPARSE) {
       /* Here link is the canonical filename (i.e. with trailing slash) */
       stat = sd->fsend("%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
                ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0);
index 26f9bd886631b474fd74c650b655609f8e570c6b..70d0154fb4da30d00d1517aa479784c32536d0d0 100644 (file)
@@ -1,16 +1,7 @@
-/*
- *  Bacula File Daemon estimate.c
- *   Make and estimate of the number of files and size to be saved.
- *
- *    Kern Sibbald, September MMI
- *
- *   Version $Id$
- *
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2001-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2001-2007 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *  Bacula File Daemon estimate.c
+ *   Make and estimate of the number of files and size to be saved.
+ *
+ *    Kern Sibbald, September MMI
+ *
+ *   Version $Id$
+ *
+ */
 
 #include "bacula.h"
 #include "filed.h"
@@ -76,6 +76,7 @@ static int tally_file(FF_PKT *ff_pkt, void *ijcr, bool top_level)
    case FT_NOFSCHG:
    case FT_INVALIDFS:
    case FT_INVALIDDT:
+   case FT_REPARSE:
    case FT_DIREND:
    case FT_SPEC:
    case FT_RAW:
index 07e0f6b2e1d3702651ed8e59d79f6bd66ca6b2ab..866cc18dd6709ffaba13dd26deb05802c75d709c 100644 (file)
@@ -174,8 +174,9 @@ void output_status(void sendit(const char *msg, int len, void *sarg), void *arg)
            edit_uint64_with_commas(njcr->JobBytes, b2),
            edit_uint64_with_commas(bps, b3));
       sendit(msg.c_str(), len, arg);
-      len = Mmsg(msg, _("    Files Examined=%s\n"),
-           edit_uint64_with_commas(njcr->num_files_examined, b1));
+      len = Mmsg(msg, _("    Files Examined=%s Errors=%d\n"),
+           edit_uint64_with_commas(njcr->num_files_examined, b1),
+           njcr->JobErrors);
       sendit(msg.c_str(), len, arg);
       if (njcr->JobFiles > 0) {
          njcr->lock();
index 18ebe09d7fa070cc3e76e1d3aa3b59eac11fc3ff..e42dcf5f6bcfd07742fdcfee530c16724bcb4987 100644 (file)
@@ -104,6 +104,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt, bool top_level)
    case FT_DIRBEGIN:
       jcr->num_files_examined--;      /* correct file count */
       return 1;                       /* ignored */
+   case FT_REPARSE: 
    case FT_DIREND:
       Dmsg1(30, "FT_DIR saving: %s\n", ff_pkt->fname);
       break;
@@ -190,7 +191,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt, bool top_level)
       stat = bnet_fsend(dir, "%d %d %s %s%c%s%c%s%c", jcr->JobFiles,
             STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname,
             0, attribs, 0, ff_pkt->link, 0);
-   } else if (ff_pkt->type == FT_DIREND) {
+   } else if (ff_pkt->type == FT_DIREND || ff_pkt->type == FT_REPARSE) {
          /* Here link is the canonical filename (i.e. with trailing slash) */
          stat = bnet_fsend(dir,"%d %d %s %s%c%s%c%c", jcr->JobFiles,
                STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->link,
index d98ba1afaee5ff7f8661d6963a10070cd74f4ed7..03b51431b5ec2c1eb140f908e69c043210fb0bfb 100644 (file)
@@ -1,13 +1,3 @@
-/*
- *  Bacula low level File I/O routines.  This routine simulates
- *    open(), read(), write(), and close(), but using native routines.
- *    I.e. on Windows, we use Windows APIs.
- *
- *    Kern Sibbald, April MMIII
- *
- *   Version $Id$
- *
- */
 /*
    Bacula® - The Network Backup Solution
 
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *  Bacula low level File I/O routines.  This routine simulates
+ *    open(), read(), write(), and close(), but using native routines.
+ *    I.e. on Windows, we use Windows APIs.
+ *
+ *    Kern Sibbald, April MMIII
+ *
+ *   Version $Id$
+ *
+ */
 
 #include "bacula.h"
 #include "find.h"
@@ -417,8 +417,8 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
          dwflags = 0;
       }
 
-      // unicode or ascii open for create write
       if (p_CreateFileW && p_MultiByteToWideChar) {   
+         // unicode open for create write
          bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar,
                 dwaccess,                /* Requested access */
                 0,                       /* Shared mode */
@@ -427,6 +427,7 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
                 dwflags,                 /* Flags and attributes */
                 NULL);                   /* TemplateFile */
       } else {
+         // ascii open
          bfd->fh = p_CreateFileA(win32_fname,
                 dwaccess,                /* Requested access */
                 0,                       /* Shared mode */
@@ -441,14 +442,14 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
    } else if (flags & O_WRONLY) {     /* Open existing for write */
       if (bfd->use_backup_api) {
          dwaccess = GENERIC_WRITE|WRITE_OWNER|WRITE_DAC;
-         dwflags = FILE_FLAG_BACKUP_SEMANTICS;
+         dwflags = FILE_FLAG_BACKUP_SEMANTICS;                          
       } else {
          dwaccess = GENERIC_WRITE;
          dwflags = 0;
       }
 
-      // unicode or ascii open for open existing write
       if (p_CreateFileW && p_MultiByteToWideChar) {   
+         // unicode open for open existing write
          bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar,
                 dwaccess,                /* Requested access */
                 0,                       /* Shared mode */
@@ -457,6 +458,7 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
                 dwflags,                 /* Flags and attributes */
                 NULL);                   /* TemplateFile */
       } else {
+         // ascii open
          bfd->fh = p_CreateFileA(win32_fname,
                 dwaccess,                /* Requested access */
                 0,                       /* Shared mode */
@@ -472,7 +474,8 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
    } else {                           /* Read */
       if (bfd->use_backup_api) {
          dwaccess = GENERIC_READ|READ_CONTROL|ACCESS_SYSTEM_SECURITY;
-         dwflags = FILE_FLAG_BACKUP_SEMANTICS;
+         dwflags = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_SEQUENTIAL_SCAN |
+                   FILE_FLAG_OPEN_REPARSE_POINT;
          dwshare = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
       } else {
          dwaccess = GENERIC_READ;
@@ -480,8 +483,8 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
          dwshare = FILE_SHARE_READ|FILE_SHARE_WRITE;
       }
 
-      // unicode or ascii open for open existing read
       if (p_CreateFileW && p_MultiByteToWideChar) {   
+         // unicode open for open existing read
          bfd->fh = p_CreateFileW((LPCWSTR)win32_fname_wchar,
                 dwaccess,                /* Requested access */
                 dwshare,                 /* Share modes */
@@ -490,6 +493,7 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
                 dwflags,                 /* Flags and attributes */
                 NULL);                   /* TemplateFile */
       } else {
+         // ascii open 
          bfd->fh = p_CreateFileA(win32_fname,
                 dwaccess,                /* Requested access */
                 dwshare,                 /* Share modes */
index ffbb08270f9c7c27a40f724f7604e14b29b2c566..ed3f6c6d2866a3d0b764df8508f08fbc452c8aef 100644 (file)
@@ -103,6 +103,7 @@ struct BFILE {
    Python_IO pio;                     /* Python I/O routines */
    PROCESS_WIN32_BACKUPAPIBLOCK_CONTEXT win32DecompContext; /* context for decomposition of win32 backup streams */
    int use_backup_decomp;             /* set if using BackupRead Stream Decomposition */
+   bool reparse_point;                /* set if reparse point */ 
 };
 
 HANDLE bget_handle(BFILE *bfd);
@@ -126,6 +127,7 @@ struct BFILE {
    Python_IO pio;                     /* Python I/O routines */
    PROCESS_WIN32_BACKUPAPIBLOCK_CONTEXT win32DecompContext; /* context for decomposition of win32 backup streams */
    int use_backup_decomp;             /* set if using BackupRead Stream Decomposition */
+   bool reparse_point;                /* not used in Unix */
 };
 
 #endif
index 05416ced8254aeff53a5fab7d92885fdc8fb4e1c..12f7c487badb84a704e6c8fd26d82449dcbacc9c 100644 (file)
@@ -78,6 +78,7 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
    bool exists = false;
    struct stat mstatp;
 
+   bfd->reparse_point = false;
    if (is_win32_stream(attr->data_stream)) {
       set_win32_backup(bfd);
    } else {
@@ -350,6 +351,9 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
 #endif
       } /* End inner switch */
 
+   case FT_REPARSE:
+      bfd->reparse_point = true;
+      /* Fall through wanted */
    case FT_DIRBEGIN:
    case FT_DIREND:
       Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname);
index dd1bbdabf4cdecee93441cd40a77ae7982a494a9..0bffa6abe44be4997c2afc42b807ae24986c4b86 100644 (file)
@@ -376,6 +376,7 @@ static int our_callback(FF_PKT *ff, void *hpkt, bool top_level)
    case FT_INVALIDFS:
    case FT_INVALIDDT:
    case FT_NOOPEN:
+   case FT_REPARSE:
 //    return ff->callback(ff, hpkt, top_level);
 
    /* These items can be filtered */
index 81c892651e18c7c7ea6841b34fbaacd3f388028a..723d45ccf77a12ab09d76ee438270186b9d2426c 100644 (file)
@@ -511,6 +511,10 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt,
       } else {
          ff_pkt->type = FT_DIRBEGIN;
       }
+      /* We have set st_rdev to 1 if it is a reparse point, otherwise 0 */
+      if (have_win32_api() && ff_pkt->statp.st_rdev) {
+         ff_pkt->type = FT_REPARSE;
+      }
       /*
        * Note, we return the directory to the calling program (handle_file)
        * when we first see the directory (FT_DIRBEGIN.
@@ -520,7 +524,7 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt,
        * in the directory is seen (i.e. the FT_DIREND).
        */
       rtn_stat = handle_file(ff_pkt, pkt, top_level);
-      if (rtn_stat < 1) {             /* ignore or error status */
+      if (rtn_stat < 1 || ff_pkt->type == FT_REPARSE) {   /* ignore or error status */
          free(link);
          return rtn_stat;
       }
index 88841f322f23adb65325a16472ada5bcb7bcd59c..32a163acc896a0bcedfc96d32883520debdbac4b 100644 (file)
@@ -802,7 +802,7 @@ void BSOCK::close()
             free_tls_connection(bsock->tls);
             bsock->tls = NULL;
          }
-         if (bsock->is_timed_out() || bsock->is_terminated()) {
+         if (bsock->is_timed_out()) {
             shutdown(bsock->m_fd, SHUT_RDWR);   /* discard any pending I/O */
          }
          socketClose(bsock->m_fd);      /* normal close */
index dd3aba84383909d7d22b1a4c34f70677ebf82ad9..1acb404e56300684783a7f3de3bfb4163fddf355 100644 (file)
@@ -569,7 +569,7 @@ void tls_bsock_shutdown(BSOCK *bsock)
    int flags;
 
    /* Set socket blocking for shutdown */
-   flags = bsock->set_blocking();
+   bsock->set_blocking();
 
    err = SSL_shutdown(bsock->tls->openssl);
 
@@ -585,9 +585,6 @@ void tls_bsock_shutdown(BSOCK *bsock)
       openssl_post_errors(M_ERROR, _("TLS shutdown failure."));
       break;
    }
-
-   /* Restore saved flags */
-   bsock->restore_blocking(flags);
 }
 
 /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */
index 9467de874d5227d2ff1a5396f9de51e724d4a967..6315fe8404415c130cb82ab9d54a28dd23ffd5c1 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 #undef  VERSION
-#define VERSION "2.1.21"
+#define VERSION "2.1.22"
 #define BDATE   "24 June 2007"
 #define LSMDATE "24Jun07"
 
index 88918b4ba7308116f73d436b9c9f3633b3a22bbf..5f50e3fd11b472bca400c665f0f20662b96783d1 100644 (file)
@@ -603,7 +603,7 @@ statDir(const char *file, struct stat *sb)
 
    HANDLE h = INVALID_HANDLE_VALUE;
 
-   // use unicode or ascii
+   // use unicode
    if (p_FindFirstFileW) {
       POOLMEM* pwszBuf = get_pool_memory (PM_FNAME);
       make_win32_path_UTF8_2_wchar(&pwszBuf, file);
@@ -617,8 +617,9 @@ statDir(const char *file, struct stat *sb)
       pftLastAccessTime = &info_w.ftLastAccessTime;
       pftLastWriteTime  = &info_w.ftLastWriteTime;
       pftCreationTime   = &info_w.ftCreationTime;
-   }
-   else if (p_FindFirstFileA) {
+
+   // use ASCII
+   } else if (p_FindFirstFileA) {
       h = p_FindFirstFileA(file, &info_a);
 
       pdwFileAttributes = &info_a.dwFileAttributes;
@@ -629,127 +630,135 @@ statDir(const char *file, struct stat *sb)
       pftCreationTime   = &info_a.ftCreationTime;
    }
 
-    if (h == INVALID_HANDLE_VALUE) {
-        const char *err = errorString();
-        Dmsg2(99, "FindFirstFile(%s):%s\n", file, err);
-        LocalFree((void *)err);
-        errno = b_errno_win32;
-        return -1;
-    }
+   if (h == INVALID_HANDLE_VALUE) {
+      const char *err = errorString();
+      Dmsg2(99, "FindFirstFile(%s):%s\n", file, err);
+      LocalFree((void *)err);
+      errno = b_errno_win32;
+      return -1;
+   }
 
-    sb->st_mode = 0777;               /* start with everything */
-    if (*pdwFileAttributes & FILE_ATTRIBUTE_READONLY)
-        sb->st_mode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
-    if (*pdwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
-        sb->st_mode &= ~S_IRWXO; /* remove everything for other */
-    if (*pdwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
-        sb->st_mode |= S_ISVTX; /* use sticky bit -> hidden */
-    sb->st_mode |= S_IFDIR;
-
-    sb->st_size = *pnFileSizeHigh;
-    sb->st_size <<= 32;
-    sb->st_size |= *pnFileSizeLow;
-    sb->st_blksize = 4096;
-    sb->st_blocks = (uint32_t)(sb->st_size + 4095)/4096;
-
-    sb->st_atime = cvt_ftime_to_utime(*pftLastAccessTime);
-    sb->st_mtime = cvt_ftime_to_utime(*pftLastWriteTime);
-    sb->st_ctime = cvt_ftime_to_utime(*pftCreationTime);
-    FindClose(h);
+   sb->st_mode = 0777;               /* start with everything */
+   if (*pdwFileAttributes & FILE_ATTRIBUTE_READONLY)
+       sb->st_mode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
+   if (*pdwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
+       sb->st_mode &= ~S_IRWXO; /* remove everything for other */
+   if (*pdwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
+       sb->st_mode |= S_ISVTX; /* use sticky bit -> hidden */
+   sb->st_mode |= S_IFDIR;
 
-    return 0;
+   /* Use st_rdev to store reparse attribute */
+   sb->st_rdev = (*pdwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) ? 1 : 0; 
+
+
+   sb->st_size = *pnFileSizeHigh;
+   sb->st_size <<= 32;
+   sb->st_size |= *pnFileSizeLow;
+   sb->st_blksize = 4096;
+   sb->st_blocks = (uint32_t)(sb->st_size + 4095)/4096;
+
+   sb->st_atime = cvt_ftime_to_utime(*pftLastAccessTime);
+   sb->st_mtime = cvt_ftime_to_utime(*pftLastWriteTime);
+   sb->st_ctime = cvt_ftime_to_utime(*pftCreationTime);
+   FindClose(h);
+
+   return 0;
 }
 
 int
 fstat(int fd, struct stat *sb)
 {
-    BY_HANDLE_FILE_INFORMATION info;
-    char tmpbuf[1024];
+   BY_HANDLE_FILE_INFORMATION info;
+   char tmpbuf[1024];
 
-    if (!GetFileInformationByHandle((HANDLE)fd, &info)) {
-        const char *err = errorString();
-        Dmsg2(99, "GetfileInformationByHandle(%s): %s\n", tmpbuf, err);
-        LocalFree((void *)err);
-        errno = b_errno_win32;
-        return -1;
-    }
+   if (!GetFileInformationByHandle((HANDLE)fd, &info)) {
+       const char *err = errorString();
+       Dmsg2(99, "GetfileInformationByHandle(%s): %s\n", tmpbuf, err);
+       LocalFree((void *)err);
+       errno = b_errno_win32;
+       return -1;
+   }
 
-    sb->st_dev = info.dwVolumeSerialNumber;
-    sb->st_ino = info.nFileIndexHigh;
-    sb->st_ino <<= 32;
-    sb->st_ino |= info.nFileIndexLow;
-    sb->st_nlink = (short)info.nNumberOfLinks;
-    if (sb->st_nlink > 1) {
-       Dmsg1(99,  "st_nlink=%d\n", sb->st_nlink);
-    }
+   sb->st_dev = info.dwVolumeSerialNumber;
+   sb->st_ino = info.nFileIndexHigh;
+   sb->st_ino <<= 32;
+   sb->st_ino |= info.nFileIndexLow;
+   sb->st_nlink = (short)info.nNumberOfLinks;
+   if (sb->st_nlink > 1) {
+      Dmsg1(99,  "st_nlink=%d\n", sb->st_nlink);
+   }
 
-    sb->st_mode = 0777;               /* start with everything */
-    if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
-        sb->st_mode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
-    if (info.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
-        sb->st_mode &= ~S_IRWXO; /* remove everything for other */
-    if (info.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
-        sb->st_mode |= S_ISVTX; /* use sticky bit -> hidden */
-    sb->st_mode |= S_IFREG;
-
-    sb->st_size = info.nFileSizeHigh;
-    sb->st_size <<= 32;
-    sb->st_size |= info.nFileSizeLow;
-    sb->st_blksize = 4096;
-    sb->st_blocks = (uint32_t)(sb->st_size + 4095)/4096;
-    sb->st_atime = cvt_ftime_to_utime(info.ftLastAccessTime);
-    sb->st_mtime = cvt_ftime_to_utime(info.ftLastWriteTime);
-    sb->st_ctime = cvt_ftime_to_utime(info.ftCreationTime);
+   sb->st_mode = 0777;               /* start with everything */
+   if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
+       sb->st_mode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
+   if (info.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
+       sb->st_mode &= ~S_IRWXO; /* remove everything for other */
+   if (info.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
+       sb->st_mode |= S_ISVTX; /* use sticky bit -> hidden */
+   sb->st_mode |= S_IFREG;
+
+   /* Use st_rdev to store reparse attribute */
+   sb->st_rdev = (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) ? 1 : 0; 
+
+   sb->st_size = info.nFileSizeHigh;
+   sb->st_size <<= 32;
+   sb->st_size |= info.nFileSizeLow;
+   sb->st_blksize = 4096;
+   sb->st_blocks = (uint32_t)(sb->st_size + 4095)/4096;
+   sb->st_atime = cvt_ftime_to_utime(info.ftLastAccessTime);
+   sb->st_mtime = cvt_ftime_to_utime(info.ftLastWriteTime);
+   sb->st_ctime = cvt_ftime_to_utime(info.ftCreationTime);
 
-    return 0;
+   return 0;
 }
 
 static int
 stat2(const char *file, struct stat *sb)
 {
-    HANDLE h;
-    int rval = 0;
-    char tmpbuf[1024];
-    conv_unix_to_win32_path(file, tmpbuf, 1024);
+   HANDLE h;
+   int rval = 0;
+   char tmpbuf[1024];
+   conv_unix_to_win32_path(file, tmpbuf, 1024);
 
-    DWORD attr = (DWORD)-1;
+   DWORD attr = (DWORD)-1;
 
-    if (p_GetFileAttributesW) {
+   if (p_GetFileAttributesW) {
       POOLMEM* pwszBuf = get_pool_memory(PM_FNAME);
       make_win32_path_UTF8_2_wchar(&pwszBuf, tmpbuf);
 
       attr = p_GetFileAttributesW((LPCWSTR) pwszBuf);
       free_pool_memory(pwszBuf);
-    } else if (p_GetFileAttributesA) {
-       attr = p_GetFileAttributesA(tmpbuf);
-    }
+   } else if (p_GetFileAttributesA) {
+      attr = p_GetFileAttributesA(tmpbuf);
+   }
 
-    if (attr == (DWORD)-1) {
-        const char *err = errorString();
-        Dmsg2(99, "GetFileAttributes(%s): %s\n", tmpbuf, err);
-        LocalFree((void *)err);
-        errno = b_errno_win32;
-        return -1;
-    }
+   if (attr == (DWORD)-1) {
+      const char *err = errorString();
+      Dmsg2(99, "GetFileAttributes(%s): %s\n", tmpbuf, err);
+      LocalFree((void *)err);
+      errno = b_errno_win32;
+      return -1;
+   }
 
-    if (attr & FILE_ATTRIBUTE_DIRECTORY)
-        return statDir(tmpbuf, sb);
+   if (attr & FILE_ATTRIBUTE_DIRECTORY) {
+      return statDir(tmpbuf, sb);
+   }
 
-    h = CreateFileA(tmpbuf, GENERIC_READ,
-                   FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
+   h = CreateFileA(tmpbuf, GENERIC_READ,
+                  FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
 
-    if (h == INVALID_HANDLE_VALUE) {
-        const char *err = errorString();
-        Dmsg2(99, "Cannot open file for stat (%s):%s\n", tmpbuf, err);
-        LocalFree((void *)err);
-        errno = b_errno_win32;
-        return -1;
-    }
+   if (h == INVALID_HANDLE_VALUE) {
+      const char *err = errorString();
+      Dmsg2(99, "Cannot open file for stat (%s):%s\n", tmpbuf, err);
+      LocalFree((void *)err);
+      errno = b_errno_win32;
+      return -1;
+   }
 
-    rval = fstat((int)h, sb);
-    CloseHandle(h);
-    return rval;
+   rval = fstat((int)h, sb);
+   CloseHandle(h);
+
+   return rval;
 }
 
 int
@@ -803,6 +812,9 @@ stat(const char *file, struct stat *sb)
       sb->st_mode |= S_IFREG;
    }
 
+   /* Use st_rdev to store reparse attribute */
+   sb->st_rdev = (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) ? 1 : 0; 
+
    sb->st_nlink = 1;
    sb->st_size = data.nFileSizeHigh;
    sb->st_size <<= 32;
@@ -815,6 +827,12 @@ stat(const char *file, struct stat *sb)
    return 0;
 }
 
+/*
+ * We write our own ftruncate because the one in the
+ *  Microsoft library mrcrt.dll does not truncate
+ *  files greater than 2GB.
+ *  KES - May 2007
+ */
 int win32_ftruncate(int fd, int64_t length) 
 {
    /* Set point we want to truncate file */
@@ -961,6 +979,7 @@ gettimeofday(struct timeval *tv, struct timezone *)
 {
     SYSTEMTIME now;
     FILETIME tmp;
+
     GetSystemTime(&now);
 
     if (tv == NULL) {
@@ -977,8 +996,8 @@ gettimeofday(struct timeval *tv, struct timezone *)
     _100nsec |= tmp.dwLowDateTime;
     _100nsec -= WIN32_FILETIME_ADJUST;
 
-    tv->tv_sec =(long) (_100nsec / 10000000);
-    tv->tv_usec = (long) ((_100nsec % 10000000)/10);
+    tv->tv_sec = (long)(_100nsec / 10000000);
+    tv->tv_usec = (long)((_100nsec % 10000000)/10);
     return 0;
 
 }
index 808fe337db3734aa216b26ebe7a56aba17ba270f..6beafd1fd5abff95ebfc001682286f060021a52a 100644 (file)
@@ -1,7 +1,16 @@
               Technical notes on version 2.1
 
 General:
+Release 2.1.22 beta Win32 binaries only:
 24Jun07
+kes  Implement Windows reparse points -- similar to directories, but
+     we do not descend into it. This is a first cut. They seem to 
+     be backed up, but restore is not yet tested.
+kes  Remove restore_blocking in tls code when shutting a socket to leave
+     it in blocking mode. Hopefully this will fix the encryption bug  
+     reported by Frank Sweetser.
+kes  When opening a file for backup, tell the OS that we are going to
+     read it sequentially -- optimization.
 kes  Change variable names in authenticate_director() to not conflict
      with member names in bat. Caused great confusion with compiler,
      but no warnings.
@@ -17,9 +26,9 @@ kes  Add Swedish sv.po file
 21Jun07
 kes  Don't print clock skew message in FD if less than 3 seconds diff.
 kes  Add a bit of VSS info to status client.
-kes  Make a gross first cut of Vista VSS, using Win2003 code.
+kes  Implement a first cut of Vista VSS, using Win2003 code.
 
-Release: 2.1.18 beta
+Release: 2.1.20 beta
 20Jun07
 kes  Fixed bug #886 (multidrive autochanger: SD doesn't use drive with
      loaded tape but uses first drive).