File Coverage

Utmp.xs
Criterion Covered Total %
statement 31 86 36.0
branch 23 62 37.1
condition n/a
subroutine n/a
pod n/a
total 54 148 36.4


line stmt bran cond sub pod time code
1             #include "EXTERN.h"
2             #include "perl.h"
3             #include "XSUB.h"
4              
5             #include
6              
7             #ifdef _AIX
8             #define _HAVE_UT_HOST 1
9             #endif
10              
11             #ifndef USER_PROCESS
12             #define EMPTY 0 /* No valid user accounting information. */
13              
14             #define RUN_LVL 1 /* The system's runlevel. */
15             #define BOOT_TIME 2 /* Time of system boot. */
16             #define NEW_TIME 3 /* Time after system clock changed. */
17             #define OLD_TIME 4 /* Time when system clock changed. */
18              
19             #define INIT_PROCESS 5 /* Process spawned by the init process. */
20             #define LOGIN_PROCESS 6 /* Session leader of a logged in user. */
21             #define USER_PROCESS 7 /* Normal process. */
22             #define DEAD_PROCESS 8 /* Terminated process. */
23              
24             #define ACCOUNTING 9
25             #endif
26              
27             #ifdef BSD
28             #define _NO_UT_ID
29             #define _NO_UT_TYPE
30             #define _NO_UT_PID
31             #define _HAVE_UT_HOST
32             #define ut_user ut_name
33             #endif
34              
35             #ifdef NOUTFUNCS
36             #include
37             #include
38             #include
39             #include
40             #include
41             #include
42             #include
43             #include
44              
45              
46              
47             /*
48             define these so it still works as documented :)
49             */
50              
51              
52             /*
53             It is almost certain that if these are not defined the fields they are
54             for are not present or this is BSD :)
55             */
56              
57              
58             static int ut_fd = -1;
59              
60             static char _ut_name[] = _PATH_UTMP;
61              
62             void utmpname(char *filename) {
63             strcpy(_ut_name, filename);
64             }
65              
66             void setutent(void) {
67             if (ut_fd < 0) {
68             if ((ut_fd = open(_ut_name, O_RDONLY)) < 0) {
69             croak("Can't open %s",_ut_name);
70             }
71             }
72              
73             lseek(ut_fd, (off_t) 0, SEEK_SET);
74             }
75              
76             void endutent(void) {
77             if (ut_fd > 0) {
78             close(ut_fd);
79             }
80              
81             ut_fd = -1;
82             }
83              
84             struct utmp *getutent(void) {
85             static struct utmp s_utmp;
86             int readval;
87              
88             if (ut_fd < 0) {
89             setutent();
90             }
91              
92             if ((readval = read(ut_fd, &s_utmp, sizeof(s_utmp))) < sizeof(s_utmp)) {
93             if (readval == 0) {
94             return NULL;
95             }
96             else if (readval < 0) {
97             croak("Error reading %s", _ut_name);
98             }
99             else {
100             croak("Partial record in %s [%d bytes]", _ut_name, readval );
101             }
102             }
103             return &s_utmp;
104             }
105              
106             #endif
107              
108              
109             static double
110 10           constant(char *name, int len, int arg)
111             {
112 10           errno = 0;
113 10 100         if (strEQ(name, "ACCOUNTING")) {
114 1           return ACCOUNTING;
115             }
116 9 100         else if (strEQ(name, "BOOT_TIME")) {
117 1           return BOOT_TIME;
118             }
119 8 100         else if (strEQ(name, "DEAD_PROCESS")) {
120 1           return DEAD_PROCESS;
121             }
122 7 100         else if (strEQ(name, "EMPTY")) {
123 1           return EMPTY;
124             }
125 6 100         else if (strEQ(name, "INIT_PROCESS")) {
126 1           return INIT_PROCESS;
127             }
128 5 100         else if (strEQ(name, "LOGIN_PROCESS")) {
129 1           return LOGIN_PROCESS;
130             }
131 4 100         else if (strEQ(name, "NEW_TIME")) {
132 1           return NEW_TIME;
133             }
134 3 100         else if (strEQ(name, "OLD_TIME")) {
135 1           return OLD_TIME;
136             }
137 2 100         else if (strEQ(name, "RUN_LVL")) {
138 1           return RUN_LVL;
139             }
140 1 50         if (strEQ(name, "USER_PROCESS")) {
141 1           return USER_PROCESS;
142             }
143             else {
144 0           errno = EINVAL;
145 0           return 0;
146             }
147             }
148              
149              
150             MODULE = Sys::Utmp PACKAGE = Sys::Utmp
151              
152             PROTOTYPES: DISABLE
153              
154              
155             double
156             constant(sv,arg)
157             PREINIT:
158             STRLEN len;
159             INPUT:
160             SV * sv
161             char * s = SvPV(sv, len);
162             int arg
163             CODE:
164 10           RETVAL = constant(s,len,arg);
165             OUTPUT:
166             RETVAL
167              
168              
169              
170             void
171             getutent(self)
172             SV *self
173             PPCODE:
174             static AV *ut;
175             static HV *meth_stash;
176             static IV ut_tv;
177             static IV _ut_pid;
178             static IV _ut_type;
179             static SV *ut_ref;
180             static char *_ut_id;
181             static struct utmp *utent;
182             static char ut_host[sizeof(utent->ut_host)];
183              
184              
185             SV *sv_ut_user;
186             SV *sv_ut_id;
187             SV *sv_ut_line;
188             SV *sv_ut_pid;
189             SV *sv_ut_type;
190             SV *sv_ut_host;
191             SV *sv_ut_tv;
192              
193 5 50         if(!SvROK(self))
194 0           croak("Must be called as an object method");
195              
196              
197 5           utent = getutent();
198              
199 5 50         if ( utent ) {
200             #ifdef _NO_UT_ID
201             _ut_id = "";
202             #else
203 0           _ut_id = utent->ut_id;
204             #endif
205             #ifdef _NO_UT_TYPE
206             _ut_type = 7;
207             #else
208 0           _ut_type = utent->ut_type;
209             #endif
210             #ifdef _NO_UT_PID
211             _ut_pid = -1;
212             #else
213 0           _ut_pid = utent->ut_pid;
214             #endif
215             #ifdef _HAVE_UT_TV
216 0           ut_tv = (IV)utent->ut_tv.tv_sec;
217             #else
218             ut_tv = (IV)utent->ut_time;
219             #endif
220             #ifdef _HAVE_UT_HOST
221 0           strncpy(ut_host, utent->ut_host,sizeof(utent->ut_host));
222             #else
223             strncpy(ut_host, "",1);
224             #endif
225              
226              
227 0           sv_ut_user = newSVpv(utent->ut_user,0);
228 0           sv_ut_id = newSVpv(_ut_id,0);
229 0           sv_ut_line = newSVpv(utent->ut_line,0);
230 0           sv_ut_pid = newSViv(_ut_pid);
231 0           sv_ut_type = newSViv(_ut_type);
232 0           sv_ut_host = newSVpv(ut_host,0);
233 0           sv_ut_tv = newSViv(ut_tv);
234              
235              
236 0 0         SvTAINTED_on(sv_ut_user);
237 0 0         SvTAINTED_on(sv_ut_host);
238              
239 0 0         if ( GIMME_V == G_ARRAY ) {
    0          
240 0           sv_ut_user = sv_2mortal(sv_ut_user);
241 0           sv_ut_id = sv_2mortal(sv_ut_id);
242 0           sv_ut_line = sv_2mortal(sv_ut_line);
243 0           sv_ut_pid = sv_2mortal(sv_ut_pid);
244 0           sv_ut_type = sv_2mortal(sv_ut_type);
245 0           sv_ut_host = sv_2mortal(sv_ut_host);
246 0           sv_ut_tv = sv_2mortal(sv_ut_tv);
247              
248 0 0         XPUSHs(sv_ut_user);
249 0 0         XPUSHs(sv_ut_id);
250 0 0         XPUSHs(sv_ut_line);
251 0 0         XPUSHs(sv_ut_pid);
252 0 0         XPUSHs(sv_ut_type);
253 0 0         XPUSHs(sv_ut_host);
254 0 0         XPUSHs(sv_ut_tv);
255              
256             }
257 0 0         else if ( GIMME_V == G_SCALAR ) {
    0          
258 0           ut = newAV();
259 0           av_push(ut,sv_ut_user);
260 0           av_push(ut,sv_ut_id);
261 0           av_push(ut,sv_ut_line);
262 0           av_push(ut,sv_ut_pid);
263 0           av_push(ut,sv_ut_type);
264 0           av_push(ut,sv_ut_host);
265 0           av_push(ut,sv_ut_tv);
266              
267 0           meth_stash = gv_stashpv("Sys::Utmp::Utent",1);
268 0           ut_ref = newRV_noinc((SV *)ut);
269 0           sv_bless(ut_ref, meth_stash);
270 0 0         XPUSHs(sv_2mortal(ut_ref));
271             }
272             else {
273 0           XSRETURN_EMPTY;
274             }
275             }
276             else {
277 5           XSRETURN_EMPTY;
278             }
279              
280              
281              
282             void
283             setutent(self)
284             SV *self
285             PPCODE:
286              
287 2 50         if(!SvROK(self))
288 0           croak("Must be called as an object method");
289              
290 2           setutent();
291              
292             void
293             endutent(self)
294             SV *self
295             PPCODE:
296              
297 0 0         if(!SvROK(self))
298 0           croak("Must be called as an object method");
299 0           endutent();
300              
301             void
302             utmpname(self, filename)
303             SV *self
304             SV *filename
305             PPCODE:
306             char *ff;
307              
308 0 0         if(!SvROK(self))
309 0           croak("Must be called as an object method");
310              
311 0 0         ff = SvPV(filename,PL_na);
312 0           utmpname(ff);
313              
314             void
315             DESTROY(self)
316             SV *self
317             PPCODE:
318              
319 5 50         if(!SvROK(self))
320 0           croak("Must be called as an object method");
321              
322 5           endutent();