LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Server (https://www.linuxquestions.org/questions/linux-server-73/)
-   -   Fix utmp - remove orphaned utmp entry (https://www.linuxquestions.org/questions/linux-server-73/fix-utmp-remove-orphaned-utmp-entry-769755/)

lrirwin 11-17-2009 02:52 PM

Fix utmp - remove orphaned utmp entry
 
This entry is to help those who have hundreds of users logged in and have a process depending on results from "who" or "w" that is broken due to an orphaned record in the active utmp file.

If you have a running system like that and you don't want to have to add a script to null the utmp file during the shutdown process and then shutdown and reboot... here is a method...

If your system has the executable "utmpdump", you're half way there...
(If not, I'll post the needed source below...)
This program will sequentially dump the content of a utmp (or wtmp) file into a text file. Because it dumps sequentially, you can determine the record number of the entry you'd like to delete by determining the line number where it occurs in the text file. I use "vi" in my example and find the line and use the Control-G command to get the line number.

The current utmp/wtmp binary records are 384 bytes, fixed length...
(If your utmp file is older, then the record size will need adjusting)
So, once you figure out which record number you want to delete, you can use "dd" to re-construct a new utmp file minus the bad record...


Here is the script that enables you to remove the bad record.
I called it "delutmpentry":
Code:

#!/bin/bash
#
# delutmpentry
#
# Remove an entry from the utmp file
# when "w" and "who" show a user logged in that really isn't
#
# Depends: /usr/bin/utmpdump, /bin/dd, /usr/bin/expr,
#          /usr/bin/vi, /bin/cat, /bin/mv, /bin/chmod, /bin/chown
#
# utmp and wtmp are 384 byte fixed length records
# utmpdump exists on some systems and can be compiled
# on others. Once it is there, you can use it to dump out the
# content of utmp/wtmp sequentially - then, once you find
# the line number in the utmpdump output file, you have
# the record number to skip over when re-creating the
# file - which you can do with dd !!!
#

OS=`uname -s | cut -c1-3`
case ${OS} in
"Lin")  ECHO="echo -e"
        ;;
"SCO")  ECHO="echo"
        ;;
esac

# Set std location of utmp file
UTMP=/var/run/utmp

/usr/bin/utmpdump $UTMP > /tmp/utmp0.$$
$ECHO "Find out what line number the entry is on and then quit vi."
$ECHO "Press enter to start vi: \c"
read ans gbg
vi /tmp/utmp0.$$
$ECHO "Enter the line number to remove: \c"
read ans gbg
SkipLines=`expr $ans + 0`
[ $SkipLines -le 0 ] && {
  $ECHO "Exiting without taking any actions."
  exit 0
}
BegLines=`expr $ans - 1`
[ $BegLine -gt 0] && dd if=$UTMP of=/tmp/utmp1.$$ bs=384 count=$BegLines
dd if=$UTMP of=/tmp/utmp2.$$ bs=384 skip=$SkipLines
cat /tmp/utmp1.$$ /tmp/utmp2.$$ > /tmp/utmp3.$$
mv $UTMP $UTMP.save$$
mv /tmp/utmp3.$$ $UTMP
chmod 644 $UTMP
chown root:utmp $UTMP

If you don't have utmpdump on your system, you need 2 things, utmpdump.c and oldutmp.h. They are GPL'd.

Here is utmpdump.c:
Code:

/*
 * utmpdump        Simple program to dump UTMP and WTMP files in
 *                raw format, so they can be examined.
 *
 * Author:        Miquel van Smoorenburg, <miquels@cistron.nl>
 *              Danek Duvall <duvall@alumni.princeton.edu>
 *
 * Version:        @(#)utmpdump  2.79  12-Sep-2000
 *
 *                This file is part of the sysvinit suite,
 *                Copyright 1991-2000 Miquel van Smoorenburg.
 *
 *                Additional Copyright on this file 1998 Danek Duvall.
 *
 *                This program is free software; you can redistribute it and/or
 *                modify it under the terms of the GNU General Public License
 *                as published by the Free Software Foundation; either version
 *                2 of the License, or (at your option) any later version.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <utmp.h>
#include <time.h>
#include <ctype.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "oldutmp.h"

struct utmp
oldtonew(struct oldutmp src)
{
        struct utmp dest;

        memset(&dest, 0, sizeof dest);
        dest.ut_type = src.ut_type;
        dest.ut_pid  = src.ut_pid;
        dest.ut_time = src.ut_oldtime;
        dest.ut_addr = src.ut_oldaddr;
        strncpy(dest.ut_id,  src.ut_id,  4);
        strncpy(dest.ut_line, src.ut_line, OLD_LINESIZE);
        strncpy(dest.ut_user, src.ut_user, OLD_NAMESIZE);
        strncpy(dest.ut_host, src.ut_host, OLD_HOSTSIZE);

        return dest;
}

struct oldutmp
newtoold(struct utmp src)
{
        struct oldutmp dest;

        memset(&dest, 0, sizeof dest);
        dest.ut_type    = src.ut_type;
        dest.ut_pid    = src.ut_pid;
        dest.ut_oldtime = src.ut_time;
        dest.ut_oldaddr = src.ut_addr;
        strncpy(dest.ut_id,  src.ut_id,  4);
        strncpy(dest.ut_line, src.ut_line, OLD_LINESIZE);
        strncpy(dest.ut_user, src.ut_user, OLD_NAMESIZE);
        strncpy(dest.ut_host, src.ut_host, OLD_HOSTSIZE);

        return dest;
}

char *
timetostr(const time_t time)
{
        static char s[29];    /* [Sun Sep 01 00:00:00 1998 PST] */

        if (time != 0)
                strftime(s, 29, "%a %b %d %T %Y %Z", localtime(&time));
        else
                s[0] = '\0';

        return s;
}

time_t
strtotime(const char *s_time)
{
        struct tm *tm = malloc(sizeof(*tm));

        if (s_time[0] == ' ' || s_time[0] == '\0')
                return (time_t)0;

        strptime(s_time, "%a %b %d %T %Y", tm);

        /* Cheesy way of checking for DST */
        if (s_time[26] == 'D')
                tm->tm_isdst = 1;

        return mktime(tm);
}

#define cleanse(x) xcleanse(x, sizeof(x))
void
xcleanse(char *s, int len)
{
        for ( ; *s && len-- > 0; s++)
                if (!isprint(*s) || *s == '[' || *s == ']')
                        *s = '?';
}

void
unspace(char *s, int len)
{
        while (*s && *s != ' ' && len--)
                ++s;

        if (len > 0)
                *s = '\0';
}

void
print_utline(struct utmp ut)
{
        char *addr_string, *time_string;
        struct in_addr in;

        in.s_addr = ut.ut_addr;
        addr_string = inet_ntoa(in);
        time_string = timetostr(ut.ut_time);
        cleanse(ut.ut_id);
        cleanse(ut.ut_user);
        cleanse(ut.ut_line);
        cleanse(ut.ut_host);

        /*            pid    id      user    line    host    addr      time */
        printf("[%d] [%05d] [%-4.4s] [%-*.*s] [%-*.*s] [%-*.*s] [%-15.15s] [%-28.28s]\n",
              ut.ut_type, ut.ut_pid, ut.ut_id, 8, UT_NAMESIZE, ut.ut_user,
              12, UT_LINESIZE, ut.ut_line, 20, UT_HOSTSIZE, ut.ut_host,
              addr_string, time_string);
}

void
dump(FILE *fp, int forever, int oldfmt)
{
        struct utmp ut;
        struct oldutmp uto;

        if (forever)
                fseek(fp, -10 * (oldfmt ? sizeof uto : sizeof ut), SEEK_END);

        do {
                if (oldfmt)
                        while (fread(&uto, sizeof uto, 1, fp) == 1)
                                print_utline(oldtonew(uto));
                else
                        while (fread(&ut, sizeof ut, 1, fp) == 1)
                                print_utline(ut);
                if (forever) sleep(1);
        } while (forever);
}

/* This function won't work properly if there's a ']' or a ' ' in the real
 * token.  Thankfully, this should never happen.  */
int
gettok(char *line, char *dest, int size, int eatspace)
{
        int bpos, epos, eaten;
        char *t;

        bpos = strchr(line, '[') - line;
        if (bpos < 0) {
                fprintf(stderr, "Extraneous newline in file.  Exiting.");
                exit(1);
        }
        line += 1 + bpos;

        epos = strchr(line, ']') - line;
        if (epos < 0) {
                fprintf(stderr, "Extraneous newline in file.  Exiting.");
                exit(1);
        }
        line[epos] = '\0';

        eaten = bpos + epos + 1;

        if (eatspace)
                if ((t = strchr(line, ' ')))
                    *t = 0;

        strncpy(dest, line, size);

        return eaten + 1;
}

void
undump(FILE *fp, int forever, int oldfmt)
{
        struct utmp ut;
        struct oldutmp uto;
        char s_addr[16], s_time[29], *linestart, *line;
        int count = 0;

        line = linestart = malloc(1024 * sizeof *linestart);
        s_addr[15] = 0;
        s_time[28] = 0;

        while(fgets(linestart, 1023, fp))
        {
                line = linestart;
                memset(&ut, '\0', sizeof(ut));
                sscanf(line, "[%hd] [%d] [%4c] ", &ut.ut_type, &ut.ut_pid, ut.ut_id);

                line += 19;
                line += gettok(line, ut.ut_user, sizeof(ut.ut_user), 1);
                line += gettok(line, ut.ut_line, sizeof(ut.ut_line), 1);
                line += gettok(line, ut.ut_host, sizeof(ut.ut_host), 1);
                line += gettok(line, s_addr, sizeof(s_addr)-1, 1);
                line += gettok(line, s_time, sizeof(s_time)-1, 0);

                ut.ut_addr = inet_addr(s_addr);
                ut.ut_time = strtotime(s_time);

                if (oldfmt) {
                        uto = newtoold(ut);
                        fwrite(&uto, sizeof(uto), 1, stdout);
                } else
                        fwrite(&ut, sizeof(ut), 1, stdout);

                ++count;
        }

        free(linestart);
}

void
usage(int result)
{
        printf("Usage: utmpdump [ -froh ] [ filename ]\n");
        exit(result);
}

int main(int argc, char **argv)
{
        int c;
        FILE *fp;
        int reverse = 0, forever = 0, oldfmt = 0;

        while ((c = getopt(argc, argv, "froh")) != EOF) {
                switch (c) {
                case 'r':
                        reverse = 1;
                        break;

                case 'f':
                        forever = 1;
                        break;

                case 'o':
                        oldfmt = 1;
                        break;

                case 'h':
                        usage(0);
                        break;

                default:
                        usage(1);
                }
        }

        if (optind < argc) {
                fprintf(stderr, "Utmp %sdump of %s\n", reverse ? "un" : "", argv[optind]);
                if ((fp = fopen(argv[optind], "r")) == NULL) {
                        perror("Unable to open file");
                        exit(1);
                }
        }
        else {
                fprintf(stderr, "Utmp %sdump of stdin\n", reverse ? "un" : "");
                fp = stdin;
        }

        if (reverse)
                undump(fp, forever, oldfmt);
        else
                dump(fp, forever, oldfmt);

        fclose(fp);

        return 0;
}

And here is the header oldutmp.h:
Code:

/*
 * oldutmp.h        Definition of the old libc5 utmp structure.
 *
 * Version:        @(#)oldutmp.h  1.00  29-Mar-1998  miquels@cistron.nl
 *
 */
#ifndef OLD_UTMP_H
#define OLD_UTMP_H

#define OLD_LINESIZE                12
#define OLD_NAMESIZE                8
#define OLD_HOSTSIZE                16

struct oldutmp {
        short        ut_type;
        int        ut_pid;
        char        ut_line[OLD_LINESIZE];
        char        ut_id[4];
        long        ut_oldtime;
        char        ut_user[OLD_NAMESIZE];
        char        ut_host[OLD_HOSTSIZE];
        long        ut_oldaddr;
};

#endif

Put utmpdump.c and oldutmp.h in a folder, go into that folder and compile using the command:
cc -O2 -s utmpdump.c -o ./utmpdump

If all is well with the compilation, move the new executable to /usr/bin and you're set.

Enjoy!

polymath69 12-01-2009 09:48 AM

Great post!
 
Thanks for your timely post. I was trying to get finger working and tracked one of the problems to a bad utmp entry on one system.

I found a couple of things in 'delutmpentry' that needed to be fixed:

[line 44] $BegLine needs to be $BegLines
[line 44] You need a space between "0" and "]"
[line 49] This may be my systems only, but the mode should be 664

I was glad that your script saved backups while I tracked these down!

Happy December out there.

Gew 02-19-2012 01:36 PM

Nice, but I'm having some issues.
 
Hi!

I have "ghost entries" in my /var/run/utmp, causing "w" to return 6 logged on users, although it's only me in.
Running Ubuntu 10.04 on this particular machine with the problems (which I also do not wish to just simply reboot).
I tried the (in thread) suggested "cc -O2 -s utmpdump.c -o ./utmpdump" and it yields lots of errors.

Code:

...
/usr/include/bits/unistd.h:234: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__confstr_chk_warn’
/usr/include/bits/unistd.h:241: error: expected ‘,’ or ‘;’ before ‘confstr’
/usr/include/bits/unistd.h:255: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:259: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h: In function ‘getgroups’:
/usr/include/bits/unistd.h:271: error: too many arguments to function ‘__getgroups_chk’
/usr/include/bits/unistd.h:274: error: too many arguments to function ‘__getgroups_chk_warn’
/usr/include/bits/unistd.h: At top level:
/usr/include/bits/unistd.h:280: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:281: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:282: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:285: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:285: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:292: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h: In function ‘ttyname_r’:
/usr/include/bits/unistd.h:296: error: ‘__buflen’ undeclared (first use in this function)
/usr/include/bits/unistd.h:297: error: too many arguments to function ‘__ttyname_r_chk’
/usr/include/bits/unistd.h:300: error: too many arguments to function ‘__ttyname_r_chk_warn’
/usr/include/bits/unistd.h:302: error: too many arguments to function ‘__ttyname_r_alias’
/usr/include/bits/unistd.h: At top level:
/usr/include/bits/unistd.h:307: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:307: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:309: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:311: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:311: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:318: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h: In function ‘getlogin_r’:
/usr/include/bits/unistd.h:322: error: ‘__buflen’ undeclared (first use in this function)
/usr/include/bits/unistd.h:323: error: too many arguments to function ‘__getlogin_r_chk’
/usr/include/bits/unistd.h:326: error: too many arguments to function ‘__getlogin_r_chk_warn’
/usr/include/bits/unistd.h:328: error: too many arguments to function ‘__getlogin_r_alias’
/usr/include/bits/unistd.h: At top level:
/usr/include/bits/unistd.h:334: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:334: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:336: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:338: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:338: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:345: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h: In function ‘gethostname’:
/usr/include/bits/unistd.h:349: error: ‘__buflen’ undeclared (first use in this function)
/usr/include/bits/unistd.h:350: error: too many arguments to function ‘__gethostname_chk’
/usr/include/bits/unistd.h:353: error: too many arguments to function ‘__gethostname_chk_warn’
/usr/include/bits/unistd.h:355: error: too many arguments to function ‘__gethostname_alias’
/usr/include/bits/unistd.h: At top level:
/usr/include/bits/unistd.h:361: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:361: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:363: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:366: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:366: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h:374: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/unistd.h: In function ‘getdomainname’:
/usr/include/bits/unistd.h:378: error: ‘__buflen’ undeclared (first use in this function)
/usr/include/bits/unistd.h:379: error: too many arguments to function ‘__getdomainname_chk’
/usr/include/bits/unistd.h:382: error: too many arguments to function ‘__getdomainname_chk_warn’
/usr/include/bits/unistd.h:384: error: too many arguments to function ‘__getdomainname_alias’
In file included from /usr/include/sys/uio.h:29,
                from /usr/include/sys/socket.h:28,
                from /usr/include/netinet/in.h:25,
                from utmpdump.c:10:
/usr/include/bits/uio.h: At top level:
/usr/include/bits/uio.h:47: error: expected specifier-qualifier-list before ‘size_t’
In file included from /usr/include/sys/socket.h:40,
                from /usr/include/netinet/in.h:25,
                from utmpdump.c:10:
/usr/include/bits/socket.h:251: error: expected specifier-qualifier-list before ‘size_t’
/usr/include/bits/socket.h:265: error: expected specifier-qualifier-list before ‘size_t’
/usr/include/bits/socket.h: In function ‘__cmsg_nxthdr’:
/usr/include/bits/socket.h:302: error: expected ‘)’ before ‘__cmsg’
/usr/include/bits/socket.h:307: error: ‘struct cmsghdr’ has no member named ‘cmsg_len’
/usr/include/bits/socket.h:307: error: expected ‘)’ before ‘~’ token
/usr/include/bits/socket.h:308: error: ‘struct msghdr’ has no member named ‘msg_control’
/usr/include/bits/socket.h:309: error: ‘struct msghdr’ has no member named ‘msg_controllen’
/usr/include/bits/socket.h:310: error: ‘struct cmsghdr’ has no member named ‘cmsg_len’
/usr/include/bits/socket.h:310: error: expected ‘)’ before ‘~’ token
/usr/include/bits/socket.h:311: error: ‘struct msghdr’ has no member named ‘msg_control’
/usr/include/bits/socket.h:311: error: ‘struct msghdr’ has no member named ‘msg_controllen’
In file included from /usr/include/netinet/in.h:25,
                from utmpdump.c:10:
/usr/include/sys/socket.h: At top level:
/usr/include/sys/socket.h:141: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/sys/socket.h:148: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/sys/socket.h:155: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/sys/socket.h:166: error: expected declaration specifiers or ‘...’ before ‘size_t’
In file included from /usr/include/sys/socket.h:251,
                from /usr/include/netinet/in.h:25,
                from utmpdump.c:10:
/usr/include/bits/socket2.h:24: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/socket2.h:24: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/socket2.h:26: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/socket2.h:28: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/socket2.h:28: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/socket2.h:35: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/socket2.h: In function ‘recv’:
/usr/include/bits/socket2.h:39: error: ‘__n’ undeclared (first use in this function)
/usr/include/bits/socket2.h:40: error: too many arguments to function ‘__recv_chk’
/usr/include/bits/socket2.h:43: error: too many arguments to function ‘__recv_chk_warn’
/usr/include/bits/socket2.h:45: error: too many arguments to function ‘__recv_alias’
/usr/include/bits/socket2.h: At top level:
/usr/include/bits/socket2.h:48: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/socket2.h:49: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/socket2.h:52: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/socket2.h:56: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/socket2.h:56: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/socket2.h:65: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/bits/socket2.h: In function ‘recvfrom’:
/usr/include/bits/socket2.h:70: error: ‘__n’ undeclared (first use in this function)
/usr/include/bits/socket2.h:72: error: too many arguments to function ‘__recvfrom_chk’
/usr/include/bits/socket2.h:75: error: too many arguments to function ‘__recvfrom_chk_warn’
/usr/include/bits/socket2.h:77: error: too many arguments to function ‘__recvfrom_alias’
In file included from utmpdump.c:11:
/usr/include/arpa/inet.h: At top level:
/usr/include/arpa/inet.h:78: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/arpa/inet.h:84: error: expected declaration specifiers or ‘...’ before ‘size_t’
/usr/include/arpa/inet.h:90: error: expected declaration specifiers or ‘...’ before ‘size_t’
utmpdump.c: In function ‘oldtonew’:
utmpdump.c:19: error: too many arguments to function ‘memset’
utmpdump.c:24: error: too many arguments to function ‘strncpy’
utmpdump.c:25: error: too many arguments to function ‘strncpy’
utmpdump.c:26: error: too many arguments to function ‘strncpy’
utmpdump.c:27: error: too many arguments to function ‘strncpy’
utmpdump.c: In function ‘newtoold’:
utmpdump.c:37: error: too many arguments to function ‘memset’
utmpdump.c:42: error: too many arguments to function ‘strncpy’
utmpdump.c:43: error: too many arguments to function ‘strncpy’
utmpdump.c:44: error: too many arguments to function ‘strncpy’
utmpdump.c:45: error: too many arguments to function ‘strncpy’
utmpdump.c: In function ‘timetostr’:
utmpdump.c:56: warning: incompatible implicit declaration of built-in function ‘strftime’
utmpdump.c: In function ‘strtotime’:
utmpdump.c:66: warning: incompatible implicit declaration of built-in function ‘malloc’
utmpdump.c: In function ‘gettok’:
utmpdump.c:168: error: too many arguments to function ‘strncpy’
utmpdump.c: In function ‘undump’:
utmpdump.c:181: warning: incompatible implicit declaration of built-in function ‘malloc’
utmpdump.c:188: error: too many arguments to function ‘memset’
utmpdump.c:203: warning: incompatible implicit declaration of built-in function ‘fwrite’
utmpdump.c:205: warning: incompatible implicit declaration of built-in function ‘fwrite’
root@LOSANGELES:~/utmpdump#

Ideas?


All times are GMT -5. The time now is 03:53 AM.