Implementing FUSE - fuse

I want to implement a file system using FUSE. When the contents of the directory is requested, only the types of files in that directory will be reported as subdirectories. For example, if there are ugur.PDF, guler.JPG and devatate.PNG files in the directory, the files themselves will not be reported, but types (PDF, JPG and PNG) will be reported instead. I tried to implement this file system. My problem is i can not imagine that how can i report without changing ls-l command? how does ls-l command work? (I have a readdir function and it loads file_type and file_name to buffer. I tried to change but i couldn't achive)

How does ls -l work? That seems to be the crux of the issue. It calls fstat(2). That system call fills the stat structure. When you implement a fuse provider, you are providing the data that ends up in the stat structure. If you want to change the directory structure, you return the necessary fabricated information for the various items.

I can think of two approaches to this:
1. Use a database like SQLite
you can store the files, path and file types in the database. Then when the user gets into some directory, you can say do some query like select file_types where path="" and populate as directories using filler()
2. Recursively traverse original path
you can create a list of all file types in the current directory, then use filler() to post them as directories. Then, when user enters any one directory, you can again do a check or something to see if cur_path is in last_path(orig directory), and you can select those file types and display them

Related

How do I get the filename of an open std::fs::File in Rust?

I have an open std::fs::File, and I want to get it's filename, e.g. as a PathBuf. How do I do that?
The simple solution would be to just save the path used in the call to File::open. Unfortunately, this does not work for me. I am trying to write a program that reads log files, and the program that writes the logs keep changing the filenames as part of it's log rotation. So the file may very well have been renamed since it was opened. This is on Linux, so renaming open files is possible.
How do I get around this issue, and get the current filename of an open file?
On a typical Unix filesystem, a file may have multiple filenames at once, or even none at all. The file metadata is stored in an inode, which has a unique inode number, and this inode number can be linked from any number of directory entries. However, there are no reverse links from the inode back to the directory entries.
Given an open File object in Rust, you can get the inode number using the ino() method. If you know the directory the log file is in, you can use std::fs::read_dir() to iterate over all entries in that directory, and each entry will also have an ino() method, so you can find the one(s) matching your open file object. Of course this approach is subject to race conditions – the directory entry may already be gone again once you try to do anything with it.
On linux, files handles held by the current process can be found under /proc/self/fd. These look and act like symlinks to the original files (though I think they may technically be something else - perhaps someone who knows more can chip in).
You can therefore recover the (possibly changed) file name by constructing the correct path in /proc/self/fd using your file descriptor, and then following the symlink back to the filesystem.
This snippet shows the steps:
use std::fs::read_link;
use std::os::unix::io::AsRawFd;
use std::path::PathBuf;
// if f is your std::fs::File
// first construct the path to the symlink under /proc
let path_in_proc = PathBuf::from(format!("/proc/self/fd/{}", f.as_raw_fd()));
// ...and follow it back to the original file
let new_file_name = read_link(path_in_proc).unwrap();

Permission denied when attempt to create/remove/rename files in write-only directory

There are tons of posts on the net saying that write permission on directory allows affected user to create/remove/rename files in that directory, but I found that it actually could not be done without execute permission set. I tried calling open/fopen/remove/rename, but without exception, they all failed.
There should be something I missed or something I misunderstood. There are some explanation that operations on directory usually involves with file operation. If it was right, I wonder what operation is involved. If directory maintains mappings from filename to inode, it seems no reason that file operation is involved when renaming.
If unexpected file operation is involved, is it possible to manipulate directory directly, bypassing such operations?
You are right, the net is full of wrong things and especially for unix file permission rules. The first links I found with a common search engine were all wrong. Very interesting!
What file permissions on directories means:
x you have "access" to the files in this directory which means you can use them. If you do not have read access but access rights, you can work with a file which you know but you can't see!
mkdir one
touch one/x.h
chmod -r one
ls one // fails!
cat one/x.h // works!
and write permission is used for changing the content of the directory. So adding and removing files from the dir is only possible if you have write permission on that dir!
Because it is impossible to read/write/execute a file which is inside a dir which you can't access, you always need access rights for the dir to work with the files inside.
Sounds a bit strange, but is simply implemented that way.

How to determine if file system path is directory or file?

I'm looking to determine if a file system path is directory or file. I'm not looking to checking for the type an existing path. I'm trying to determine if the path function argument string is a referring to a directory or file.
How do I make a distinction between a file and a directory when this:
/Users/thomas/Desktop/node
The following path could refer to a directory node, or a file node without an extension.
I was thinking about using a trailing / to connote directory.
So this would mean a directory:
/Users/thomas/Desktop/node/
And this would mean a file:
/Users/thomas/Desktop/node
However node's path methods like .resolve() and .join() do not take into consideration the trailing / and always remove it. So is this good practice?
There is no way to check if an arbitrary string is a directory or file if it does not exist.
However for existing paths, you can use fs.stat() on the path, which will give you an object that has methods for checking the path type (e.g. isDirectory(), isFile(), etc).

Linux: what is link

I'm new in Linux I'm just using windwos GUI before but I have a question: what is LINK in Linux? I know it have tow type but I don't know what is the advantage of them normally in windows has shortcut to reference app from the difference path if LINK in Linux have the same feature why it have tow type?
Thank you to answer.
First You should be know what is Inode ? to understand advantage of link type let me
An inode is an entry in inodetable, containing information ( the metadata ) about a regular file and directory. An inode is a data structure on a traditional Linux file system such as ext3 or ext4.
Inode number also called as index number , it consists following attributes.
File types ( executable, block special etc)
Permissions ( read, write etc)
UID ( Owner )
GID ( Group )
FileSize
Time stamps including last access, last modification and last
inode number change.
File deletion time
Number of links ( soft/hard )
Location of file on harddisk.
Some other metadata about file.
to Display Inode use this command+flags
ls –il
What is a link?
A link is simply a way to refer to the contents of a file.
Types of link:
Hardlink(Another name for the file/inode in the disk)
Softlink/symbolic link (Pointer to the file location)
How to create Links in linux ?
Hard link ln existingfile newfile
Note : Hardlinksare not allowed for directories
Soft link ln –s existingfile newfile
A soft link will have a different Inode number than the source file, which will be having a pointer to the source file but hard link will be using the same Inode number as the source file.
Soft link is like shortcut in windows. It doesn’t contain any information about the destination file or contents of the file, instead of that, it simply contains the pointer to the location of the destination file.
Soft Links You can make links for files & folder & you can create link (shortcut) on different partition & got different inode number from original.
If real copy is deleted the link will not work.
Hard Links
For files only & you cannot create on different partition ( it should be on same partition ) & got same inode number as original
If therealcopy is deleted the link will work( because it act as original file )
There are two types because it evolved that way -- and they are implemented differently:
hard links came first. Every file is represented in a directory file by a name and inode value. Think of inode as the disk-address or block number. A hard-linked file's inode is in more than one directory file (or more than once in a given directory file, using a different filename), and each directory entry is the "same" file (different names, of course).
symbolic links came later. They are a special entry in a directory file which have the name of another file rather than an inode value.
There is a clear distinction between a symbolic link and the actual file to which it points: if you remove the file, you have a broken link. This is different from hard links - removing one name will not damage the other(s).
Links are a very handy way to create a shortcut to an original directory. Links are used in many instances: Sometimes to create a convenient path to a directory buried deep within the file hierarchy; other uses for links include:
Linking libraries
Making sure files are in constant locations (without having to move the original)
Keeping a “copy” of a single file in multiple locations.
In Linux there are two different types of links:
Hard links
Symbolic links
The difference between the two are significant. With hard links, you can only link to files (and not directories); you cannot reference a file on a different disk or volume, and they reference the same inode as the original source. A hard link will continue to remain usable, even if the original file is removed.
Symbolic links, on the other hand, can link to directories, reference a file/folder on a different disk or volume, will exist as a broken (unusable) link if the original location is deleted, reference abstract filenames and directories (as opposed to physical locations), and are given their own, unique inode.

Adding files to sourcecontrol on linux using cleartool

I have a file that i want to add to sourcecontrol on linux using cleartool .
I've followed the IBM documentation for this, i've tried this:
cleartool mkelem testScript.sh
I got an error: Can't modify directory "." because it is not checked out.
I also would like to know how can i checkout/checkin files or directories and setting activities.
You need to checkout the parent folder first.
cd /path/to/file/
cleartool mkact newfile
cleartool checkout -c "add file" .
cleartool mkelem testScript.sh
cleartool checkin -nc
The cleartool mkact would work if you are in an UCM view.
It will create and set a new activity, which will record the files and folder you will modify.
Here, the new activity newFile will record the new version of the parent folder, as well as the version 0 and 1 of the file.
You should create separate questions for .. separate questions...
Going back to the original - the reason why it isn't working is, as VonC has pointed out, you haven't checked out the parent of the file. Remember, when you run "cleartool mkelem", you are about to modify the contents of the parent directory (. in this case) by adding a new "pointer" to the element you're now creating. As with everything else in clearcase, when you want to modify the contents of an element, you have to check it out first.
One of ClearCase's greatest strength (and hardest to wrap one's head around) is the concept of an "element", IMO. "Everything" behaves similarly with an element. Making any change to an "element" (file or directory) means you have to check it out first to make that change.
In the case of a file, that's easy to grasp - you're just editing lines in a file. For a directory, it's almost as easy - you can think of a directory as just a list of pointers to data blobs. We make the name of the blob something convenient we can remember (like foo.java or myapplication.cc or README.md). But we can also change the name of the pointer (even though it points to the same data blob) by renaming a file. We can remove the pointer to the blob without impacting the blob itself by using "rmname". That's essentially what "rmname" does.
In ClearCases' case, the mkelem command is a little bit special - it creates the initial datablob, and adds a pointer to that datablob in the current directory (kind of does 2 things at once).

Resources