Sabtu, 28 November 2015

FUSE (File System in Userspace)

Assalamualaikum wr. wb.

   Kembali lagi dengan saya teman-teman, kembali di coretan-coretan yang semoga agak penting seperti biasanya :D . Setelah berminggu-minggu berdiam akhirnya kembali lagi di Blog Ku tercinta LOL. Bahasan yang saya bawa kali ini cukup berat (setidaknya menurut saya), yaitu tentang FUSE. Tapi bukan fuse yang ini yaa..
   Yap, diatas itu adalah fuse, tapi fuse yang saya bahas yaitu File System in Userspace. File system atau sistem berkas sendiri adalah sebuah struktur logika yang digunakan untuk mengendalikan semua akses terhadap data-data yang ada di dalam harddisk. Sementara FUSE merupakan mekanisme sistem operasi untuk sistem operasi Unix-like yang memungkinkan pengguna tidak ber-hak istimewa menciptakan file system mereka sendiri tanpa mengubah kode kernel. Hal ini dicapai dengan menjalankan kode file system di userspace, sedangkan modul FUSE hanya menyediakan "jembatan" untuk antarmuka kernel yang sebenarnya.
   Template code fuse bisa kita dapatkan di http://fuse.sourceforge.net/doxygen/fusexmp_8c.htm.Dan cara install fuse tadi adalah sebagai berikut :
  1. Gunakan hak akses super user (sudo su)
  2. Ketikan perintah ./configure
  3. Ketikan perintah make
  4. Ketikan perintah make install
Lalu, untuk contohnya, berikut adalah code fuse yang telah dimodifikasi agar dapat membuat sebuah file terkunci setelah di copy-paste. Artinya, setelah sebuah file di copy-paste, maka file tersebut tidak bisa dicopy, dibuka, ataupun direname.


#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>
#include <stdlib.h>

static const char *dirpath = "/home/deni/Documents";
char simpen[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];
  
 if(strcmp(path,"/") == 0)
    {
        path=dirpath;
        sprintf(fpath,"%s",path);
    }
    else sprintf(fpath, "%s%s",dirpath,path);

    dp = opendir(path);
    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_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 fpath[1000];
    sprintf(fpath,"%s%s",dirpath,from);
char fpath2[1000];
    sprintf(fpath2,"%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 fpath[1000];
    sprintf(fpath,"%s%s",dirpath,from);
    char fpath2[1000];
    sprintf(fpath2,"%s%s",dirpath,to);
    res = rename(fpath, fpath2);
    if(res == -1)
        return -errno;

    return 0;
}

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_link(const char *from, const char *to)
{
    int res;
char fpath[1000];
    sprintf(fpath,"%s%s",dirpath,from);
char fpath2[1000];
    sprintf(fpath2,"%s%s",dirpath,to);
    res = link(fpath, fpath2);
    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(simpen,fpath);
    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;
   chmod(simpen,0000);
    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) fpath;
    (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) 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,
    .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,
    //.statfs    = xmp_statfs,
    .release    = xmp_release,
    .fsync    = xmp_fsync
   
};

int main(int argc, char *argv[])
{
    fuse_main(argc, argv, &xmp_oper);
    return 0;
}
 

Cara compile code tersebut adalah dengan mengetik gcc -Wall [namafile].c `pkg-config fuse –cflags –libs` -o [namafile] di terminal. Selanjutnya, buat sebuah directory untuk mount file di Document, contohnya  /home/deni/cobamount. Dan cara run programnya adalah dengan cara ./[namafile] /home/deni/cobamount.
Yap, seperti itulah FUSE dan semoga bermanfaat ya.. 
Sampai jumpa di artikel berikutnya ya....
Wassalamualaikum wr.wb.
 

Sabtu, 07 November 2015

Pemutar Musik Linux


    Assalamualaikum wr.wb.

    Kembali lagi di blog sederhana saya ya teman-teman :D
    Untuk kali ini, saya akan memberikan sebuah code sebuah apikasi yang menggunakan thread. Yap, thread. Sebelumnya, saya akan menjelaskan apa itu sebenarnya thread. Oke, langsung saja ya, nggak perlu panjang lebar haha, thread dalam sistem operasi adalah pengontrol aliran program dan pelaksanaan program dengan menggunakan satu buah kendali atau kendali tunggal. Jadi semua proses di sistem operasi akan di kendalikan oleh thread tadi.
    Salah satu keuntungan dari thread adalah sangat ampuh untuk mengoptimalkan prosesor komputer kita. Caranya yaitu dengan menggunakan Hyperthreading. Hyper Threading bekerja dengan cara memberi intruksi melalui software untuk membelah diri (splitting) menjadi beberapa thread (aliran). Teknologi ini menyediakan thread-level paralel di setiap prosesornya yang membuat penggunaan sumber daya menjadi lebih efisien dan bisa membuat beberapa thread uuntuk berjalan di setiap inti (core) prosesor.
    Ya seperti yang sudah saya bilang sebelumnya, saya akan memberikan contoh code yang menggunakan thread tadi. Aplikasi kali ini merupakan sebuah aplikasi multimedia, lebih tepatnya aplikasi pemutar musik. Tapi, sebelum menggunakan aplikasi ini, harus sudah menginstall vlc player di komputer temen-temen semua, karena dasar dari pemutar musiknya adalah vlc player tersebut.
Untuk mendapatkan vlc player nya sendiri bisa di download dan install dari terminal dengan cara ketik “sudo apt-get update” dan “sudo apt-get install vlc vlc-plugin-* mozilla-plugin-vlc”.
    Langsung saja, check this out guys....

#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>

int rawr;
pthread_t tid[2];
char lagu[20];
int t;
char buf[20];

void* player(void *arg)
{
    system(buf);
    system("clear");
}
void* help(void *arg)
{
    char help[5], cmd[15];
    pthread_t id=pthread_self();
    while (1)
    {
        scanf("%s", help);
        if (strcmp(help, "help") == 0)
        {
            while (1)
            {
                printf("Menu\n");
                printf("1. List\t2. Play\t3.Pause\n4. Continue\t5.Stop\n");
                printf("Command : ");
                scanf("%s", cmd);
                if (strcmp(cmd, "Play") == 0)
                {
                    system("clear");
                    scanf("%s", lagu);
                    snprintf(buf, sizeof(buf), "cvlc %s.mp3", lagu);
                    rawr=pthread_create(&(tid[1]), NULL, &player, NULL);
                }
                else if (strcmp(cmd, "List") == 0)
                {
                    system("clear");
                    system("ls | grep .mp3");
                }
                else if (strcmp(cmd, "Pause") == 0)
                {
                    system("clear");
                    scanf("%d", &t);
                    sleep(t);
                    system("pkill -SIGCONT vlc");
                }
                else if (strcmp(cmd, "Continue") == 0)
                {
                    scanf("%d", &t);
                    sleep(t);
                    system("clear");
                    system("pkill - SIGCONT vlc");
                }
                else if (strcmp(cmd, "Stop") == 0)
                {
                    system("clear");
                    scanf("%d", &t);
                    sleep(t);
                    system("pkill vlc");
                }
            }
        }
    }
    return NULL;
}
int main(void)
{
    chdir("Music");
    int i = 0;
        rawr=pthread_create(&(tid[i]),NULL,&help,NULL);
        if (rawr != 0)
            printf("\ncan't create thread : [%s]", strerror(rawr));
        else
            //printf("\n Thread created succesfully\n");
        i++;

    pthread_join(tid[0],NULL);
    pthread_join(tid[1],NULL);
return 0;
}

    Ya itulah source code dari aplikasi pemutar music nya. Akan saya sedikit jelaskan tentang aplikasinya. Jadi, sebelum masuk ke menu, kita harus mengetik “help” untuk mengeluarkan menunya. Setelah itu akan muncul 5 menu yaitu List, Play, Pause, Continue, dan Stop. List digunakan untuk mengetahui apa saja music mp3 yang ada di dalam foder music. Cara kerja Play yaitu dengan mengetikkan “Play[spasi]Judul_lagu”. Selanjutnya untuk menu Pause, Continue, dan Stop ditambah angka di belakangnya yang merupakan hitungan setelah berapa detik dia akan jeda, lanjut, atau berhenti dari pemutar musik teersebut.
    Demikian penjelasan dari saya kali ini, semoga bisa menambah wawasan teman-teman semua dan sampai ketemu lagi di artikel saya selanjutnya :)
    Wassalamualaikum wr.wb.