免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 9494 | 回复: 10
打印 上一主题 下一主题

[C] Linux下如何获取所有登陆的用户名 [复制链接]

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-01-14 23:36 |只看该作者 |倒序浏览
rt,用C实现。大家指点一下。除了从ps的输出读取之外,还有其他的什么方法。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2008-01-14 23:51 |只看该作者
w

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
3 [报告]
发表于 2008-01-15 00:02 |只看该作者
老大的意思是用who吗?

论坛徽章:
0
4 [报告]
发表于 2008-01-15 00:15 |只看该作者
  从文件里面直接可以读到。

论坛徽章:
0
5 [报告]
发表于 2008-01-15 09:21 |只看该作者
原帖由 Godbach 于 2008-1-15 00:02 发表
老大的意思是用who吗?

试验一下再问

论坛徽章:
0
6 [报告]
发表于 2008-01-15 09:24 |只看该作者
原帖由 Godbach 于 2008-1-15 00:02 发表
老大的意思是用who吗?

刚好有一个
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <utmp.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <time.h>

int main(int argc, char **argv)
{
    struct utmp *ut;
    struct stat st;
    int         devlen, len;
    time_t      now, idle;

    if (argc > 1)
                exit(1);

    setutent();
    devlen = sizeof("/dev/") - 1;
    printf("USER       TTY      IDLE      FROM           HOST\n");

    while ((ut = getutent()) != NULL) {
        char name[40];
if ((1||ut->ut_user[0]) && ut->ut_type == USER_PROCESS) {
            len = strlen(ut->ut_line);
            if (ut->ut_line[0] == '/') {
               strncpy(name, ut->ut_line, len);
               name[len] = '\0';
               strcpy(ut->ut_line, ut->ut_line + devlen);
            } else {
               strcpy(name, "/dev/");
               strncpy(name+devlen, ut->ut_line, len);
               name[devlen+len] = '\0';
            }

            printf("%-10s %-8s ", ut->ut_user, ut->ut_line);

            if (stat(name, &st) == 0) {
                now = time(NULL);
                idle = now -  st.st_atime;

                if (idle < 60)
                    printf("00:00m    ");
                else if (idle < (60 * 60))
                    printf("00:%02dm    ", (int)(idle / 60));
                else if (idle < (24 * 60 * 60))
                    printf("%02d:%02dm    ", (int)(idle / (60 * 60)),
                           (int)(idle % (60 * 60)) / 60);
else
                    printf("%02dyears   ", (int) (idle / (24 * 60 * 60 * 365)));
            } else
                printf("%-8s  ", "?");

            printf("%-12.12s   %s\n", ctime((time_t*)&(ut->ut_tv.tv_sec)) + 4, ut->ut_host);
        }
    }
    endutent();

    return 0;
}

论坛徽章:
5
摩羯座
日期:2014-07-22 09:03:552015元宵节徽章
日期:2015-03-06 15:50:392015亚冠之大阪钢巴
日期:2015-06-12 16:01:352015年中国系统架构师大会
日期:2015-06-29 16:11:2815-16赛季CBA联赛之四川
日期:2018-12-17 14:10:21
7 [报告]
发表于 2008-01-15 10:28 |只看该作者
通过查看who的命令文档可以查看到登陆用的信息被记录到了/var/run/utmp,/var/log/wtmp文件中,关于相关的结构可以在/usr/include/utmp.h下查看,在该文件中包含了一个头文件#include <bits/utmp.h>,这个文件中有具体的utmp结构,下面来看一看bits/utmp.h文件的相关部分:



  1. struct utmp

  2. {

  3.   short int ut_type;              

  4.   pid_t ut_pid;                 

  5.   char ut_line[UT_LINESIZE];   

  6.   char ut_id[4];            

  7.   char ut_user[UT_NAMESIZE];

  8.   char ut_host[UT_HOSTSIZE];  

  9.   struct exit_status ut_exit;   

  10. #if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32

  11.   int32_t ut_session;            

  12.   struct

  13.   {

  14.     int32_t tv_sec;              

  15.     int32_t tv_usec;            

  16.   } ut_tv;                     

  17. #else

  18.   long int ut_session;         
  19.   struct timeval ut_tv;         

  20. #endif



  21.   int32_t ut_addr_v6[4];     

  22.   char __unused[20];           /* Reserved for future use.  */

  23. };

复制代码


结构中包含了登陆的类型,拥护名,主机名,登陆时间,登陆的控制台等等!下面再来看一看登陆类型的结构:



  1. #define EMPTY            0     



  2. #define RUN_LVL         1   

  3. #define BOOT_TIME    2     

  4. #define NEW_TIME      3     

  5. #define OLD_TIME       4     



  6. #define INIT_PROCESS       5     

  7. #define LOGIN_PROCESS   6     

  8. #define USER_PROCESS      7     

  9. #define DEAD_PROCESS     8     

复制代码


类型分别为空,runlevel,reboot,newtime,oldtime,initprocess,login,用户等等,本文主要介绍的是USER_PROCESS这一项。如果要记录用户登陆的时间的话,当然就要用到时间的函数,也就是ctime函数,函数从/usr/include/time.h里面可以找到:

  1. extern char *ctime (__const time_t *__timer) __THROW;
复制代码


主要的操作还是打开文件和读取文件,也就是open和read函数,打开的文件是/var/run/utmp。在/usr/include/paths.h里面有定义。同时也可以查看到各种路径的定义。

  下面开始编写简单的程序:

  1. #include<stdio.h>

  2. #include<utmp.h>

  3. #include<unistd.h>

  4. #include<fcntl.h>

  5. #include<time.h>



  6. void Timeformat(long timearg)

  7. {

  8.     char *p;    /*声明一个指针变量,在后面用来存放时间的地址*/

  9.     p=ctime(&timearg); /*格式化时间*/

  10.     printf("%12.12s\n", p+4); /*ctime返回的字符串从第四个字符开始*/

  11. }
复制代码
  1. /*以上为格式化输出时间*/

  2. void Showmessage(struct utmp * utmparg)

  3. {

  4.    

  5.    if(utmparg->ut_type != USER_PROCESS)/*判断登陆类型时候是“用户”*/

  6.    return;

  7.    printf("%-8.8s", utmparg->ut_name ); /*输出登陆的用户名*/

  8.    printf(" ");

  9.    printf("%-8.8s",utmparg->ut_line); /*输出登陆的TTY*/

  10.    printf(" ");

  11.    Timeformat(utmparg->ut_time); /*输出登陆的时间*/



  12. }
复制代码




  1. /*以上为输出当我们输入who命令后输出的信息*/

  2. int main()

  3. {

  4.     struct utmp pointer;   /*声明utmp结构变量*/

  5.     int utmpfd;  /*打开的utmp文件存放在这里*/

  6.     int re=sizeof(pointer);

  7.    

  8.     if((utmpfd = open(UTMP_FILE, O_RDONLY)) == 1){/*打开utmp文件,前面说过UTMP_FILE文件在paths.h中有定义*/

  9.     printf("error\n");

  10.     exit(1);

  11.     }



  12.     while( read(utmpfd, &pointer, re) == re)/*读取文件中的内容*/

  13.     Showmessage(&pointer); /*调用Showmessage函数*/

  14.     close(utmpfd); /*关闭utmp文件*/

  15.     return 0;

  16. }
复制代码

[ 本帖最后由 T-bagwell 于 2008-1-15 10:31 编辑 ]

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
8 [报告]
发表于 2008-01-15 11:52 |只看该作者
多谢楼上各位指点

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
9 [报告]
发表于 2008-01-15 11:54 |只看该作者
原帖由 flw2 于 2008-1-15 09:21 发表

试验一下再问


呵呵,这种方法我知道。只是在有些裁剪的Linux上不支持这个命令。

论坛徽章:
0
10 [报告]
发表于 2008-01-15 13:49 |只看该作者
popen("who|awk '{print $1}'","r");
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP