4-1 수정 (과제1-, 과제-2)

do·2022년 3월 29일
0

API

목록 보기
17/42

1. SetUID
2. SetGID
3. Sticky Bit
4. 파일 시스템 및 I-node와 데이터 블록의 관계
5. umask

과제 - 1 수정

fileinfo 파일 정보 출력

수정사항
1. char* 동적할당 -> char[]
2. 에러 처리

#include <stdio.h>
#include <sys/stat.h>   //lstat
#include <string.h>     //strcpy
#include <unistd.h>     //readlink

enum { ARGC_ERROR = -2, LSTAT_ERROR = -1, PRINT_ERROR = -3 };
enum { STRTOK_SUCCESS = 0, PRINT_SUCCESS = 1 };

char* my_strtok(char* str, const char* delim)
{
	static char* str_copy = NULL;
	char* delim_copy = NULL;

	(str!=NULL) ? (str_copy=str) : (str=str_copy);

	if (*str_copy=='\0')
		return NULL;

	while (*str_copy){
		delim_copy = (char*)delim;
		while (*delim_copy){
			if (*str_copy == *delim_copy){
				*str_copy = '\0';
				str_copy++;
				return str;
			}
			delim_copy++;
		}
		str_copy++;
	}

	return STRTOK_SUCCESS;
}

int PrintName(char* str)
{
	int j = 0;

	if (strcpy(str, strrchr(str, '/')) == NULL)
		return PRINT_ERROR;

	for (int i = 0; i < (int)strlen(str); i++) {
		if (str[i] != '/')
			str[j++] = str[i];
	}
	str[j] = '\0';

	return PRINT_SUCCESS;
}

int main(int argc, char* argv[])
{
	if (argc != 2) {
		printf("하나의 파일을 입력해주세요.\n");
		return ARGC_ERROR;
	}

	struct stat file; //파일 정보 구조체

	if (lstat(argv[1], &file) == -1 || argv[1] == NULL) {
		printf("파일을 읽을 수 없습니다.\n");
		return LSTAT_ERROR;
	}

	/* 파일 경로 */
	char path[256];
	strcpy(path, argv[1]);
	printf("path: ");
	char* temp = my_strtok(path, "/");
	while (temp != NULL) {
		printf("%s/", temp);
		temp = my_strtok(NULL, "/");
	}
	printf("\n");

	/* 파일명 */
	char name[256];
	strcpy(name, argv[1]);
	PrintName(name);
	printf("file name: %s\n", name);

	`/* 심볼릭 링크일 경우, 원본 파일명 */
	if (S_ISLNK(file.st_mode)) {
		char link_name[256];
		memset(link_name, 0x00, 256);
		readlink(argv[1], link_name, 256);
		PrintName(link_name);
		printf("original file name: %s\n", link_name);
	}

	printf("inode num: %ld\n", file.st_ino);
	printf("user id: %d\n", file.st_uid);
	printf("group id: %d\n", file.st_gid);
	printf("size: %ld\n", file.st_size);

	/* 파일 타입 정보 */
	char* type;
	if (S_ISREG(file.st_mode))
		type = "regular file";
	else if (S_ISDIR(file.st_mode))
		type = "directory";
	else if (S_ISLNK(file.st_mode))
		type = "symbolic link";
	printf("type: %s\n", type);

	/* 파일 모드 정보 */
	//(file.st_mode 값은 100755로 출력됨)
	char mode[12];
	memset(mode, '-', sizeof(mode));
    
	int setNum[12] = { 0x800, 0x400, 0x200, 00400, 00200, 00100,
					   00040, 00020, 00010, 00004, 00002, 00001};
	char* setMode = "sgbrwxrwxrwx";
    
	printf("mode: ");
	for (int i = 0; i < (int)sizeof(mode); i++) {
		if ((file.st_mode & setNum[i]) != 0) {
			mode[i] = setMode[i];
			printf("%c", mode[i]);
	}
	else
		printf("%c", mode[i]);
	}
	printf("\n");

	return 0;
}                             

과제 - 2

ch_mod 권한 변경

#include <stdio.h>
#include <sys/types.h> //chmod
#include <sys/stat.h> //chmod stat
#include <string.h> //strcpy strtok

enum { FILE_ERROR = -1, COUNT_ERROR = -2, MODE_ERROR = -3 };

int main(int argc, char** argv)
{
    struct stat buf; //파일 정보 구조체
    
    if (stat(argv[1], &buf) == -1) { //에러발생-1
        printf("파일을 잘 못 입력하였습니다.\n");
        return FILE_ERROR;
    }

    if (argc != 3) {
        printf("인자는 2개만 입력해주세요.\n");
        return COUNT_ERROR;
    }

    mode_t t = 0;
    char mode[10]; //9자리 모드
    strcpy(mode, argv[2]); //입력받은 두번째 인자를 모드에 복사

    for (int i = 0; i < 3; i++) {
        if (mode[i * 3] != 'r' && mode[i * 3] != '-')
            return MODE_ERROR; //0,3,6번째의 단어가 r 또는 - 가 아니면 에러 리턴
        else if (mode[i * 3] == 'r')
            t += S_IREAD >> (i * 3);
            
            //rwxrwxrwx 중
            //User Read는 mode_t 값들 중 S_IREAD로 표기됨
            //Group Read는 S_IREAD를 오른쪽으로 3비트 연산한 값
            //Others Read는 S_IREAD를 오른쪽으로 6비트 연산한 값

        if (mode[i * 3 + 1] != 'w' && mode[i * 3 + 1] != '-')
            return MODE_ERROR;
        else if (mode[i * 3 + 1] == 'w')
            t += S_IWRITE >> (i * 3);

        if (mode[i * 3 + 2] != 'x' && mode[i * 3 + 2] != '-')
            return MODE_ERROR;
        else if (mode[i * 3 + 2] == 'x')
            t += S_IEXEC >> (i * 3);
    }

    /*
    if (mode[0] == 'r')
        t += S_IREAD;
    if (mode[1] == 'w')
        t += S_IWRITE;
    if (mode[2] == 'x')
        t += S_IEXEC;
    if (mode[3] == 'r')
    	t += S_IREAD >> 3;
	if (mode[4] == 'w')
        t += S_IWRITE >> 3;
    if (mode[5] == 'x')
        t += S_IEXEC >> 3;
    if (mode[6] == 'r')
        t += S_IREAD >> 6;
    if (mode[7] == 'w')
        t += S_IWRITE >> 6;
    if (mode[8] == 'x')
        t += S_IEXEC >> 6;
    */

    chmod(argv[1], t);
    printf("mode change %s\n", argv[2]);

    return 0;
}                         

0개의 댓글