Major coreutils update.
[platform/upstream/busybox.git] / coreutils / who.c
1 /* vi: set sw=4 ts=4: */
2 /*----------------------------------------------------------------------
3  * Mini who is used to display user name, login time, 
4  * idle time and host name.
5  *
6  * Author: Da Chen  <dchen@ayrnetworks.com>
7  *
8  * This is a free document; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation:
11  *    http://www.gnu.org/copyleft/gpl.html
12  *
13  * Copyright (c) 2002 AYR Networks, Inc. 
14  *----------------------------------------------------------------------
15  */
16
17 #include <sys/types.h>
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <stdlib.h>
21 #include <utmp.h>
22 #include <sys/stat.h>
23 #include <errno.h>
24 #include <string.h>
25 #include <time.h>
26 #include "busybox.h"
27
28 extern int who_main(int argc, char **argv)
29 {
30     struct utmp *ut;
31     struct stat st;
32     int         devlen, len;
33     time_t      now, idle; 
34
35     if (argc > 1) 
36         bb_show_usage();
37
38     setutent();
39     devlen = sizeof("/dev/") - 1;
40     printf("USER       TTY      IDLE      FROM           HOST\n"); 
41
42     while ((ut = getutent()) != NULL) {
43         char name[40];
44
45         if (ut->ut_user[0] && ut->ut_type == USER_PROCESS) { 
46             len = strlen(ut->ut_line);
47             if (ut->ut_line[0] == '/') { 
48                strncpy(name, ut->ut_line, len);
49                name[len] = '\0';
50                strcpy(ut->ut_line, ut->ut_line + devlen);
51             } else {
52                strcpy(name, "/dev/");
53                strncpy(name+devlen, ut->ut_line, len);
54                name[devlen+len] = '\0';
55             }
56            
57             printf("%-10s %-8s ", ut->ut_user, ut->ut_line);
58
59             if (stat(name, &st) == 0) {
60                 now = time(NULL);        
61                 idle = now -  st.st_atime;
62             
63                 if (idle < 60)
64                     printf("00:00m    ");
65                 else if (idle < (60 * 60)) 
66                     printf("00:%02dm    ", (int)(idle / 60));
67                 else if (idle < (24 * 60 * 60)) 
68                     printf("%02d:%02dm    ", (int)(idle / (60 * 60)),
69                            (int)(idle % (60 * 60)) / 60);
70                 else if (idle < (24 * 60 * 60 * 365)) 
71                     printf("%03ddays   ", (int)(idle / (24 * 60 * 60)));
72                 else 
73                     printf("%02dyears   ", (int) (idle / (24 * 60 * 60 * 365)));
74             } else 
75                 printf("%-8s  ", "?");       
76       
77             printf("%-12.12s   %s\n", ctime(&(ut->ut_tv.tv_sec)) + 4, ut->ut_host);
78         }
79     }
80     endutent();
81
82     return 0;
83 }