Sunday, March 5, 2017

KERANGKA ACUAN KERJA - SISTEM INFORMASI BARANG TEMUAN MASJID

KERANGKA ACUAN KERJA
SISTEM INFORMASI BARANG TEMUAN MASJID
   A.     Latar Belakang
Dalam era modern saat ini, tentunya kebutuhan informasi dan teknologi sangat dibuthkan dalam  bidang apapun termasuk masjid. Banyaknya barang-barang jamaah masjid yang tertinggal di masjid dan kurangnya informasi penemuan barang. Hal itu dikarenakan banyaknya barang yang tertinggal sehinnga akan sangat bnyak mengeluarkan pengumuman jika diumumkan secara manual. Namun jika diumumkan secara massal orang tidak akan tahu apakah barang mereka yang tertinggal sudah ditemukan atau belum.

   B.     Maksud dan Tujuan
Maksud dari perancangan perangkat lunak ini berfungsi untuk menangani pengelolaan barang temuan pada masjid manarul ilmi ITS.
Tujuan dari pembuatan sistem informasi ini adalah:
1.     Mempermudah pengurus masjid mengumumkan barang yang ditemukan di sekitar masjid kepada seluruh pengunjung masjid.
2.   Mempermudah pengunjung masjid dalam menemukan barang yang tertinggal di masjid.

   C.     Sasaran
Sasaran proyek ini yaitu tersedianya sistem informasi yang memudahkan pengunjung dan pengurus masjid dalam mengelola barang yang hilang atau ditemukan di masjid.

   D.     Nama dan Organisasi Pengguna Jasa
Nama Organisasi yang menggunakan jasa yaitu Masjid Manarul Ilmi ITS.

   E.      Sumber Pendanaan
Sumber pendanaan yaitu dana mandiri dari kas JMMI sebesar Rp. 4.500.000,00.

   F.      Lingkup, Lokasi, Fasilitas, dan Alih Pengetahuan
1.      Lingkup Kegiatan
·        Pembuatan modul dari aplikasi sistem informasi barang temuan masjid
·        Pengembangan basis data
·        Pembuatan dokumentasi lengkap
2.      Lokasi Kegiatan
Tempat pembuatan aplikasi ini dilakukan di lingkungan sekretariat JMMI ITS.
3.      Data dan Fasilitas Penunjang
a.      Pengguna Jasa
·        Konsultasi kebutuhan
·        Data pengguna
b.      Penyedia Jasa
·        Konsultasi kebutuhan.
·        Ruang kerja untuk pelaksanaan proyek pembuatan sistem informasi.
·        Laporan pembuatan dan dokumentasi panduan pengoperasian sistem.
4.      Alih Pengetahuan
·        Konsultasi
·        Training
·        Pendampingan

   G.     Metodologi
Dalam pembuatan sistem informasi barang temuan masjid kami menggunakan sistem prototype. Setelah mendapatkan seluruh kebutuhan dari sistem maka prototype dibuat. Prototype akan dievaluasi oleh klien dan akan diperbaiki lagi hingga prototype terakhir.

   H.     Jangka Waktu Pelaksanaan
Jangka waktu pembuatan aplikasi ini yaitu 3 bulan.

   I.       Kualifikasi
·        Bersedia tidak menyebarkan data yang bersifat internal
·        Berkomitmen terhadap pekerjaan
·        Menggunakan metode yang baik dan benar
·        Berpengalaman
·        Sanggup memberi garansi

   J.       Tenaga Ahli
·        Project Manager (1 orang), berpengalaman kerja minimal 2 tahun dengan pendidikan minimal S1 Teknik Informatika.
·        System analyst (1 orang) dengan pendidikan minimal S1 Teknik Informatika.
·        Designer (1 orang) dengan pendidikan minimal S1 Teknik Informatika.
·         Programmer (2 orang), berpendidikan minimal S1 Teknik Informatika.
·        Database Administrator (1 orang) dengan pendidikan minimal S1 Teknik Informatika.
·         Dokumentator (1 orang) dengan pendidikan minimal S1 Teknik Informatika. 

   K.      Keluaran
Keluaran dari proyek pembuatan sistem informasi ini adalah
a.      Sistem informasi barang temuan masjid Manarul Ilmi ITS.
b.      Dokumentasi dan laporan akhir pembuatan sistem.
c.      User manual.
d.      Pelatihan, pendampingan, garansi, dan pemeliharaan sistem.
e.      Source Code program

   L.      Pelaporan
a.      Laporan Pendahuluan
·        Rencana kerja menyeluruh
·        Jadwal kegiatan
b.      Laporan Interim
·        Hasil yang sudah dicapai
·        Masalah pelaksanaan dan solusi
·        Rencana baru selanjutnya
c.      Laporan Akhir
·        Laporan pendahuluan
·        Laporan mingguan
·        Keluaran proyek
d.      Laporan Mingguan pada Pertemuan Rutin


Revisi
Pelaporan (serahan pekerjaan)
Data dan Fasilitas Penunjang
Alih pengetahuan
lingkup kegiatan
metodologi

Sunday, February 19, 2017

Manajemen Proyek Perangkat Lunak

Deskripsi Manajemen Proyek Perangkat Lunak
oleh Christyanto Liman - 5114100087

A. Deskripsi

Manajemen proyek adalah suatu disiplin dari mengawali, merencanakan, mengeksekusi, mengontrol dan menutup pekerjaan dari sebuah tim untuk mencapai tujuan tertentu dan memenuhi suatu kriteria keberhasilan tertentu. Suatu proyek merupakan pekerjaan sementara untuk menghasilkan suatu produk, jasa atau hasil. Suatu proyek sudah ditentukan mulai dan selesainya, biasanya berbatas waktu dan biaya, dan harus mencapai sebuah tujuan tertentu untuk membawa perubahan menguntungkan atau pertambahan nilai dari hasil proyek.

Tantangan utama dari manajemen proyek adalah untuk menyelesaikan semua tujuan proyek dengan diberikannya batasan-batasan. Informasi yang didapat biasanya dideskripsikan dalam user atau project manual yang dibuat ketika awal dari proses pengembangan. Batasan utama dari suatu proyek adalah cakupan proyek, waktu, kualitas dan budget.

Manajemen proyek perangkat lunak merupakan sebuah sendi dan ilmu dari perencanaan dam memimpin proyek perangkat lunak. Manajemen proyek perangkat lunak adalah sub-disiplin dari management proyek dimana proyek perangkat lunak direncanakan, diimplementasikan, dipantau dan dikendalikan.

B. Tujuan/Manfaat
         
          Ada beberapa tujuan/manfaat yang didapat dari manajemen proyek perangkat lunak.
1.     Efisiensi, baik dari sisi biaya, sumber daya maupun waktu.
2.  Kontrol terhadap proyek lebih baik, sehingga proyek bisa sesuai dengan scope, biaya, sumberdaya dan waktu yang telah ditentukan.
3.     Meningkatkan kualitas.
4.     Meningkatkan produktifitas.
5.     Bisa menekan resiko yang timbul sekecil mungkin.
6.     Koordinasi internal yang lebih baik.
7.      Meningkatkan semangat, tanggung jawab serta loyalitas tim terhadap proyek, yaitu dengan penugasan yang jelas kepada masing-masing anggota tim.

C. Stakeholder

            Stakeholder merupakan infividu, kelompok atau organisasi yang berpengaruh, terpengaruh atau merasakan sendiri akan terpengaruh oleh keputusan, aktivitas, dan hasil dari suatu proyek. Ada beberapa stakeholder dalam suatu proyek, antara lain:

·         Client
Client merupakan orang yang mengawali suatu proyek dan kemudian menjadi pemilik dari proyek atau hasil dari proyek.

·         Investor
Investor merupakan pihak yang menyediakan biaya proyek. Investor dapat terdiri dari client itu sendiri ataupun sponsor. .

·         Project Manager
Project Manager merupakan ahli di bidang manajemen proyek. Project Manager memiliki tanggung jawab untuk merencanakan, pengadaan, dan eksekusi dari sebuah proyek.

·         Designer
Designer dalam suatu proyek perangkat lunak merupakan individu yang menentukan kebutuhan, spesifikasi, proses bisnis, membuat arsitektur, mendesain tampilan, menuliskan algoritma dan menyelesaikan masalah teknis dan domain dalam suatu perangkat lunak.

·         Analyst
Analyst merupakan individu yang mempelajari domain aplikasi perangkat lunak, menyiapkan kebutuhan perangkat lunak dan dokumen spesifikasi.

·         Programmer
Programmer merupakan individu atau kelompok yang mengimplementasikan suatu rencana proyek dalam bahasa pemrograman untuk menghasilkan suatu perangkat lunak.

·         Tester
Tester bertugas sebagai penguji dari suatu perangkat lunak. Tester memastikan seluruh fungsi suatu perangkat lunak dapat berjalan baik sesuai dengan tujuannya sebelum perangkat lunak tersebut dirilis.

·         End User
End user merupakan individu yang pada akhirnya menggunakan perangkat lunak yang telah dibuat dari suatu proyek.

D. Contoh Proyek: Sistem Informasi Barang Temuan Masjid

·         Deskripsi
Sistem informasi barang temuan masjid ini merupakan aplikasi perangkat lunak berbasis web yang menyediakan informasi tentang barang-barang yang ditemukan di masjid Manarul Ilmi ITS. Dengan adanya sistem informasi ini, pengguna dapat mengisi dan melihat daftar barang yang ditemukan di sekitar masjid secara online.

·         Biaya
Biaya yang digunakan untuk proyek ini adalah
-          Biaya project team            : Rp. 4.000.000,00
-          Biaya perawatan sistem    : Rp.    500.000,00

·         Screenshoot


Halaman awal

Halaman daftar barang temuan

Halaman tambah barang temuan


Daftar Pustaka

P Thompson. 1990 The client role in project management. Internet papers
https://en.wikipedia.org/wiki/Software_project_management
https://en.wikipedia.org/wiki/Project_management
https://en.wikipedia.org/wiki/Project_manager
https://en.wikipedia.org/wiki/Software_analyst
http://kelompokmpc.blogspot.co.id/
http://noverse.com/blog/2010/01/what-is-a-software-designer/

Saturday, November 28, 2015

FILE SYSTEM and FUSE

Pagi Semua… Kali ini Aku akan Menjelaskan tentang File System.
Apa itu File System? File System adalah bagian dari sistem operasi yang mengatur file, bagaimana file tersebut dibentuk, diberi nama, diakses, digunakan, dilindungi, diimplementasikan, dan diatur. Ada beberapa tipe file system, beberapa diantaranya adalah:
a.       Disk File System yaitu file system yang menggunakan media fisik seperti disk sebagai media penyimpanan
Contoh: FAT32, NTFS, HFS, ext3, ext4
b.      Flash File system : Merupakan file system yang didesain untuk menyimpan file dalam media penyimpanan berbasis flash memory.
Contoh: JFFS, JFFS2, YAFFS, UBIFS, LogFS
c.      Tape File System atau Linear Tape FS (LTFS) : merupakan file system yang menyimpan file dalam tape atau magnetic tape.
Contoh: IBM LTFS-SDE, HP LTFS
d.      Database File System : Merupakan file system yang menyimpan file sebagai gumpalan dalam sebuah database, bukan dalam hierarki direktori.
Contoh: IBM DB2
e.      Network File System : merupakan file system yang bertindak sebagai client untuk file access protocol yang jauh, menyediakan akses ke file dalam sebuah server.
Contoh: NFS, AFS, SMB protocol
f.       dan lain-lain
Selain File System diatas, ada File System lain yang dibuat oleh system sendiri  yang digunakan untuk mengatur beberapa jenis File System yaitu Virtual File System. Virtual File System (VFS) adalah file system abstrak yang memungkinkan aplikasi client untuk mengakses berbagai file system konkret dengan cara yang sama. Virtual File System berfungsi sebagai pengatur dari semua file system yang sudah di mount.VFS dapat digunakan juga sebagai jembatan atara file system Windows, Mac OS dan Unix. VFS memberikan interface antara kernel dan file system konkret. Virtual File System terdiri dari 3 bagian utama yaitu Superblock, Inode, dan Dentry. Superblock merepresentasikan setiap file system yang telah di mount. inode kependekan dari index-nodes, inode berisi metadata dari file. Inode menunjuk ke superblock dari file system dari sebuah file. Inode berisi data file seperti nomer seri, mode proteksi, ownoer, ukuran, tanggal akses file terakhir, tanggal pembuatan dan modifikasi. Dentry berguna untuk meng-encode struktur tree file system dan nama dari file.
FUSE (Filesystem in Userspace) adalah suatu metode yang dilakukan sistem operasi dimana pengguna yang tidak memiliki akses bisa membuat file system mereka sendiri tanpa harus mengedit kernel. FUSE mengakses dua bagian dari sistem operasi: Userspace dan Kernel. Pada kernel, terdapat Virtual File System dan module FUSE. Keduanya digunakan untuk pengaksesan FUSE. Di bagian Userspace, user mengakses file system. Melalui command yang telah diinterpretasikan oleh glibc, command dikirim ke VFS. Kemudian VFS bergerak ke module FUSE, karena direktori yang diakses merupakan filesystem berbasis FUSE. Kemudian kernel FUSE melalui glibc dan libfuse sebelum akhirnya mengakses filesystem yang dimaksud. Setelah itu, hasil pengaksesan filesystem tersebut dikirim kembali ke kernel FUSE (misalkan, ada filesystem 'myFUSE' yang mengembalikan direktori filesystem yang bersangkutan. Direktori tersebut dikirim ke kernel FUSE). Kemudian kembali ke VFS dan akhirnya kembali ke Userspace lagi.
Kelebihan dari FUSE antara lain:
a.      FUSE tidak bertempat di Kernel, sehingga lebih mudah jika ingin menyebarkan code yang menggunakan FUSE. Karena tidak bertempat di kernel, proses pengetesan dan debugging menjadi lebih mudah dan cepat
b.      Apabila terdapat suatu bug, fix-patch tidak harus menunggu revisi kernel dilakukan. Peng-update-an lebih cepat jika memang dibutuhkan
c.      Kegagalan pada filesystem FUSE tidak berpengaruh pada kernel, karena FUSE tidak bertempat di Kernel
d.      Tidak membutuhkan privilege dari administrator untuk mengakses FUSE, sehingga bisa dijalankan lebih cepat

Template FUSE lengkap bisa dilihat DISINI!

Untuk pengimplementasian FUSE mari kita coba untuk mengubah nama file / ekstensi file ketika file terbuka, memunculkan notifikasi dan memindahkan file tersebut ke suatu folder.File yang akan diimplementasikan adalah file berekstensi .c, .doc, dan .3gp.
Untuk melakukan ini kita membutuhkan 3 fungsi dari FUSE yaitu getatrr, readdirr, dan read.  Fungsi getatrr berguna untuk mendapatkan file yang akan dibuka, tanpa getatrr kita tidak bisa membaca file tersebut. Fungsi readdirr berguna untuk membaca direktori dari file yang akan dibuka. Fungsi read digunakan untuk membaca file dan melakukan sesuatu saat file dibuka, fungsi ini yang nantinya kita ubah untuk menyelesaikan masalah diatas. Untuk fungsi getatrr dan readdirr kita juga ubah sedikit hanya untuk mendapatkan path dari file.

Mari kita mulai !

1.     Buat file c untuk menuliskan kodingan.
2.      Tuliskan include fungsi getatrr sebagai berikut

#define FUSE_USE_VERSION 26

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#ifdef linux
#define _XOPEN_SOURCE 700
#endif

#include <fuse.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <sys/time.h>
#ifdef HAVE_SETXATTR
#include <sys/xattr.h>
#endif

static const char *dirpath = "/home/yozora/Downloads";

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;
}
3.       Sesuaikan dirpath di static const char *dirpath = "/home/yozora/Downloads"; dengan path folder yang akan di-mount ke FUSE di komputer anda.
4.      Tuliskan fungsi readdirr sebagai berikut

static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
                                     off_t offset, struct fuse_file_info *fi)
{
               char fpath[1000];
               if(strcmp(path,"/") == 0)
               {
                              path=dirpath;
                              sprintf(fpath,"%s",path);
               }
               else sprintf(fpath, "%s%s",dirpath,path);
              
               DIR *dp;
               struct dirent *de;

               (void) offset;
               (void) fi;

               dp = opendir(fpath);
               if (dp == NULL)
                              return -errno;

               while ((de = readdir(dp)) != NULL) {
                              struct stat st;
                              memset(&st, 0, sizeof(st));
                              st.st_ino = de->d_ino;
                              st.st_mode = de->d_type << 12;
                              if (filler(buf, de->d_name, &st, 0))
                                             break;
               }
                                          
               closedir(dp);
               return 0;
}
5.      Tuliskan fungsi read sebagai berikut

static int xmp_read(const char *path, char *buf, size_t size, off_t offset,
                                  struct fuse_file_info *fi)
{
               int fd;
               int res;
               char fpath[1000];
               sprintf(fpath,"%s%s",dirpath,path);
              
               (void) fi;
              
               char ext[1000];
               int i;
               for(i = 0; i < strlen(fpath) && fpath[i] != '.'; i++);     //mengekstrak ekstensi file
               strcpy(ext, fpath+i);
              
               char cmd[1000];
              
               fd = open(fpath, O_RDONLY);
               if (fd == -1)
                              return -errno;
               else
               {
                              if(strcmp(ext, ".c") == 0 || strcmp(ext, ".3gp") == 0 || strcmp(ext, ".doc") == 0|| strcmp(ext, ".ditandai") == 0)
                              {
                                             system("zenity --width 400 --error --title 'Error' --text 'Terjadi Kesalahan! File berisi konten berbahaya.'");

                                             char from[1000], to[1000], newFolder[1000], filename[1000];
                                            
                                             //mengambil direktori dari file
                                             strcpy(newFolder, fpath);
                                            
                                             //menghapus filename dan menambahkan 'rahasia'
                                             for(i = strlen(newFolder) - 1; newFolder[i] != '/'; newFolder[i--] = 0);
                                             strcat(newFolder, "rahasia");
                                            
                                             //mengambil filename
                                             for(i = strlen(fpath) - 1; fpath[i] != '/'; i--);
                                             strcpy(filename, fpath+(i+1) ); //+1 untuk menghilangkan tanda ‘/’
                                            
                                             //Mengecek ada tidaknya folder rahasia
                                             struct stat s;
                                             if (stat(newFolder, &s) != 0)          //0 berarti folder tersebut tidak ada
                                                            mkdir(newFolder, 0777); //membuat folder 'rahasia' folder ke direktori mountnya
                                            
                                             sprintf(from, "%s", fpath);  //mengambil path file awal
                                             sprintf(to, "%s/%s.ditandai", newFolder, filename);            //membuat path tujuan pemindahan file ke folder ‘rahasia’ dan menambahkan ekstensi ‘.ditandai’
                                            
                                             sprintf(cmd, "mv %s %s", from, to);           //Merename dan memindah file
                                             system(cmd);
                                             return -errno;                                   }
              
                              res = pread(fd, buf, size, offset);
                              if (res == -1)
                                             res = -errno;

                              close(fd);
               }
               return res;
}

6.      Tuliskan fungsi operasi FUSE dan main sebagai berikut

static struct fuse_operations xmp_oper = {
               .getattr = xmp_getattr,
               .readdir = xmp_readdir,
              
               .read                     = xmp_read,
};

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

7.      Compile file tersebut dengan menuliskan
gcc -Wall [nama file].c `pkg-config fuse --cflags --libs` -o [nama file]
8.      Buat sebuah direktori untuk tempat tujuan mount fuse, misalnya: /tmp/fuse
9.      Jalankan fuse tadi dengan cara: ./[nama file] /tmp/fuse
10.   Cobalah buka file yang ada (catatan bukalah melalui terminal, jika membuka file langsung, maka saat membuka folder peringatan akan keluar karena saat kita membuka folder maka otomatis file didalamnya akan terbaca langsung) 
11.   SELESAI!

Sekian Pembahasan File System dan FUSE semoga bermanfaat! Sampai jumpa lagi!


Template FUSE Lengkap

/*
  FUSE: Filesystem in Userspace
  Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
  Copyright (C) 2011       Sebastian Pipping <sebastian@pipping.org>
  This program can be distributed under the terms of the GNU GPL.
  See the file COPYING.
*/
#define FUSE_USE_VERSION 30
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef linux
/* For pread()/pwrite()/utimensat() */
#define _XOPEN_SOURCE 700
#endif
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <sys/time.h>
#ifdef HAVE_SETXATTR
#include <sys/xattr.h>
#endif
static int xmp_getattr(const char *path, struct stat *stbuf)
{
        int res;
        res = lstat(path, stbuf);
        if (res == -1)
                return -errno;
        return 0;
}
static int xmp_access(const char *path, int mask)
{
        int res;
        res = access(path, mask);
        if (res == -1)
                return -errno;
        return 0;
}
static int xmp_readlink(const char *path, char *buf, size_t size)
{
        int res;
        res = readlink(path, buf, size - 1);
        if (res == -1)
                return -errno;
        buf[res] = '\0';
        return 0;
}
static int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
                       off_t offset, struct fuse_file_info *fi)
{
        DIR *dp;
        struct dirent *de;
        (void) offset;
        (void) fi;
        dp = opendir(path);
        if (dp == NULL)
                return -errno;
        while ((de = readdir(dp)) != NULL) {
                struct stat st;
                memset(&st, 0, sizeof(st));
                st.st_ino = de->d_ino;
                st.st_mode = de->d_type << 12;
                if (filler(buf, de->d_name, &st, 0))
                        break;
        }
        closedir(dp);
        return 0;
}
static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
{
        int res;
        /* On Linux this could just be 'mknod(path, mode, rdev)' but this
           is more portable */
        if (S_ISREG(mode)) {
                res = open(path, O_CREAT | O_EXCL | O_WRONLY, mode);
                if (res >= 0)
                        res = close(res);
        } else if (S_ISFIFO(mode))
                res = mkfifo(path, mode);
        else
                res = mknod(path, mode, rdev);
        if (res == -1)
                return -errno;
        return 0;
}
static int xmp_mkdir(const char *path, mode_t mode)
{
        int res;
        res = mkdir(path, mode);
        if (res == -1)
                return -errno;
        return 0;
}
static int xmp_unlink(const char *path)
{
        int res;
        res = unlink(path);
        if (res == -1)
                return -errno;
        return 0;
}
static int xmp_rmdir(const char *path)
{
        int res;
        res = rmdir(path);
        if (res == -1)
                return -errno;
        return 0;
}
static int xmp_symlink(const char *from, const char *to)
{
        int res;
        res = symlink(from, to);
        if (res == -1)
                return -errno;
        return 0;
}
static int xmp_rename(const char *from, const char *to)
{
        int res;
        res = rename(from, to);
        if (res == -1)
                return -errno;
        return 0;
}
static int xmp_link(const char *from, const char *to)
{
        int res;
        res = link(from, to);
        if (res == -1)
                return -errno;
        return 0;
}
static int xmp_chmod(const char *path, mode_t mode)
{
        int res;
        res = chmod(path, mode);
        if (res == -1)
                return -errno;
        return 0;
}
static int xmp_chown(const char *path, uid_t uid, gid_t gid)
{
        int res;
        res = lchown(path, uid, gid);
        if (res == -1)
                return -errno;
        return 0;
}
static int xmp_truncate(const char *path, off_t size)
{
        int res;
        res = truncate(path, size);
        if (res == -1)
                return -errno;
        return 0;
}
#ifdef HAVE_UTIMENSAT
static int xmp_utimens(const char *path, const struct timespec ts[2])
{
        int res;
        /* don't use utime/utimes since they follow symlinks */
        res = utimensat(0, path, ts, AT_SYMLINK_NOFOLLOW);
        if (res == -1)
                return -errno;
        return 0;
}
#endif
static int xmp_open(const char *path, struct fuse_file_info *fi)
{
        int res;
        res = open(path, fi->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,
                    struct fuse_file_info *fi)
{
        int fd;
        int res;
        (void) fi;
        fd = open(path, 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, struct fuse_file_info *fi)
{
        int fd;
        int res;
        (void) fi;
        fd = open(path, O_WRONLY);
        if (fd == -1)
                return -errno;
        res = pwrite(fd, buf, size, offset);
        if (res == -1)
                res = -errno;
        close(fd);
        return res;
}
static int xmp_statfs(const char *path, struct statvfs *stbuf)
{
        int res;
        res = statvfs(path, stbuf);
        if (res == -1)
                return -errno;
        return 0;
}
static int xmp_release(const char *path, struct fuse_file_info *fi)
{
        /* Just a stub.  This method is optional and can safely be left
           unimplemented */
        (void) path;
        (void) fi;
        return 0;
}
static int xmp_fsync(const char *path, int isdatasync,
                     struct fuse_file_info *fi)
{
        /* Just a stub.  This method is optional and can safely be left
           unimplemented */
        (void) path;
        (void) isdatasync;
        (void) fi;
        return 0;
}
#ifdef HAVE_POSIX_FALLOCATE
static int xmp_fallocate(const char *path, int mode,
                        off_t offset, off_t length, struct fuse_file_info *fi)
{
        int fd;
        int res;
        (void) fi;
        if (mode)
                return -EOPNOTSUPP;
        fd = open(path, O_WRONLY);
        if (fd == -1)
                return -errno;
        res = -posix_fallocate(fd, offset, length);
        close(fd);
        return res;
}
#endif
#ifdef HAVE_SETXATTR
/* xattr operations are optional and can safely be left unimplemented */
static int xmp_setxattr(const char *path, const char *name, const char *value,
                        size_t size, int flags)
{
        int res = lsetxattr(path, name, value, size, flags);
        if (res == -1)
                return -errno;
        return 0;
}
static int xmp_getxattr(const char *path, const char *name, char *value,
                        size_t size)
{
        int res = lgetxattr(path, name, value, size);
        if (res == -1)
                return -errno;
        return res;
}
static int xmp_listxattr(const char *path, char *list, size_t size)
{
        int res = llistxattr(path, list, size);
        if (res == -1)
                return -errno;
        return res;
}
static int xmp_removexattr(const char *path, const char *name)
{
        int res = lremovexattr(path, name);
        if (res == -1)
                return -errno;
        return 0;
}
#endif /* HAVE_SETXATTR */
static struct fuse_operations xmp_oper = {
        .getattr        = xmp_getattr,
        .access         = xmp_access,
        .readlink       = xmp_readlink,
        .readdir        = xmp_readdir,
        .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,
#ifdef HAVE_UTIMENSAT
        .utimens        = xmp_utimens,
#endif
        .open           = xmp_open,
        .read           = xmp_read,
        .write          = xmp_write,
        .statfs         = xmp_statfs,
        .release        = xmp_release,
        .fsync          = xmp_fsync,
#ifdef HAVE_POSIX_FALLOCATE
        .fallocate      = xmp_fallocate,
#endif
#ifdef HAVE_SETXATTR
        .setxattr       = xmp_setxattr,
        .getxattr       = xmp_getxattr,
        .listxattr      = xmp_listxattr,
        .removexattr    = xmp_removexattr,
#endif
};
int main(int argc, char *argv[])
{
        umask(0);
        return fuse_main(argc, argv, &xmp_oper, NULL);
}