Skip to content

Instantly share code, notes, and snippets.

@kimhoki
Created June 16, 2015 11:28
Show Gist options
  • Save kimhoki/812951ddc4d3ed7cea97 to your computer and use it in GitHub Desktop.
Save kimhoki/812951ddc4d3ed7cea97 to your computer and use it in GitHub Desktop.
[미완성]_myls
//*********************************************************************
// My ls Ver 0.1.0
//2007 Made By Paek Jae-Dong
//E-mail: pjd@kw.ac.kr
//Blog: rabe.egloos.com
//*********************************************************************
// My ls Ver 0.2.1
//2015 Made By kimhoki
//E-mail: exampleohki@gmail.com
//Blog: blog.naver.com/exampleohki
//*********************************************************************
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
//#include <term.h>
#define PATH_LENGTH 200
//옵션에대한 값을 지정
#define FLAG_ALL 0x01
#define FLAG_INODE 0x02
#define FLAG_LONG 0x04
#define FLAG_RECUR 0x08
#define FILEINFO struct file_info
//파일길이를 지정
#define FILENAME_SIZE 256
struct file_info{
char filename[FILENAME_SIZE+1];
unsigned long inode;
unsigned long mode;
unsigned long nlink;
unsigned long uid;
unsigned long gid;
unsigned long size;
//마지막 수정시간 출력
time_t atime;
//이 파일이 차지하는 block수
unsigned long blocks;
struct file_info *next;
};
void seek_dir(char *dir,int opt); //디렉토리를 순회하는 함수
void print_long(FILEINFO *list_head,int opt); //-l옵션이 있을때 화면에 파일정보를 출력함
//-l옵션이 있을때 파일정보를 링크드리스트에 저장하는 함수
void save_long(FILEINFO **list_head,struct stat *cur_stat,struct dirent *cur_dir,int opt);
void print_normal(FILEINFO *list_head,int opt); //-l 옵션이 없을때 화면에 파일정보를 출력하는 함수
//-l 옵션이 없을때 파일정보를 링크드리스트에 저장하는 함수
void save_normal(FILEINFO **list_head,struct stat *cur_stat,struct dirent *cur_dir,int opt);
void free_list(FILEINFO *list_head); //링크드리스트의 메모리를 해제하는 함수
void sort_list(FILEINFO *list_head); //링크드리스트에 저장된 자료를 파일이름순으로 정렬하는 함수
int long_len(unsigned long num); //unsigned long 값을 입력받아 자리수를 리턴하는 함수
static void usage(void);
int main(int argc,char** argv)
{
// int a = 0;
char i,j=0;
int ret;
int opt=0; //옵션을 저장하는 변수
char path[PATH_LENGTH]; // 실행시 path옵션을 안주었을때의 디폴트 경로값
char a[10][100];
while ((ret = getopt(argc, argv, "AaCcdFfhiklnqRrSstuwx1: ")) != -1)
{
//while( optind < argc)
//printf( " %s\n", argv[optind++]);
switch(ret)
{
case 'A': opt |= FLAG_ALL; break;
case 'a': opt |= FLAG_ALL; break;
case 'C': break;
case 'c': break;
case 'd': break;
case 'F': break;
case 'f': break;
case 'h': break;
case 'i': opt |= FLAG_INODE; break;
case 'k': break;
case 'l': opt |= FLAG_LONG; break;
case 'n': break;
case 'q': break;
case 'R': opt |= FLAG_RECUR; break;
case 'r': break;
case 'S': break;
case 's': break;
case 't': break;
case 'u': break;
case 'w': break;
case 'x': break;
case '1': break;
default: break;
}
}
/**
argc -= optind;
argv += optind;
* path[i] = *(int*)argv[optind++];
* argv = (char**)&path;
**/
for(i=0; optind < argc; optind++)
path[i++] = *(int*)argv[optind];
printf("%d\n",path[i]);
// for(i=0; i==NULL; i++)
// printf("%d",path[i++]);
//while( optind < argc)
// strcpy(a,argv[optind]);
// printf( " %s \n", argv[optind++]);
// printf("%c[1;31m",27); //색변경
// printf("\ndirectory path:");
// seek_dir(path,opt); //디렉토리를 순회함
// printf("%c[0m\n",27); //색변경
return 0;
}
int long_len(unsigned long num) //화면에 정렬하여 출력하기위하여 칸수를 계산
{
int nCount=0;
while( num%10 || num/10 ){
num /=10;
nCount++;
}
return nCount;
}
void free_list(FILEINFO *list_head){
FILEINFO *tmp_list;
while(list_head != NULL){ //메모리 해제하기
tmp_list = list_head;
list_head = list_head->next;
free(tmp_list);
}
}
//링크드리스트에 들어있는자료를 파일이름순으로 정렬
void sort_list(FILEINFO *list_head){
FILEINFO *tmp_list_left;
FILEINFO *tmp_list_right;
FILEINFO tmp_list;
FILEINFO *tmp_listp;
if( list_head == NULL )
return ;
if( list_head->next == NULL)
return ;
tmp_list_left = list_head;
tmp_list_right = list_head->next;
while( tmp_list_left->next != NULL){
while(tmp_list_right != NULL){
//두개의 리스트를 서로 exchange하는 코드
if( strcmp(tmp_list_left->filename,tmp_list_right->filename) >0 ){
memcpy(&tmp_list , tmp_list_left,sizeof(FILEINFO));
memcpy(tmp_list_left , tmp_list_right,sizeof(FILEINFO));
memcpy(tmp_list_right , &tmp_list,sizeof(FILEINFO));
tmp_listp = tmp_list_left->next;
tmp_list_left->next = tmp_list_right->next;
tmp_list_right->next = tmp_listp;
}
tmp_list_right = tmp_list_right->next;
}
tmp_list_left = tmp_list_left->next;
tmp_list_right = tmp_list_left->next;
}
}
void seek_dir(char *dir,int opt)
{
DIR *dp;
struct dirent *entry;
struct stat tmp_stat;
FILEINFO *tmp_list;
FILEINFO *list_head;
list_head = NULL;
printf("%c[1;31m",27); //색변경
printf("%s\n",dir); //경로를 출력
if((dp = opendir(dir)) == NULL){ //디렉토리 스트림을 Open함
fprintf(stderr,"directory open error: %s\n",dir);
return;
}
chdir(dir);
while((entry = readdir(dp)) != NULL){ //디렉토리정보를 한개씩 읽어옴
lstat(entry->d_name, &tmp_stat);
if( opt & FLAG_LONG) //옵션에 따라 파일정보를 저장하는 방식을 달리함
save_long(&list_head,&tmp_stat,entry,opt);
else
save_normal(&list_head,&tmp_stat,entry,opt);
}
sort_list(list_head); //읽어온 자료를 정렬함
if( opt & FLAG_LONG) //옵션에 따라 파일정보를 출력하는 방식을 달리함
print_long(list_head,opt);
else
print_normal(list_head,opt);
tmp_list = list_head;
while( tmp_list != NULL) {
if(S_ISDIR(tmp_list->mode)){
// '.' 과 '..'은 재귀 에서 배제함
if( strcmp(".",tmp_list->filename) == 0 || strcmp("..",tmp_list->filename) == 0 ){
tmp_list = tmp_list->next;
continue;
}
if( opt & FLAG_RECUR){ //재귀 옵션이 있을때만 실행
printf("%c[1;31m",27); //색변경
printf("\n\ndirectory path:%s",dir);
seek_dir(tmp_list->filename,opt);
}
}
tmp_list = tmp_list->next;
}
chdir("..");
closedir(dp);
free_list(list_head); //파일정보가 저장된 메모리를 해제함
}
void save_long(FILEINFO **list_head,struct stat *cur_stat,struct dirent *cur_dir,int opt)
{
FILEINFO *cur_list=(*list_head);
if( *list_head != NULL)
while( cur_list->next != NULL)
cur_list = cur_list->next;
if( cur_dir->d_name[0] == '.' )
if( !(opt & FLAG_ALL) )
return; //all옵션이 없으면 .으로 시작하는 파일은 스킵힌다.
if( (*list_head) == NULL){ //리스트의 맨처음일때
cur_list = (FILEINFO *)malloc(sizeof(FILEINFO));
cur_list->next = NULL;
*list_head = cur_list;
}else{
cur_list->next = (FILEINFO *)malloc(sizeof(FILEINFO));
cur_list = cur_list->next;
cur_list->next = NULL;
}
cur_list->inode = cur_stat->st_ino;
cur_list->mode = cur_stat->st_mode;
strcpy(cur_list->filename ,cur_dir->d_name);
//hard-link 수
cur_list->nlink = cur_stat->st_nlink;
//User ID
cur_list->uid = cur_stat->st_uid;
//Group ID
cur_list->gid = cur_stat->st_gid;
//File Size
cur_list->size = cur_stat->st_size;
//마지막 수정시간
cur_list->atime = cur_stat->st_atime; //시간값을 분석하여 구조체에 저장
//이 파일이 차지하는 block수
cur_list->blocks = cur_stat->st_blocks;
}
void print_long(FILEINFO *list_head,int opt)
{
FILEINFO *cur_list;
unsigned long tmp_perm;
struct tm *tm_ptr;
int i;
cur_list = list_head;
while(cur_list != NULL){
tmp_perm = cur_list->mode;
//File Type에따라서 출력할 색을 달리함
if(S_ISREG(cur_list->mode)){
if(cur_list->mode & 01001001) //실행파일인지 검사
printf("%c[1;32m",27);
else
printf("%c[0m",27);
printf("REG ");
}else if(S_ISDIR(cur_list->mode)){
printf("%c[1;34m",27);
printf("DIR ");
}else if(S_ISCHR(cur_list->mode)){
printf("%c[1;37m",27);
printf("CHR ");
}else if(S_ISBLK(cur_list->mode)){
printf("%c[1;33m",27);
printf("BLK ");
}else if(S_ISFIFO(cur_list->mode)){
printf("%c[1;37m",27);
printf("FIFO ");
}else if(S_ISLNK(cur_list->mode)){
printf("%c[1;36m",27);
printf("LNK ");
}else if(S_ISSOCK(cur_list->mode)){
printf("%c[1;35m",27);
printf("SOCK ");
}
//#define setcolor_CYAN(); printf("%c[1;36m",27);
//30->기본색 밝은 회색
//31->밝은 빨강
//32->실행파일 녹색
//33-> 노랑
//34->디렉토리 밝은파랑
//35->연보라
//36-> 밝은 CYAN 링크
//37->밝은 흰색
if(opt & FLAG_INODE)
printf("%u ",(unsigned int)cur_list->inode);
//Permission 출력
for(i=0;i<3;i++)
{
if(tmp_perm & S_IRUSR)
printf("r");
else
printf("-");
if(tmp_perm & S_IWUSR)
printf("w");
else
printf("-");
if(tmp_perm & S_IXUSR)
printf("x");
else
printf("-");
tmp_perm <<=3;
}
//hard-link 수 출력
printf(" %2u",(unsigned int)cur_list->nlink);
//User ID출력
printf(" %5u",(unsigned int)cur_list->uid);
//Group ID출력
printf(" %5u",(unsigned int)cur_list->gid);
//File Size 출력
printf(" %12u",(unsigned int)cur_list->size);
//마지막 수정시간 출력
tm_ptr = gmtime(&cur_list->atime); //시간값을 분석하여 구조체에 저장
printf(" %02d/%02d/%2d %02d:%02d",tm_ptr->tm_year%100,tm_ptr->tm_mon,tm_ptr->tm_mday,tm_ptr->tm_hour,tm_ptr->tm_min);
//이 파일이 차지하는 block수
printf("%5u",(unsigned int)cur_list->blocks);
//파일이름 출력
printf(" %s",cur_list->filename);
printf("\n");
cur_list = cur_list->next;
}
}
void save_normal(FILEINFO **list_head,struct stat *cur_stat,struct dirent *cur_dir,int opt)
{
FILEINFO *cur_list=*list_head;
if( *list_head != NULL)
while( cur_list->next != NULL)
cur_list = cur_list->next;
if( cur_dir->d_name[0] == '.')
if( !(opt & FLAG_ALL) )
return; //all옵션이 없으면 .과 ..은 스킵한다.
if( (*list_head) == NULL){ //리스트의 맨처음일때
cur_list = (FILEINFO *)malloc(sizeof(FILEINFO));
cur_list->next = NULL;
*list_head = cur_list;
}else{
cur_list->next = (FILEINFO *)malloc(sizeof(FILEINFO));
cur_list = cur_list->next;
cur_list->next = NULL;
}
cur_list->inode = cur_stat->st_ino;
cur_list->mode = cur_stat->st_mode;
strcpy(cur_list->filename ,cur_dir->d_name);
}
void print_normal(FILEINFO *list_head,int opt)
{
FILEINFO *cur_list;
int i,j;
int col_length_name[15]; //정렬을위해 칸 너비를 저장하는 배열
int col_length_inode[15];
int col_num=0;
int nCount;
int index;
int term_x,term_y; //터미널의 크기를 읽어오는 함수
for(i=0;i<15;i++){
col_length_name[i] = 0;
col_length_inode[i] = 0;
}
//터미널 화면의 크기 정보를 얻어옴
//setupterm(NULL,fileno(stdout),(int *)0);
term_y = 30;//tigetnum("lines"); //현재 터미널의 크기를 얻어온다.
term_x = 30;//tigetnum("cols");
for(j=15;j>0;j--){
cur_list = list_head;
index =0;
nCount = 0;
//파일 정보 출력시 세로정렬을 위한 최적의 칸 너비를 계산하는 코드부분
while(cur_list != NULL){
if( col_length_name[index%j] < strlen(cur_list->filename) )
col_length_name[index%j] = strlen(cur_list->filename);
if( opt & FLAG_INODE){
if( col_length_inode[index%j] < long_len(cur_list->inode) )
col_length_inode[index%j] =long_len(cur_list->inode);
}
nCount = 0;
for(i=0;i<j;i++){
nCount += col_length_name[i]+2;
if( opt & FLAG_INODE)
nCount += col_length_inode[i]+1;
}
if(term_x < nCount)
break;
nCount = 0;
index ++;
index = index %j;
cur_list = cur_list->next;
}
if(cur_list == NULL){
col_num = j;
break;
}
}
cur_list = list_head;
index = 0;
while(cur_list != NULL){
if(S_ISREG(cur_list->mode)){
if(cur_list->mode & 01001001) //실행파일인지 검사
printf("%c[1;32m",27);
else
printf("%c[0m",27);
}else if(S_ISDIR(cur_list->mode)){
printf("%c[1;34m",27);
}else if(S_ISCHR(cur_list->mode)){
printf("%c[1;37m",27);
}else if(S_ISBLK(cur_list->mode)){
printf("%c[1;33m",27);
}else if(S_ISFIFO(cur_list->mode)){
printf("%c[1;37m",27);
}else if(S_ISLNK(cur_list->mode)){
printf("%c[1;36m",27);
}else if(S_ISSOCK(cur_list->mode)){
printf("%c[1;35m",27);
}
if( opt & FLAG_INODE )
printf(" %*u",col_length_inode[index],(unsigned int)cur_list->inode);
printf(" %*s ",col_length_name[index],cur_list->filename);
cur_list = cur_list->next;
if( index == col_num -1)
printf("\n");
index ++;
index = index % col_num;
}
}
static void usage(void)
{
(void)fprintf(stderr,
"usage: ls [-AaCcdFfhiklnqRrSstuwx1] [file ...]\n");
exit(EXIT_FAILURE);
}
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char a[10][100];
int i, j=0;
if(argc <2)
return 0;
for(i=1; i< argc; i++)
{
strcpy(a[j++],argv[i]);
}
for(i =0; i<j ; i++)
printf("a[%d]: %s\n",i,a[i]);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment