openenvutils/commandshell/shell/src/watch.c
changeset 0 2e3d3ce01487
child 4 0fdb7f6b0309
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     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