Skip to content

Commit 6785985

Browse files
committed
ssu_rsync basic function implement
1 parent 2da5440 commit 6785985

File tree

5 files changed

+244
-34
lines changed

5 files changed

+244
-34
lines changed

common.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#include "common.h"
22

33
/**
4-
* @brief 실행 시간 출력
5-
* @param begin_t 시작 시간
6-
* @param end_t 종료 시간
4+
* @brief 실행 시간 출력
5+
* @param begin_t 시작 시간
6+
* @param end_t 종료 시간
77
*/
8-
void ssu_runtime(struct timeval *begin_t, struct timeval *end_t) // 실행시간 출력
8+
void ssu_runtime(struct timeval *begin_t, struct timeval *end_t) // 실행 시간 출력
99
{
1010
end_t->tv_sec -= begin_t->tv_sec;
1111

cron_support.c

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
/**
22
* @file cron_support.c
3-
* @brief ssu_crontab, ssu_crond에서 공통적으로 사용되는 함수
4-
* @author 김병준 (kbj9704@gmail.com)
3+
* @brief ssu_crontab, ssu_crond에서 공통적으로 사용되는 함수
4+
* @author 김병준 (kbj9704@gmail.com)
55
*/
6-
76
#include "cron_support.h"
87

98
extern char reservation_command[BUFFER_SIZE][MAX_BUFFER_SIZE];
109

1110
/**
12-
* @brief 입력한 명령행을 토큰 구조체로 변환
13-
* @param command 명령행 토큰 구조체
14-
* @param command_buffer 명령 문자열
11+
* @brief 입력한 명령행을 토큰 구조체로 변환
12+
* @param command 명령행 토큰 구조체
13+
* @param command_buffer 명령 문자열
1514
*/
16-
void make_command_token(CommandToken *command, char *command_buffer) // 입력한 명령행을 토큰 구조체로 변환
15+
void make_command_token(CommandToken *command, char *command_buffer) // 입력한 명령행을 토큰 구조체로 변환
1716
{
1817
char *tmp;
1918
char *last;
@@ -36,16 +35,16 @@ extern char reservation_command[BUFFER_SIZE][MAX_BUFFER_SIZE];
3635
#ifdef DEBUG
3736
printf("make_command_token(): command->argv[%d] = %s\n", command->argc, tmp);
3837
#endif
39-
command->argv[command->argc] = (char *)calloc(BUFFER_SIZE, sizeof(char)); // 명령행 인자 메모리 공간 할당
38+
command->argv[command->argc] = (char *)calloc(BUFFER_SIZE, sizeof(char));
4039
strcpy(command->argv[command->argc++], tmp);
4140
}
4241
}
4342

4443
/**
45-
* @brief 명령행 구조체 초기화
46-
* @param command 명령행 구조체
44+
* @brief 명령행 구조체 초기화
45+
* @param command 명령행 구조체
4746
*/
48-
void free_command_token(CommandToken *command) // 명령행 구조체 초기화
47+
void free_command_token(CommandToken *command) // 명령행 구조체 초기화
4948
{
5049
int i;
5150

@@ -55,9 +54,9 @@ extern char reservation_command[BUFFER_SIZE][MAX_BUFFER_SIZE];
5554
}
5655

5756
/**
58-
* @brief 예약 명령 목록 가져오기
57+
* @brief 예약 명령 목록 가져오기
5958
*/
60-
int get_reservation_command(void) // 예약 명령 목록 가져오기
59+
int get_reservation_command(void) // 예약 명령 목록 가져오
6160
{
6261
FILE *fp;
6362

@@ -79,13 +78,13 @@ extern char reservation_command[BUFFER_SIZE][MAX_BUFFER_SIZE];
7978
}
8079

8180
/**
82-
* @brief 로그 파일에 이력 기록
83-
* @param command_type 명령 타입 번호
84-
* @param command 명령 문자열
81+
* @brief 로그 파일에 이력 기록
82+
* @param command_type 명령 타입 번호
83+
* @param command 명령 문자열
8584
*/
86-
void write_log(int command_type, char *command) // 로그 파일에 이력 기록
85+
void write_log(int command_type, char *command) // 로그 파일에 이력 기록
8786
{
88-
FILE *fp;
87+
//FILE *fp;
8988
time_t now_t;
9089
struct tm *now_tm;
9190
char temp[MAX_BUFFER_SIZE];

ssu_crontab.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,14 +256,11 @@ bool is_period(char *period, int period_type) // 주기 인자 검사
256256
while ((tmp = strtok(NULL, ",")) != NULL)
257257
#ifdef DEBUG
258258
{
259-
// 1-2. 맨 앞에 기호만 나왔을 경우
260-
if (tmp[0] == '-' || tmp[0] == '/')
261-
return false;
262259
printf("is_period(): type = %d, period_token[%d] = %s\n", period_type, period_token_count, tmp);
263260
strcpy(period_token[period_token_count++], tmp);
264261
}
265262
#else
266-
strcpy(period_token[period_token_count++], tmp);
263+
strcpy(period_token[period_token_count++], tmp);
267264
#endif
268265

269266
// 2. 슬래쉬(/), 바(-) 분리

ssu_rsync.c

Lines changed: 198 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,205 @@
55
*/
66
#include "ssu_rsync.h"
77

8-
int main(void)
8+
/**
9+
* @brief ssu_rsync 메인 함수
10+
* @param argc 인자 개수
11+
* @param argv 인자 문자열
12+
*/
13+
int main(int argc, char *argv[])
914
{
15+
// 실행 시간 측정
1016
struct timeval begin_t, end_t;
1117

12-
gettimeofday(&begin_t, NULL);
13-
printf("Rsync!\n");
14-
gettimeofday(&end_t, NULL);
15-
ssu_runtime(&begin_t, &end_t);
16-
return 0;
18+
// 파일 경로
19+
char src_path[MAX_BUFFER_SIZE];
20+
char dst_path[MAX_BUFFER_SIZE];
21+
22+
// 옵션
23+
bool option_r = false;
24+
bool option_t = false;
25+
bool option_m = false;
26+
27+
// 유효 검사
28+
bool is_invalid = false;
29+
bool is_src = false;
30+
bool is_dst = false;
31+
32+
33+
gettimeofday(&begin_t, NULL); // 측정 시작
34+
35+
if (argc < 3) { // 인자 개수가 부족할 경우
36+
fprintf(stderr, "ssu_rsync(): Usage: %s [OPTION] <SOURCE> <DESTINATION>\n", argv[0]);
37+
exit(1);
38+
}
39+
40+
for (int i = 0; i < argc; i++) {
41+
42+
// 옵션 파싱
43+
if (argv[i][0] == '-') {
44+
if (!strcmp(argv[i], "-r"))
45+
option_r = true;
46+
else if (!strcmp(argv[i], "-t"))
47+
option_t = true;
48+
else if (!strcmp(argv[i], "-m"))
49+
option_m = true;
50+
else {
51+
is_invalid = true;
52+
break;
53+
}
54+
continue;
55+
}
56+
57+
// 목적 경로 파싱
58+
if (!is_src) {
59+
if (access(argv[i], F_OK) < 0) {
60+
fprintf(stderr, "ssu_rsync(): access error for %s\n", argv[i]);
61+
is_invalid = true;
62+
exit(1);
63+
} else
64+
realpath(argv[i], src_path); // 절대 경로로 변환
65+
66+
is_src = true;
67+
continue;
68+
}
69+
70+
// 위치 경로 파싱
71+
if (!is_dst) {
72+
if (access(argv[i], F_OK) < 0) {
73+
fprintf(stderr, "ssu_rsync(): access error for %s\n", argv[i]);
74+
is_invalid = true;
75+
exit(1);
76+
} else
77+
realpath(argv[i], dst_path); // 절대 경로로 변환
78+
79+
is_dst = true;
80+
continue;
81+
}
82+
}
83+
84+
// 파싱 중 에러 발견
85+
if (is_invalid)
86+
exit(1);
87+
else if (!is_src) {
88+
fprintf(stderr, "ssu_rsync(): <SOURCE> doesn't exist\n");
89+
exit(1);
90+
} else if (!is_dst) {
91+
fprintf(stderr, "ssu_rsync(): <DESTINATION> doesn't exist\n");
92+
exit(1);
93+
}
94+
95+
gettimeofday(&end_t, NULL); // 측정 종료
96+
ssu_runtime(&begin_t, &end_t); // 실행 시간 출력
97+
exit(0);
98+
}
99+
100+
/**
101+
* @brief 노드 생성
102+
* @return 새로운 노드
103+
*/
104+
file_node *make_node(void) // 노드 생성
105+
{
106+
file_node *tmp = calloc(true, sizeof(file_node));
107+
108+
memset(tmp->name, 0, BUFFER_SIZE);
109+
tmp->next = NULL;
110+
tmp->child = NULL;
111+
tmp->namelist = NULL;
112+
tmp->size = 0;
113+
tmp->status = UNCHCK;
114+
115+
return tmp;
116+
}
117+
118+
/**
119+
* @brief 디렉토리 파일 목록 트리화
120+
* @param path 디렉토리 경로
121+
* @return 트리의 루트노드
122+
*/
123+
file_node *make_list(char *path) // 디렉토리 파일 목록 트리화
124+
{
125+
file_node *head, *now;
126+
// 파일 : 노드 생성(절대경로/이름, 상태정보)
127+
// 디렉토리: 트리 생성
128+
int file_count;
129+
int is_dirattr = true;
130+
int i;
131+
132+
// 부모: 현재 경로, 디렉토리 상태정보, 파일 목록 정보
133+
// 자식: 절대경로 파일이름, 파일 상태정보, 다음 파일 포인터 및 디렉토리 하위 부모노드 포인터
134+
head = make_node();
135+
now = head;
136+
137+
strcpy(head->name, path); // 현재 경로 저장
138+
stat(head->name, &(head->attr)); // 상태 정보 저장
139+
140+
file_count = scandir(head->name, &(head->namelist), NULL, alphasort); // 현재 경로의 모든 파일 탐색 및 개수 저장
141+
for(i = 0; i < file_count; i++) {
142+
143+
if(!strcmp(head->namelist[i]->d_name, ".") || !strcmp(head->namelist[i]->d_name, "..")) // 현재, 상위 디렉토리 접근 지정자 생략
144+
continue;
145+
146+
file_node *new = make_node(); // 새로운 노드 생성
147+
148+
sprintf(new->name, "%s/%s", path, head->namelist[i]->d_name); // 파일 이름 저장
149+
stat(new->name, &(new->attr));
150+
151+
if(S_ISDIR(new->attr.st_mode)) // 현재 경로의 파일 목록 중 탐색한 파일이 디렉토리일 경우
152+
new = make_list(new->name); // 해당 디렉토리 파일 목록 트리화
153+
else
154+
new->size = new->attr.st_size;
155+
156+
if(is_dirattr) { // 현재 노드가 현재 경로의 부모노드일 경우
157+
now->child = new;
158+
now = now->child;
159+
is_dirattr = false;
160+
} else { // 아닐 경우 형제로 연결
161+
now->next = new;
162+
now = now->next;
163+
}
164+
}
165+
head->size = count_size(head);
166+
return head;
167+
}
168+
169+
/**
170+
* @brief 디렉토리 크기 반환
171+
* @param 디렉토리 노드
172+
* @return 디렉토리 크기
173+
*/
174+
int count_size(file_node *head) // 디렉토리 크기 반환
175+
{
176+
file_node *now;
177+
int size;
178+
179+
size = false;
180+
181+
if(S_ISDIR(head->attr.st_mode))
182+
now = head->child;
183+
else
184+
return head->attr.st_size;
185+
186+
while(now != NULL) {
187+
size += now->size;
188+
now = now->next;
189+
}
190+
191+
return size;
192+
}
193+
194+
/**
195+
* @brief 모니터링 파일 목록 메모리 할당 해제
196+
* @param head 트리의 루트 노드
197+
*/
198+
void free_list(file_node *head) // 모니터링 파일 목록 메모리 할당 해제
199+
{
200+
// 모든 노드들을 찾아서 메모리 할당을 해제한다.
201+
if(head->child != NULL) // 자식 탐색
202+
free_list(head->child);
203+
204+
if(head->next != NULL) // 형제 탐색
205+
free_list(head->next);
206+
207+
free(head->namelist);
208+
free(head); // 메모리 엑세스 허용
17209
}

ssu_rsync.h

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,33 @@
11
/**
22
* @file ssu_rsync.h
3-
* @brief ssu_rsync에서 사용되는 라이브러리, 매크로 정의
4-
* @author 김병준 (kbj9704@gmail.com)
3+
* @brief ssu_rsync에서 사용되는 라이브러리, 매크로, 프로토타입 선언
4+
* @author 김병준 (kbj9704@gmail.com)
55
*/
66
#ifndef SSU_RSYNC_H
77
#define SSU_RSYNC_H
88

9+
#include <dirent.h>
10+
#include <sys/stat.h>
911
#include "common.h"
1012

13+
// 모니터링 상태
14+
#define UNCHCK -1
15+
#define CHCKED 0
16+
#define CREATE 2
17+
#define MODIFY 3
18+
19+
typedef struct ssu_fileNode{ // 모니터링 파일 목록 구조체
20+
char name[BUFFER_SIZE]; // 파일 이름
21+
struct stat attr; // 파일 상태 정보
22+
struct dirent **namelist; // 디렉토리 경우 하위 파일 목록
23+
struct ssu_fileNode *next; // 하위 디렉토리 파일 포인터
24+
struct ssu_fileNode *child; // 같은 레벨의 다음 파일 포인터
25+
int size; // 파일 크기
26+
int status; // 모니터링 확인 상태
27+
} file_node;
28+
29+
file_node *make_node(void); // 노드 생성
30+
file_node *make_list(char *path); // 디렉토리 파일 목록 트리화
31+
int count_size(file_node *head); // 디렉토리 크기 반환
32+
void free_list(file_node *head); // 모니터링 파일 목록 메모리 할당 해제
1133
#endif // SSU_RSYNC_H

0 commit comments

Comments
 (0)