~ubuntu-branches/ubuntu/oneiric/bombono-dvd/oneiric

« back to all changes in this revision

Viewing changes to libs/boost-lib/libs/filesystem/v3/src/unique_path.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessio Treglia
  • Date: 2010-11-04 11:46:25 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20101104114625-2tfaxma74eqggp5r
Tags: 0.8.0-0ubuntu1
* New upstream release (LP: #670193).
* Refresh 02_sparc.diff patch.
* Replace 05-boost_filesystem-link.patch with 05-fix_boost.patch, it fixes
  build failure with Boost <= 1.44.
* Bump Standards.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//  filesystem system_crypt_random.cpp  ------------------------------------------------//
 
2
 
 
3
//  Copyright Beman Dawes 2010
 
4
 
 
5
//  Distributed under the Boost Software License, Version 1.0.
 
6
//  See http://www.boost.org/LICENSE_1_0.txt
 
7
 
 
8
//  Library home page: http://www.boost.org/libs/filesystem
 
9
 
 
10
//--------------------------------------------------------------------------------------// 
 
11
 
 
12
#include <boost/config.hpp>
 
13
#if !defined( BOOST_NO_STD_WSTRING )
 
14
// Boost.Filesystem V3 and later requires std::wstring support.
 
15
// During the transition to V3, libraries are compiled with both V2 and V3 sources.
 
16
// On old compilers that don't support V3 anyhow, we just skip everything so the compile
 
17
// will succeed and the library can be built.
 
18
 
 
19
// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows
 
20
// the library is being built (possibly exporting rather than importing code)
 
21
#define BOOST_FILESYSTEM_SOURCE 
 
22
 
 
23
#ifndef BOOST_SYSTEM_NO_DEPRECATED 
 
24
# define BOOST_SYSTEM_NO_DEPRECATED
 
25
#endif
 
26
 
 
27
#include <boost/filesystem/v3/operations.hpp>
 
28
 
 
29
# ifdef BOOST_POSIX_API
 
30
#   include <fcntl.h>
 
31
# else // BOOST_WINDOWS_API
 
32
#   include <windows.h>
 
33
#   include <wincrypt.h>
 
34
#   pragma comment(lib, "Advapi32.lib")
 
35
# endif
 
36
 
 
37
namespace {
 
38
 
 
39
void fail(int err, boost::system::error_code* ec)
 
40
{
 
41
  if (ec == 0)
 
42
    BOOST_FILESYSTEM_THROW( boost::system::system_error(err,
 
43
      boost::system::system_category(),
 
44
      "boost::filesystem::unique_path"));
 
45
 
 
46
  ec->assign(err, boost::system::system_category());
 
47
  return;
 
48
}
 
49
 
 
50
void system_crypt_random(void* buf, std::size_t len, boost::system::error_code* ec)
 
51
{
 
52
# ifdef BOOST_POSIX_API
 
53
 
 
54
  int file = open("/dev/urandom", O_RDONLY);
 
55
  if (file == -1)
 
56
  {
 
57
    file = open("/dev/random", O_RDONLY);
 
58
    if (file == -1)
 
59
    {
 
60
      fail(errno, ec);
 
61
      return;
 
62
    }
 
63
  }
 
64
 
 
65
  size_t bytes_read = 0;
 
66
  while (bytes_read < len)
 
67
  {
 
68
    ssize_t n = read(file, buf, len - bytes_read);
 
69
    if (n == -1)
 
70
    {
 
71
      close(file);
 
72
      fail(errno, ec);
 
73
      return;
 
74
    }
 
75
    bytes_read += n;
 
76
    buf = static_cast<char*>(buf) + n;
 
77
  }
 
78
 
 
79
  close(file);
 
80
 
 
81
# else // BOOST_WINDOWS_API
 
82
 
 
83
  HCRYPTPROV handle;
 
84
  int errval = 0;
 
85
 
 
86
  if (!::CryptAcquireContextW(&handle, 0, 0, PROV_RSA_FULL, 0))
 
87
  {
 
88
    errval = ::GetLastError();
 
89
    if (errval == NTE_BAD_KEYSET)
 
90
    {
 
91
      if (!::CryptAcquireContextW(&handle, 0, 0, PROV_RSA_FULL, CRYPT_NEWKEYSET))
 
92
      {
 
93
        errval = ::GetLastError();
 
94
      }
 
95
      else errval = 0;
 
96
    }
 
97
  }
 
98
 
 
99
  if (!errval)
 
100
  {
 
101
    BOOL gen_ok = ::CryptGenRandom(handle, len, static_cast<unsigned char*>(buf));
 
102
    if (!gen_ok)
 
103
      errval = ::GetLastError();
 
104
    ::CryptReleaseContext(handle, 0);
 
105
  }
 
106
 
 
107
  if (!errval) return;
 
108
 
 
109
  fail(errval, ec);
 
110
# endif
 
111
}
 
112
 
 
113
}  // unnamed namespace
 
114
 
 
115
namespace boost { namespace filesystem3 { namespace detail {
 
116
 
 
117
BOOST_FILESYSTEM_DECL
 
118
path unique_path(const path& model, system::error_code* ec)
 
119
{
 
120
  std::wstring s (model.wstring());  // std::string ng for MBCS encoded POSIX
 
121
  const wchar_t hex[] = L"0123456789abcdef";
 
122
  const int n_ran = 16;
 
123
  const int max_nibbles = 2 * n_ran;   // 4-bits per nibble
 
124
  char ran[n_ran];
 
125
 
 
126
  int nibbles_used = max_nibbles;
 
127
  for(std::wstring::size_type i=0; i < s.size(); ++i)
 
128
  {
 
129
    if (s[i] == L'%')                        // digit request
 
130
    {
 
131
      if (nibbles_used == max_nibbles)
 
132
      {
 
133
        system_crypt_random(ran, sizeof(ran), ec);
 
134
        if (ec != 0 && *ec)
 
135
          return "";
 
136
        nibbles_used = 0;
 
137
      }
 
138
      int c = ran[nibbles_used/2];
 
139
      c >>= 4 * (nibbles_used++ & 1);  // if odd, shift right 1 nibble
 
140
      s[i] = hex[c & 0xf];             // convert to hex digit and replace
 
141
    }
 
142
  }
 
143
 
 
144
  if (ec != 0) ec->clear();
 
145
 
 
146
  return s;
 
147
}
 
148
 
 
149
}}}
 
150
 
 
151
#endif  // no wide character support