utmp¸¦ ÀÌ¿ëÇÑ »ç¿ëÀÚ Á¤º¸ ¾ò±â
ÃÑ ÆäÀÌÁö ¼ö : 3224

Àüü ÇÔ¼ö/¿ë¾î»çÀü
Facebook Joinc ±×·ì   Joinc QA »çÀÌÆ®
ÇöÀçÀ§Ä¡ : article>utmp



joinc´Â Firefox¿Í chrome¿¡¼­ Å×½ºÆ® Çß½À´Ï´Ù. IE¿¡¼­´Â Å×À̺íÀÌ ±úÁö°Å³ª À̹ÌÁö°¡ º¸ÀÌÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ƯÈ÷ ±¸±Û DocsÀ̹ÌÁöÀÇ °æ¿ì ¿¢¹Úó¸®µÉ ¼ö ÀÖ½À´Ï´Ù.

utmp ¸¦ ÀÌ¿ëÇÑ À¯Àú ·Î±×ÀÎ Á¤º¸ ¾ò±â

utmp¿¡ ´ëÇÑ ³»¿ëÀº °¢ Unix ¸¶´Ù ´Ù¸¦¼ö Àִµ¥, ÀÌ ±â»ç´Â Linux readhat 7.x À» ±âÁØÀ¸·Î ÀÛ¼ºÇϵµ·Ï ÇϰڴÙ.

¿©·¯ºÐÀÌ ½Ã½ºÅÛ °ü¸®ÀÚ¶ó¸é, ÇöÀç ½Ã½ºÅÛ¿¡ ´©°¡ ÀÛ¾÷À» Çϰí ÀÖ´ÂÁö, ¾î¶² ÀÛ¾÷À»ÇÏ´ÂÁö µî¿¡ ´ëÇÑ Á¤º¸¸¦ ¾Ë¾Æ¾ßµÉ ¶§°¡ ÀÖÀ»°ÍÀÌ´Ù. ÀÌ·²°æ¿ì ½Ã½ºÅÛ °ü¸®ÀÚ´Â "w" ¸¦ »ç¿ëÇØ¼­ ÇöÀç Á¢±ÙÇÑ »ç¿ëÀÚÀÇ Á¤º¸¸¦ ¾Ë¾Æº¸·Á°í ½ÃµµÇÒ °ÍÀÌ´Ù.

[root@localhost test]$ w 
 11:43am  up 270 days,  9:25,  3 users,  load average: 3.12, 3.22, 3.24 
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU  WHAT 
mercy4u  pts/1    s210-205-210-195 11:25am 41.00s  0.09s  0.06s  -bash  
root     pts/2    s210-205-210-195 11:43am 18.00s  0.05s  0.05s  -bash  
mercy4u  pts/4    s210-205-210-195 11:43am  0.00s  0.06s  0.02s  w  
 

À§ÀÇ °á°ú¿¡¼­ º¸µíÀÌ "w" ¸í·ÉÀ» ÀÌ¿ëÇØ¼­ ¿ì¸®´Â ½Ã½ºÅÛ¿¡ Á¢±ÙÇÑ »ç¿ëÀÚ¿¡ ´ëÇÑ ´Ù¾çÇÑ Á¤º¸¸¦ ¾òÀ»¼ö ÀÖ. ÀÌ·¯ÇÑ Á¤º¸´Â utmp¶ó°í ÇÏ´Â À¯Àú·Î±×ÀÎ ·Î±× ½Ã½ºÅÛÀ» ÀÌ¿ëÇØ¼­ ¾ò¾î¿Ã ¼ö ÀÖ´Ù.

¿¹Á¦ : myutmp.c
#include <unistd.h> 
#include <utmp.h> 
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <time.h> 
#include <fcntl.h> 
#include <string.h> 
#include <stdlib.h> 
 
 
int get_current_pid(int login_pid); 
char *get_current_procname(int proc_num); 
 
 
int main(int argc, char **argv) 
{ 
    struct utmp *utmpfp; 
    struct utmp *myutmp; 
 
    char *tty_name = NULL; 
    char *host_ip; 
 
    char now_local_time[50]; 
 
    time_t the_time; 
    struct tm *tm_ptr; 
 
    myutmp = malloc(sizeof(struct utmp)); 
    //utmpfp = malloc(sizeof(struct utmp)); 
    setutent(); 
 
    while ((utmpfp = getutent()) != NULL) 
    { 
        the_time = utmpfp->ut_time; 
        tm_ptr = localtime(&the_time); 
        sprintf(now_local_time, "%d/%02d/%02d %02d:%02d", 
                                tm_ptr->tm_year+1900, tm_ptr->tm_mon+1, 
                                tm_ptr->tm_mday, tm_ptr->tm_hour, 
                                tm_ptr->tm_min); 
 
        host_ip = utmpfp->ut_host; 
        if (strlen(host_ip) < 1) 
            host_ip = "-"; 
        if (utmpfp->ut_type == USER_PROCESS) 
        { 
            printf("%-12s %-8s %-12s %s   %s\n", 
                        utmpfp->ut_user, 
                        utmpfp->ut_line, 
                        host_ip, 
                        now_local_time, 
                        get_current_procname(get_current_pid(utmpfp->ut_pid))); 
        } 
    } 
 
    setutent(); 
    printf("\nmy utmp info is ---\n"); 
    tty_name = ttyname(0); 
 
    printf("%s\n",tty_name+5); 
    strcpy(myutmp->ut_line, tty_name+5); 
    utmpfp = getutline(myutmp); 
    if(utmpfp == NULL) 
    { 
        printf("Not Fild utmp\n"); 
        exit(0); 
    } 
 
    printf("%d\n", utmpfp->ut_time); 
    the_time = utmpfp->ut_time; 
    tm_ptr = localtime(&the_time); 
    sprintf(now_local_time, "%d/%02d/%02d %02d:%02d", 
                            tm_ptr->tm_year+1900, tm_ptr->tm_mon+1, 
                            tm_ptr->tm_mday, tm_ptr->tm_hour, 
                            tm_ptr->tm_min); 
    printf("%-12s %-8s %-12s %s   %s\n", 
                utmpfp->ut_user, 
                utmpfp->ut_line, 
                host_ip, 
                now_local_time, 
                get_current_procname(get_current_pid(utmpfp->ut_pid))); 
 
    return 1; 
} 
 
int get_current_pid(int login_pid) 
{ 
    int  fd; 
    char buf[255]; 
    char stat_file[25]; 
    int  field_num = 7; 
    int  i, j; 
    int  buf_index; 
    char current_pid[11]; 
 
    memset(buf, '\0', 255); 
    sprintf(stat_file, "/proc/%d/stat", login_pid); 
 
    if ((fd = open(stat_file, O_RDONLY)) == -1) 
    { 
        printf("error\n"); 
        return -1; 
    } 
 
    read(fd, buf, 255); 
    j = 0; 
    for (i = 0, buf_index=0; i < 255; i++) 
    { 
        if (buf[i] == ' ') 
        { 
            j++; 
        } 
        else 
        { 
            if (j == field_num) 
            { 
                current_pid[buf_index] = buf[i]; 
                buf_index++; 
            } 
            if (j > field_num) 
                break; 
        } 
    } 
    close(fd); 
    return atoi(current_pid); 
} 
 
char *get_current_procname(int proc_num) 
{ 
    char *buf; 
    char proc_file[256]; 
 
    buf = (char *)malloc(256); 
    memset(buf, '\0', 256); 
 
    memset(proc_file, '\0', 256); 
    sprintf(proc_file, "/proc/%d/exe", proc_num); 
 
    readlink(proc_file, buf, 256); 
    return buf; 
} 
 
À§ ÇÁ·Î±×·¥À» ¼³¸íÇϱâ Àü¿¡ utmp(5) ±¸Á¶Ã¼¿¡ ´ëÇØ¼­ ¾Ë¾Æº¸µµ·Ï ÇÏÀÚ. utmp ±¸Á¶Ã¼´Â ¾Æ·¡¿Í °°Àº ³»¿ëÀ» °¡Áø´Ù.
struct utmp 
{ 
    short ut_type;              /* type of login */ 
    pid_t ut_pid;               /* pid of login process */ 
    char ut_line[UT_LINESIZE];  /* device name of tty - "/dev/" */ 
    char ut_id[4];              /* init id or abbrev. ttyname */ 
    char ut_user[UT_NAMESIZE];  /* user name */ 
    char ut_host[UT_HOSTSIZE];  /* hostname for remote login */ 
    struct exit_status ut_exit; /* The exit status of a 
                                   process marked as DEAD_PROCESS. */ 
    long ut_session;            /* session ID, used for 
 
    struct timeval ut_tv;       /* time entry was made.  */ 
    int32_t ut_addr_v6[4];      /* IP address of remote host.  */ 
    char pad[20];               /* Reserved for future use.  */ 
}; 
 
ut_type Àº ·Î±×ÀΠŸÀÔÀ¸·Î ¹Ì¸® µðÆÄÀÎµÈ °ªµéÀ» °¡Áö°í ÀÖ´Ù. ÀÌ¿¡ ´ëÇÑ ³»¿ëÀº utmp ÀÇ ¸Ç ÆäÀÌÁö¸¦ Âü°íÇϱ⠹ٶõ´Ù.
¿ì¸®°¡ º¸°íÀÚ ÇÏ´Â ·Î±×ÀΠŸÀÔÀÇ À¯Àú´Â, ÀÏ¹Ý À¯Àú ·¹º§¿¡¼­ Á¢±ÙÇÑ °æ¿ì¿¡ ÇÑÇϹǷΠut_type ÀÌ "USER_PROCESS"ÀÎ utmp Á¤º¸¸¸ °¡Á®¿Àµµ·Ï ÇϰڴÙ.
shell ¸í·É¾î·Î »ç¿ëÇÏ´Â "w" ¿ª½Ã ut_type ÀÌ "USER_PROCESS" Àΰæ¿ì¸¸ °¡Á®¿À´Âµ¥, ÀÌ·¯ÇÑ ut_type ÀÇ °ªÀº USER_PROCESS ·Î 7·Î µðÆÄÀεǾî ÀÖÀ¸¸ç,

ÀÌ ½î¾²ÀÇ Ã¹ºÎºÐ¿¡¼­´Â getutent(3) ÇÔ¼ö¸¦ ÀÌ¿ëÇÏ¿© utmpÆÄÀÏÀÇ °¡ÀåÃÖ±ÙÀÇ ÆÄÀÏ À§Ä¡¿¡¼­ ºÎÅÍ utmp Á¤º¸¸¦ ÀоîµéÀÌ°Ô ´Âµ¥, setutent(3)À» ÅëÇÏ¿© utmpÆÄÀÏ ÀÇ À§Ä¡¸¦ °¡ÀåóÀ½À¸·Î µ¹·ÈÀ½À¸·Î, utmpÀÇ Ã³À½Á¤º¸ºÎÅÍ Àоî¿À°Ô µÉ°ÍÀÌ´Ù. (±»ÀÌ stutent ¸¦ »ç¿ëÇÒÇÊ¿ä´Â ¾øÁö¸¸ ¾ÈÀüÇÑ ÇÁ·Î±×·¡¹Ö ½À°üÀ» À§Çؼ­..) ÀÌÁ¤º¸´Â utmpfp ±¸Á¶Ã¼¿¡ ÀúÀåÀ̵ǰí, ´õÀÌ»ó utmp Á¤º¸°¡ ³ª¿ÀÁö ¾ÊÀ»¶§±îÁö - NULL À» ¸¸³ª±â Àü±îÁö - ¹Ýº¹½ÇÇàµÇ°Ô µÈ´Ù.

while ·çÇÁ¹® ¾È¿¡¼­´Â getutent ¸¦ ÅëÇØ¼­ °¡Á®¿Â Á¤º¸¸¦ ÀÌ¿ëÇØ¼­ »ç¿ëÀÚ°¡ º¸±âÆíÇÑ ÇüÅ·Πµ¹·ÁÁÖ°Ô µÈ´Ù.
ÀÌ ÇÁ·Î±×·¥¿¡¼­ »ç¿ëÀÚ¿¡°Ô µ¹·ÁÁÖ´Â Á¤º¸´Â, ·Î±×Àνð£, »ç¿ëÅ͹̳ÎÀ̸§, È£½ºÆ® ¾ÆÀÌÇÇ, ±×¸®°í ÇöÀç ÁøÇàÁßÀÎ process ÀÇ À̸§À» µ¹·ÁÁÖ°Ô µÈ´Ù.

´ëºÎºÐÀÇ Á¤º¸µéÀº ´Ü¼øÈ÷ utmp ±¸Á¶Ã¼ÀÇ ¸â¹öµéÀ» Ãâ·Â½ÃŲ°ÍÀε¥, ´Ù¸¸ ÇöÀç ÁøÇàÁßÀÎ process °¡ ¹«¾ùÀÎÁö¸¦ È®ÀÎÇϱâ À§ÇÏ¿©¼­, º°µµÀÇ ÇÔ¼ö¸¦ ÀÛ¼ºÇÏ¿´´Ù.

get_current_pid ´Â ÇöÀç »ç¿ëÀÚ°¡ ½ÇÇàÁßÀÎ ÇÁ·Î±×·¥(ÇÁ·Î¼¼½º)ÀÇ pid ¸¦ °¡Á®¿À°í, get_current_procname ´Â get_current_pid ¸¦ ÅëÇØ¼­ ÇöÀç ½ÇÇàÁßÀÎ ÇÁ·Î¼¼½ºÀÇ pid ¸¦ ³Ñ°Ü¹Þ¾Æ¼­, pid ¿¡ ¸Â´Â ¸í·É¾îÀÇ À̸§À» µ¹·ÁÁØ´Ù.
ÀÌ¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ³»¿ëÀ» ¾Ë°í ½Í´Ù¸é proc ÆÄÀϽýºÅÛ¿¡ ´ëÇÑ ÀÌÇØ°¡ ÇÊ¿äÇѵ¥, »ó´çÈ÷ ¹æ´ëÇÑ ³»¿ëÀ̹ǷÎ, ¿©±â¿¡¼­´Â °³³ä¸¸ ¼³¸íÇÏ°í ³Ñ¾î°¡µµ·Ï ÇϰڴÙ.

¸®´ª½º´Â ¸ðµç ÇÁ·Î¼¼½ºÀÇ Á¤º¸¸¦ /proc ¹Ø¿¡ ÀÚ½ÅÀÇ pid À̸§ÀÇ µð·ºÅ丮¿¡ ÀúÀåÀ»ÇÏ°Ô µÈ´Ù. Áï ³»°¡ ÇöÀç vi ¸¦ ½ÇÇà½ÃÄ״µ¥, ÀÌ vi ¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ÇÁ·Î¼¼½º Á¤º¸¸¦ ¾Ë±â¸¦ ¿øÇÑ´Ù¸é ps µîÀ» ÀÌ¿ëÇØ¼­ vi ÀÇ pid ¸¦ ¾Ë¾Æ³»°í, /proc/pid À¸·Î À̵¿Çϸé ÇÁ·Î¼¼½ºÀÇ »ó¼¼ÇÑ Á¤º¸¸¦ ±â·ÏÇÑ ÆÄÀϵéÀ» ¿­¶÷ÇÔÀ¸·Î½á ÇÁ·Î¼¼½ºÀÇ Á¤º¸¸¦ ¾Ë¾Æ³¾¼ö ÀÖ´Ù.
/proc/pid ·Î À̵¿Çϸé ÀÌÁß stat ¶ó´Â ÆÄÀÏÀÌ º¸ÀϰÍÀÌ´Ù. stat¿¡´Â ÇÁ·Î¼¼½ºÀÇ pid, ¸í·É¾î, ppid(ºÎ¸ðÇÁ·Î¼¼½ºÀÇ pid) µî ÇÁ·Î¼¼½ºÀÇ Àü¹ÝÀûÀÎ Á¤º¸¸¦ ¾Ë¾Æ³¾¼ö Àִµ¥, 8¹øÂ° Çʵ尪À» ÀÌ¿ëÇØ¼­ °¡ÀåÃÖ±Ù¿¡ ½ÇÇàµÈ ÇÁ·Î¼¼½ºÀÇ pid °ªÀ» ¾Ë¾Æ³¾¼ö ÀÖ´Ù.(Á¤È®ÇϰԴ gid ÀÌÁö¸¸ ¿ì¸®°¡ ¾Ë¾Æ³»°íÀÚ ÇÏ´Â pid ¿Í µ¿ÀÏÇÑ °ªÀ» º¸¿©ÁֹǷΠ³Ñ¾î°¡µµ·Ï ÇϰڴÙ. ¿©±â¿¡ ´ëÇѳ»¿ëÀº À¯´Ð½º ÇÁ·Î¼¼½º¿¡ ´ëÇÑ ¸Þ´º¾óÀ» ÂüÁ¶Çϱ⠹ٶõ´Ù.)

±×¸®°í /proc/pid ¸¦ »ìÇ¥º¸¸é exe ¶ó´Â ½Éº¼¸µ ¸µÅ©µÈ ÆÄÀÏÀ» º¼¼ö ÀÖÀ»°ÍÀε¥, À̰ÍÀº ÇöÀç ÇÁ·Î¼¼½º¸¦ ½ÇÇà½ÃŲ ¸í·É¾î¿¡ ´ëÇÑ ½Éº¼¸¯¸µÅ©ÀÌ´Ù.

°á·ÐÀûÀ¸·Î ¿ì¸®´Â /proc/pid/stat ¸¦ ÀÌ¿ëÇØ¼­ ÇöÀç ½ÇÇàÁßÀÎ ÇÁ·Î¼¼½ºÀÇ pid¸¦ ¾Ë¼ö ÀÖÀ½À¸·Î ÇØ´ç ÇÁ·Î¼¼½º pid ÀÇ proc µð·ºÅ丮·Î À̵¿Çؼ­ exeÆÄÀÏÀÌ ¾î¶² ¸í·É¾î¿¡ ½Éº¼¸¯¸µÅ© µÇ¾îÀÖ´ÂÁö¸¦ È®ÀÎÇØ¼­, »ç¿ëÀÚ°¡ Áö±Ý ½ÇÇàÁßÀÎ ÇÁ·Î±×·¥ÀÌ ¾î¶²°ÍÀÎÁö¸¦ ¾Ë¼ö ÀÖ°Ô µÈ´Ù. ½Éº¼¸¯¸µÅ©ÀÇ ¿øº»ÆÄÀÏÀ̸§Àº readlink(2) ¸¦ ÀÌ¿ëÇØ¼­ °¡Á®¿Ã¼ö ÀÖ´Ù.

´Ù½ÃÇѹø Á¤¸®ÇØ º¸ÀÚ¸é get_current_pid ¸¦ ÀÌ¿ë /proc/pid/stat ÆÄÀÏÀ» ºÐ¼®Çؼ­ ÇöÀç ½ÇÇàÁßÀÎ ÇÁ·Î¼¼½ºÀÇ pid(current_pid) ¸¦ °¡Á®¿À°í, get_current_procname À» ÀÌ¿ëÇØ¼­ /proc/current_pid/exe ÀÇ ½Éº¼¸µÅ©µÈ ¿øº»ÀÇ ÆÄÀÏÀ̸§À» ÀÐ¾î ¿ÈÀ¸·Î½á »ç¿ëÀÚÀÇ ÇöÀçÁøÇàÁßÀÎ ÇÁ·Î±×·¥¸íÀ» ¾ò¾î¿À°Ô µÇ´Â°ÍÀÌ´Ù.

ÇÁ·Î±×·¥ÀÇ ¸¶Áö¸·¿¡¼­´Â getutline(3)ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼­ ÀÚ±âÀÚ½ÅÀÇ utmp Á¤º¸¸¦ Ãâ·ÂÇϵµ·Ï ¸¸µé¾ú´Ù. getutline ´Â tty ¹øÈ£¸¦ ÀÌ¿ëÇØ¼­ utmp Á¤º¸¸¦ °¡Á®¿Â´Ù. ttyÀÇ À̸§Àº ttyname(3) À» ÀÌ¿ëÇØ¼­ ¾ò¾î¿Ã¼ö ÀÖ´Ù.

¾Æ·¡´Â ÇÁ·Î±×·¥À» ½ÇÇà½ÃŲ °á°úÀÌ´Ù
[root@localhost test]# ./myutmp  
root         tty1     -            2002/09/16 22:12    
root         pts/0    -            2002/09/17 01:34    
root         pts/1    -            2002/09/16 22:13    
root         pts/2    -            2002/09/16 22:13    
root         pts/3    -            2002/09/20 11:53    
root         pts/4    -            2002/09/21 01:51    
root         pts/5    -            2002/09/21 02:03    
root         pts/6    -            2002/09/21 02:28    
root         pts/7    -            2002/09/21 03:07    
root         pts/8    -            2002/09/17 00:43    
root         pts/9    -            2002/09/18 00:13    
root         pts/10   -            2002/09/21 03:08    
root         pts/11   -            2002/09/21 03:11    
root         pts/12   -            2002/09/18 00:52    
root         pts/13   -            2002/09/22 11:14    
root         pts/14   -            2002/09/22 11:15    
root         pts/15   -            2002/09/22 11:16    
root         pts/16   -            2002/09/19 23:37    
root         pts/17   -            2002/09/22 11:32    
my utmp info is --- 
root         pts/14   -            2002/09/22 11:15    
 
EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù.