//myls.c
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <pwd.h>
#include <grp.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#define BUF_SIZE 512
#define mode_l "-l"
#define mode_a "-a"
#define mode_al "-al"
#define mode_nomal "nomal"
char type(mode_t mode);
char* perm(mode_t mode);
void printStat(char* pathname, char* file, struct stat* st);
void ls(char* dir, char* mode);
void ls_nomal(char* dir);
void file_l(char* filename, char* mode);
void file_nomal(char* filename, char* mode);
char path[BUF_SIZE];
int main(int argc, char** argv) {
char* dir;
if (argc == 1) { // myls
dir = ".";
ls(dir, mode_nomal);
}
else if (argc == 2) { // myls -a/-l/filename/dir
dir = ".";
ls(dir, argv[1]);
}
else if (argc == 3) { // myls -a/-l/-al filename/dir
ls(argv[2], argv[1]);
}
else {
printf("입력 error\n");
return 0;
}
exit(0);
}
void file_nomal(char* filename,char *mode) {
DIR* dp;
struct dirent* d;
char dir[BUF_SIZE];
int set = 1;
memset(dir, 0, BUF_SIZE);
sprintf(dir, "./%s", filename);
if ((dp = opendir(dir)) == NULL) {
memset(dir, 0, BUF_SIZE);
sprintf(dir, ".");
if ((dp = opendir(dir)) == NULL)
perror("dir error");
}
while ((d = readdir(dp)) != NULL) {
if (!strcmp(filename, d->d_name)) {
printf("%10s ", d->d_name);
set = 0;
}
}
closedir(dp);
if (set)
ls_nomal(filename);
}
void file_l(char* filename, char *mode) {
DIR* dp;
struct dirent* d;
struct stat st;
int set = 1;
char* dir = ".";
if ((dp = opendir(dir)) == NULL)
perror("name error");
while ((d = readdir(dp)) != NULL) {
if (!strcmp(d->d_name, filename)) {
sprintf(path, "%s/%s", dir, d->d_name);
if (lstat(path, &st) < 0)
perror(path);
printStat(path, d->d_name, &st);
putchar('\n');
}
}
closedir(dp);
}
void printStat(char* pathname, char* file, struct stat* st) {
//printf("%5ld ", st->st_blocks);
printf("%c%s ", type(st->st_mode), perm(st->st_mode));
printf("%3ld ", st->st_nlink);
printf("%s %s ", getpwuid(st->st_uid)->pw_name, getgrgid(st->st_gid)->gr_name);
printf("%9ld ", st->st_size);
printf("%.12s ", ctime(&st->st_mtime) + 4);
printf("%s", file);
}
char type(mode_t mode) {
if (S_ISREG(mode))
return('-');
if (S_ISDIR(mode))
return('d');
if (S_ISCHR(mode))
return('c');
if (S_ISBLK(mode))
return('b');
if (S_ISLNK(mode))
return('l');
if (S_ISFIFO(mode))
return('p');
if (S_ISSOCK(mode))
return('s');
}
char* perm(mode_t mode) {
int i;
static char perms[10];
strcpy(perms, "---------");
for (i = 0; i < 3; i++) {
if (mode & (S_IREAD >> i * 3))
perms[i * 3] = 'r';
if (mode & (S_IWRITE >> i * 3))
perms[i * 3 + 1] = 'w';
if (mode & (S_IEXEC >> i * 3))
perms[i * 3 + 2] = 'x';
}
return(perms);
}
void ls_nomal(char* dir) {
DIR* dp;
struct dirent* d;
struct stat st;
if ((dp = opendir(dir)) == NULL)
perror("name error");
while ((d = readdir(dp)) != NULL)
if (strncmp(d->d_name, ".", 1))
printf("%s\n", d->d_name);
closedir(dp);
}
void ls(char *dir,char* mode) {
DIR* dp;
struct dirent* d;
struct stat st;
if ((dp = opendir(dir)) == NULL) {
if (!strcmp(mode, mode_l) || !strcmp(mode, mode_al))
file_l(dir, mode);
else
file_nomal(dir, mode);
}
else {
if (!strcmp(mode, mode_a)) {
while ((d = readdir(dp)) != NULL)
printf("%s\n", d->d_name);
}
else if (!strcmp(mode, mode_l)) {
while ((d = readdir(dp)) != NULL) {
if (strncmp(d->d_name, ".", 1)) { // 숨김파일이 아니면
sprintf(path, "%s/%s", dir, d->d_name);
if (lstat(path, &st) < 0)
perror(path);
printStat(path, d->d_name, &st);
putchar('\n');
}
}
}
else if (!strcmp(mode, mode_al)) {
while ((d = readdir(dp)) != NULL) {
sprintf(path, "%s/%s", dir, d->d_name);
if (lstat(path, &st) < 0)
perror(path);
printStat(path, d->d_name, &st);
putchar('\n');
}
}
else if (!strcmp(mode, mode_nomal)) {
ls_nomal(dir);
}
else
file_nomal(mode, mode_nomal);
}
closedir(dp);
}