5
5
*/
6
6
#include "ssu_rsync.h"
7
7
8
+ // 옵션
9
+ bool option_r = false;
10
+ bool option_t = false;
11
+ bool option_m = false;
12
+
8
13
/**
9
14
* @brief ssu_rsync 메인 함수
10
15
* @param argc 인자 개수
@@ -16,71 +21,106 @@ int main(int argc, char *argv[])
16
21
struct timeval begin_t , end_t ;
17
22
18
23
// 파일 경로
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;
24
+ char src_path [MAX_BUFFER_SIZE ] = { 0 };
25
+ char dst_path [MAX_BUFFER_SIZE ] = { 0 };
26
26
27
27
// 유효 검사
28
+ char opt ;
29
+ struct stat statbuf ;
28
30
bool is_invalid = false;
29
31
bool is_src = false;
30
32
bool is_dst = false;
31
33
32
-
33
34
gettimeofday (& begin_t , NULL ); // 측정 시작
34
35
35
36
if (argc < 3 ) { // 인자 개수가 부족할 경우
36
37
fprintf (stderr , "ssu_rsync(): Usage: %s [OPTION] <SOURCE> <DESTINATION>\n" , argv [0 ]);
37
38
exit (1 );
38
39
}
39
40
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
- }
41
+ for (int i = 1 ; i < argc ; i ++ ) {
42
+ #ifdef DEBUG
43
+ printf ("ssu_rsync(): argv[%d] = %s\n" , i , argv [i ]);
44
+ #endif
45
+ // 옵션 생략
46
+ if (argv [i ][0 ] == '-' )
54
47
continue ;
55
- }
56
48
57
- // 목적 경로 파싱
49
+ // 타겟 경로 파싱
58
50
if (!is_src ) {
59
51
if (access (argv [i ], F_OK ) < 0 ) {
52
+ #ifdef DEBUG
60
53
fprintf (stderr , "ssu_rsync(): access error for %s\n" , argv [i ]);
54
+ #endif
61
55
is_invalid = true;
62
- exit (1 );
63
- } else
64
- realpath (argv [i ], src_path ); // 절대 경로로 변환
65
-
56
+ break ;
57
+ }
58
+
59
+ realpath (argv [i ], src_path ); // 절대 경로로 변환
60
+ #ifdef DEBUG
61
+ printf ("ssu_rsync(): src_path = %s\n" , src_path );
62
+ #endif
66
63
is_src = true;
67
64
continue ;
68
65
}
69
66
70
- // 위치 경로 파싱
67
+ // 동기화 경로 파싱
71
68
if (!is_dst ) {
72
69
if (access (argv [i ], F_OK ) < 0 ) {
70
+ #ifdef DEBUG
73
71
fprintf (stderr , "ssu_rsync(): access error for %s\n" , argv [i ]);
72
+ #endif
74
73
is_invalid = true;
75
- exit (1 );
76
- } else
77
- realpath (argv [i ], dst_path ); // 절대 경로로 변환
74
+ break ;
75
+ }
78
76
77
+ realpath (argv [i ], dst_path ); // 절대 경로로 변환
78
+ #ifdef DEBUG
79
+ printf ("ssu_rsync(): dst_path = %s\n" , dst_path );
80
+ #endif
81
+ lstat (dst_path , & statbuf );
82
+ if (!S_ISDIR (statbuf .st_mode )) { // 동기화 경로가 디렉토리가 아닐 경우
83
+ #ifdef DEBUG
84
+ fprintf (stderr , "ssu_rsync(): dst_path doesn't directory\n" );
85
+ #endif
86
+ is_invalid = true;
87
+ break ;
88
+ }
79
89
is_dst = true;
80
90
continue ;
81
91
}
82
92
}
83
93
94
+ // 옵션 파싱
95
+ while ((opt = getopt (argc , argv , "rtm" )) != -1 ) {
96
+ switch (opt ) {
97
+ case 'r' :
98
+ #ifdef DEBUG
99
+ printf ("ssu_rsync(): R option found\n" );
100
+ #endif
101
+ option_r = true;
102
+ break ;
103
+ case 't' :
104
+ #ifdef DEBUG
105
+ printf ("ssu_rsync(): T option found\n" );
106
+ #endif
107
+ option_t = true;
108
+ break ;
109
+ case 'm' :
110
+ #ifdef DEBUG
111
+ printf ("ssu_rsync(): M option found\n" );
112
+ #endif
113
+ option_m = true;
114
+ break ;
115
+ default :
116
+ #ifdef DEBUG
117
+ printf ("ssu_rsync(): invalid option found\n" );
118
+ #endif
119
+ is_invalid = true;
120
+ break ;
121
+ }
122
+ }
123
+
84
124
// 파싱 중 에러 발견
85
125
if (is_invalid )
86
126
exit (1 );
@@ -91,12 +131,34 @@ int main(int argc, char *argv[])
91
131
fprintf (stderr , "ssu_rsync(): <DESTINATION> doesn't exist\n" );
92
132
exit (1 );
93
133
}
94
-
134
+
135
+ syncronized (src_path , dst_path );
136
+
95
137
gettimeofday (& end_t , NULL ); // 측정 종료
96
138
ssu_runtime (& begin_t , & end_t ); // 실행 시간 출력
97
139
exit (0 );
98
140
}
99
141
142
+ /**
143
+ * @brief 동기화 함수
144
+ * @param src_path 타겟 경로
145
+ * @param dst_path 동기화 경로
146
+ */
147
+ void syncronized (char * src_path , char * dst_path ) // 동기화 함수
148
+ {
149
+ file_node * src_list ; // 타겟 경로 파일 목록
150
+ file_node * dst_list ; // 동기화 경로 파일 목록
151
+
152
+ src_list = make_list (src_path );
153
+ dst_list = make_list (dst_path );
154
+
155
+ compare_list (src_list , dst_list -> child ); // 파일 목록 트리 비교
156
+
157
+ free_list (src_list );
158
+ free_list (dst_list );
159
+
160
+ }
161
+
100
162
/**
101
163
* @brief 노드 생성
102
164
* @return 새로운 노드
@@ -191,6 +253,88 @@ int count_size(file_node *head) // 디렉토리 크기 반환
191
253
return size ;
192
254
}
193
255
256
+ /**
257
+ * @brief 파일 목록 트리 비교
258
+ * @param src_list 타겟 파일 목록
259
+ * @param dst_list 동기화 디렉토리 파일 목록
260
+ */
261
+ void compare_list (file_node * src_list , file_node * dst_list ) // 파일 목록 트리 비교
262
+ {
263
+ file_node * now ;
264
+
265
+ if (src_list == NULL || dst_list == NULL ) // 둘중 하나라도 비교 대상이 존재하지 않을 경우
266
+ return ;
267
+
268
+ now = src_list ;
269
+
270
+ while (now != NULL ) { // 타겟 파일 탐색
271
+
272
+ compare_file (now , dst_list );
273
+
274
+ if (option_r ) // R 옵션이 존재하는 경우
275
+ if (now -> child != NULL )
276
+ compare_list (now -> child , dst_list );
277
+
278
+ now = now -> next ;
279
+ }
280
+ }
281
+
282
+ /**
283
+ * @brief 파일 정보 비교
284
+ * @param src_file 타겟 파일 노드
285
+ * @param dst_file 동기화 디렉토리 파일 노드
286
+ */
287
+ int compare_file (file_node * src_file , file_node * dst_file ) // 파일 정보 비교
288
+ {
289
+ file_node * now ;
290
+
291
+ now = dst_file ;
292
+
293
+ while (now != NULL ) {
294
+
295
+ #ifdef DEBUG
296
+ printf ("compare_file(): src_file->name = %s, now->name = %s\n" , src_file -> name , now -> name );
297
+ #endif
298
+ if (!strcmp (src_file -> name , now -> name )) { // 해당 이름을 가진 파일이 기존에 이미 존재할 경우
299
+
300
+ #ifdef DEBUG
301
+ printf ("compare_file(): founded\n" );
302
+ #endif
303
+ src_file -> status = CHCKED ;
304
+
305
+ if (src_file -> attr .st_mtime != now -> attr .st_mtime ) { // 해당 파일이 수정되었을 경우
306
+ #ifdef DEBUG
307
+ printf ("compare_file(): mtime different\n" );
308
+ #endif
309
+ src_file -> status = MODIFY ; // 타겟 파일의 상태 변경
310
+ }
311
+
312
+ if (src_file -> size != now -> size ) { // 해당 파일의 크기가 변경되었을 경우
313
+
314
+ #ifdef DEBUG
315
+ printf ("compare_file(): size different\n" );
316
+ #endif
317
+ src_file -> status = MODIFY ;
318
+ }
319
+
320
+ now -> status = CHCKED ;
321
+ #ifdef DEBUG
322
+ printf ("compare_file(): src_file->status = %d, now->status = %d\n" , src_file -> status , now -> status );
323
+ #endif
324
+ return true;
325
+ }
326
+
327
+ if (option_r )
328
+ if (now -> child != NULL ) // 디렉토리 안에 파일이 존재할 경우
329
+ if (compare_file (src_file , now -> child ))
330
+ break ;
331
+
332
+ now = now -> next ;
333
+ }
334
+
335
+ return false;
336
+ }
337
+
194
338
/**
195
339
* @brief 모니터링 파일 목록 메모리 할당 해제
196
340
* @param head 트리의 루트 노드
0 commit comments