magic nums to defines and don't check ut_name and ut_line length because it can't...
[monky] / src / users.c
1 /* Conky, a system monitor, based on torsmo
2  *
3  * Any original torsmo code is licensed under the BSD license
4  *
5  * All code written since the fork of torsmo is licensed under the GPL
6  *
7  * Please see COPYING for details
8  *
9  * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
10  * Copyright (c) 2005-2008 Brenden Matthews, Philip Kovacs, et. al.
11  *      (see AUTHORS)
12  * All rights reserved.
13  *
14  * This program is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation, either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * You should have received a copy of the GNU General Public License
24  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
25  *
26  * $Id$
27  *
28  */
29
30 #include "conky.h"
31 #include <utmp.h>
32 #include <time.h>
33
34 #define BUFLEN 512
35
36 static void user_name(char *ptr)
37 {
38         const struct utmp *usr = 0;
39
40         setutent();
41         while ((usr = getutent()) != NULL) {
42                 if (usr->ut_type == USER_PROCESS) {
43                         if (strlen(ptr) + strlen(usr->ut_name) + 1 <= BUFLEN) {
44                                 strncat(ptr, usr->ut_name, UT_NAMESIZE);
45                         }
46                 }
47         }
48 }
49 static void user_num(int *ptr)
50 {
51         const struct utmp *usr;
52         int users_num = 0;
53
54         setutent();
55         while ((usr = getutent()) != NULL) {
56                 if (usr->ut_type == USER_PROCESS) {
57                         ++users_num;
58                 }
59         }
60         *ptr = users_num;
61 }
62 static void user_term(char *ptr)
63 {
64         const struct utmp *usr;
65
66         setutent();
67         while ((usr = getutent()) != NULL) {
68                 if (usr->ut_type == USER_PROCESS) {
69                         if (strlen(ptr) + strlen(usr->ut_line) + 1 <= BUFLEN) {
70                                 strncat(ptr, usr->ut_line, UT_LINESIZE);
71                         }
72                 }
73         }
74 }
75 static void user_time(char *ptr)
76 {
77         const struct utmp *usr;
78         time_t log_in, real, diff;
79         struct tm *dtime;
80         char buf[BUFLEN] = "";
81
82         setutent();
83         while ((usr = getutent()) != NULL) {
84                 if (usr->ut_type == USER_PROCESS) {
85                         log_in = usr->ut_time;
86                         time(&real);
87                         diff = difftime(real, log_in);
88                         dtime = localtime(&diff);
89                         dtime->tm_year = dtime->tm_year - 70;
90                         dtime->tm_mon = dtime->tm_mon - 1;
91                         dtime->tm_mday = dtime->tm_mday - 1;
92                         if (dtime->tm_year > 0) {
93                                 strftime(buf, BUFLEN, "%yy %mm %dd %Hh %Mm", dtime);
94                         } else if (dtime->tm_mon > 0) {
95                                 strftime(buf, BUFLEN, "%mm %dd %Hh %Mm", dtime);
96                         } else if (dtime->tm_mday > 0) {
97                                 strftime(buf, BUFLEN, "%dd %Hh %Mm", dtime);
98                         } else if (dtime->tm_hour > 0) {
99                                 strftime(buf, BUFLEN, "%Hh %Mm", dtime);
100                         } else if (dtime->tm_min > 0) {
101                                 strftime(buf, BUFLEN, "%Mm", dtime);
102                         }
103                         if (strlen(ptr) + strlen(buf) + 1 <= BUFLEN) {
104                                 strncat(ptr, buf, BUFLEN);
105                         }
106                 }
107         }
108 }
109
110 static void users_alloc(struct information *ptr)
111 {
112         if (ptr->users.names == NULL) {
113                 ptr->users.names = malloc(text_buffer_size);
114
115         }
116         if (ptr->users.terms == NULL) {
117                 ptr->users.terms = malloc(text_buffer_size);
118         }
119         if (ptr->users.times == NULL) {
120                 ptr->users.times = malloc(text_buffer_size);
121         }
122 }
123
124 void update_users(void)
125 {
126         struct information *current_info = &info;
127         char temp[BUFLEN] = "";
128         int t;
129         users_alloc(current_info);
130         user_name(temp);
131         if (temp != NULL) {
132                 if (current_info->users.names) {
133                         free(current_info->users.names);
134                         current_info->users.names = 0;
135                 }
136                 current_info->users.names = malloc(text_buffer_size);
137                 strncpy(current_info->users.names, temp, text_buffer_size);
138         } else {
139                 if (current_info->users.names) {
140                         free(current_info->users.names);
141                         current_info->users.names = 0;
142                 }
143                 current_info->users.names = malloc(text_buffer_size);
144                 strncpy(current_info->users.names, "broken", text_buffer_size);
145         }
146         user_num(&t);
147         if (t != 0) {
148                 if (current_info->users.number) {
149                         current_info->users.number = 0;
150                 }
151                 current_info->users.number = t;
152         } else {
153                 current_info->users.number = 0;
154         }
155         temp[0] = 0;
156         user_term(temp);
157         if (temp != NULL) {
158                 if (current_info->users.terms) {
159                         free(current_info->users.terms);
160                         current_info->users.terms = 0;
161                 }
162                 current_info->users.terms = malloc(text_buffer_size);
163                 strncpy(current_info->users.terms, temp, text_buffer_size);
164         } else {
165                 if (current_info->users.terms) {
166                         free(current_info->users.terms);
167                         current_info->users.terms = 0;
168                 }
169                 current_info->users.terms = malloc(text_buffer_size);
170                 strncpy(current_info->users.terms, "broken", text_buffer_size);
171         }
172         user_time(temp);
173         if (temp != NULL) {
174                 if (current_info->users.times) {
175                         free(current_info->users.times);
176                         current_info->users.times = 0;
177                 }
178                 current_info->users.times = malloc(text_buffer_size);
179                 strncpy(current_info->users.times, temp, text_buffer_size);
180         } else {
181                 if (current_info->users.times) {
182                         free(current_info->users.times);
183                         current_info->users.times = 0;
184                 }
185                 current_info->users.times = malloc(text_buffer_size);
186                 strncpy(current_info->users.times, "broken", text_buffer_size);
187         }
188 }