Rabu, 02 Desember 2015

masalah fuse

Jihad dan Sekar adalah teman baik dan sangat dekat. Karena kedekatan itulah, timbul rasa

yang berbeda di hati Jihad untuk Sekar. Suatu hari, Jihad mengutarakan isi hatinya kepada

Sekar. Namun, Sekar ingin melihat dulu kesungguhan Jihad, Ia memberikan syarat bagi

Jihad untuk mendapatkan hatinya. Syarat tersebut adalah Sekar ingin Jihad

membuatkannya sebuah implementasi dari fuse yang baru saja didapatkannya dari asistensi

praktikum sistem operasi. Sebelumnya, ketika asistensi hanya diajarkan implementasi dasar

yaitu mengaitkan direktori lain (mount) dengan fuse. Padahal ketika dikaitkan dengan

direktori (mount) Sekar ingin agar implementasi fuse tersebut memiliki kriteria sebagai

berikut:
File dalam direktori tersebut hanya bisa di­copy atau dipindahkan sebanyak satu kali,

sehingga file yang telah di­copy atau dipindahkan tersebut tidak dapat di­copy atau

dipindahkan lagi (file terkunci). Contoh: terdapat file A. jika file A dicopy atau

dipindahkan maka akan terbentuk file salinan atau hasil pindahan file A, sedangkan

file A sendiri tidak bisa diapa­apakan lagi (terkunci). Namun file salinan A tetap bisa

dicopy atau dipindahkan, begitu seterusnya. (Kelas B​)

//cara mengerjakan soal adalah dengan open,read,write

static const char *dirpath = "/home/anindita/bisadong"; //ini yang mau di mount
char alamat[1000];//nyimpen alamat file yg dicopy

static int xmp_getattr(const char *path, struct stat *stbuf) //buat ambil atribut,kayak location dll
{
    int res;
    char fpath[1000]; //utk nyimpan gabungan dirpath dan fpath
    sprintf(fpath,"%s%s",dirpath,path);//buat gabungin, lalu disimpan di fpath
    res = lstat(fpath, stbuf);//fungsinya
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_readlink(const char *path, char *buf, size_t size) //untuk membaca link
{
    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) //untuk ambil direktori
{
    DIR *dp;
    struct dirent *de;
    int res = 0;
    char fpath[1000];
    sprintf(fpath,"%s%s",dirpath,path); //gabungin path dan dirpath ke fpath
   
    if(strcmp(path,"/") == 0) //ambil file lokasinya yg dipisah pakai tanda "/"
    {
        path=dirpath;
        sprintf(fpath,"%s",path); //masukin path ke fpath
    }
    else sprintf(fpath, "%s%s",dirpath,path);

   
    dp = opendir(fpath);//buka direktorinya
    if(dp==NULL)
    {
        return -errno;
    }
    while((de = readdir(dp))!=NULL)//membaca isi dari direktori
    {
        res = filler(h, de->d_name, de->d_type);
        if(res!=0) break;
    }
    //system("notify-send hello");
    closedir(dp);
    return res;
}

static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)//mknod adalah fungsi untuk membuat node file (yg belum ada isinya)
{
    int res;
    char fpath[1000];
    sprintf(fpath,"%s%s",dirpath,path); //gabungin path dan dirpath ke fpath
    res = mknod(fpath, mode, rdev);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_mkdir(const char *path, mode_t mode) //untuk membuat direktori baru
{
    int res;
    char fpath[1000];
    sprintf(fpath,"%s%s",dirpath,path);//gabungin path dan dirpath ke fpath
    res = mkdir(path, mode);//untuk membuat direktori baru
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_unlink(const char *path)//remove file
{
    int res;
    char fpath[1000];
    sprintf(fpath,"%s%s",dirpath,path);//gabungin path dan dirpath ke fpath
    res = unlink(fpath);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_rmdir(const char *path)//remove direktori
{
    int res;
    char fpath[1000];
    sprintf(fpath,"%s%s",dirpath,path);//gabungin path dan dirpath ke fpath
    res = rmdir(fpath);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_symlink(const char *from, const char *to)//creates a symbolic link.
{
    int res;
    char fpath[1000];
    sprintf(fpath,"%s%s",from,to);
    res = symlink(from, to);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_rename(const char *from, const char *to)//untuk mengubah nama file
{
    int res;
    char fpath[1000];
    //sprintf(fpath,"%s%s",from,to);//
    res = rename(from, to);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_link(const char *from, const char *to)//membuat hard link ke file
{
    int res;
    char fpath[1000];
    //sprintf(fpath,"%s%s",from,to);
    res = link(from, to);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_chmod(const char *path, mode_t mode)//memberi/mengubah akses/permission menjadi seperti yang diinginkan
{
    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)//mengganti owner dari file
{
    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_utime(const char *path, struct utimbuf *buf)//untuk memberikan akses, merubah berapa kali dia bisa diakses dan di modif
{
    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)//untuk membuka file
{
    int res;
    char fpath[1000];
    sprintf(fpath,"%s%s",dirpath,path);////gabungin path dan dirpath ke fpath
    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)//untuk membaca file
{
    int fd;
    int res;
    char fpath[1000];
    sprintf(fpath,"%s%s",dirpath,path);//gabungin path dan dirpath ke fpath
    strcpy(alamat,fpath);   //menyimpan alamat file yg dicopy
    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,//untuk mengedit isi file
                     off_t offset)
{
    int fd;
    int res;
    char fpath[1000];
   
    sprintf(fpath,"%s%s",dirpath,path);////gabungin path dan dirpath ke fpath
    fd = open(path, O_WRONLY);
    if(fd == -1)
        return -errno;
    chmod (alamat,0000);//0000 agar sudah tidak bisa diakses lagi
    res = pwrite(fd, buf, size, offset);
    if(res == -1)
        res = -errno;
   
    close(fd);
    return res;
}
/*
static int xmp_statfs(struct fuse_statfs *fst)
{
    struct statfs st;
    int rv = statfs("/",&st);
    if(!rv) {
        fst->block_size  = st.f_bsize;
        fst->blocks      = st.f_blocks;
        fst->blocks_free = st.f_bavail;
        fst->files       = st.f_files;
        fst->files_free  = st.f_ffree;
        fst->namelen     = st.f_namelen;
    }
    return rv;
}
*/
static int xmp_release(const char *path, int flags)
{
    /* Just a stub.  This method is optional and can safely be left
       unimplemented */
    char fpath[1000];
    sprintf(fpath,"%s%s",dirpath,path);
    (void) path;
    (void) flags;
    return 0;
}

static int xmp_fsync(const char *path, int isdatasync)
{
    /* Just a stub.  This method is optional and can safely be left
       unimplemented */
    char fpath[1000];
    sprintf(fpath,"%s%s",dirpath,path);
    (void) path;
    (void) isdatasync;
    return 0;
}

static struct fuse_operations xmp_oper = {
    //char fpath[1000];
    //sprintf(fpath,"%s%s",dirpath,path);
    .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,
    //.utime    = xmp_utime,
    .open    = xmp_open,
    .read    = xmp_read,
    .write    = xmp_write,
    //.statfs    = xmp_statfs,
    //.release    = xmp_release,
    //.fsync    = xmp_fsync
   
};

int main(int argc, char *argv[])
{
    //char fpath[1000];
    //sprintf(fpath,"%s%s",dirpath,path);
    fuse_main(argc, argv, &xmp_oper);
    return 0;
}