gethostbyname() 함수

 

도메인(문자열) 정보로 ip, 별칭 등 host에 대한 정보를 구하는 함수.

 

#include <netdb.h>

struct hostent *gethostbyname(const char *name);

 

서버 이름 또는 도메인(예. www.it-note.kr)으로부터 주소정보(IP Address)를 얻습니다. 주소 정보는 local computer의 /etc/hosts 파일 또는 DNS 서버로 부터 주소 정보를 얻습니다.

 

 

struct hostent 구조체

struct hostent {
    char  *h_name;            /* official name of host */
    char **h_aliases;         /* alias list */
    int    h_addrtype;        /* host address type : AF_INET 또는 AF_INET6 */
    int    h_length;          /* length of address */
    char **h_addr_list;       /* list of addresses */
}

#define h_addr h_addr_list[0] /* for backward compatibility */ 

 

파라미터

name
    - IP 주소를 얻으려는 서버 이름 또는 서버에 대한 도메인명

 

RETURN

NULL
    - 오류가 발생하였습니다.

NULL 아님
    - struct hostent *를 return하며, 주소는 h_addr 멤버 변수에 저장되며, 
      그 주소의 길이는 h_length에 저장됩니다.
    - h_addr의 format은 network byte order의 주소이며, 
      인터넷 표준 점표기법으로 표시하려면 inet_ntoa( )로 변환이  필요합니다.

 


활용 예제

 

Sample

#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define SERVER_PORT   6905
#define SERVER_NAME   "www.it-note.kr"

......

int main(int argc, char **argv)
{
    struct hostent *he;
    struct sockaddr_in server_addr;
    int  sock;

    ......

    if((he = gethostbyname(SERVER_NAME)) == NULL) {
        fprintf(stderr, "%s는 등록되지 않은 서버명입니다.\n", SERVER_NAME);
        return -1;
    }

    memset(&server_addr, 0x00, sizeof(struct sockaddr_in));
    server_addr.sin_samily = AF_INET;
    memcpy(server_addr.sin.sin_addr, he->h_addr, he->h_length);
    server_addr.sin_port   = htons(SERVER_PORT);

    if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        fprintf(stderr, "Socket 생성 오류: %s\n", strerror(errno));
        return -1;
    }

    if(connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) == -1) {
        fprintf(stderr, "Connection Error: %s\n", strerror(errno));
        close(sock);
        return -1;
    }

    ......
}

 

 

참고 :
https://www.it-note.kr/22

[VB6.0] 내부함수 __vbaStrCopy

 

__vbaStrCopy 함수는 값을 복사해오는 함수로 보인다.

 

 

__vbaStrCopy

[int] __vbaStrCopy( BSTR* Source, BSTR* Destination );

This routine copies a BSTR from one memory location to another.

The Source BSTR is placed in EDX, the Destination BSTR is placed in ECX.

The return value is an integer in EAX which is a duplicate pointer to the Destination.

Code Example:

.text:00401961 mov edx, offset aString ; "STRING"

.text:00401966 lea ecx, [ebp-1Ch]

.text:00401969 mov [ebp-1Ch], esi

.text:0040196C call ds:__vbaStrCopy

.text:00401972 mov eax, [ebp-1Ch]

Explanation of code example:

You can see the string being moved into EDX and then a stack location into ECX. The copied string is then at both [ECX] and [EDX] and the return value in EAX is the same pointer as [ECX].

(c) 2004 Telos & SneakCharm

 

 

한글 번역

 

__vbaStrCopy

[int] __vbaStrCopy( BSTR* Source, BSTR* Destination );

이 루틴은 한 메모리 위치에서 다른 메모리 위치로 BSTR을 복사합니다.

Source BSTR은 EDX에 배치되고 Destination BSTR은 ECX에 배치됩니다.

반환 값은 목적지에 대한 중복 포인터인 EAX의 정수입니다.

코드 예제 :

.text:00401961 mov edx, offset aString ; "STRING"

.text:00401966 lea ecx, [ebp-1Ch]

.text:00401969 mov [ebp-1Ch], esi

.text:0040196C call ds:__vbaStrCopy

.text:00401972 mov eax, [ebp-1Ch]

코드 예제 설명 :

문자열이 EDX로 이동한 다음 스택 위치가 ECX로 이동하는 것을 볼 수 있습니다. 그러면 복사된 문자열은 [ECX]와 [EDX]에 모두 있으며 EAX의 반환 값은 [ECX]와 동일한 포인터입니다.

(c) 2004 Telos & SneakCharm

 

 

 

 

추가 ++)

BSTR에 대해... BSTR이란 무엇인가??

 

http://golbeng.egloos.com/86921

 

문자열을 표현하는 방법에는 다음과 같은 두가지 방법이 있다.

1. 일련의 문자들을 기록한 뒤, 맨 끝에 문자열의 끝을 나타내는 특별한 식별자를 기록한다.

2. 맨 앞에 문자열을 나타내는 총 바이트 수를 기록한 뒤, 일련의 문자들을 기록한다.

1번의 경우에 해당하는 대표적인 경우가 C/C++의 문자열이다.

C/C++에서는 문자열의 끝을 나타내기 위해 널(NULL) 문자를 사용한다.

2번의 경우에 해당하는 경우는 베이직이나 파스칼의 문자열이다.

우리가 다루고자 하는 BSTR도 바로 2번과 같은 형태를 가진 문자열이다.

자, BSTR에 대해 알아보자.

BSTR 타입은 마이크로소프트의 비주얼 베이직 개발팀에 의해 만들어 졌다.

비주얼 베이직은 포인터를 지원하지 못했기 때문에, 기존의 가상함수 테이블을 이용한

함수 호출이 불가능하였다. 이에 비주얼 베이직 개발팀은 IDispatch 인터페이스를

고안해 내었다. 비주얼 베이직과 COM 객체가 원활히 통신하기 위해서 COM에서 비주얼

베이직의 문자열 타입을 지원하게 되는 결과를 낳았는데, 그것이 바로 BSTR이다.

그래서, 이름이 BSTR(Basic STRing의 약자이다!)이기도 하다.

또한, BSTR는 COM에서 유니코드(Unicode) 문자열을 나타내는데 자주 사용된다.

비주얼 베이직(BSTR)는 개념적으로 2개의 필드로 구성된다.

첫번째 필드는 4바이트(unsigned long)로 구성되고, 실제 문자열의 총 바이트 수를 나타낸다.

(유니코드 문자들의 총 개수가 아니라, 바이트 수임에 명심하라!)

두번째 필드는 실제 문자열이며, NULL로 끝난다.

(다른 형식의 문자열과 호환성을 위해서 NULL로 끝나는 것 같다.)

(첫번째 필드에 기록된 총 바이트 수는 NULL 문자를 제외한 것임에 또한 명심하라!)

또한, 두번째 필드에 기록되는 문자들은 2바이트로 구성된다. 유니코드 문자이기 때문이다.

이렇듯 BSTR는 실질적으로 두 개의 필드로 구성되어 있다.

그러나, BSTR 타입은 표준 유니코드 문자 포인터에 지나지 않는다.

(실제로 BSTR 타입은 typedef OLECHAR __RPC_FAR* BSTR 로 정의되어 있다.

OLECHAR __RPC_FAR* 를 나타내는 타입인 것이다. OLECHAR은 결국 wchar_t의

다른 이름일 뿐이다.)

BSTR 포인터는 BSTR 타입 데이터의 두번째 필드, 즉 실제 문자열 부분을 가리킨다.

BSTR는 이렇게 정의되기 때문에 두 개의 필드로 구성됨을 알 필요없이,

보통의 유니코드 문자열과 똑같이 다룰 수 있는 것이다.

또한 BSTR 문자열은 COM에서 대표적으로 사용되는 유니코드 문자열이고,

COM은 다른 프로세스, 다른 컴퓨터 사이에서 사용될 수 있다.

그러므로 BSTR 문자열을 위한 메모리 할당/해제를 위해서 언어 종속적인

기능(new/delete, malloc/free ...)을 사용해서는 안된다.

COM이 제공하는 메모리 할당기로부터 할당/해제되어야 한다.

COM의 메모리 할당기를 사용하면서, 사용하기 편하게 하기 위해서

COM은 BSTR 문자열에 관한 API들을 제공한다.

SysAllocString(), SysFreeString(), SysReAllocString, SysStringLen()가 같이

"Sys.."로 시작하는 함수들이 그러한 COM이 제공하는 API 함수이다.

 

 

 

참고 : 

https://blog.naver.com/huangha/221738850374

setresuid( )함수 setresgid( )함수

 

setresuid( )함수 : 각각의 인자가 real UID, effective UID, saved set-user-ID를 변경함

setresgid( )함수 : 각각의 인자가 real GID, effective GID, saved set-group-ID를 변경함

 

setresuid/setresgid : SET R(eal), E(ffective), S(aved) UID/GID
: 현재 동작 중인 프로세스의 권한을 변경한다.

 

예제

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>

int main(int argc, char **argv, char **envp)
{
	gid_t gid;
	uid_t uid;
	gid = getegid();
	uid = geteuid();
	
	setresgid(gid, gid, gid);
	setresuid(uid, uid, uid);
	
	system("/usr/bin/env echo and now what?");
}

 


□ RUID(Real User ID)

  ○ 프로세스의 실제 소유자 

  ○ 시그널 전송 시 사용됨. unprivileged 프로세스는 본인의 RUID, EUID가 상대방의 RUID, SUID와 동일할 때 시그널

      전송 가능



□ EUID(Effective User ID)

  ○ 일반적으로 RUID와 EUID는 동일

  ○ EUID는 SetUID 권한이 설정된 실행 파일에 의해 변경됨

  ○ EUID는 일시적으로 다른 계정의 UID를 저장

  ○ EUID에 저장된 UID에 따라 프로세스의 권한이 결정됨



□ SUID(Saved set-user-ID)

  ○ SUID는 프로세스의 권한을 낮게 변경했다가 원래대로 복구할 때 사용됨

  ○ 프로세스의 권한이 낮게 변경될 때, 변경 전의 EUID는 SUID에 저장됨

  ○ 이후, 낮은 권한이 원래 권한으로 복구될 때, SUID는 EUID에 저장됨

참고 :

https://blog.naver.com/starjhjh/222286475230

'Programming Language > C Language' 카테고리의 다른 글

gethostname() 함수  (0) 2021.07.06
C언어) getuid() 함수  (0) 2021.06.16
C언어) getgid() 함수  (0) 2021.06.16
C언어) 파일 디스크립터(FD, File Descriptor)  (0) 2021.06.15
C언어) read() 함수  (0) 2021.06.15

C함수 실제 사용자 ID 구하기

getuid() 함수

 

실제 사용자 ID를 구합니다.

  • 헤더: unistd.h
  • 형태: uid_t getuid(void)
  • 인수: -
  • 반환: uid_t getuid()는 항상 성공하며, 사용자 ID를 반환

 

예제

#include <stdio.h>
#include <unistd.h>

int main()
{
   printf( "%d\n", getuid());
   return 0;
}

 

실행 결과

$ ./a.out
500
$

 

 

참고 :

https://badayak.com/4383

C함수 실제 그룹 ID 구하기

getgid() 함수

 

실제 그룹 ID를 구합니다.

  • 헤더: unistd.h
  • 형태: uid_t getgid(void)
  • 인수: -
  • 반환: uid_t getgid()는 항상 성공하며 사용자 ID를 반환
  •  

예제

#include <stdio.h>
#include <unistd.h>

int main()
{
   printf( "%d\n", getgid());
   return 0;
}

 

실행 결과

$ ./a.out
500
$

 

 

참고 :

https://badayak.com/4385

파일 디스크립터 (FD, File Descriptor)란,

 

Unix OS에서 네트워크 소켓과 같은 파일이나 기타 입력/출력 리소스에 액세스하는 데 사용되는 추상표현이다.

 

즉, 시스템으로 부터 할당받은 파일이나 소켓을 대표하는 정수다.

파일 디스크립터는 음이 아닌 정수(Non-negative Integer)로, 일반적으로 형식 int로 C 프로그래밍 언어로 표현된다(음수 값은 "무값" 또는 오류 조건을 나타내기 위해 예약된다).
(Window에서는 file handle이라고 부르고 값은 랜덤하게 할당된다.)

 

FD의 0번에서 2번까지는 고정되어 있다. (unistd.h 헤더파일에 명시)

각 Unix 프로세스는 세 가지 standard streams에 해당하는 고정된 standard POSIX file descriptors를 가진다.

표준입력 및 표준출력도 파일 디스크립터로 표현이 되는데 이들은 프로그램이 시작되면 기본적으로 열리고, 종료 시 자동으로 닫힌다.

표 출처 위키피디아 https://en.wikipedia.org/wiki/File_descriptor

 

  • 표준 입력(Standard Input) : File Descriptor 0
  • 표준 출력(Standard Output) : File Descriptor 1
  • 표준 에러 출력(Standard Error) : File Descriptor 2

 

파일 디스크립터가 단순히 숫자인 이유는 프로세스가 유지하고 있는 file descriptors 테이블의 인덱스이기 때문이다. 

일 오픈 or 소켓생성 시 부여되는 파일 디스크립터는 3부터 시작한다.

프로세스가 실행 중에 파일을 Open 하면 커널은 해당 프로세스의 파일 디스크립터 숫자 중에 사용하지 않는 가장 작은 값을 할당해 준다.

그 다음 프로세스가 열려있는 파일에 시스템 콜을 이용해서 접근할 때, 파일 디스크립터 값을 이용해 파일을 지칭할 수 있다. 

사진 출처 https://dev-ahn.tistory.com/96

file descriptors 테이블의 각 항목은 FD 플래그 파일 테이블로의 포인터를 가지고 있다.

이 포인터를 이용하여 FD 를 통해 시스템의 파일을 참조 할 수 있는 것이다.

프로세스는 이런 FD 테이블과 파일 테이블의 정보를 직접 고칠 수 없으며, 반드시 커널을 통해서 수정을 해야 한다.

 

 

FD의 최대값은 OPEN_MAX라는 값이다.

즉, 하나의 프로세스 당 최대 OPEN_MAX개의 파일을 열 수 있다. OPEN_MAX 값은 플랫폼에 따라 다르다.

최대 파일 갯수는 다음의 방법을 사용하여 알아볼 수 있다. 내 mac에서는 2560개의 값이 나왔다.

 

OPEN_MAX는 단일 프로그램에 허용되는 최대 열린 파일 수를 정의하는 상수다.

Unix 시스템에서 C언어의 OPEN_MAX는 limits.h에 정의돼있다.

OPEN_MAX와 FOPEN_MAX와 _SC_OPEN_MAX는 조금씩 다르다고 한다. (출처)

 

방법 1) 터미널에서 getconf 명령어로 확인

getconf OPEN_MAX


/* 결과값 */
2560

 

방법 2) <unistd.h>의 sysconf() 함수로 확인

#include <unistd.h>
#include <stdio.h>

int	main(void){
	int	max;

	max = sysconf(_SC_OPEN_MAX);
	printf("%d\n", max);
	return(0);
}


/* 컴파일 후 결과값 */
2560

 

 


스토리 비유하기

(출처 : mintnlatte.tistory.com/266)
전화 한 통만 하면 필요한 논문을 복사해 주는 곳이 있다. 그리고 그곳의 단골손님 영수가 있다. 그런데 이 녀석은 매번 똑같은 논문의 일부분을 복사해 달라고 한다. “아저씨~ ‘고도의 정보화 사회가 되어 가면서, 인간의 삶의 질과 관계된 문제들이 점점 더 그 중요성이 더해짐에 따라 감각, 지각, 사고, 성격, 지능, 적성 등의 인간적 특징들이 고려됐을 때의 인간의 원리에 대한 연구’ 라는 논문 26쪽부터 30쪽까지 복사해 주세요” 이 녀석은 보통 이런 식으로 하루에도 여러 번 주문을 한다. 설상가상으로 말하는 속도도 느린 편이다. 그래서 아저씨가 말씀하시길 “그 논문은 이제부터 너의 18번이다! 그냥 저의 18번 논문 26쪽부터 30쪽까지 복사해 주세요 라고 해라!”영수는 그 이후로도 최소 50자가 넘는 제목의 논문만 복사 주문을 한다. 그 때 마다 아저씨는 논문에 새로운 번호를 할당해 준다(중복되지 않는). 그래야 영수와의 대화 속에서 스트레스를 덜 받을 수 있기 때문이다.

여기서 아저씨는 시스템이고, 영수는 개발자를 의미한다.

그리고 숫자는 파일 디스크립터이고, 논문은 소켓이나 파일을 의미한다.

파일(혹은 소켓)을 생성할 때마다 시스템은 그러한 숫자를 생성해서 건네줄 것이다. 그것이 시스템과 개발자가 편하게 대화하는 방법이 된다.

결국 파일 디스크립터란 시스템이 만들어 놓은 것을 가리키기 좋게 하기 위해 시스템이 우리들에게 건네주는 숫자에 지나지 않는다.

 

 


출처

파일 디스크립터

위키피디아 en.wikipedia.org/wiki/File_descriptor

mint&latte, mintnlatte.tistory.com/266

dev-ahn, dev-ahn.tistory.com/96

 

파일 디스크립터의 OPEN_MAX

네이버블로그 우동 blog.naver.com/PostView.nhn?blogId=s2kiess&logNo=220119492474&proxyReferer=https:%2F%2Fwww.google.com%2F

Javaer101 www.javaer101.com/article/2890626.html

 

 

 

참고 :

https://code4human.tistory.com/123

'Programming Language > C Language' 카테고리의 다른 글

C언어) getuid() 함수  (0) 2021.06.16
C언어) getgid() 함수  (0) 2021.06.16
C언어) read() 함수  (0) 2021.06.15
C언어) open() 함수  (0) 2021.06.15
C언어) strstr() 함수  (0) 2021.06.15

+ Recent posts