|
1 #ifndef __SYMBIAN32__ |
|
2 // watch.c - login/logout watching |
|
3 // |
|
4 // © Portions Copyright (c) Symbian Software Ltd 2007. All rights reserved. |
|
5 // |
|
6 /* |
|
7 * This file is part of zsh, the Z shell. |
|
8 * |
|
9 * Copyright (c) 1992-1997 Paul Falstad |
|
10 * All rights reserved. |
|
11 * |
|
12 * Permission is hereby granted, without written agreement and without |
|
13 * license or royalty fees, to use, copy, modify, and distribute this |
|
14 * software and to distribute modified versions of this software for any |
|
15 * purpose, provided that the above copyright notice and the following |
|
16 * two paragraphs appear in all copies of this software. |
|
17 * |
|
18 * In no event shall Paul Falstad or the Zsh Development Group be liable |
|
19 * to any party for direct, indirect, special, incidental, or consequential |
|
20 * damages arising out of the use of this software and its documentation, |
|
21 * even if Paul Falstad and the Zsh Development Group have been advised of |
|
22 * the possibility of such damage. |
|
23 * |
|
24 * Paul Falstad and the Zsh Development Group specifically disclaim any |
|
25 * warranties, including, but not limited to, the implied warranties of |
|
26 * merchantability and fitness for a particular purpose. The software |
|
27 * provided hereunder is on an "as is" basis, and Paul Falstad and the |
|
28 * Zsh Development Group have no obligation to provide maintenance, |
|
29 * support, updates, enhancements, or modifications. |
|
30 * |
|
31 */ |
|
32 #include "zsh.mdh" |
|
33 |
|
34 /* Headers for utmp/utmpx structures */ |
|
35 #ifdef HAVE_UTMP_H |
|
36 # include <utmp.h> |
|
37 #endif |
|
38 #ifdef HAVE_UTMPX_H |
|
39 #ifndef __SYMBIAN32__ |
|
40 # include <utmpx.h> |
|
41 #endif//__SYMBIAN32__ |
|
42 #endif |
|
43 |
|
44 #ifdef __SYMBIAN32__ |
|
45 #ifdef __WINSCW__ |
|
46 #pragma warn_unusedarg off |
|
47 #pragma warn_possunwant off |
|
48 #endif//__WINSCW__ |
|
49 #endif//__SYMBIAN32__ |
|
50 |
|
51 /* Find utmp file */ |
|
52 #if !defined(REAL_UTMP_FILE) && defined(UTMP_FILE) |
|
53 # define REAL_UTMP_FILE UTMP_FILE |
|
54 #endif |
|
55 #if !defined(REAL_UTMP_FILE) && defined(_PATH_UTMP) |
|
56 # define REAL_UTMP_FILE _PATH_UTMP |
|
57 #endif |
|
58 #if !defined(REAL_UTMP_FILE) && defined(PATH_UTMP_FILE) |
|
59 # define REAL_UTMP_FILE PATH_UTMP_FILE |
|
60 #endif |
|
61 |
|
62 /* Find wtmp file */ |
|
63 #if !defined(REAL_WTMP_FILE) && defined(WTMP_FILE) |
|
64 # define REAL_WTMP_FILE WTMP_FILE |
|
65 #endif |
|
66 #if !defined(REAL_WTMP_FILE) && defined(_PATH_WTMP) |
|
67 # define REAL_WTMP_FILE _PATH_WTMP |
|
68 #endif |
|
69 #if !defined(REAL_WTMP_FILE) && defined(PATH_WTMP_FILE) |
|
70 # define REAL_WTMP_FILE PATH_WTMP_FILE |
|
71 #endif |
|
72 |
|
73 /* Find utmpx file */ |
|
74 #if !defined(REAL_UTMPX_FILE) && defined(UTMPX_FILE) |
|
75 # define REAL_UTMPX_FILE UTMPX_FILE |
|
76 #endif |
|
77 #if !defined(REAL_UTMPX_FILE) && defined(_PATH_UTMPX) |
|
78 # define REAL_UTMPX_FILE _PATH_UTMPX |
|
79 #endif |
|
80 #if !defined(REAL_UTMPX_FILE) && defined(PATH_UTMPX_FILE) |
|
81 # define REAL_UTMPX_FILE PATH_UTMPX_FILE |
|
82 #endif |
|
83 |
|
84 /* Find wtmpx file */ |
|
85 #if !defined(REAL_WTMPX_FILE) && defined(WTMPX_FILE) |
|
86 # define REAL_WTMPX_FILE WTMPX_FILE |
|
87 #endif |
|
88 #if !defined(REAL_WTMPX_FILE) && defined(_PATH_WTMPX) |
|
89 # define REAL_WTMPX_FILE _PATH_WTMPX |
|
90 #endif |
|
91 #if !defined(REAL_WTMPX_FILE) && defined(PATH_WTMPX_FILE) |
|
92 # define REAL_WTMPX_FILE PATH_WTMPX_FILE |
|
93 #endif |
|
94 |
|
95 /* Decide which structure to use. We use a structure that exists in * |
|
96 * the headers, and require that its corresponding utmp file exist. * |
|
97 * (wtmp is less important.) */ |
|
98 |
|
99 #if !defined(WATCH_STRUCT_UTMP) && defined(HAVE_STRUCT_UTMPX) && defined(REAL_UTMPX_FILE) |
|
100 # define WATCH_STRUCT_UTMP struct utmpx |
|
101 # ifdef HAVE_STRUCT_UTMPX_UT_XTIME |
|
102 # undef ut_time |
|
103 # define ut_time ut_xtime |
|
104 # else /* !HAVE_STRUCT_UTMPX_UT_XTIME */ |
|
105 # ifdef HAVE_STRUCT_UTMPX_UT_TV |
|
106 # undef ut_time |
|
107 # define ut_time ut_tv.tv_sec |
|
108 # endif /* HAVE_STRUCT_UTMPX_UT_TV */ |
|
109 # endif /* !HAVE_STRUCT_UTMPX_UT_XTIME */ |
|
110 # define WATCH_UTMP_FILE REAL_UTMPX_FILE |
|
111 # ifdef REAL_WTMPX_FILE |
|
112 # define WATCH_WTMP_FILE REAL_WTMPX_FILE |
|
113 # endif |
|
114 # ifdef HAVE_STRUCT_UTMPX_UT_HOST |
|
115 # define WATCH_UTMP_UT_HOST 1 |
|
116 # endif |
|
117 # ifdef __APPLE__ |
|
118 # define ut_name ut_user |
|
119 # endif |
|
120 #endif |
|
121 |
|
122 #if !defined(WATCH_STRUCT_UTMP) && defined(HAVE_STRUCT_UTMP) && defined(REAL_UTMP_FILE) |
|
123 # define WATCH_STRUCT_UTMP struct utmp |
|
124 # define WATCH_UTMP_FILE REAL_UTMP_FILE |
|
125 # ifdef REAL_WTMP_FILE |
|
126 # define WATCH_WTMP_FILE REAL_WTMP_FILE |
|
127 # endif |
|
128 # ifdef HAVE_STRUCT_UTMP_UT_HOST |
|
129 # define WATCH_UTMP_UT_HOST 1 |
|
130 # endif |
|
131 #endif |
|
132 |
|
133 #ifdef WATCH_UTMP_UT_HOST |
|
134 # define DEFAULT_WATCHFMT "%n has %a %l from %m." |
|
135 #else /* !WATCH_UTMP_UT_HOST */ |
|
136 # define DEFAULT_WATCHFMT "%n has %a %l." |
|
137 #endif /* !WATCH_UTMP_UT_HOST */ |
|
138 |
|
139 /**/ |
|
140 char const * const default_watchfmt = DEFAULT_WATCHFMT; |
|
141 |
|
142 #ifdef WATCH_STRUCT_UTMP |
|
143 |
|
144 # include "watch.pro" |
|
145 |
|
146 # ifndef WATCH_WTMP_FILE |
|
147 # define WATCH_WTMP_FILE "/dev/null" |
|
148 # endif |
|
149 |
|
150 static int wtabsz; |
|
151 static WATCH_STRUCT_UTMP *wtab; |
|
152 static time_t lastutmpcheck; |
|
153 |
|
154 /* get the time of login/logout for WATCH */ |
|
155 |
|
156 /**/ |
|
157 static time_t |
|
158 getlogtime(WATCH_STRUCT_UTMP *u, int inout) |
|
159 { |
|
160 FILE *in; |
|
161 WATCH_STRUCT_UTMP uu; |
|
162 int first = 1; |
|
163 int srchlimit = 50; /* max number of wtmp records to search */ |
|
164 |
|
165 if (inout) |
|
166 return u->ut_time; |
|
167 if (!(in = fopen(WATCH_WTMP_FILE, "r"))) |
|
168 return time(NULL); |
|
169 fseek(in, 0, 2); |
|
170 do { |
|
171 if (fseek(in, ((first) ? -1 : -2) * sizeof(WATCH_STRUCT_UTMP), 1)) { |
|
172 fclose(in); |
|
173 return time(NULL); |
|
174 } |
|
175 first = 0; |
|
176 if (!fread(&uu, sizeof(WATCH_STRUCT_UTMP), 1, in)) { |
|
177 fclose(in); |
|
178 return time(NULL); |
|
179 } |
|
180 if (uu.ut_time < lastwatch || !srchlimit--) { |
|
181 fclose(in); |
|
182 return time(NULL); |
|
183 } |
|
184 } |
|
185 while (memcmp(&uu, u, sizeof(uu))); |
|
186 |
|
187 do |
|
188 if (!fread(&uu, sizeof(WATCH_STRUCT_UTMP), 1, in)) { |
|
189 fclose(in); |
|
190 return time(NULL); |
|
191 } |
|
192 while (strncmp(uu.ut_line, u->ut_line, sizeof(u->ut_line))); |
|
193 fclose(in); |
|
194 return uu.ut_time; |
|
195 } |
|
196 |
|
197 /* Mutually recursive call to handle ternaries in $WATCHFMT */ |
|
198 |
|
199 # define BEGIN3 '(' |
|
200 # define END3 ')' |
|
201 |
|
202 /**/ |
|
203 static char * |
|
204 watch3ary(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt) |
|
205 { |
|
206 int truth = 1, sep; |
|
207 |
|
208 switch (*fmt++) { |
|
209 case 'n': |
|
210 truth = (u->ut_name[0] != 0); |
|
211 break; |
|
212 case 'a': |
|
213 truth = inout; |
|
214 break; |
|
215 case 'l': |
|
216 if (!strncmp(u->ut_line, "tty", 3)) |
|
217 truth = (u->ut_line[3] != 0); |
|
218 else |
|
219 truth = (u->ut_line[0] != 0); |
|
220 break; |
|
221 # ifdef WATCH_UTMP_UT_HOST |
|
222 case 'm': |
|
223 case 'M': |
|
224 truth = (u->ut_host[0] != 0); |
|
225 break; |
|
226 # endif /* WATCH_UTMP_UT_HOST */ |
|
227 default: |
|
228 prnt = 0; /* Skip unknown conditionals entirely */ |
|
229 break; |
|
230 } |
|
231 sep = *fmt++; |
|
232 fmt = watchlog2(inout, u, fmt, (truth && prnt), sep); |
|
233 return watchlog2(inout, u, fmt, (!truth && prnt), END3); |
|
234 } |
|
235 |
|
236 /* print a login/logout event */ |
|
237 |
|
238 /**/ |
|
239 static char * |
|
240 watchlog2(int inout, WATCH_STRUCT_UTMP *u, char *fmt, int prnt, int fini) |
|
241 { |
|
242 char buf[40], buf2[80]; |
|
243 time_t timet; |
|
244 struct tm *tm; |
|
245 char *fm2; |
|
246 # ifdef WATCH_UTMP_UT_HOST |
|
247 char *p; |
|
248 int i; |
|
249 # endif /* WATCH_UTMP_UT_HOST */ |
|
250 |
|
251 while (*fmt) |
|
252 if (*fmt == '\\') { |
|
253 if (*++fmt) { |
|
254 if (prnt) |
|
255 putchar(*fmt); |
|
256 ++fmt; |
|
257 } else if (fini) |
|
258 return fmt; |
|
259 else |
|
260 break; |
|
261 } |
|
262 else if (*fmt == fini) |
|
263 return ++fmt; |
|
264 else if (*fmt != '%') { |
|
265 if (prnt) |
|
266 putchar(*fmt); |
|
267 ++fmt; |
|
268 } else { |
|
269 if (*++fmt == BEGIN3) |
|
270 fmt = watch3ary(inout, u, ++fmt, prnt); |
|
271 else if (!prnt) |
|
272 ++fmt; |
|
273 else |
|
274 switch (*(fm2 = fmt++)) { |
|
275 case 'n': |
|
276 printf("%.*s", (int)sizeof(u->ut_name), u->ut_name); |
|
277 break; |
|
278 case 'a': |
|
279 printf("%s", (!inout) ? "logged off" : "logged on"); |
|
280 break; |
|
281 case 'l': |
|
282 if (!strncmp(u->ut_line, "tty", 3)) |
|
283 printf("%.*s", (int)sizeof(u->ut_line) - 3, u->ut_line + 3); |
|
284 else |
|
285 printf("%.*s", (int)sizeof(u->ut_line), u->ut_line); |
|
286 break; |
|
287 # ifdef WATCH_UTMP_UT_HOST |
|
288 case 'm': |
|
289 for (p = u->ut_host, i = sizeof(u->ut_host); i && *p; i--, p++) { |
|
290 if (*p == '.' && !idigit(p[1])) |
|
291 break; |
|
292 putchar(*p); |
|
293 } |
|
294 break; |
|
295 case 'M': |
|
296 printf("%.*s", (int)sizeof(u->ut_host), u->ut_host); |
|
297 break; |
|
298 # endif /* WATCH_UTMP_UT_HOST */ |
|
299 case 'T': |
|
300 case 't': |
|
301 case '@': |
|
302 case 'W': |
|
303 case 'w': |
|
304 case 'D': |
|
305 switch (*fm2) { |
|
306 case '@': |
|
307 case 't': |
|
308 fm2 = "%l:%M%p"; |
|
309 break; |
|
310 case 'T': |
|
311 fm2 = "%K:%M"; |
|
312 break; |
|
313 case 'w': |
|
314 fm2 = "%a %f"; |
|
315 break; |
|
316 case 'W': |
|
317 fm2 = "%m/%d/%y"; |
|
318 break; |
|
319 case 'D': |
|
320 if (fm2[1] == '{') { |
|
321 char *dd, *ss; |
|
322 int n = 79; |
|
323 |
|
324 for (ss = fm2 + 2, dd = buf2; |
|
325 n-- && *ss && *ss != '}'; ++ss, ++dd) |
|
326 *dd = *((*ss == '\\' && ss[1]) ? ++ss : ss); |
|
327 if (*ss == '}') { |
|
328 *dd = '\0'; |
|
329 fmt = ss + 1; |
|
330 fm2 = buf2; |
|
331 } |
|
332 else fm2 = "%y-%m-%d"; |
|
333 } |
|
334 else fm2 = "%y-%m-%d"; |
|
335 break; |
|
336 } |
|
337 timet = getlogtime(u, inout); |
|
338 tm = localtime(&timet); |
|
339 ztrftime(buf, 40, fm2, tm); |
|
340 printf("%s", (*buf == ' ') ? buf + 1 : buf); |
|
341 break; |
|
342 case '%': |
|
343 putchar('%'); |
|
344 break; |
|
345 case 'S': |
|
346 txtset(TXTSTANDOUT); |
|
347 tsetcap(TCSTANDOUTBEG, -1); |
|
348 break; |
|
349 case 's': |
|
350 txtset(TXTDIRTY); |
|
351 txtunset(TXTSTANDOUT); |
|
352 tsetcap(TCSTANDOUTEND, -1); |
|
353 break; |
|
354 case 'B': |
|
355 txtset(TXTDIRTY); |
|
356 txtset(TXTBOLDFACE); |
|
357 tsetcap(TCBOLDFACEBEG, -1); |
|
358 break; |
|
359 case 'b': |
|
360 txtset(TXTDIRTY); |
|
361 txtunset(TXTBOLDFACE); |
|
362 tsetcap(TCALLATTRSOFF, -1); |
|
363 break; |
|
364 case 'U': |
|
365 txtset(TXTUNDERLINE); |
|
366 tsetcap(TCUNDERLINEBEG, -1); |
|
367 break; |
|
368 case 'u': |
|
369 txtset(TXTDIRTY); |
|
370 txtunset(TXTUNDERLINE); |
|
371 tsetcap(TCUNDERLINEEND, -1); |
|
372 break; |
|
373 default: |
|
374 putchar('%'); |
|
375 putchar(*fm2); |
|
376 break; |
|
377 } |
|
378 } |
|
379 if (prnt) |
|
380 putchar('\n'); |
|
381 |
|
382 return fmt; |
|
383 } |
|
384 |
|
385 /* check the List for login/logouts */ |
|
386 |
|
387 /**/ |
|
388 static void |
|
389 watchlog(int inout, WATCH_STRUCT_UTMP *u, char **w, char *fmt) |
|
390 { |
|
391 char *v, *vv, sav; |
|
392 int bad; |
|
393 |
|
394 if (!*u->ut_name) |
|
395 return; |
|
396 |
|
397 if (*w && !strcmp(*w, "all")) { |
|
398 (void)watchlog2(inout, u, fmt, 1, 0); |
|
399 return; |
|
400 } |
|
401 if (*w && !strcmp(*w, "notme") && |
|
402 strncmp(u->ut_name, get_username(), sizeof(u->ut_name))) { |
|
403 (void)watchlog2(inout, u, fmt, 1, 0); |
|
404 return; |
|
405 } |
|
406 for (; *w; w++) { |
|
407 bad = 0; |
|
408 v = *w; |
|
409 if (*v != '@' && *v != '%') { |
|
410 for (vv = v; *vv && *vv != '@' && *vv != '%'; vv++); |
|
411 sav = *vv; |
|
412 *vv = '\0'; |
|
413 if (strncmp(u->ut_name, v, sizeof(u->ut_name))) |
|
414 bad = 1; |
|
415 *vv = sav; |
|
416 v = vv; |
|
417 } |
|
418 for (;;) |
|
419 if (*v == '%') { |
|
420 for (vv = ++v; *vv && *vv != '@'; vv++); |
|
421 sav = *vv; |
|
422 *vv = '\0'; |
|
423 if (strncmp(u->ut_line, v, sizeof(u->ut_line))) |
|
424 bad = 1; |
|
425 *vv = sav; |
|
426 v = vv; |
|
427 } |
|
428 # ifdef WATCH_UTMP_UT_HOST |
|
429 else if (*v == '@') { |
|
430 for (vv = ++v; *vv && *vv != '%'; vv++); |
|
431 sav = *vv; |
|
432 *vv = '\0'; |
|
433 if (strncmp(u->ut_host, v, strlen(v))) |
|
434 bad = 1; |
|
435 *vv = sav; |
|
436 v = vv; |
|
437 } |
|
438 # endif /* WATCH_UTMP_UT_HOST */ |
|
439 else |
|
440 break; |
|
441 if (!bad) { |
|
442 (void)watchlog2(inout, u, fmt, 1, 0); |
|
443 return; |
|
444 } |
|
445 } |
|
446 } |
|
447 |
|
448 /* compare 2 utmp entries */ |
|
449 |
|
450 /**/ |
|
451 static int |
|
452 ucmp(WATCH_STRUCT_UTMP *u, WATCH_STRUCT_UTMP *v) |
|
453 { |
|
454 if (u->ut_time == v->ut_time) |
|
455 return strncmp(u->ut_line, v->ut_line, sizeof(u->ut_line)); |
|
456 return u->ut_time - v->ut_time; |
|
457 } |
|
458 |
|
459 /* initialize the user List */ |
|
460 |
|
461 /**/ |
|
462 static void |
|
463 readwtab(void) |
|
464 { |
|
465 WATCH_STRUCT_UTMP *uptr; |
|
466 int wtabmax = 32; |
|
467 FILE *in; |
|
468 |
|
469 wtabsz = 0; |
|
470 if (!(in = fopen(WATCH_UTMP_FILE, "r"))) |
|
471 return; |
|
472 uptr = wtab = (WATCH_STRUCT_UTMP *)zalloc(wtabmax * sizeof(WATCH_STRUCT_UTMP)); |
|
473 while (fread(uptr, sizeof(WATCH_STRUCT_UTMP), 1, in)) |
|
474 # ifdef USER_PROCESS |
|
475 if (uptr->ut_type == USER_PROCESS) |
|
476 # else /* !USER_PROCESS */ |
|
477 if (uptr->ut_name[0]) |
|
478 # endif /* !USER_PROCESS */ |
|
479 { |
|
480 uptr++; |
|
481 if (++wtabsz == wtabmax) |
|
482 uptr = (wtab = (WATCH_STRUCT_UTMP *)realloc((void *) wtab, (wtabmax *= 2) * |
|
483 sizeof(WATCH_STRUCT_UTMP))) + wtabsz; |
|
484 } |
|
485 fclose(in); |
|
486 |
|
487 if (wtabsz) |
|
488 qsort((void *) wtab, wtabsz, sizeof(WATCH_STRUCT_UTMP), |
|
489 (int (*) _((const void *, const void *)))ucmp); |
|
490 } |
|
491 |
|
492 /* Check for login/logout events; executed before * |
|
493 * each prompt if WATCH is set */ |
|
494 |
|
495 /**/ |
|
496 void |
|
497 dowatch(void) |
|
498 { |
|
499 FILE *in; |
|
500 WATCH_STRUCT_UTMP *utab, *uptr, *wptr; |
|
501 struct stat st; |
|
502 char **s; |
|
503 char *fmt; |
|
504 int utabsz = 0, utabmax = wtabsz + 4; |
|
505 int uct, wct; |
|
506 |
|
507 s = watch; |
|
508 |
|
509 holdintr(); |
|
510 if (!wtab) { |
|
511 readwtab(); |
|
512 noholdintr(); |
|
513 return; |
|
514 } |
|
515 if ((stat(WATCH_UTMP_FILE, &st) == -1) || (st.st_mtime <= lastutmpcheck)) { |
|
516 noholdintr(); |
|
517 return; |
|
518 } |
|
519 lastutmpcheck = st.st_mtime; |
|
520 uptr = utab = (WATCH_STRUCT_UTMP *) zalloc(utabmax * sizeof(WATCH_STRUCT_UTMP)); |
|
521 |
|
522 if (!(in = fopen(WATCH_UTMP_FILE, "r"))) { |
|
523 free(utab); |
|
524 noholdintr(); |
|
525 return; |
|
526 } |
|
527 while (fread(uptr, sizeof *uptr, 1, in)) |
|
528 # ifdef USER_PROCESS |
|
529 if (uptr->ut_type == USER_PROCESS) |
|
530 # else /* !USER_PROCESS */ |
|
531 if (uptr->ut_name[0]) |
|
532 # endif /* !USER_PROCESS */ |
|
533 { |
|
534 uptr++; |
|
535 if (++utabsz == utabmax) |
|
536 uptr = (utab = (WATCH_STRUCT_UTMP *)realloc((void *) utab, (utabmax *= 2) * |
|
537 sizeof(WATCH_STRUCT_UTMP))) + utabsz; |
|
538 } |
|
539 fclose(in); |
|
540 noholdintr(); |
|
541 if (errflag) { |
|
542 free(utab); |
|
543 return; |
|
544 } |
|
545 if (utabsz) |
|
546 qsort((void *) utab, utabsz, sizeof(WATCH_STRUCT_UTMP), |
|
547 (int (*) _((const void *, const void *)))ucmp); |
|
548 |
|
549 wct = wtabsz; |
|
550 uct = utabsz; |
|
551 uptr = utab; |
|
552 wptr = wtab; |
|
553 if (errflag) { |
|
554 free(utab); |
|
555 return; |
|
556 } |
|
557 queue_signals(); |
|
558 if (!(fmt = getsparam("WATCHFMT"))) |
|
559 fmt = DEFAULT_WATCHFMT; |
|
560 while ((uct || wct) && !errflag) |
|
561 if (!uct || (wct && ucmp(uptr, wptr) > 0)) |
|
562 wct--, watchlog(0, wptr++, s, fmt); |
|
563 else if (!wct || (uct && ucmp(uptr, wptr) < 0)) |
|
564 uct--, watchlog(1, uptr++, s, fmt); |
|
565 else |
|
566 uptr++, wptr++, wct--, uct--; |
|
567 unqueue_signals(); |
|
568 free(wtab); |
|
569 wtab = utab; |
|
570 wtabsz = utabsz; |
|
571 fflush(stdout); |
|
572 } |
|
573 |
|
574 /**/ |
|
575 int |
|
576 bin_log(UNUSED(char *nam), UNUSED(char **argv), UNUSED(Options ops), UNUSED(int func)) |
|
577 { |
|
578 if (!watch) |
|
579 return 1; |
|
580 if (wtab) |
|
581 free(wtab); |
|
582 wtab = (WATCH_STRUCT_UTMP *)zalloc(1); |
|
583 wtabsz = 0; |
|
584 lastutmpcheck = 0; |
|
585 dowatch(); |
|
586 return 0; |
|
587 } |
|
588 |
|
589 #else /* !WATCH_STRUCT_UTMP */ |
|
590 |
|
591 /**/ |
|
592 void dowatch(void) |
|
593 { |
|
594 } |
|
595 |
|
596 /**/ |
|
597 int |
|
598 bin_log(char *nam, char **argv, Options ops, int func) |
|
599 { |
|
600 return bin_notavail(nam, argv, ops, func); |
|
601 } |
|
602 |
|
603 #endif /* !WATCH_STRUCT_UTMP */ |
|
604 |
|
605 #endif //__SYMBIAN32__ |
|
606 |