C 언어로 리눅스 명령어 실행하기

프로그래밍/C, C++|2020. 1. 8. 15:16
반응형

C 프로그래밍을 할 때, 리눅스 시스템의 명령을 사용해야 하는 경우가 있습니다.

아래 소스와 같이 사용이 가능합니다.


# vi sysdocu.c


#include <stdio.h>


int main()

{

    printf("\n아래는 현재 디렉토리의 파일 리스트 입니다.\n\n");

    system("ls -al");


    return 0;

} 



실행 가능한 바이너리 파일로 변환합니다.


# cc -o sysdocu sysdocu.c


변환된 파일을 실행합니다.


# ./sysdocu



반응형

댓글()

c언어 파일 이벤트 감시 (inotify)

프로그래밍/C, C++|2020. 1. 8. 15:03
반응형

맨 하단에 있는 Example code 를 확인합니다.

해당 코드는 특정 디렉토리 내의 하위 디렉토리 및 파일에 대한 이벤트를 감지하여 줍니다.

단일 파일에 대한 감시를 원할 경우 디렉토리를 만들어 그 안에 파일을 넣어두거나, 소스를 수정하여 사용하도록 합니다.

사용법은 test.c 파일로 내용을 저장하여 실행 파일로 만들면 됩니다.

# cc -o test test.c

# ./test &


==================================================================================

리눅스에서는 커널 2.6.13 부터 파일시스템 이벤트를 모니터링할 수 있는 메커니즘을 제공합니다. inotify와 dnotify인데요, 이 글에서는 inotify만 다룰 계획입니다. inotify가 dnotify를 대체하기 위한 녀석이기 때문이죠.


Inotify는 파일이나 디렉토리를 개별적으로 모니터링 할 수 있도록 해줍니다. 여기서 한가지 유의할 점은 디렉토리 모니터링 시 재귀적으로 모니터링 되진 않는다는 것입니다. 만약 하위 모든 디렉토리를 모니터링 하기 위해선 각 디렉토리에 대해 모니터링을 하도록 해야합니다. 


한가지 Inotify의 사용 예시를 생각해보죠. 여러분이 Daemon과 Daemon의 설정 파일을 제공한다고 가정했을 때, 누군가 설정파일을 변경 시 Daemon에서 이걸 알고 처리할 수 있도록 하는 기능 추가 시 유용할 수 있습니다.


그럼, inotify API와 사용법을 알아본 후 예제 코드를 살펴보시죠.


  •  Inotify API

[SYNOPSIS]

#include <sys/inotify.h>


int inotify_init(void);


return

초기화된 inotify instance를 가리키는 file descriptor


inotify instance를 초기화 하기 위한 함수입니다. 성공하면 파일 디스크립터를 리턴하고, 에러 발생 시 -1을 리턴하고, errno가 설정됩니다. 여기서 파일 디스크립터는 inotify instance를 참조할 때 사용되어집니다.



[SYNOPSIS]

#include <sys/inotify.h>


int inotify_add_watch(int fd, const char *pathname, uint32_t mask);


Parameter

fd : inotify_init() 에서 리턴받은 file descriptor

pathname : 모니터링 리스트에 생성되거나 수정되는 파일

mask : pathname에 모니터링할 이벤트 지정 마스크


return

추가 또는 수정된 inotify instance를 가리키는 file descriptor


file descriptor가 가리키는 inotify instance의 모니터링 리스트에 새로운 파일 또는 디렉토리를 추가하거나 기존에 추가되어 있던 항목을 수정하기 위해 사용됩니다. 기존에 추가 되어있다면 mask만 수정됩니다. mask의 종류는 매우 다양하며 몇 가지만 뒤에서 알아보겠습니다.



[SYNOPSIS]

#include <sys/inotify.h>


int inotify_rm_watch(int fd, int wd);


Parameter

fd : inotify_init() 에서 리턴받은 file descriptor

wd : inotify_add_watch()의 이전 호출이 리턴한 file descriptor.


return

수정된 inotify instance를 가리키는 file descriptor


File descriptor fd가 가리키는 inotify instance로부터 wd로 지정한 모니터링 리스트를 제거합니다.


  •  Inotify Event Mask

위에서 inotify_add_watch() API를 설명할 때 parameter로 이벤트 관련된 mask를 설명드렸었습니다. 이 parameter는 pathname에 대해 모니터링할 이벤트를 전달할 수 있는데요. 그 중 몇 가지를 알아보도록 하겠습니다.


아래 표 중 입력은 실제 mask로 지정할 수 있는 이벤트이며, 출력은 지정하지 않아도 모니터링 가능한 이벤트입니다.


 Mask

입력

출력

설명 

 IN_ACCESS

파일 접근 가능 ( read() )

IN_ATTRIB

파일 메타데이터 변경됨

 IN_CLOSE_WRITE

Write 위해 열린 파일이 닫힘

IN_CLOSE_NOWRITE

ReadOnly로 열린 파일이 닫힘

IN_CLOSE


IN_CLOSE_WRITE | IN_CLOSE_NOWRITE 

IN_CREATE

모니터링 디렉토리 내의 파일 or 디렉토리 생성됨 

IN_DELETE

모니터링 디렉토리 내의 파일 or 디렉토리 삭제됨 

 IN_DELETE_SELF

모니터링 중인 디렉토리 or 파일이 삭제됨 

IN_MODIFY

파일이 수점됨 

 IN_MOVE_SELF

모니터링 중인 디렉토리 or 파일이 이동됨 

IN_MOVE_FROM

파일이 모니터링중인 디렉토리 밖으로 이동됨

IN_MOVE_TO

파일이 모니터링중인 디렉토리로 이동됨 

IN_OPEN

파일이 열림 

 IN_ALL_EVENTS

 

위의 모든 이벤트를 포함함. 

 IN_DONT_FOLLOW

 

Symbolic Link를 역참조하지 않음


위의 mask외에도 여러 mask가 있습니다. 상세한 내용은 man-page를 참고하시면 좋을 것 같습니다.


  •  Inotify_event

그럼 이제 모니터링한 파일 or 디렉토리에서 발생한 이벤트를 어떻게 읽어올 것인지 살펴보겠습니다. inotify_event를 이용해 이벤트를 읽어옵니다. 보통 read()를 사용하나, Blocking 되는 문제가 있어, select나 poll 같은 Multiflexing I/O들을 많이 사용합니다. 여기서는 read()를 이용한 설명을 드리겠습니다. 아래는 inotify_event 구조체를 나타낸 것입니다. 


1
2
3
4
5
6
7
8
struct inotify_event {
    int      wd;       /* Watch descriptor */
    uint32_t mask;     /* Mask describing event */
    uint32_t cookie;   /* Unique cookie associating related
                                     events (for rename(2)) */
    uint32_t len;      /* Size of name field */
    char     name[];   /* Optional null-terminated name */
};

cs


  • Example Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <poll.h>
#include <errno.h>
#include <unistd.h>
#include <sys/inotify.h>
 
#define INOTIFY_PATH "/tmp/"
 
static void __handle_inotify_event(const struct inotify_event *event)
{
    if (event->mask & IN_ACCESS)
        printf("IN_ACCESS ");
    if (event->mask & IN_ATTRIB)
        printf("IN_ATTRIB ");
    if (event->mask & IN_CLOSE_NOWRITE)
        printf("IN_CLOSE_NOWRITE ");
    if (event->mask & IN_CLOSE_WRITE)
        printf("IN_CLOSE_WRITE ");
    if (event->mask & IN_CREATE)
        printf("IN_CREATE ");
    if (event->mask & IN_DELETE)
        printf("IN_DELETE ");
    if (event->mask & IN_ISDIR)
        printf("IN_ISDIR ");
    if (event->mask & IN_MODIFY)
        printf("IN_MODIFY ");
    if (event->mask & IN_MOVE_SELF)
        printf("IN_MOVE_SELF ");
    if (event->mask & IN_MOVED_FROM)
        printf("IN_MOVED_FROM ");
    if (event->mask & IN_MOVED_TO)
        printf("IN_MOVED_TO ");
    if (event->mask & IN_OPEN)
        printf("IN_OPEN ");
    if (event->len > 0)
        printf(": name = %s\n", event->name);
}
 
int main(int argc, char *argv[])
{
    int ret;
    int fd;
    int wd;
    char buf[4096] __attribute__ ((aligned(__alignof__(struct inotify_event))));
    char *ptr;
    ssize_t size;
    const struct inotify_event *event;
 
    fd = inotify_init();
    if (fd < 0) {
        perror("inotify_init");
        exit(EXIT_FAILURE);
    }
 
    wd = inotify_add_watch(fd, INOTIFY_PATH, IN_MODIFY | IN_CREATE | IN_DELETE);
    if (wd < 0) {
        fprintf(stderr, "Failed to add watch [%s] [%s]", INOTIFY_PATH, strerror(errno));
        perror("inotify_add_watch");
        exit(EXIT_FAILURE);
    }
 
    while (1) {
        size = read(fd, buf, sizeof(buf));
        if (size == -1 && errno != EAGAIN) {
            perror("read");
            fprintf(stderr, "read : %s", strerror(errno));
            exit(EXIT_FAILURE);
        }
 
        if (size <= 0)
            break;
 
        for (ptr = buf; ptr < buf + size; ptr += sizeof(struct inotify_event) + event->len) {
            event = (struct inotify_event *)ptr;
            __handle_inotify_event(event);
        }
    }
 
    ret = inotify_rm_watch(fd, wd);
    if (ret < 0) {
        fprintf(stderr, "Failed to rm watch [fd : %d] [wd : %d] [%s]", fd, wd, strerror(errno));
        perror("inotify_rm_watch");
        exit(EXIT_FAILURE);
    }
 
    return 0;
}
 
cs



출처: https://sonseungha.tistory.com/436 [Developer's Delight]

반응형

댓글()

특정 필드에 동일 데이터가 있을 경우 update, 없으면 insert

리눅스/MySQL|2019. 12. 27. 08:30
반응형

아래 예저는 users 테이블의 ID 필드에 동일한 값이 있을 경우 update 를, 없는 경우 insert 를 해주는 한 줄 쿼리 문입니다.

 

mysql> CREATE TABLE `users` (
`no` int(10) NOT NULL AUTO_INCREMENT,

`ID` varchar(16) NOT NULL,
`NAME` text,
PRIMARY KEY (`no`))
ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

 

아래와 같이 ID 필드는 유일한 값만 있도록 설정하는 것이 포인트!

mysql> alter table users ADD UNIQUE (ID);

 

현재 테이블 상태 입니다.

mysql> desc users;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| no    | int         | NO   | PRI | NULL    | auto_increment |
| ID    | varchar(16) | NO   | UNI | NULL    |                |
| NAME  | text        | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+

 

입력을 해봅니다.

mysql> INSERT INTO users (ID, NAME) VALUES ('sysdocu', 'HongKilDong') ON DUPLICATE KEY UPDATE NAME='HongKilDong';

 

ID (sysdocu) 가 없으면 INSERT 쿼리문을,

ID (sysdocu) 가 존재할 때는 NAME 컬럼만 UPDATE 합니다.

 

반응형

댓글()

로딩중 이미지 많은곳

자료실|2019. 12. 26. 09:30
반응형

https://loading.io/



반응형

댓글()

레이어가 겹칠때 하단 레이어는 터치 비활성화 시키기

프로그래밍/Android (Java)|2019. 12. 24. 08:33
반응형

레이어가 겹치게 되면 경우에 따라 상단 또는 하단 레이어가 터치 됩니다.

하단에 가려진 레이어를 터치되지 않도록 하려면 아래와 같이 하는 방법이 있습니다.

 

아래와 같이 layout 을 꾸미게 되면 3번 레이어가 최상단에 올라옵니다.

 

1번 레이어

2번 레이어

3번 레이어

 

이때 3번 레이어에 setClickable(true);  를 설정 합니다.

 

 

반응형

댓글()

어플에 애드몹 광고 넣기 예제

프로그래밍/Android (Java)|2019. 12. 20. 14:23
반응형

예제 소스 배포

https://github.com/googleads/googleads-mobile-android-examples/tree/master/java/admob

 

예제 소스 다운로드

https://github.com/googleads/googleads-mobile-android-examples/archive/master.zip

 

압축 파일 다운로드 후 원하는 광고 방식의 소스를 활용하면 됩니다.

 

----------

 

안드로이드에서 설명하는 예제 (쉬움)

https://developers.google.com/admob/android/quick-start

 

----------

 

반응형

댓글()

httpd 2.4.41 에 mod_security 2.9.1 + OWASP 설치

리눅스/Security|2019. 12. 17. 12:38
반응형

httpd 는 2.4.11 이상의 버전에서 OWASP 룰을 사용하도록 합니다.

2.4.10 이전 버전에서는 OWASP 설정 파일 사용시 특정라인 구분을 이해하지 못하는 버그가 있습니다.

아래 예제는 2.4.41 환경에서 진행 했습니다.



1. mod_security 2.9.1 설치


# cd /usr/local/src

# wget https://src.fedoraproject.org/lookaside/pkgs/mod_security/modsecurity-2.9.1.tar.gz/0fa92b852abc857a20b9e24f83f814cf/modsecurity-2.9.1.tar.gz

# tar xvzf modsecurity-2.9.1.tar.gz

# cd modsecurity-2.9.1

# ./configure

# make

# make install

# cp -arp modsecurity.conf-recommended /usr/local/apache/conf/modsecurity.conf

# cp unicode.mapping /usr/local/apache/conf/



2. OWASP (Open Web Application Security Project) 룰 설치


룰은 편의를 위해 apache/conf 에 들어가서 다운로드 하도록 합니다.


# cd /usr/local/apache/conf

# git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git

# cd owasp-modsecurity-crs

# mv crs-setup.conf.example crs-setup.conf

# vi crs-setup.conf


# 추가

SecRuleEngine On

SecAuditEngine On

SecAuditLog /usr/local/apache/logs/mod_security.log

SecAuditLogParts ABCFHZ

SecDataDir /tmp 


* 또는 아래 룰 배포 사이트에서 원하는 버전을 수동으로 다운 받아 사용할 수 있습니다.

https://github.com/SpiderLabs/owasp-modsecurity-crs/releases


# wget https://github.com/SpiderLabs/owasp-modsecurity-crs/archive/v3.2.0.tar.gz

# tar xvzf v3.2.0.tar.gz



3. 아파치 설정


설정 파일을 열어 모듈을 추가 합니다.


# vi ../httpd.conf


LoadModule security2_module modules/mod_security2.so


<IfModule security2_module>

    Include conf/owasp-modsecurity-crs/crs-setup.conf

    Include conf/owasp-modsecurity-crs/rules/*.conf

</IfModule>


* mod_security 는 mod_unique_id 모듈을 필요로 합니다.

   기존 설정에 활성화 되어있지 않을 경우, 주석을 해제하여 활성화 하도록 합니다.


설정을 적용합니다.


# /usr/local/apache/bin/apachectl restart





반응형

댓글()

쉘스크립트 실행 에러 ($'\r': command not found)

리눅스/OS 일반|2019. 12. 16. 11:24
반응형

$'\r': command not found


오류 출력시 아래와 같이 조치합니다.

스크립트 작성 환경에 따라 행 뒤에 ^M 가 붙게 되는데, 이것을 없애야 정상 동작하므로

vi 로 파일을 열고 아래와 같이 치환 합니다.


# sed -i -e "s/\r$//" test.sh



반응형

댓글()

root 관리자 계정 이름을 다른 아이디로 변경 하기

리눅스/MySQL|2019. 12. 6. 16:31
반응형

root 라는 사용자 명은 유추 가능하므로 보안상 다른 계정명으로 변경하여 운영하는 것이 좋습니다.

방법은 간단합니다.

mysql 데이터 베이스 user 테이블에 있는 root 문자를 원하는 계정명으로 업데이트 하면 됩니다.



# mysql -u root -p

Enter password: (관리자 패스워드 입력)


mysql> use mysql;


root 라는 사용자명은 유추 가능하므로 보안상 다른 계정명으로 변경합니다.

mysql> update user set user='sysdocu' where user='root';


mysql> flush privileges;


mysql> exit



그 다음 부터는 변경된 계정명으로 로그인이 가능합니다.

# mysql -u sysdocu -p

Enter password: (관리자 패스워드 입력)



[참고]

관리자 계정 추가를 원할 경우 아래와 같은 모든 DB 접근 권한을 주면 됩니다.


mysql> grant all privileges on *.* to sysdocu@localhost identified by '12345678';

mysql> flush privileges;

반응형

댓글()

쉘스크립트에서 환경 변수 입력, 적용, 스크립트 종료 후에도 사용하기

프로그래밍/BASH SHELL|2019. 11. 29. 17:28
반응형

#!/bin/bash

echo "alias c='clear'" >> ~/.bashrc    # 환경 변수 입력

. ~/.bashrc                                                    # 적용 (스크립트 종료시까지 유효)

exec bash                                                      # 쉘스크립트 종료 후에도 적용 유지 (본 코드는 스크립트 맨 아래에 사용해야 한다. 이 아래에 코드를 넣으면 실행되지 않기 때문이다.)





반응형

댓글()

vim 사용시 검색 단어 바탕색 표시하기 (하이라이트)

리눅스/OS 일반|2019. 11. 8. 14:18
반응형

vim 을 설치해서 사용하다 보면 OS 버전 또는 vim 버전에 따라 검색 (/ 누르고 문자 입력) 단어 바탕색이 칠해지지 않는 경우를 보게 됩니다.

이럴때 검색 단어가 눈에 확 띄도록 옵션을 주어 사용이 가능합니다.


(vim 편집기를 열고 있는 상태에서)


1. 배경 설정

:set hlsearch


2. 배경 설정 해제

:set nohlsearch



반응형

댓글()