当前位置: 技术问答>linux和unix
怎么用C或JAVA实现读取LINUX的 /var/log/wtmp 日志文件
来源: 互联网 发布时间:2015-09-05
本文导语: 谢谢 | #include #include #include #include #include #include #include #include #include #include #include #define OUT_NAMESIZE 8 #define OUT_LINESIZE 8 #define OUT_HOSTSIZE 16 struct olastlog { time_t ll_time; char ll_li...
谢谢
|
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define OUT_NAMESIZE 8
#define OUT_LINESIZE 8
#define OUT_HOSTSIZE 16
struct olastlog {
time_t ll_time;
char ll_line[OUT_LINESIZE];
char ll_host[OUT_HOSTSIZE];
};
struct outmp {
char ut_line[OUT_LINESIZE];
char ut_name[OUT_NAMESIZE];
char ut_host[OUT_HOSTSIZE];
long ut_time;
};
void usage(void);
void convert(const char *, int, int);
/*
* NB: We cannot convert lastlog yet, but we don't need either.
*/
void
usage(void)
{
errx(EX_USAGE, "usage: wtmp [-f] [-n] /var/log/wtmp*");
}
int
main(int argc, char **argv)
{
int errs, i, nflag, forceflag, rv;
errs = nflag = forceflag = 0;
while ((i = getopt(argc, argv, "fn")) != -1)
switch (i)
{
case 'f':
forceflag++;
break;
case 'n':
nflag++;
break;
default:
errs++;
}
argc -= optind;
argv += optind;
if (argc 0; argc--, argv++)
convert(*argv, nflag, forceflag);
return 0;
}
void
convert(const char *name, int nflag, int forceflag)
{
struct stat sb;
struct timeval tv[2];
char xname[1024], yname[1024];
unsigned char buf[128]; /* large enough to hold one wtmp record */
int fd1, fd2;
size_t off, shouldbe;
int old, new;
time_t now, early, *t;
struct tm tm;
struct utmp u;
struct outmp *ou;
enum { OLD, NEW } which = OLD; /* what we're defaulting to */
if (stat(name, &sb) == -1)
{
warn("Cannot stat file "%s", continuing.", name);
return;
}
now = time(NULL);
/* some point in time very early, before 386BSD 0.0 */
tm.tm_sec = 0; tm.tm_min = 0; tm.tm_hour = 0;
tm.tm_mday = 1; tm.tm_mon = 2; tm.tm_year = 92;
tm.tm_isdst = 0;
early = mktime(&tm);
tv[0].tv_sec = sb.st_atimespec.tv_sec;
tv[0].tv_usec = sb.st_atimespec.tv_nsec / 1000;
tv[1].tv_sec = sb.st_mtimespec.tv_sec;
tv[1].tv_usec = sb.st_mtimespec.tv_nsec / 1000;
/* unzipping is handled best externally */
if (strlen(name) > 3 && memcmp(&name[strlen(name) - 3], ".gz", 3) == 0)
{
warnx("Cannot handle gzipped files, ignoring "%s".", name);
return;
}
(void) snprintf(xname, sizeof xname, "%s.new", name);
if (!nflag && (fd1 = open(xname, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
err(EX_CANTCREAT, "Can't create new wtmp file");
if ((fd2 = open(name, O_RDONLY, 0)) == -1)
err(EX_UNAVAILABLE, "input file magically disappeared, i'm confused");
old = new = 0; off = 0;
memset(buf, 0, sizeof buf);
while (read(fd2, &buf[off], sizeof(time_t)) == sizeof(time_t))
{
t = (time_t *)&buf[off];
off += sizeof(time_t);
if (off sizeof buf)
{
if (!forceflag)
{
(void) unlink(xname);
errx(EX_UNAVAILABLE, "I can't seem to make sense out of file "%s",n"
"Could have forced using -f.",
name);
}
else
{
warnx("Record # %d in file "%s" seems bogusn"
"(time: %d, previous time: %d, now: %d),n"
"continuing anyway.",
old + new + 1, name, *t, early, now);
if (which == NEW)
{
(void)lseek(fd2, sizeof(struct utmp) - sizeof buf, SEEK_CUR);
goto write_new;
}
else
{
(void)lseek(fd2, sizeof(struct outmp) - sizeof buf, SEEK_CUR);
goto write_old;
}
}
}
continue;
}
/* time is reasonable, we seem to have collected a full entry */
if (off == sizeof(struct utmp))
{
/* new wtmp record */
which = NEW;
write_new:
new++;
if (!nflag)
{
if (write(fd1, buf, sizeof(struct utmp)) != sizeof(struct utmp))
err(EX_IOERR, "writing file "%s"", xname);
}
}
else if (off == sizeof(struct outmp))
{
/* old fart */
which = OLD;
write_old:
old++;
if (!nflag)
{
ou = (struct outmp *)buf;
memset(&u, 0, sizeof u);
memcpy(&u.ut_line, ou->ut_line, OUT_LINESIZE);
memcpy(&u.ut_name, ou->ut_name, OUT_NAMESIZE);
memcpy(&u.ut_host, ou->ut_host, OUT_HOSTSIZE);
memcpy(&u.ut_time, &ou->ut_time, sizeof u.ut_time);
if (write(fd1, &u, sizeof(struct utmp)) != sizeof(struct utmp))
err(EX_IOERR, "writing file "%s"", xname);
}
}
else
{
if (!forceflag)
{
warnx("Illegal record in file "%s", ignoring.", name);
off = 0;
continue;
}
else
{
warnx("Illegal record in file "%s", considering it %s one.",
name, (which == OLD? "an old": "a new"));
shouldbe = (which == OLD? sizeof(struct outmp): sizeof(struct utmp));
if (off
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define OUT_NAMESIZE 8
#define OUT_LINESIZE 8
#define OUT_HOSTSIZE 16
struct olastlog {
time_t ll_time;
char ll_line[OUT_LINESIZE];
char ll_host[OUT_HOSTSIZE];
};
struct outmp {
char ut_line[OUT_LINESIZE];
char ut_name[OUT_NAMESIZE];
char ut_host[OUT_HOSTSIZE];
long ut_time;
};
void usage(void);
void convert(const char *, int, int);
/*
* NB: We cannot convert lastlog yet, but we don't need either.
*/
void
usage(void)
{
errx(EX_USAGE, "usage: wtmp [-f] [-n] /var/log/wtmp*");
}
int
main(int argc, char **argv)
{
int errs, i, nflag, forceflag, rv;
errs = nflag = forceflag = 0;
while ((i = getopt(argc, argv, "fn")) != -1)
switch (i)
{
case 'f':
forceflag++;
break;
case 'n':
nflag++;
break;
default:
errs++;
}
argc -= optind;
argv += optind;
if (argc 0; argc--, argv++)
convert(*argv, nflag, forceflag);
return 0;
}
void
convert(const char *name, int nflag, int forceflag)
{
struct stat sb;
struct timeval tv[2];
char xname[1024], yname[1024];
unsigned char buf[128]; /* large enough to hold one wtmp record */
int fd1, fd2;
size_t off, shouldbe;
int old, new;
time_t now, early, *t;
struct tm tm;
struct utmp u;
struct outmp *ou;
enum { OLD, NEW } which = OLD; /* what we're defaulting to */
if (stat(name, &sb) == -1)
{
warn("Cannot stat file "%s", continuing.", name);
return;
}
now = time(NULL);
/* some point in time very early, before 386BSD 0.0 */
tm.tm_sec = 0; tm.tm_min = 0; tm.tm_hour = 0;
tm.tm_mday = 1; tm.tm_mon = 2; tm.tm_year = 92;
tm.tm_isdst = 0;
early = mktime(&tm);
tv[0].tv_sec = sb.st_atimespec.tv_sec;
tv[0].tv_usec = sb.st_atimespec.tv_nsec / 1000;
tv[1].tv_sec = sb.st_mtimespec.tv_sec;
tv[1].tv_usec = sb.st_mtimespec.tv_nsec / 1000;
/* unzipping is handled best externally */
if (strlen(name) > 3 && memcmp(&name[strlen(name) - 3], ".gz", 3) == 0)
{
warnx("Cannot handle gzipped files, ignoring "%s".", name);
return;
}
(void) snprintf(xname, sizeof xname, "%s.new", name);
if (!nflag && (fd1 = open(xname, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1)
err(EX_CANTCREAT, "Can't create new wtmp file");
if ((fd2 = open(name, O_RDONLY, 0)) == -1)
err(EX_UNAVAILABLE, "input file magically disappeared, i'm confused");
old = new = 0; off = 0;
memset(buf, 0, sizeof buf);
while (read(fd2, &buf[off], sizeof(time_t)) == sizeof(time_t))
{
t = (time_t *)&buf[off];
off += sizeof(time_t);
if (off sizeof buf)
{
if (!forceflag)
{
(void) unlink(xname);
errx(EX_UNAVAILABLE, "I can't seem to make sense out of file "%s",n"
"Could have forced using -f.",
name);
}
else
{
warnx("Record # %d in file "%s" seems bogusn"
"(time: %d, previous time: %d, now: %d),n"
"continuing anyway.",
old + new + 1, name, *t, early, now);
if (which == NEW)
{
(void)lseek(fd2, sizeof(struct utmp) - sizeof buf, SEEK_CUR);
goto write_new;
}
else
{
(void)lseek(fd2, sizeof(struct outmp) - sizeof buf, SEEK_CUR);
goto write_old;
}
}
}
continue;
}
/* time is reasonable, we seem to have collected a full entry */
if (off == sizeof(struct utmp))
{
/* new wtmp record */
which = NEW;
write_new:
new++;
if (!nflag)
{
if (write(fd1, buf, sizeof(struct utmp)) != sizeof(struct utmp))
err(EX_IOERR, "writing file "%s"", xname);
}
}
else if (off == sizeof(struct outmp))
{
/* old fart */
which = OLD;
write_old:
old++;
if (!nflag)
{
ou = (struct outmp *)buf;
memset(&u, 0, sizeof u);
memcpy(&u.ut_line, ou->ut_line, OUT_LINESIZE);
memcpy(&u.ut_name, ou->ut_name, OUT_NAMESIZE);
memcpy(&u.ut_host, ou->ut_host, OUT_HOSTSIZE);
memcpy(&u.ut_time, &ou->ut_time, sizeof u.ut_time);
if (write(fd1, &u, sizeof(struct utmp)) != sizeof(struct utmp))
err(EX_IOERR, "writing file "%s"", xname);
}
}
else
{
if (!forceflag)
{
warnx("Illegal record in file "%s", ignoring.", name);
off = 0;
continue;
}
else
{
warnx("Illegal record in file "%s", considering it %s one.",
name, (which == OLD? "an old": "a new"));
shouldbe = (which == OLD? sizeof(struct outmp): sizeof(struct utmp));
if (off