summaryrefslogtreecommitdiff
path: root/Core/Unix/Solaris/CoreSolaris.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Core/Unix/Solaris/CoreSolaris.cpp')
-rw-r--r--Core/Unix/Solaris/CoreSolaris.cpp174
1 files changed, 174 insertions, 0 deletions
diff --git a/Core/Unix/Solaris/CoreSolaris.cpp b/Core/Unix/Solaris/CoreSolaris.cpp
new file mode 100644
index 0000000..63736db
--- /dev/null
+++ b/Core/Unix/Solaris/CoreSolaris.cpp
@@ -0,0 +1,174 @@
+/*
+ Copyright (c) 2008-2009 TrueCrypt Developers Association. All rights reserved.
+
+ Governed by the TrueCrypt License 3.0 the full text of which is contained in
+ the file License.txt included in TrueCrypt binary and source code distribution
+ packages.
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/mount.h>
+#include <sys/mntent.h>
+#include <sys/mnttab.h>
+#include "CoreSolaris.h"
+#include "Core/Unix/CoreServiceProxy.h"
+
+namespace TrueCrypt
+{
+ CoreSolaris::CoreSolaris ()
+ {
+ }
+
+ CoreSolaris::~CoreSolaris ()
+ {
+ }
+
+ DevicePath CoreSolaris::AttachFileToLoopDevice (const FilePath &filePath, bool readOnly) const
+ {
+ list <string> args;
+ args.push_back ("-a");
+ args.push_back (filePath);
+
+ return StringConverter::Trim (Process::Execute ("lofiadm", args));
+ }
+
+ void CoreSolaris::DetachLoopDevice (const DevicePath &devicePath) const
+ {
+ list <string> args;
+ args.push_back ("-d");
+ args.push_back (devicePath);
+
+ for (int t = 0; true; t++)
+ {
+ try
+ {
+ Process::Execute ("lofiadm", args);
+ break;
+ }
+ catch (ExecutedProcessFailed&)
+ {
+ if (t > 5)
+ throw;
+ Thread::Sleep (200);
+ }
+ }
+ }
+
+ HostDeviceList CoreSolaris::GetHostDevices (bool pathListOnly) const
+ {
+ HostDeviceList devices;
+
+ foreach_ref (const FilePath &devPath, Directory::GetFilePaths ("/dev/rdsk", false))
+ {
+ string drivePath = devPath;
+ if (drivePath.rfind ("p0") == drivePath.size() - 2)
+ {
+ make_shared_auto (HostDevice, device);
+ device->Path = drivePath;
+
+ try
+ {
+ device->Size = GetDeviceSize (device->Path);
+ }
+ catch (...)
+ {
+ device->Size = 0;
+ }
+
+ if (device->Size == 0)
+ continue;
+
+ device->MountPoint = GetDeviceMountPoint (device->Path);
+ device->SystemNumber = 0;
+
+ devices.push_back (device);
+
+ for (int partNumber = 1; partNumber <= 32; partNumber++)
+ {
+ stringstream partPath;
+ partPath << drivePath.substr (0, drivePath.size() - 1) << partNumber;
+
+ if (FilesystemPath (partPath.str()).IsBlockDevice() || FilesystemPath (partPath.str()).IsCharacterDevice())
+ {
+ make_shared_auto (HostDevice, partition);
+ partition->Path = partPath.str();
+
+ try
+ {
+ partition->Size = GetDeviceSize (partition->Path);
+ }
+ catch (...)
+ {
+ partition->Size = 0;
+ }
+
+ if (partition->Size == 0)
+ continue;
+
+ partition->MountPoint = GetDeviceMountPoint (partition->Path);
+ partition->SystemNumber = 0;
+
+ device->Partitions.push_back (partition);
+ }
+ }
+ }
+ }
+
+ return devices;
+ }
+
+ MountedFilesystemList CoreSolaris::GetMountedFilesystems (const DevicePath &devicePath, const DirectoryPath &mountPoint) const
+ {
+ MountedFilesystemList mountedFilesystems;
+
+ FILE *mtab = fopen ("/etc/mnttab", "r");
+ throw_sys_sub_if (!mtab, "/etc/mnttab");
+ finally_do_arg (FILE *, mtab, { fclose (finally_arg); });
+
+ int getmntentResult;
+ struct mnttab entry;
+ while ((getmntentResult = getmntent (mtab, &entry)) == 0)
+ {
+ make_shared_auto (MountedFilesystem, mf);
+
+ if (entry.mnt_special)
+ mf->Device = DevicePath (entry.mnt_special);
+ else
+ continue;
+
+ if (entry.mnt_mountp)
+ mf->MountPoint = DirectoryPath (entry.mnt_mountp);
+
+ if (entry.mnt_fstype)
+ mf->Type = entry.mnt_fstype;
+
+ if ((devicePath.IsEmpty() || devicePath == mf->Device) && (mountPoint.IsEmpty() || mountPoint == mf->MountPoint))
+ mountedFilesystems.push_back (mf);
+ }
+
+ throw_sys_if (getmntentResult > 0);
+
+ return mountedFilesystems;
+ }
+
+ void CoreSolaris::MountFilesystem (const DevicePath &devicePath, const DirectoryPath &mountPoint, const string &filesystemType, bool readOnly, const string &systemMountOptions) const
+ {
+ try
+ {
+ // Try to mount FAT by default as mount is unable to probe filesystem type on Solaris
+ CoreUnix::MountFilesystem (devicePath, mountPoint, filesystemType.empty() ? "pcfs" : filesystemType, readOnly, systemMountOptions);
+ }
+ catch (ExecutedProcessFailed&)
+ {
+ if (!filesystemType.empty())
+ throw;
+
+ CoreUnix::MountFilesystem (devicePath, mountPoint, filesystemType, readOnly, systemMountOptions);
+ }
+ }
+
+ auto_ptr <CoreBase> Core (new CoreServiceProxy <CoreSolaris>);
+ auto_ptr <CoreBase> CoreDirect (new CoreSolaris);
+}