Sabtu, 28 November 2015

Fuse make you con-FUSE-D

Halo lagi reader
Sekarang saya mau bagi ilmu lagi tentang fuse dan sedikit tentang filesystem


File System terdiri dari kata File dan System.


File :  kumpulan informasi yang berhubungan dan  tersimpan di dalam secondary storage, secara konsep file mempunyai beberapa tipe ada yang bertipe Data terdiri dari character, numeric, dan binary ada juga file yang bertipe program.
System :  Suatu jaringan kerja dari prosedur-prosedur yang saling berhubungan, berkumpul bersama-sama untuk melakukan suatu kegiatan atau untuk menyelesaikan suatu sasaran tertentu
Kalau masih bingung, File system itu seperti kita bisa menghapus direktori, rename file, atau membuat file/folder baru, atau sebagainya. Dan itu semua diatur oleh Komponen yang bernama "Kernel"

FUSE adalah kepanjangan dari Filesystem in Userspace. Itu berarti kita dapat membuat File System semau kita.

Gambarannya sebagai berikut

Dengan adanya Fuse kita bisa membuat filesystem kita sendiri tanpa bergantung pada konfigurasi kernel. Keren bukan? :D

Untuk mendapatnkan Komponen FUSE, anda dapat melakukan beberapa langkah berikut:

1. Download FUSE dari http://fuse.sourceforge.net/ pada bagian Download stable release
2. Extract file tar.gz dan masuk ke direktori FUSE. (tar –xvzf fuse-2.9.4.tar.gz)
3. Lakukan installasi FUSE dengan cara :

a. Gunakan hak akses super user (sudo su)
b. Ketikkan perintah ./configure
c. Ketikkan perintah make
d. Ketikkan perintah make install

4. FUSE siap digunakan ^_^

Jika anda telah selesai menginstall FUSE, langkah selanjutnya adalah bermain dengan FUSE milik anda. Berikut ada contoh code FUSE yang dapat anda gunakan

#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/ncc/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_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler)
{
 char fpath[1000];
 if(strcmp(path,"/") == 0)
 {
  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)
 {
  res = filler(h, de->d_name, de->d_type);
  if(res!=0) break;
 }

System ("notify-send ini masuk fuse");
 closedir(dp);
 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,
 //.release = xmp_release,
 //.fsync = xmp_fsync,
 //.readdir = hello_readdir
};

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

Ganti bagian static const char *dirpath = "/home/mhr7/Downloads" dengan
static const char *dirpath = "/home/[nama user kalian]/Downloads"

Simpan kemudian compile dengan menggunakan perintah: gcc -Wall [nama file].c `pkg-config fuse --cflags --libs` -o [nama file]

Kemudian buat sebuah direktori, misalnya: /tmp/fuse
Coba jalankan fuse tadi dengan cara: ./[nama file] /tmp/fuse
Maka semua isi direktori /home/[nama user kalian]/Downloads akan dimount ke direktori /tmp/fuse

Coba masuk ke /tmp/fuse dan jalankan perintah ls, maka semua isi direktori tersebut akan ditampilkan dan akan muncul notifikasi di bagian atas kanan monitor anda.

Jika anda menemui file .txt dalam folder anda, maka anda dapat mengclick file tersebut. Tapi tidak bisa membukanya. Karena fungsi "xmp_open" belum anda tuliskan. Saya sarankan anda untuk mengakses http://fuse.sourceforge.net/doxygen/fusexmp_8c.html untuk melihat dan mencopy fungsi-fungsi yang masih berstatus comment pada code anda.

Agar anda dapat membuka dan melihat file .txt anda, saya anjurkan anda untuk menuliskan fungsi "xmp_wirte", "xmp_open", "xmp_read", sekaligus dan menghapus comment yang ada di situ

Ada kasus lain nih, "Kok fuse di PCmu bisa, tapi di PCku kok ngga bisa?". 
Setelah dicompile, kok malah ada "warning undefined pointer type pada .open dan .write". dan yang salah adalah dibagian "void fi"

Jangan khawatir, sebetulnya itu hanya masalah versi saja. Saya sarankan anda mencoba berbagai :

#define FUSE_USE_VERSION 30 [coba 22/26/28]
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef linux
/* For pread()/pwrite()/utimensat() */
#define _XOPEN_SOURCE 700 [kalau di pc saya saya gunakan 500, di teman saya 600]
#endif

Sekian yang dapat saya bagi bersama, Sebetulnya ini masih secuplik kecil dari keseluruhan quest yang saat itu saya kerjakan. kalau masih belom faham, Bisa langsung email saja ke saya. Atau jika masih ada waktu, akan saya update postingan ini tergantung dari respond temen2 sekalian.

Terimakasih telah membaca :D

Kamis, 05 November 2015

IPC - PIPE untuk sinkronisasi data anatar terminal dalam satu pc

Halo temen2, kali ini saya belajar hal baru lagi lho dari LINUX
Kali ini yang saya pelajarai adalah mengenai PIPE

 IPC (Inter-Process Communication) adalah komunikasi antar proses untuk mengirim data dari satu proses ke proses yang lain, baik antar proses dalam satu komputer maupun proses-proses dalam komputer yang berbeda. Salah satu metode IPC adalah 'pipe'.
     Pipe merupakan komunikasi sekuensial antar proses yang saling terelasi, namun pipe memiliki kelemahan yaitu hanya bisa digunakan untuk komunikasi antar proses yang saling berhubungan, dan komunikasinya yang dilakukan adalah secara sekuensial. Urutan informasi yang ada dalam sebuah pipe ada yang mirip dengan antrian queue. Jika komunikasi yang diinginkan adalah komunikasi dua arah maka kita harus membuat dua pipe, karena sebuah pipe hanya bisa digunakan untuk komunikasi satu arah saja. 

kali ini, saya membunyai tugas baru, yaitu membuat suatu aplikasi yang saling terhubung. Aplikasi tersebut adalah aplikasi penjualan sederhana.
Ketentuan aplikasi tersebut adalah sebagai berikut:
1. Toko tersebut menjual beberapa barang yaitu, ram, vga, motherboard, psu, harddisk, dan prosessor
2. Bila ingin menambah stok/ membeli barang, cukup dengan memilih pilihan di menu lalu menginputkan "apa yang ingin kita beli <spasi> jumlahnya"
3. Setelah terjadi transaksi data harus terupdate.

Jadi begini langkahnya:
Pertama kita deklarasi terlebih dahulu sistem apa yang ingin kita gunakan dengan perintah "#include "



Lalu kita,inisialisasi terlebih dahulu apa yang akan kita buat. Dalam kasus tersebut, nama barang tidak perlu diubah ubah, jadi cukup dibikin sebagai static char saja.



Kemudian kita atur main menu program tersebut


Maka akan tampak seperti berikut



Pada menu pertama, terdapat 2 menu lagi yaitu lihat langsung atau sinkronisasi. Kenapa harus ada sinkronisasi? Karena disitulah pipe digunakan. bagaimana cara penulisannya? Cara penulisannya sebagai berikut




Dalam proses sinkronisasi, terdapat suatu while yang maksudnya adalah untuk menunggu file pipe yang bersifat "sementar" tersebut dibikin dengan cara memilih save change pada terminal lawan.



Kemudian fitur yang satunya lagi digunakan untuk sekedar melihat saja. Dan hanya berubah setelah di sinkronisasi


Lalu, fitur kedua adalah fitur untuk menambah stok (penjual) atau membeli (pembeli)
fungsi tersebut sederhana, yaitu sekedar mengurangi (pembeli) atau menjumlahkan (penjual) dari stok yang tersedia.

Begini kodingannya :


Dan begini tampilannya
inputkan dengan format "nama barang <spasi> jumlah"




fungsi terakhir adalah fungsi save change. Fungsi tersebut adalah fungsi pipe yang dibuat untuk mengirimkan data pipe salah satu terminal yang telah diubah.


mkfifo adalah suatu perintah untuk memerintah untuk membuat pipe dengan format "mkfifo(nama_file, 0666)"
0666 adalah kode yang paling sering digunakan untuk pembuatan pipe yang bersifat sequential

Secara keseluruhan, total program adalah sebagai berikut :

#include <fcntl.h> //File beli Altrenatif
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#define MAX_INP 20
#define INP 6

int main(){
char * tmp_jual = "/tmp/pipe_jual";
char * tmp_beli = "/tmp/pipe_beli";
int i, j, file_jual, file_beli, optMenu, optInput, optSee, found;
int jumlah_barang[INP], tmp_jumlah;
char nama_barang[20][20], tmp_barang[20];

//Inisialisasi
strcpy(nama_barang[0],"ram\t");
strcpy(nama_barang[1],"harddisk");
strcpy(nama_barang[2],"motherboard");
strcpy(nama_barang[3],"psu\t");
strcpy(nama_barang[4],"vga\t");
strcpy(nama_barang[5],"prosessor");
memset(&jumlah_barang, 0, sizeof(int));

system("clear");

memset(&jumlah_barang, 0, sizeof(jumlah_barang));

puts("OINK SHOPPING Pembeli");
puts("Apa yang ingin anda tahu?\n1 Lihat barang\n2 Beli barang\n3 Save change\n4 Exit\n");
printf("Input : ");
scanf("%d", &optMenu);
do{
tmp_jumlah=0;
optSee = 0;
found = 0;
optInput = 4;

if(optMenu==1){ // opsi lihat barang
while(optSee!=3){
system("clear");
puts("1 sinkronisasi\n2 lihat langsung\n\nInput : ");
scanf("%d", &optSee);
if(optSee==1){
puts("Menunggu penjual menyimpan hasilnya");
while((file_jual=open(tmp_jual, O_RDONLY)) == -1) //menunggu si penjual membuat pipe
sleep(1);
file_jual = open(tmp_jual, O_RDONLY); //membuka pipe
read(file_jual, &jumlah_barang, sizeof(jumlah_barang)); //membaca pipe yang berisi array data sekarang dan disimpan dalam array jumlah_barang
close(file_jual);
puts("Sinkronisasi berhasil . . .");
sleep(3);
}

else if(optSee==2){
system("clear");
for(i=0; i<INP; i++)
printf("%d %s \tsejumlah %d\n", i+1, nama_barang[i], jumlah_barang[i]);
printf("Input 3 untuk kembali ke menu awal\n");scanf("%d", &optSee);
}
}
}
else if(optMenu==2){ //beli barang
while(optInput!=0)
{
system("clear");
printf("Masukkan nama barang : ");//format masukan "nama_barang <spasi> jumlah"
scanf("%s", tmp_barang);
scanf("%d", &tmp_jumlah);
if(strcmp(tmp_barang, "ram")==0){
if(jumlah_barang[0]-tmp_jumlah<0){ // kalo dia beli sampe stoknya habis ya printf "maaf stok habis"
puts("Maaf stok terbatas");
}
else
jumlah_barang[0]-=tmp_jumlah; //semumpama masih ada ya sekedar dikurangi
}
else if(strcmp(tmp_barang, "harddisk")==0){
if(jumlah_barang[1]-tmp_jumlah<0){
puts("Maaf stok terbatas");
}
else
jumlah_barang[1]-=tmp_jumlah;
}
else if(strcmp(tmp_barang, "motherboard")==0){
if(jumlah_barang[2]-tmp_jumlah<0){
puts("Maaf stok terbatas");
}
else
jumlah_barang[2]-=tmp_jumlah;
}
else if(strcmp(tmp_barang, "psu")==0){
if(jumlah_barang[3]-tmp_jumlah<0){
puts("Maaf stok terbatas");
}
else
jumlah_barang[3]-=tmp_jumlah;
}
else if(strcmp(tmp_barang, "vga")==0){
if(jumlah_barang[4]-tmp_jumlah<0){
puts("Maaf stok terbatas");
}
else
jumlah_barang[4]-=tmp_jumlah;
}
else if(strcmp(tmp_barang, "prosessor")==0){
if(jumlah_barang[5]-tmp_jumlah<0){
puts("Maaf stok terbatas");
}
else
jumlah_barang[5]-=tmp_jumlah;
}
else //kalau seumpama salah ketik, berarti barangnya tidak ada
{
puts("Barang tidak ada dalam list, tolong cek kembali\n");
}
printf("\nInputkan barang lagi?\n1 untuk iya\n0 untuk tidak\n\nInput : ");
scanf("%d", &optInput);// 1 untuk iya, 0 untuk kembali
}
}
else if(optMenu==3){
mkfifo(tmp_beli, 0666);
file_beli = open(tmp_beli, O_WRONLY); // Membuka file yang sudah dibuat dengan akses write
write(file_beli, jumlah_barang, sizeof(jumlah_barang)); //menulis file dalam pipe
close(file_beli);
}
system("clear");
puts("OINK SHOPPING Pembeli");
puts("Apa yang ingin anda tahu?\n1 Lihat barang\n2 Beli barang\n3 Save change\n4 Exit\n");
printf("Input : ");
scanf("%d", &optMenu);

} while(optMenu!=4);

return 0;
}

Sekian ilmu yang bisa saya bagi kali ini. Semoga bermanfaat bagi kalian.
Thanks for visiting my blog :D

Sabtu, 17 Oktober 2015

Membuat Script untuk mengubah gambar berwarna berubah menjadi gambar grayscale

Halo, saya kembali lagi nih
Beberapa waktu lalu saya telah diajari tentang fungsi daemon umtuk membuat bebrapa program keren.

Taukah anda tentang apa itu daemon?
Ini kita berbicara daemon dalam OS Linux lho . . .

Jadi daemon bisa didefinisikan sebagai metode untuk membuat suatu "scheduled command". Biasanya metode ini digunakan untuk maintenance PC.

Kali ini saya telah diajari untuk membuat program daemon menggunakan bahasa C.
berikut script programnya:

#include<sys/types.h>
#include<sys/stat.h>
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<errno.h>
#include<unistd.h>
#include<syslog.h>
#include<string.h>

int main(void)
{
    pid_t pid, sid;

strcpy(convert,"convert ");
strcpy(tengah, "-colorspace Gray ");
    pid = fork();
    if (pid < 0) {
            exit(EXIT_FAILURE);
    }

    if (pid > 0) {
            exit(EXIT_SUCCESS);
    }

    umask(0);

    sid = setsid();
    if (sid < 0) {
            exit(EXIT_FAILURE);
    }


    if ((chdir("/")) < 0) {
            exit(EXIT_FAILURE);
    }

    close(STDIN_FILENO);
    //close(STDOUT_FILENO);
    close(STDERR_FILENO);


    while (1) {
        printf("Hello World/n");
sleep(5);
    }
    exit(EXIT_SUCCESS);
}


Sebetulnya inti atau basic operation dari program tersebut terletak pada command "while(1){ ". Sleep disitu berfungsi sebagai jeda antar berjalannya perintah tersebut ke perintah tersebut lagi.

setelah selesai membuat program tersebut jangan lupa dicompile dengan perintah "gcc -o <nama sumber>.c <nama yang diinginkan>". bila berhasil maka akan muncul file baru yang berbentuk persegi ungu.



jika ingin menjalankannya jalankan file yang telah anda compile tadi. atau dalam terminal anda ketik" ./<nama yg sudah di compile>". Maka program tersebut akan jalan, dan anda bisa melihat hasilnya.

--------------------

Dan jika anda merasa sudah cukup, hentikan daemon anda dengan cara mangetikkan "pkill <namaExecutableYang Berjalan>"

Sekarang mari kita mengubah gambar berwarna menjadi grayscale
perintah yang digunakan adalah "convert <PathGambar><NamaGambar.jpg> -colorspace Gray <PathTujuan><NamafileBaru.jpg>"

Dalam Linux, terdapat aplikasi menarik. Fungsi aplikasi tersebut adalah aplikasi manipulasi citra. nama aplikasi tersebut adalah "ImageMagick". Aplikasi ini pula yang dapat mendukung command "convert " diatas.

Dan kini kita ingin membuat gambar yang kita klik langsung berubah warna kan?
kita harus bisa tahu terlebih dahulu tentang proses yang berjalan. Dna itu bisa diakses dengan perintah "ps x". dan karena kita ingin mencari program "imageViewer" yang kita jalankan, kita perlu modifikasi perintah "ps x" tadi menjadi "ps x | grep ".jpg" " fungsimya umtuk mendapatkan nama dan alamat path file yang kita buka tersebut. lalu karena kita hanya membutuhkan nama file tersebut, maka kita bisa langsung menggunakan perintah "awk -F'/' '{print $8}'". Fungsi perintah tersebut adalah untuk memoting string yang telah kita dapatkan. Dan fungsi "cut -d ' ' -f1" berarti memotong kata-kata berdasarkan spasi. f1 berarti kata pertama. "cut -d ' .' -f1" berarti memotong kata berdasarkan tanda ".", karena kita hanya butuh nama file tersebut saja.

Jadi script yang sudah jadi akan tampak seperti berikut:

#!/bin/bash
cd /home/mhr7/Documents/Kuliah/Sisop/Modul2
active=$(ps x | grep '.jpg' | awk -F'/' '{print $8}' | cut -d ' ' -f1 | cut -d '.' -f1)".jpg"
actived=$(ps x | grep '.jpg' | awk -F'/' '{print $8}' | cut -d ' ' -f1 | cut -d '.' -f1)"_copy.jpg"
convert $active -colorspace Gray $actived

Save file tersebut dalam format .sh layaknya script bash biasa.

Tunggu!!!!!
kenapa di awal ada perintah "cd"???
Lalu gimana cara gabungin bash script ke script yang memiliki format .c?

Ini dia caranya . . . .

Editlah script anda yang berformat c. Lalu fokuskan pada basic opertaion anda.
while (1) {
        printf("Hello World/n");
sleep(5);
    }
Ubahlah " printf("Hello World/n"); " menjadi "system("bash <pathFile>/NamaScriptBash.sh"); "
contohnya seperti ini:
"system("bash /home/mhr7/Documents/Kuliah/Sisop/Modul2/No2.sh"); "

setelah itu compile lagi dengan menggunakan command gcc seperti sebelumnya.
Lihatlah apa yang terjadi.

Ketika anda klik gambar dalam folder tempat sourceCode.sh anda berasal, maka tiba-tiba akan muncul gambar grayscale disebelahnya :D

HOREE !!!!
Mission Success !!!!

sekian dahulu ilmu yang bisa saya bagi
Kalau masih bingung, contact saja saya melalui email yang tersedia di blog ini :D
Terimakasih

Sabtu, 26 September 2015

Tutorial download file, buat direktori, dan pindahkan file tersebut menggunakan Bash Scripting

Assalamualaikum Wr.Wb.
Sudah lama saya tidak mempost sesuatu di blog saya. Dan sekarang saya ingin berbagi ilmu nih tentang Bash scripting, dan menggunakan bash scripting sebagai perintah untuk PC agar mendownload sesuatu dari suatu url dengan otomatis.

Awal mulanya, bagi para pembaca yang sudah mengenal Linux, pasti sudah tidak asing dengan istilah "Bash Scripting". Bagi pemula, jangan khawatir, biar saya beri panduan untuk membuat program downloader tersebut. Kali ini saya ingin mendownload suatu file dengan format "jam_menit_detik.txt" (contoh: 17_18_19) ke dalam folder "tanggal_bulan_tahun" (contoh: 11_12_2013) dari sistem komputer tersebut.

Jadi begini langkahnya:
1. pastikan terlebih dahulu bahwa anda telah memiliki url yang akan anda gunakan sebagai target download. Sebagai contoh, kita menggunakan url dalam "negeri" yaitu http://10.151.36.201/sisop/jadwal.txt.

Sayangnya url ini hanya bisa digunakan untuk LAN wilayah ITS Surabaya saja.

2. Siapkan lembar kosong untuk script yang akan kita tulis. Dalam linux, kita bisa menggunakan "gedit" atau text editor, atau dalam terminal linux bisa menggunakan "nano". sebagai contoh saya menggunakan Text Editor



3.. Kita harus bisa mendapatkan tanggal, bulan, tahun, yang nantinya akan digunakan untuk menamai folder yang kita tuju.
Cara mendapatkannya adalah dengan menuliskan command berikut dalam script anda

now="$(date +'%d_%m_%y')"
now adalah variabel baru yang nantinya adalah gabungan dari variabel yang berada di sebelah kanan. Date +%d adalah perintah untuk mendapatkan tanggal sistem kini, %m untuk mendapatkan bulan terkini dalam sistem, sedangkan %y untuk mendapatkan tahun terkini sistem kita. Dengan demikin now adalah string yang berisi "dd_mm_yy".

Juga kita harus mendapatkan jam, menit, detik, sistem komputer yang nantinya akan digunakan untuk menamai file yang akan kita download.
Cara mendapatkannya adalah dengan menuliskan command berikut pada script anda
hour="$(date +'%I_%M_%S')"
hour adalah variabel baru. date+ %I adalah perintah untuk mendapatkan Jam terkini dalam sistem, %M untuk mendapatkan menit terkini dalam sistem, %S untuk mendapatkan detik terkini dalam sistem. Dengan demikian hour adalah string yang berisi "jam_menit_detik".



4. Download file yang kita tuju dengan menggunakan perintah "wget" dengan format "wget <url tujuan>"
wget <url tujuan>
Karena kita ingin menamai file tersebut, tambahkan perintah -O (Uppercase). Jadi command linenya menjadi berikut "wget <url tujuan> -O <nama file yang sesuai format>"
karena tadi kita sudah sepakat menamai file dengan format "jam_menit_detik.txt" jadi nama tersebut dapat kita akses dengan simbol "$". Jadi bisa dituliskan sebagai berikut :


5. Oh iya, kita juga harus menyipakan folder sebagai penampung download kan? Sebelumnya kita juga sepakat kalau format folder tersebut adalah "tanggal_bulan_tahun". Perintahnya sederhana yaitu dengan perintah "mkidr <nama folder>". Karena tadi kita sudah memiliki variabel "now" yang akan kita gunakan sebagai nama folder, maka bisa dituliskan dalam script:



6. Setelah semua siap, satu lagi yang belum kita lakukan, yaitu memindahkan file hasil download menuju ke folder yang telah disiapkan. Kali ini perintah yang dapat digunakan adalah "mv". format penulisannya adalah "mv [Option] <path sumber data> <path tujuan>"
mv [OPTION] <path asal> <path tujuan>/ <nama file>

7. Sudah selesaikah? mari kita coba. sebelumnya simpan terlebih dahulu script tersebut. untuk mengeksekusinya kita beri perintah "./", dengan format
./<path dan nama script>

Lalu Jalankan terminal dengan cara tekan tombol Windows lalu ketik "terminal"



8. Ada masalahkah?



mungkin anda belum mengubah hak aksess pc anda. ubahlah dengan menggunakan perintah "chmod", dengan format
chmod 777 <nama script>
apabila sudah selesai, coba kita eksekusi lagi...



9. Apa berhasil? Apabila berhasil, dalam terminal akan tertulis seperti berikut:



10. Masih belum yakin? Coba saja anda cek berkas download anda dalam Files
sudah ketemu kah?




kalau sudah maka SELAMAT, script anda BERHASIL

cukup sekian yang bisa saya bagi. Apabila masih kurang jelas, bisa menghubungi saya melalui email yang terdapat di profil saya.
terimakasih telah mampir

Wassalamualaikum Wr.Wb.