// compute the name of the lock file for this file
CC_SHA1_CTX ctx;
CC_SHA1_Init(&ctx);
- CC_SHA1_Update(&ctx, (const void*) mFile.c_str(), mFile.length());
+ CC_SHA1_Update(&ctx, (const void*) mFile.c_str(), (CC_LONG)mFile.length());
u_int8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1_Final(digest, &ctx);
}
}
-static std::string RemoveDoubleSlashes(const std::string &path)
-{
- std::string result;
- unsigned i;
- for (i = 0; i < path.length(); ++i)
- {
- result += path[i];
- if ((i < path.length() - 2) && path[i] == '/' && path[i + 1] == '/')
- {
- i += 1; // skip a second '/'
- }
- }
-
- return result;
-}
-
-
-
//
// Make sure the directory up to inDir exists inDir *must* end in a slash.
//
void
AtomicFile::mkpath(const std::string &inDir, mode_t mode)
{
- for (std::string::size_type pos = 0; (pos = inDir.find('/', pos + 1)) != std::string::npos;)
- {
- std::string path = inDir.substr(0, pos);
- const char *cpath = path.c_str();
- struct stat sb;
- if (::stat(cpath, &sb))
- {
- // if we are creating a path in the user's home directory, override the user's mode
- std::string homedir = getenv("HOME");
-
- // canonicalize the path (remove double slashes)
- string canonPath = RemoveDoubleSlashes(cpath);
-
- if (canonPath.find(homedir, 0) == 0)
- {
- mode = 0700;
- }
-
- if (errno != ENOENT || ::mkdir(cpath, mode))
- UnixError::throwMe(errno);
- }
- else if (!S_ISDIR(sb.st_mode))
- CssmError::throwMe(CSSM_ERRCODE_OS_ACCESS_DENIED); // @@@ Should be is a directory
- }
+ // see if the file already exists and is a directory
+ struct stat st;
+ int result = stat(inDir.c_str(), &st);
+
+ if (result == 0) // file exists
+ {
+ if ((st.st_mode & S_IFDIR) == 0)
+ {
+ // whatever was there, it wasn't a directory. That's really bad, so complain
+ syslog(LOG_ALERT, "Needed a directory at %s, but the file that was there was not one.\n", inDir.c_str());
+ UnixError::throwMe(ENOTDIR);
+ }
+ }
+ else
+ {
+ // the file did not exist, try to create it
+ result = mkpath_np(inDir.c_str(), 0777); // make the directory with umask
+ if (result != 0)
+ {
+ // mkpath_np does not set errno, you have to look at the result.
+ UnixError::throwMe(result);
+ }
+ }
+
+ // Double check and see if we got what we hoped for
+ result = stat(inDir.c_str(), &st);
+ if (result != 0)
+ {
+ UnixError::throwMe(errno);
+ }
+
+ if ((st.st_mode & S_IFDIR) == 0)
+ {
+ // we didn't create a dictionary? That's curious...
+ syslog(LOG_ALERT, "Failed to create a directory when we asked for one to be created at %s\n", inDir.c_str());
+ UnixError::throwMe(ENOTDIR);
+ }
}
int
}
else
{
- munmap(mBuffer, mLength);
+ munmap(mBuffer, (size_t)mLength);
}
}
lseek(mFileRef, 0, SEEK_SET);
ssize_t pos = 0;
- ssize_t bytesToRead = mLength;
+ ssize_t bytesToRead = (ssize_t)mLength;
while (bytesToRead > 0)
{
ssize_t bytesRead = ::read(mFileRef, mBuffer + pos, bytesToRead);
else
{
// mmap the buffer into place
- mBuffer = (uint8*) mmap(NULL, mLength, PROT_READ, MAP_PRIVATE, mFileRef, 0);
+ mBuffer = (uint8*) mmap(NULL, (size_t)mLength, PROT_READ, MAP_PRIVATE, mFileRef, 0);
if (mBuffer == (uint8*) -1)
{
int error = errno;
secdebug("atomicfile", "%p allocated %s buffer %p size %qd", this, mPath.c_str(), mBuffer, bytesLeft);
- ssize_t maxEnd = inOffset + inLength;
+ off_t maxEnd = inOffset + inLength;
if (maxEnd > mLength)
{
maxEnd = mLength;
// put the dir into a canonical form
string dir = mFile.dir();
- int i = dir.length() - 1;
+ int i = (int)dir.length() - 1;
// walk backwards until we get to a non / character
while (i >= 0 && dir[i] == '/')