Tutorial Linux Part 6: Fuse pada Linux


Selamat datang kembali pada tutorial Linux. Kali ini, saya akan membahas tentang FUSE yang memliki kepanjang File System User Space. Disini akan saya tunjukkan bagaimana cara membuat file system sendiri di Linux dengan menggunakan FUSE. Di bawah ini akan saya tunjukkan implementasi dasar FUSE pada bahasa C.

#include <fuse.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <sys/statfs.h>
static const char *dirpath = "/home/user/Documents";
static int xmp_getattr(const char *path, struct stat *stbuf)
{
int res;
char fpath[1000];
sprintf(fpath,"%s%s", dirpath, path);
res = lstat(fpath, stbuf);
if(res == -1)
return -errno;
return 0;
}
static int xmp_readlink(const char *path, char *buf, size_t size)
{
int res;
char fpath[1000];
sprintf(fpath,"%s%s", dirpath, path);
res = readlink(fpath, buf, size - 1);
if(res == -1)
return -errno;
buf[res] = '\0';
return 0;
}
static int xmp_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler)
{
char fpath[1000];
if(strcmp(path,"/") == 0){ // jika root
path=dirpath;
sprintf(fpath,"%s", path);
}
else sprintf(fpath, "%s%s", dirpath, path);
int res = 0;
DIR *dp;
struct dirent *de;
dp = opendir(fpath);
if(dp == NULL)
return -errno;
while((de = readdir(dp)) != NULL){ // membaca tiap direktori
res = filler(h, de->d_name, de->d_type);
if(res != 0)
break;
}
system("notify-send Hai_Cintaku");
closedir(dp);
return res;
}
static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
{
int res;
char fpath[1000];
sprintf(fpath,"%s%s", dirpath, path);
res = mknod(fpath, mode, rdev);
if(res == -1)
return -errno;
return 0;
}
static int xmp_mkdir(const char *path, mode_t mode)
{
int res;
char fpath[1000];
sprintf(fpath,"%s%s", dirpath, path);
res = mkdir(fpath, mode);
if(res == -1)
return -errno;
return 0;
}
static int xmp_unlink(const char *path)
{
int res;
char fpath[1000];
sprintf(fpath,"%s%s", dirpath, path);
res = unlink(fpath);
if(res == -1)
return -errno;
return 0;
}
static int xmp_rmdir(const char *path)
{
int res;
char fpath[1000];
sprintf(fpath,"%s%s", dirpath, path);
res = rmdir(fpath);
if(res == -1)
return -errno;
return 0;
}
static int xmp_symlink(const char *from, const char *to)
{
int res;
char ffrom[1000];
char fto[1000];
sprintf(ffrom,"%s%s",dirpath,from);
sprintf(fto,"%s%s",dirpath,to);
res = symlink(ffrom, fto);
if(res == -1)
return -errno;
return 0;
}
static int xmp_rename(const char *from, const char *to)
{
int res;
char ffrom[1000];
char fto[1000];
sprintf(ffrom,"%s%s",dirpath,from);
sprintf(fto,"%s%s",dirpath,to);
res = rename(ffrom, fto);
if(res == -1)
return -errno;
return 0;
}
static int xmp_link(const char *from, const char *to)
{
int res;
char ffrom[1000];
char fto[1000];
sprintf(ffrom,"%s%s",dirpath,from);
sprintf(fto,"%s%s",dirpath,to);
res = link(ffrom, fto);
if(res == -1)
return -errno;
return 0;
}
static int xmp_chmod(const char *path, mode_t mode)
{
int res;
char fpath[1000];
sprintf(fpath,"%s%s", dirpath, path);
res = chmod(fpath, mode);
if(res == -1)
return -errno;
return 0;
}
static int xmp_chown(const char *path, uid_t uid, gid_t gid)
{
int res;
char fpath[1000];
sprintf(fpath,"%s%s", dirpath, path);
res = lchown(fpath, uid, gid);
if(res == -1)
return -errno;
return 0;
}
static int xmp_truncate(const char *path, off_t size)
{
int res;
char fpath[1000];
sprintf(fpath,"%s%s", dirpath, path);
res = truncate(fpath, size);
if(res == -1)
return -errno;
return 0;
}
static int xmp_utime(const char *path, struct utimbuf *buf)
{
int res;
char fpath[1000];
sprintf(fpath,"%s%s", dirpath, path);
res = utime(fpath, buf);
if(res == -1)
return -errno;
return 0;
}
static int xmp_open(const char *path, int flags)
{
int res;
char fpath[1000];
sprintf(fpath,"%s%s", dirpath, path);
res = open(fpath, flags);
if(res == -1)
return -errno;
close(res);
return 0;
}
static int xmp_read(const char *path, char *buf, size_t size, off_t offset)
{
int fd;
int res;
char fpath[1000];
sprintf(fpath,"%s%s", dirpath, path);
fd = open(fpath, O_RDONLY);
if(fd == -1)
return -errno;
res = pread(fd, buf, size, offset);
if(res == -1)
res = -errno;
close(fd);
return res;
}
static int xmp_write(const char *path, const char *buf, size_t size, off_t offset)
{
int fd;
int res;
char fpath[1000];
sprintf(fpath,"%s%s", dirpath, path);
fd = open(fpath, O_WRONLY);
if(fd == -1)
return -errno;
res = pwrite(fd, buf, size, offset);
if(res == -1)
res = -errno;
close(fd);
return res;
}
static struct fuse_operations xmp_oper = {
.getattr = xmp_getattr,
.readlink = xmp_readlink,
.getdir = xmp_getdir,
.mknod = xmp_mknod,
.mkdir = xmp_mkdir,
.symlink = xmp_symlink,
.unlink = xmp_unlink,
.rmdir = xmp_rmdir,
.rename = xmp_rename,
.link = xmp_link,
.chmod = xmp_chmod,
.chown = xmp_chown,
.truncate = xmp_truncate,
.utime = xmp_utime,
.open = xmp_open,
.read = xmp_read,
.write = xmp_write,
};
int main(int argc, char *argv[])
{
fuse_main(argc, argv, &xmp_oper);
return 0;
}

Kode Fuse diatas memiliki semua fungsi – fungsi dari FUSE. Namun jika kamu ingin tidak membutuh kan beberapa dari fungsi tersebut, kamu juga bisa menghilangkan beberapa fungsinya. Di bawah ini akan saya tunjukkan implementasi FUSE yang jika kita meng-copy sebuah file, maka file yang asli tidak akan bisa dibuka ataupun dicopy lagi. Untuk membuat file system seperti itu, maka kita dapat memodifikasi fungsi read dan write nya. Di bawah ini adalah hasil modifikasinya

#ifdef linux
/* For pread()/pwrite() */
#define _XOPEN_SOURCE 500
#endif
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <sys/statfs.h>
static const char *dirpath ="/home/fourirakbar/modul4/coba";
char alamat[1000];
static int xmp_getattr(const char *path, struct stat *stbuf)
{
int res;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
res = lstat(fpath, stbuf);
if (res == -1)
return -errno;
return 0;
}
static int xmp_readlink(const char *path, char *buf, size_t size)
{
int res;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
res = readlink(fpath, buf, size - 1);
if (res == -1)
return -errno;
buf[res] = '\0';
return 0;
}
static int xmp_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler)
{
DIR *dp;
struct dirent *de;
int res = 0;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
dp = opendir(fpath);
if(dp == NULL)
return -errno;
while((de = readdir(dp)) != NULL)
{
res = filler(h, de->d_name, de->d_type);
if(res != 0)
break;
}
closedir(dp);
return res;
}
static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
{
int res;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
res = mknod(fpath, mode, rdev);
if(res == -1)
return -errno;
return 0;
}
static int xmp_mkdir(const char *path, mode_t mode)
{
int res;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
res = mkdir(fpath, mode);
if(res == -1)
return -errno;
return 0;
}
static int xmp_unlink(const char *path) //saat kita melakukan delete
{
int res,res2;
char fpath[1000], temp[1000];
sprintf(fpath, "%s%s", dirpath, path);
strcpy(temp,fpath);
res = unlink(fpath);
do
{
sprintf(temp, "%s-copy", fpath); //kita mengecek folder backup nya
res2=unlink(temp); //jika terdapat folder backup, maka backup tersebut akan di delete
}
while(res2!=-1);
if(res == -1)
return -errno;
return 0;
}
static int xmp_rmdir(const char *path)
{
int res;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
res = rmdir(fpath);
if(res == -1)
return -errno;
return 0;
}
static int xmp_symlink(const char *from, const char *to)
{
int res;
char from1[1000];
char to1[1000];
sprintf(from1,"%s%s", dirpath, from);
sprintf(to1,"%s%s", dirpath, to);
res = symlink(from, to);
if(res == -1)
return -errno;
return 0;
}
static int xmp_rename(const char *from, const char *to)
{
int res;
char from1[1000];
char to1[1000];
sprintf(from1,"%s%s", dirpath, from);
sprintf(to1,"%s%s.copy", dirpath, to);
res = rename(from1, to1);
if (res == -1)
return -errno;
return 0;
}
static int xmp_link(const char *from, const char *to)
{
int res;
char from1[1000];
char to1[1000];
sprintf(from1,"%s%s", dirpath, from);
sprintf(to1,"%s%s", dirpath, to);
res = link(from, to);
if(res == -1)
return -errno;
return 0;
}
static int xmp_chmod(const char *path, mode_t mode)
{
int res;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
res = chmod(fpath, mode);
if(res == -1)
return -errno;
return 0;
}
static int xmp_chown(const char *path, uid_t uid, gid_t gid)
{
int res;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
res = lchown(fpath, uid, gid);
if(res == -1)
return -errno;
return 0;
}
static int xmp_truncate(const char *path, off_t size)
{
int res;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
res = truncate(fpath, size);
if(res == -1)
return -errno;
return 0;
}
static int xmp_utime(const char *path, struct utimbuf *buf)
{
int res;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
res = utime(fpath, buf);
if(res == -1)
return -errno;
return 0;
}
static int xmp_open(const char *path, int flags)
{
int res;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
res = open(fpath, flags);
if(res == -1)
return -errno;
close(res);
return 0;
}
static int xmp_read(const char *path, char *buf, size_t size, off_t offset)
{
int fd;
int res;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
strcpy(alamat,path);
fd = open(fpath, O_RDONLY);
if(fd == -1)
return -errno;
res = pread(fd, buf, size, offset);
if(res == -1)
res = -errno;
close(fd);
return res;
}
static int xmp_write(const char *path, const char *buf, size_t size, off_t offset) //saat write file
{
int fd;
int res;
int res1;
char fpath[1000],temp1[1000];
char newname[]= "barucopy";
sprintf(fpath, "%s%s", dirpath, path);
fd = open(fpath, O_WRONLY);
sprintf(temp1, "%s%s", dirpath, alamat);
res1 = chmod(temp1, 0000);
if(res1 == -1)
res1 = -errno;
if(fd == -1)
return -errno;
res = pwrite(fd, buf, size, offset);
if(res == -1)
res = -errno;
close(fd);
rename(path,newname);
return res;
}
static int xmp_release(const char *path, int flags)
{
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
(void) fpath;
(void) flags;
return 0;
}
static int xmp_fsync(const char *path, int isdatasync)
{
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
(void) fpath;
(void) isdatasync;
return 0;
}
static struct fuse_operations xmp_oper = {
.getattr = xmp_getattr,
.readlink = xmp_readlink,
.getdir = xmp_getdir,
.mknod = xmp_mknod,
.mkdir = xmp_mkdir,
.symlink = xmp_symlink,
.unlink = xmp_unlink, // delete
.rmdir = xmp_rmdir,
.rename = xmp_rename,
.link = xmp_link,
.chmod = xmp_chmod,
.chown = xmp_chown,
.truncate = xmp_truncate,
.utime = xmp_utime,
.open = xmp_open,
.read = xmp_read,
.write = xmp_write,
.release = xmp_release,
.fsync = xmp_fsync
};
int main(int argc, char *argv[])
{
fuse_main(argc, argv, &xmp_oper);
return 0;
}

Tidak ada komentar:

Posting Komentar