ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/user_stats.c
Revision: 1.29
Committed: Sat Feb 20 17:55:04 2010 UTC (14 years, 2 months ago) by tdb
Content type: text/plain
Branch: MAIN
CVS Tags: LIBSTATGRAB_0_17, HEAD
Changes since 1.28: +16 -3 lines
Log Message:
Support utmpx in user_stats as well as utmp.

File Contents

# Content
1 /*
2 * i-scream libstatgrab
3 * http://www.i-scream.org
4 * Copyright (C) 2000-2004 i-scream
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 * 02111-1307 USA
20 *
21 * $Id: user_stats.c,v 1.28 2005/09/24 13:29:23 tdb Exp $
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include "statgrab.h"
32 #include "vector.h"
33 #ifdef ALLBSD
34 #include <sys/types.h>
35 #endif
36 #if defined(NETBSD) || defined(OPENBSD)
37 #include <limits.h>
38 #endif
39 #ifdef OPENBSD
40 #include <sys/param.h>
41 #endif
42 #ifndef WIN32
43 #ifdef HAVE_UTMPX
44 #include <utmpx.h>
45 #else
46 #include <utmp.h>
47 #endif
48 #endif
49 #ifdef CYGWIN
50 #include <sys/unistd.h>
51 #endif
52 #ifdef HPUX
53 #include <utmp.h>
54 #endif
55 #ifdef WIN32
56 #include <windows.h>
57 #include <lm.h>
58 #endif
59
60 sg_user_stats *sg_get_user_stats(){
61 int num_users = 0, pos = 0, new_pos;
62 VECTOR_DECLARE_STATIC(name_list, char, 128, NULL, NULL);
63 static sg_user_stats user_stats;
64 #if defined(ALLBSD) && !defined(HAVE_UTMPX)
65 struct utmp entry;
66 FILE *f;
67
68 if ((f=fopen(_PATH_UTMP, "r")) == NULL){
69 sg_set_error_with_errno(SG_ERROR_OPEN, _PATH_UTMP);
70 return NULL;
71 }
72 while((fread(&entry, sizeof(entry),1,f)) != 0){
73 if (entry.ut_name[0] == '\0') continue;
74
75 new_pos = pos + strlen(entry.ut_name) + 1;
76 if (VECTOR_RESIZE(name_list, new_pos) < 0) {
77 return NULL;
78 }
79
80 strcpy(name_list + pos, entry.ut_name);
81 name_list[new_pos - 1] = ' ';
82 pos = new_pos;
83 num_users++;
84 }
85 fclose(f);
86 #elif defined (WIN32)
87 LPWKSTA_USER_INFO_0 buf = NULL;
88 LPWKSTA_USER_INFO_0 tmp_buf;
89 unsigned long entries_read = 0;
90 unsigned long entries_tot = 0;
91 unsigned long resumehandle = 0;
92 NET_API_STATUS nStatus;
93 int i;
94 char name[256];
95
96 do {
97 nStatus = NetWkstaUserEnum(NULL, 0, (LPBYTE*)&buf,
98 MAX_PREFERRED_LENGTH, &entries_read,
99 &entries_tot, &resumehandle);
100 if((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA)) {
101 if((tmp_buf = buf) == NULL) {
102 continue;
103 }
104 for (i=0; i<entries_read; i++) {
105 //assert(tmp_buf != NULL);
106 if (tmp_buf == NULL) {
107 sg_set_error(SG_ERROR_PERMISSION, "User list");
108 break;
109 }
110 /* It's in unicode. We are not. Convert */
111 WideCharToMultiByte(CP_ACP, 0, tmp_buf->wkui0_username, -1, name, sizeof(name), NULL, NULL);
112
113 new_pos = pos + strlen(name) + 1;
114 if(VECTOR_RESIZE(name_list, new_pos) < 0) {
115 NetApiBufferFree(buf);
116 return NULL;
117 }
118 strcpy(name_list + pos, name);
119 name_list[new_pos - 1] = ' ';
120 pos = new_pos;
121
122 tmp_buf++;
123 num_users++;
124 }
125 } else {
126 sg_set_error(SG_ERROR_PERMISSION, "User enum");
127 return NULL;
128 }
129 if (buf != NULL) {
130 NetApiBufferFree(buf);
131 buf=NULL;
132 }
133 } while (nStatus == ERROR_MORE_DATA);
134 if (buf != NULL) {
135 NetApiBufferFree(buf);
136 }
137 #else
138 /* This works on everything else. */
139 #ifdef HAVE_UTMPX
140 struct utmpx *entry;
141 setutxent();
142 while((entry=getutxent()) != NULL) {
143 #else
144 struct utmp *entry;
145 setutent();
146 while((entry=getutent()) != NULL) {
147 #endif
148 if (entry->ut_type != USER_PROCESS) continue;
149
150 new_pos = pos + strlen(entry->ut_user) + 1;
151 if (VECTOR_RESIZE(name_list, new_pos) < 0) {
152 return NULL;
153 }
154
155 strcpy(name_list + pos, entry->ut_user);
156 name_list[new_pos - 1] = ' ';
157 pos = new_pos;
158 num_users++;
159 }
160 #ifdef HAVE_UTMPX
161 endutxent();
162 #else
163 endutent();
164 #endif
165 #endif
166
167 /* Remove the extra space at the end, and append a \0. */
168 if (num_users != 0) {
169 pos--;
170 }
171 if (VECTOR_RESIZE(name_list, pos + 1) < 0) {
172 return NULL;
173 }
174 name_list[pos] = '\0';
175
176 user_stats.num_entries = num_users;
177 user_stats.name_list = name_list;
178 return &user_stats;
179 }