Add more paths in getRootPaths for Linux

This commit is contained in:
FreeSlave 2016-04-02 00:43:18 +03:00
parent e525e13e73
commit 67ccdc54a2
1 changed files with 95 additions and 0 deletions

View File

@ -115,6 +115,54 @@ struct RootEntry {
return path;
}
version(linux)
{
import core.stdc.stdio : FILE;
struct mntent
{
char *mnt_fsname; /* Device or server for filesystem. */
char *mnt_dir; /* Directory mounted on. */
char *mnt_type; /* Type of filesystem: ufs, nfs, etc. */
char *mnt_opts; /* Comma-separated options for fs. */
int mnt_freq; /* Dump frequency (in days). */
int mnt_passno; /* Pass number for `fsck'. */
};
extern(C) @nogc nothrow
{
FILE *setmntent(const char *file, const char *mode);
mntent *getmntent(FILE *stream);
mntent *getmntent_r(FILE * stream, mntent *result, char * buffer, int bufsize);
int addmntent(FILE* stream, const mntent *mnt);
int endmntent(FILE * stream);
char *hasmntopt(const mntent *mnt, const char *opt);
}
string unescapeLabel(string label)
{
import std.string : replace;
return label.replace("\\x20", " ")
.replace("\\x9", " ") //actually tab
.replace("\\x5c", "\\")
.replace("\\xA", " "); //actually newline
}
bool isSpecialFileSystem(const(char)[] dir, const(char)[] type)
{
import std.string : startsWith;
if (dir.startsWith("/dev") || dir.startsWith("/proc") || dir.startsWith("/sys") ||
dir.startsWith("/var/run") || dir.startsWith("/var/lock"))
{
return true;
}
if (type == "tmpfs" || type == "rootfs" || type == "rpc_pipefs") {
return true;
}
return false;
}
}
/// returns array of system root entries
@property RootEntry[] getRootPaths() {
RootEntry[] res;
@ -122,6 +170,53 @@ struct RootEntry {
version (Posix) {
res ~= RootEntry(RootEntryType.ROOT, "/", "File System"d);
}
version(linux) {
import std.string : fromStringz;
import std.format : format;
mntent ent;
char[1024] buf;
FILE* f = setmntent("/etc/mtab", "r");
if (f) {
scope(exit) endmntent(f);
while(getmntent_r(f, &ent, buf.ptr, cast(int)buf.length) !is null) {
auto fsName = fromStringz(ent.mnt_fsname);
auto mountDir = fromStringz(ent.mnt_dir);
auto type = fromStringz(ent.mnt_type);
if (mountDir == "/" || //root is already added
isSpecialFileSystem(mountDir, type)) //don't list special file systems
{
continue;
}
string label;
enum byLabel = "/dev/disk/by-label";
try {
foreach(entry; dirEntries(byLabel, SpanMode.shallow))
{
if (entry.isSymlink) {
auto normalized = buildNormalizedPath(byLabel, entry.readLink);
if (normalized == fsName) {
label = entry.name.baseName.unescapeLabel();
}
}
}
} catch(Exception e) {
}
if (!label.length) {
label = format("%s volume", type);
}
auto entryType = (type == "vfat") ? RootEntryType.REMOVABLE : RootEntryType.FIXED; //just a guess
res ~= RootEntry(entryType, mountDir.idup, label.toUTF32);
}
}
}
version (Windows) {
import win32.windows;
uint mask = GetLogicalDrives();