Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 5e8bbc3

Browse files
committed
implement ssu_rsync base, -r, -m complete
1 parent 960ee46 commit 5e8bbc3

File tree

2 files changed

+171
-22
lines changed

2 files changed

+171
-22
lines changed

‎ssu_rsync.c‎

Lines changed: 164 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,21 @@ char src_path[MAX_BUFFER_SIZE] = { 0 }; // 타겟 경로
1111
char dst_path[MAX_BUFFER_SIZE] = { 0 }; // 동기화 경로
1212
char swap_path[MAX_BUFFER_SIZE] = { 0 }; // 스왑 파일
1313

14+
// 옵션
1415
bool option_r = false; // R 옵션
1516
bool option_t = false; // T 옵션
1617
bool option_m = false; // M 옵션
1718
bool is_complete = false; // 동기화 완료 확인
1819

20+
// 디스크럽터
1921
int in_fd; // 표준 입력
2022
int out_fd; // 표준 출력
2123
int err_fd; // 표준 에러
2224

23-
change_file change_list[BUFFER_SIZE]; // 변경 목록
25+
file_node change_list[BUFFER_SIZE]; // 변경 목록
26+
char **saved_argv;
27+
int saved_argc;
28+
2429

2530
/**
2631
* @brief ssu_rsync 메인 함수
@@ -46,14 +51,16 @@ int main(int argc, char *argv[])
4651
gettimeofday(&begin_t, NULL); // 측정 시작
4752

4853
if (argc < 3) { // 인자 개수가 부족할 경우
49-
fprintf(stderr, "ssu_rsync(): Usage: %s [OPTION] <SOURCE> <DESTINATION>\n", argv[0]);
54+
print_usage(argv[0]);
5055
exit(1);
5156
}
5257

5358
getcwd(pwd, MAX_BUFFER_SIZE);
5459
signal(SIGUSR1, swap_handler);
5560
signal(SIGUSR2, swap_handler);
5661

62+
copy_argument(argc, argv);
63+
5764
for (int i = 1; i < argc; i++) {
5865
#ifdef DEBUG
5966
printf("ssu_rsync(): argv[%d] = %s\n", i, argv[i]);
@@ -138,13 +145,8 @@ int main(int argc, char *argv[])
138145
}
139146

140147
// 파싱 중 에러 발견
141-
if (is_invalid)
142-
exit(1);
143-
else if (!is_src) {
144-
fprintf(stderr, "ssu_rsync(): <SOURCE> doesn't exist\n");
145-
exit(1);
146-
} else if (!is_dst) {
147-
fprintf(stderr, "ssu_rsync(): <DESTINATION> doesn't exist\n");
148+
if (is_invalid || !is_src || !is_dst) {
149+
print_usage(argv[0]);
148150
exit(1);
149151
}
150152

@@ -169,6 +171,21 @@ int main(int argc, char *argv[])
169171
exit(0);
170172
}
171173

174+
/**
175+
* @brief 명령행 인자 백업
176+
* @param argc 인자 개수
177+
* @param argv 인자 문자열 배열
178+
*/
179+
void copy_argument(int argc, char *argv[]) // 명령행 인자 백업
180+
{
181+
saved_argc = argc;
182+
saved_argv = calloc(argc, sizeof(char*));
183+
for(int i = 0; i < saved_argc; i++) {
184+
saved_argv[i] = calloc(MAX_BUFFER_SIZE, sizeof(char));
185+
strcpy(saved_argv[i], argv[i]);
186+
}
187+
}
188+
172189
/**
173190
* @brief 표준 입출력 전환
174191
* @param signo 시그널
@@ -221,6 +238,11 @@ void syncronize(char *src_path, char *dst_path) // 동기화 함수
221238
if (option_m)
222239
change_count = write_change_list(dst_list->child, change_count, DELETE, true); // 삭제 혹은 수정된 파일 확인
223240

241+
//if (option_t)
242+
// refresh_tar(change_count);
243+
//else
244+
renewal(change_count);
245+
224246
free_list(src_list);
225247
free_list(dst_list);
226248
is_complete = true;
@@ -342,8 +364,8 @@ void compare_list(file_node *src_list, file_node *dst_list) // 파일 목록 트
342364

343365
compare_file(now, dst_list);
344366

345-
if (now->child != NULL)
346-
compare_list(now->child, dst_list);
367+
if (now->child != NULL)
368+
compare_list(now->child, dst_list);
347369

348370
now = now->next;
349371
}
@@ -398,9 +420,9 @@ bool compare_file(file_node *src_file, file_node *dst_file) // 파일 정보 비
398420
return true;
399421
}
400422

401-
if(now->child != NULL) // 디렉토리 안에 파일이 존재할 경우
402-
if(compare_file(src_file, now->child))
403-
break;
423+
if(now->child != NULL) // 디렉토리 안에 파일이 존재할 경우
424+
if(compare_file(src_file, now->child))
425+
break;
404426

405427
now = now->next;
406428
}
@@ -462,6 +484,123 @@ int write_change_list(file_node *head, int idx, int status, bool is_first) //
462484
return idx;
463485
}
464486

487+
/**
488+
* @brief 파일 동기화
489+
* @param count 변경 사항 개수
490+
*/
491+
void renewal(int count) // 파일 동기화
492+
{
493+
int src_fd, dst_fd;
494+
char path[MAX_BUFFER_SIZE];
495+
char buf[MAX_BUFFER_SIZE];
496+
struct stat statbuf;
497+
struct utimbuf attr;
498+
size_t length;
499+
500+
for (int i = 0; i < count; i++) {
501+
502+
switch (change_list[i].status) {
503+
case DELETE:
504+
505+
lstat(change_list[i].name, &statbuf);
506+
if (S_ISDIR(statbuf.st_mode))
507+
remove_directory(change_list[i].name);
508+
else
509+
remove(change_list[i].name);
510+
break;
511+
512+
case CREATE:
513+
case MODIFY:
514+
515+
memset(path, 0, MAX_BUFFER_SIZE);
516+
517+
lstat(change_list[i].name, &statbuf);
518+
sprintf(path, "%.*s/%s", (int)strlen(dst_path), dst_path, change_list[i].name + strlen(pwd) + 1); // 동기화 파일 경로 생성
519+
520+
if (S_ISDIR(statbuf.st_mode))
521+
mkdir(path, 0755);
522+
else {
523+
if ((src_fd = open(change_list[i].name, O_RDONLY)) < 0) { // 타겟 읽기 전용 열기
524+
fprintf(stderr, "renewal(): open error for %s\n", change_list[i].name);
525+
break;
526+
}
527+
528+
if ((dst_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, statbuf.st_mode)) < 0) { // 동기화 파일 열기
529+
fprintf(stderr, "renewal(): open error for %s\n", path);
530+
break;
531+
}
532+
533+
while ((length = read(src_fd, buf, MAX_BUFFER_SIZE)) > 0) // 동기화 파일 쓰기 (새로쓰기 혹은 덮어쓰기)
534+
write(dst_fd, buf, length);
535+
536+
close(src_fd);
537+
close(dst_fd);
538+
}
539+
540+
// 동기화 파일 속성 및 권한 복원
541+
attr.actime = statbuf.st_atime;
542+
attr.modtime = statbuf.st_mtime;
543+
utime(path, &attr);
544+
chmod(path, statbuf.st_mode);
545+
break;
546+
}
547+
}
548+
549+
write_log(count);
550+
}
551+
552+
/**
553+
* @brief 로그 파일 작성
554+
* @param 변경 사항 개수
555+
*/
556+
void write_log(int count) // 로그 파일 작성
557+
{
558+
FILE *fp;
559+
time_t now_t;
560+
struct tm *now_tm;
561+
char command[MAX_BUFFER_SIZE];
562+
563+
if (count == 0) {
564+
fprintf(stderr, "write_log(): up-to-date %s\n", dst_path);
565+
return;
566+
}
567+
568+
if ((fp = fopen(RSYNC_LOG, "r+")) == NULL) // 로그파일 열기
569+
fp = fopen(RSYNC_LOG, "w"); // 존재하지 않을 경우 생성
570+
571+
fseek(fp, 0, SEEK_END);
572+
573+
// 헤더 명령행 문자열 생성
574+
strcpy(command, get_file_name(saved_argv[0]));
575+
for (int i = 1; i < saved_argc; i++) {
576+
strcat(command, " ");
577+
strcat(command, saved_argv[i]);
578+
}
579+
580+
#ifdef DEBUG
581+
printf("write_log(): command = %s\n", command);
582+
#endif
583+
584+
// 헤더 시간 생성
585+
time(&now_t);
586+
now_tm = localtime(&now_t);
587+
588+
fprintf(fp, "[%.24s] %s\n", asctime(now_tm), command); // 헤더 라인 쓰기
589+
590+
//if(option_p)
591+
592+
for (int i = 0; i < count; i++) // 변경 사항 쓰기
593+
switch (change_list[i].status) {
594+
case DELETE:
595+
fprintf(fp, " %s delete\n", change_list[i].name + strlen(dst_path) + 1);
596+
break;
597+
case CREATE:
598+
case MODIFY:
599+
fprintf(fp, " %s %dbytes\n", change_list[i].name + strlen(src_path) + 1, change_list[i].size);
600+
break;
601+
}
602+
}
603+
465604
/**
466605
* @brief 모니터링 파일 목록 메모리 할당 해제
467606
* @param head 트리의 루트 노드
@@ -494,15 +633,15 @@ void recovery(int signo) // SIGINT 시그널 처리
494633
if(is_complete) // 동기화가 완료되었을 경우
495634
return;
496635

497-
sprintf(command, "tar -xvf %.*s", (int)strlen(swap_path), swap_path); // 복원 명령어 생성(압축 해제)
636+
sprintf(command, "tar -xvf %s.swp", get_file_name(dst_path)); // 복원 명령어 생성(압축 해제)
498637
#ifdef DEBUG
499638
printf("recovery(): command = %s\n", command);
500639
#endif
501640
remove_directory(dst_path); // 기존 동기화 디렉토리 삭제
502641
kill(getpid(), SIGUSR1); // 표준 입출력 닫기
503642
system(command); // 복원 명령어 실행
504643
kill(getpid(), SIGUSR2);
505-
remove(swap_path); // swap 파일 삭제
644+
remove(command+9); // swap 파일 삭제
506645
}
507646
exit(1);
508647
}
@@ -555,3 +694,12 @@ char *get_file_name(char *path) // 파일명 추출
555694

556695
return tmp + 1;
557696
}
697+
698+
/**
699+
* @brief 사용법 출력
700+
* @param 실행파일 문자열
701+
*/
702+
void print_usage(char *execute_file) // 사용법 출력
703+
{
704+
fprintf(stderr, "ssu_rsync(): Usage: %s [OPTION] <SOURCE> <DESTINATION>\n", execute_file);
705+
}

‎ssu_rsync.h‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@
66
#ifndef SSU_RSYNC_H
77
#define SSU_RSYNC_H
88

9+
#include <fcntl.h>
910
#include <dirent.h>
1011
#include <signal.h>
12+
#include <utime.h>
1113
#include <sys/stat.h>
14+
#include <sys/types.h>
1215
#include "common.h"
1316

1417
/**
@@ -35,12 +38,7 @@ typedef struct ssu_fileNode{ // 모니터링 파일 목록 구조체
3538
int status; // 모니터링 확인 상태
3639
} file_node;
3740

38-
typedef struct ssu_changeItem {
39-
char name[BUFFER_SIZE];
40-
int status;
41-
int size;
42-
} change_file;
43-
41+
void copy_argument(int argc, char *argv[]); // 명령행 인자 백업
4442
void swap_handler(int signo); // 표준입출력 전환
4543
void syncronize(char *src_path, char *dst_path); // 동기화 함수
4644
file_node *make_node(void); // 노드 생성
@@ -49,8 +47,11 @@ int count_size(file_node *head); // 디렉토리 크기 반환
4947
void compare_list(file_node *src_list, file_node *dst_list); // 파일 목록 트리 비교
5048
bool compare_file(file_node *src_file, file_node *dst_file); // 파일 정보 비교
5149
int write_change_list(file_node *head, int idx, int status, bool is_first); // 변경사항 목록 작성
50+
void write_log(int count); // 로그 파일 작성
5251
void free_list(file_node *head); // 모니터링 파일 목록 메모리 할당 해제
52+
void renewal(int count); // 파일 동기화
5353
void recovery(int signo); // SIGINT 시그널 처리
5454
void remove_directory(const char *path); // 디렉토리 삭제
5555
char *get_file_name(char *path); // 파일명 추출
56+
void print_usage(char *execute_file); // 사용법 출력
5657
#endif // SSU_RSYNC_H

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /