Grape-kun adalah seorang penjaga hewan di kebun binatang, dia mendapatkan tugas dari atasannya untuk melakukan penjagaan pada beberapa hewan-hewan yang ada di kebun binatang sebelum melakukan penjagaan Grape-kun harus mengetahui terlebih dahulu hewan apa aja yang harus dijaga dalam drive kebun binatang tersebut terdapat folder gambar dari hewan apa saja yang harus dijaga oleh Grape-kun. Berikut merupakan link download dari drive kebun binatang tersebut : https://drive.google.com/uc?export=download&id=1oDgj5kSiDO0tlyS7-20uz7t20X3atwrq
- Grape-kun harus mendownload file tersebut untuk disimpan pada penyimpanan local komputernya. Dan untuk melakukan melihat file gambar pada folder yang telah didownload Grape-kun harus melakukan unzip pada folder tersebut.
- Setelah berhasil melakukan unzip Grape-kun melakukan pemilihan secara acak pada file gambar tersebut untuk melakukan shift penjagaan pada hewan tersebut.
- Karena Grape-kun adalah orang yang perfeksionis Grape-kun ingin membuat direktori untuk memilah file gambar tersebut. Direktori tersebut dengan nama HewanDarat, HewanAmphibi, dan HewanAir. Setelah membuat direktori tersebut Grape-kun harus melakukan filter atau pemindahan file gambar hewan sesuai dengan tempat tinggal nya.
- Setelah mengetahui hewan apa saja yang harus dijaga Grape-kun melakukan zip kepada direktori yang dia buat sebelumnya agar menghemat penyimpanan.
Catatan : untuk melakukan zip dan unzip tidak boleh menggunakan system
Untuk compile dengan perintah sebagai berikut :
gcc -0 binatang binatang.c -lcurl -lzip Setelah berhasil compile, maka jalankan dengan menggunakan command berikut :
./binatangPertama, definisikan library yang akan digunakan untuk membuat sebuah program penyelesaian tersebut. Dalam kasus penyelesaian tersebut, saya menggunakan library antara lain :
stdio.h: library standar C yang menyediakan fungsi input/output standar seperti printf(), scanf(), dan lain-lain.curl/curl.h: library untuk melakukan transfer data dengan protokol internet seperti HTTP, FTP, SMTP, dan lain-lain.stdlib.h: library standar C yang menyediakan fungsi untuk manajemen memori seperti alokasi dan dealokasi memori, konversi tipe data, dan lain-lain.unistd.h: library standar C yang menyediakan fungsi-fungsi sistem seperti sleep(), fork(), dan lain-lain.sys/wait.h: library standar C yang menyediakan fungsi untuk mengatur proses seperti wait(), waitpid(), dan lain-lain.dirent.h: library untuk mengakses direktori dan berkas-berkas yang ada di dalamnya.string.h: library standar C yang menyediakan fungsi-fungsi pemrosesan string seperti strcpy(), strcat(), dan lain-lain.sys/stat.h: library untuk mendapatkan informasi tentang status suatu berkas atau direktori seperti ukuran, waktu pembuatan, dan lain-lain.zip.h: library untuk melakukan kompresi dan dekompresi berkas dalam format ZIP.time.h: library untuk mengakses dan memanipulasi informasi waktu seperti tanggal, jam, dan lain-lain.sys/types.h: library standar C yang menyediakan definisi tipe data umum seperti pid_t, size_t, dan lain-lain.errno.h: library standar C yang menyediakan variabel errno untuk menangkap kesalahan sistem yang terjadi selama program berjalan.
Kemudian membuat 1 fungsi yaitu int main () sebagai program utama dengan berbagai fungsi didalamnya yaitu :
// diubah menjadi docs karena pake wget dan no check-certif (non-aktif ssl/tls saat unduh lwt https)
char *srcf_download = "wget --no-check-certificate 'https://docs.google.com/uc?export=download&id=1oDgj5kSiDO0tlyS7-20uz7t20X3atwrq' -O binatang.zip";
// Perintah untuk download file dari link
system(srcf_download);Untuk hasil-nya seperti berikut :
Penjelasan :
- Mendefinisikan perintah
downloadmenggunakanchar pointerdengan nama variabelsrcf_download - Menjalankan perintah
downloaddengan menggunakan perintahsystemdan bantuan perintahwgetdenganURL Drivediubah di-passing menjadiURL Docsuntuk mengunduh file secara non-interaktif dari jaringan (tidak memerlukan interaksi/input user). Opsi--no-check-certificatepada perintahwgetdigunakan untuk menonaktifkan SSL/TLS saat melakukan pengunduhan. -O binatang.zipmerupakan argumen untuk menentukan nama file dari hasil download. Dalam hal ini, tentu nama yang akan disimpan yaitu sesuai dengan nama file pada drive yaitubinatang.zip.
int pid, outStatus;
CURL *myCurl; //req http ke server untuk download (wget)
CURLcode resCurl; //def status hasil dari curl
FILE *fiPo; //repr file (menyimpan hasil download)
srand(time(NULL)); //inisiasi seed acakPenjelasan :
pidsebagai Process ID yang dihasilkan oleh fungsifork()nantinyaoutStatussebagai output status dari proses child yang dihasilkan oleh fungsiwaitpid()myCurlsebagai variabel untuk menyimpan pointer ke objek CURL, yang berfungsi untuk melakukan request HTTP menggunakan library curlresCurlsebagai variabel hasil yang digunakan untuk menyimpan hasil status operasi yang dijalankan oleh objek CURLfiPosebagai representasi file pointer untuk menyimpan pointer ke file yang akan digunakan untuk menyimpan hasil downloadsrand(time(NULL))digunakan untuk inisiasi seed acak dengan menggunakan fungsisrand()dan memasukkan nilaitime(NULL)sebagai parameter.
// Unzip file hasil download
pid = fork(); //make child process
if (pid == 0) {
execlp("unzip", "unzip", "binatang.zip", NULL);
exit(1);
} else if (pid > 0) {
waitpid(pid, &outStatus, 0);Untuk hasil-nya seperti berikut :
Penjelasan :
- Membuat child proses dengan
pid = fork() - Child proses digunakan untuk menjalankan perintah
unzippada filebinatang.zipdenganexeclp(). Jika gagal program akan terminate denganexit(1) - Setelah child proses selesai, maka parent process akan menunggu hingga child process selesai dijalankan menggunakan fungsi
waitpid()Fungsinya yaitu digunakan untuk menunggu hingga child process dengan pid yang diidentifikasi selesai dijalankan dan memberikan status keluaran (output) dari child process tersebut pada variabeloutStatus
//cek child process apakah clear (0 = sukses)
if (WIFEXITED(outStatus) && WEXITSTATUS(outStatus) == 0) {
// pilih file gambar acak
DIR *dir;
struct dirent *itm; //item to dirent
char *imgName = malloc(sizeof(char) * 500); //size name imgPenjelasan :
if (WIFEXITED(outStatus) && WEXITSTATUS(outStatus) == 0)digunakna untuk Memeriksa status keluaran child process. WIFEXITED digunakan untuk memeriksa apakah child process telah berakhir, dan WEXITSTATUS digunakan untuk memeriksa status keluaran dari child process. Dalam hal ini, jika status keluaran dari child process sama dengan0, maka child process dianggap berhasil dan program akan melanjutkan ke tahap selanjutnya.DIR *dirdigunakan untuk membuat pointer untuk direktori yang akan diproses.struct dirent *itmdigunakan untuk membuat pointer untuk item yang ditemukan dalam direktori.char *imgName = malloc(sizeof(char) * 500)digunakan untuk membuat pointerimgNamedengan alokasi memori sebesar500 byte.imgNameakan menyimpan nama file gambaracakyang dipilih selanjutnya.
//current dir
char *currDir = ".";
dir = opendir(currDir);
if (dir == NULL) {
perror("Gagal membuka direktori.");
exit(1);
}Penjelasan :
char *currDir = "."digunakan untuk mendefinisikan variabelcurrDirsebagai string dengan nilai".", yang merupakandirektori saat ini.dir = opendir(currDir)digunakan untuk membuka direktori yang diarahkan oleh variabel currDir menggunakan fungsi opendir. Fungsi ini akan mengembalikan pointer ke direktori yang telah dibuka.if (dir == NULL)digunakan untuk memeriksa apakah pembukaan direktori berhasil. Jika dir sama denganNULL, maka pembukaan direktori gagal dengan mengeluarkan pesan error"Gagal membuka direktori."dan program terminate denganexit(1).
if (dir != NULL) {
int fileCount = 0;
while ((itm = readdir(dir)) != NULL) {
//menangkap hanya nama file ber-ekstensi .jpg
if (strstr(itm->d_name, ".jpg") == NULL) {
continue;
}
//di generate random
if (rand() % ++fileCount == 0) {
strcpy(imgName, itm->d_name);
}
}
closedir(dir);
} else {
perror("");
return 1;
}Penjelasan :
- Kebalikan dengan kondisi sebelumnya, yaitu jika
dir != NULLatau berhasil membuka direktori maka melakukan inisiasi variabelfileCount(untuk menyimpan jumlah file gambar) dengan nilai0 - Kemudian dilakukan loop while untuk membaca
setiap itemdi dalam direktori hingga tidak ada lagi item yang bisa dibaca. - Didalam loop, dilakukan pengecekan apakah nama file mengandung ekstensi
".jpg". Jika tidak, maka loop dilanjutkan ke item selanjutnya. Loop hanya menangkap file yang mengandung ekstensi.jpg - Setelah itu, jika file memiliki ekstensi ".jpg",
increment nilai fileCount, lalu dilakukan perhitungan random untuk menentukan apakah file tersebut akan dipilih. Jika file terpilih (nilai random adalah 0), maka nama file disalin ke variabelimgName. - Setelah loop selesai, direktori ditutup dengan
closedir(dir). - Jika dir bernilai NULL (gagal membuka direktori), akan menampilkan pesan error dan mengembalikan nilai 1 (terminate).
// Shift Grape-kun menjaga hewan
printf("Saat ini, Grape-kun melakukan penjagaan hewan : %s\n\n", imgName);Untuk hasil-nya seperti berikut :
Penjelasan :
- Setelah dipilih secara acak, pilihan yang telah dipilih tersebut
dicetak dalam consoledengan menggunakanprintf
//array habitat
char* jenisHewan[] = {"HewanDarat", "HewanAmphibi", "HewanAir"};
//sum elemen dalam jenisHewan
int totalJenis = sizeof(jenisHewan) / sizeof(jenisHewan[0]); //ukuran total Penjelasan :
- Setelah berhasil memilih random, selanjutnya yaitu deklarasi array
jenisHewanberisi tiga elemen yaitu"HewanDarat","HewanAmphibi", dan"HewanAir" - Kemudian dilakukan
perhitungan jumlah elemen pada array jenisHewandengan cara menghitungtotal ukuran array dalam byte (sizeof(jenisHewan))dibagi denganukuran tiap elemen (sizeof(jenisHewan[0])) - Dengan cara ini, kita bisa mendapatkan jumlah total elemen pada array jenisHewan tanpa harus menghitung manual. Hasil perhitungan tersebut disimpan dalam variabel
totalJenis
// perulangan untuk cek direktori hewan
for (int idx = 0; idx < totalJenis; idx++) {
// inisiasi file/dir
struct stat FD = {};
// cek kondisi direktori
if (stat(jenisHewan[idx], &FD) == -1) {
if (mkdir(jenisHewan[idx], 0777) == -1) { // mode semua (rwx)
printf("Direktori gagal dibuat!\n");
exit(1);
} else {
printf("Direktori %s berhasil dibuat! \n", jenisHewan[idx]);
}
}
}Penjelasan :
- Setelah mendeklarasi array direktori, selanjutnya yaitu memeriksa direktori hewan dengan perulangan.
- Didalamnya di-inisiasi filde/direktori variabel
FDdenganstruct stat kosong - Setelah itu melakukan cek kondisi direktori dengan menggunakan stat. Fungsi ini akan mengembalikan nilai
-1jika tidak dapat membaca status dari direktori. - Jika direktori tidak ada, maka akan dibuat direktori baru menggunakan fungsi
mkdirdengan mode akses0777(semua memiliki hak akses read, write, dan execute). Jika tidak berhasil dibuat, maka program akan mencetak pesan"Direktori gagal dibuat!"dan program keluar/terminate dengan exit status1 - Sebaliknya, jika direktori berhasil dibuat, akan mencetak pesan
"Direktori %s berhasil dibuat!"dengan nama direktori yang dibuat.
*NB : Untuk membuat direktori tidak disertakan dokumentasi karena program hanya sekali jalan dari download hingga melakukan zipping, tetapi hanya ditampilkan berupa bukti pesan telah berhasil seperti berikut :
// Pindahkan file-file hewan sesuai habitat nya (direktori-nya)
system("find . -iname '*_darat.jpg' -exec mv -n {} HewanDarat/ \\;");
system("find . -iname '*_amphibi.jpg' -exec mv -n {} HewanAmphibi/ \\;");
system("find . -iname '*_air.jpg' -exec mv -n {} HewanAir/ \\;");
printf("Bagus! Hewan berhasil dipindahkan sesuai jenisnya.\n\n");
}
}Penjelasan :
- Setelah direktori berhasil dibuat, langkah selanjutnya yaitu
meng-klasifikasikanhewan sesuai denganjenisnya - Klasifikasi dengan menggunakan bantuan
systemdan perintahfindyang digunakan untuk mencari nama file dengan akhiran'*_darat.jpg','*_amphibi.jpg','*_air.jpg'pada direktori tempat program dijalankan. Kemudian dipindahkan sesuai jenisnya yaituHewanDarat/,HewanAmphibi/,HewanAir/. Pemindahan file-file ini dengan bantuan perintahmvdan argumen-nyang digunakan tersebut bertujuan agar file tidak ditimpa jika file dengan nama yang sama sudah ada di direktori tujuan. - Terakhir jika proses pemindahan sudah selesai, akan mengeluarkan pesan
"Bagus! Hewan berhasil dipindahkan sesuai jenisnya"
*NB : Untuk meng-klasifikasikan/memindahkan sesuai direktori jenis juga tidak disertakan dokumentasi karena program hanya sekali jalan dari download hingga melakukan zipping, tetapi hanya ditampilkan berupa bukti pesan telah berhasil seperti berikut :
//fungsi zip menggunakan data pointer
void zipDir(const char* dir_name) {
pid_t pid;
int statPros;
pid = fork(); // buat child proses
if (pid < 0) {
fprintf(stderr, "Yah Proses fork gagal!\n");
exit(EXIT_FAILURE);
} else if (pid == 0) {
// child process
char zip_name[100];
sprintf(zip_name, "%s.zip", dir_name);
execlp("zip", "zip", "-r", zip_name, dir_name, NULL);
exit(EXIT_SUCCESS);
} else {
// parent process
waitpid(pid, &statPros, 0);Penjelasan :
- Setelah di-klasifikasikan sesuai dengan jenisnya, langkah selanjutnya yaitu melakukan
zippada ketiga direktori tersebut - Langkah awal yaitu membuat fungsi
zipDirdengan satu argumen yaitudir_namemenggunakanconst char pointer - Setelah itu mendeklarasikan variabel
piddengan tipe datapid_tdan variabelstatProsdengan tipe dataint - Kemudian membuat child proses dengan
pid = fork() - Setelah membuat child proses, terdapat conditional statement dengan pernyataan jika
pid < 0maka kondisi gagal yang kemudian mengeluarkan pesan"Yah Proses fork gagal!"dan program akan selesai/terminate - Sebaliknya, jika kondisi
pid == 0maka program akan berjalan dengan mendeklarasikan variabelchar zip_name[100]dengan tipe datachardan berukuran100. - Setelah itu,
sprintf(zip_name, "%s.zip", dir_name)akan menyalinnama direktori (dir_name)ke variabelzip_namedengan menambahkan ekstensi.zip - Kemudian terdapat proses
execlp("zip", "zip", "-r", zip_name, dir_name, NULL)yang digunakan untuk menjalankan perintah zip dengan argumen-r (rekursif)dannama file zip (zip_name)yang ingin dicompress beserta direktorinya (dir_name). - Jika proses menjalankan perintah zip telah selesai maka program akan
exit(EXIT_SUCCESS) - Kondisi sebaliknya,
waitpid(pid, &statPros, 0)menunggu child process selesai dieksekusi dengan menggunakanwaitpiddan menyimpan status dari child process ke variabelstatPros.
// remove dir setelah zip
char rmvDir[100];
sprintf(rmvDir, "rm -rf %s", dir_name);
system(rmvDir);
}
}Penjelasan :
- Setelah proses zip selesai, dikarenakan pada perintah
agar menghemat penyimpanan, maka dilakukanremovepada folder yang sebelumnya dilakukanzip. - Langkah awal yang dilakukan yaitu dengan mendeklarasikan variabel
rmvDirsebagai array dengan panjang karakter100dan tipe datachar. - Setelah itu, dalam
sprintf(rmvDir, "rm -rf %s", dir_name)digunakansprintfuntuk memformat string ke variabel rmvDir. String ini akan berisi commandrm -rfyang akan digunakan untuk menghapus direktori dengan nama yang disimpan didir_name. - Dan pada akhirnya menggunakan bantuan
system(rmvDir)untuk menjalankan commandrm -rfuntuk menghapus direktori yang disimpan didir_name. Fungsi system digunakan untuk mengeksekusi command di dalam shell dan mengembalikan status hasil eksekusi.
// def value dari dir_name
char dirDar[100] = "HewanDarat";
char dirAmp[100] = "HewanAmphibi";
char dirAir[100] = "HewanAir";
// zip semua dir
zipDir(dirDar);
zipDir(dirAmp);
zipDir(dirAir);
printf("Selamat! Proses Zip folder berhasil.\n");
return 0;
}Untuk hasil-nya seperti berikut :
*Tampilan ketika didalam folder linux :
*Tampilan jika dibuka satu-per-satu dalam folder linux :
*Tampilan pesan console :
Penjelasan :
char dir...[100] = "Hewan..."merupakan variabel definisi dari argumendir_namepada fungsizipDirzipDir(...)merupakan proses fungsi dijalankan setelah melewati conditional statements- Setelah proses zip selesai, akan mengeluarkan pesan
"Selamat! Proses Zip folder berhasil"dan program selesai.
Thank you for visiting this repository, stay tuned for more projects!









