diff options
author | joerg <joerg@FreeBSD.org> | 1997-01-02 11:54:59 +0000 |
---|---|---|
committer | joerg <joerg@FreeBSD.org> | 1997-01-02 11:54:59 +0000 |
commit | a3c2fb96f7b46dbb7f264397fa698d6c352f41d2 (patch) | |
tree | 38f83eb2186ddf51d3dc2bf50d1a80622ee7b146 /tools | |
parent | a7feb61d49a3935714dc63c1a37a697a584ada9b (diff) | |
download | FreeBSD-src-a3c2fb96f7b46dbb7f264397fa698d6c352f41d2.zip FreeBSD-src-a3c2fb96f7b46dbb7f264397fa698d6c352f41d2.tar.gz |
Add a -f (`force') option to cvt-wtmp. This might help people with
slightly bogus wtmp files (it definately helps in Jordan's case).
Also add a README explaining what all this is for.
Diffstat (limited to 'tools')
-rw-r--r-- | tools/3.0-upgrade/Makefile | 3 | ||||
-rw-r--r-- | tools/3.0-upgrade/README | 29 | ||||
-rw-r--r-- | tools/3.0-upgrade/cvt-wtmp.c | 77 |
3 files changed, 94 insertions, 15 deletions
diff --git a/tools/3.0-upgrade/Makefile b/tools/3.0-upgrade/Makefile index 68ab9f1..fedda74 100644 --- a/tools/3.0-upgrade/Makefile +++ b/tools/3.0-upgrade/Makefile @@ -1,5 +1,8 @@ all: cvt-wtmp +CLEANFILES += cvt-wtmp + cvt-wtmp: cvt-wtmp.c /usr/include/utmp.h + .include <bsd.prog.mk> diff --git a/tools/3.0-upgrade/README b/tools/3.0-upgrade/README new file mode 100644 index 0000000..0d14d7b --- /dev/null +++ b/tools/3.0-upgrade/README @@ -0,0 +1,29 @@ +By 1996/12/04, the utmp element size has been changed, in order to +allow for longer usernames. This change renders all existing wtmp +files unusable. The cvt-wtmp utility is provided as an aid to convert +your old wtmp files into the new format, so you don't lose the +existing track record. + +The tool cannot handle gzip'ed wtmp backups, so unzip them first if +you need. Then simply call it as: + + ./cvt-tmp /var/log/wtmp* + +The old wtmp files are being renamed to <file>.bak, so nothing will be +lost even in case of a failure. If you are only about to test whether +the tool will grok your files correctly, you can run it as: + + ./cvs-tmp -n /var/log/wtmp* + +The tool tries an ``educated guess'', based on the reasonability of +the timestamp values in the wtmp file. If it fails to recognize the +format of your wtmp, it normally bails out, or at least ignores +garbage records. In this case, rename the .bak files to the original +name, and try to force the conversion: + + ./cvs-tmp -f /var/log/wtmp.xxx + +Make sure to verify the result however! + + +Dresden, Jan 2, 1996 Joerg <joerg@freebsd.org> diff --git a/tools/3.0-upgrade/cvt-wtmp.c b/tools/3.0-upgrade/cvt-wtmp.c index 9d034b1..3f18d15 100644 --- a/tools/3.0-upgrade/cvt-wtmp.c +++ b/tools/3.0-upgrade/cvt-wtmp.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id$ + * $Id: cvt-wtmp.c,v 1.1 1996/12/16 16:12:35 joerg Exp $ * */ @@ -63,7 +63,7 @@ struct outmp { }; void usage(void); -void convert(const char *, int); +void convert(const char *, int, int); /* * NB: We cannot convert lastlog yet, but we don't need either. @@ -72,19 +72,23 @@ void convert(const char *, int); void usage(void) { - errx(EX_USAGE, "usage: cvt-wtmp [-n] /var/log/wtmp*"); + errx(EX_USAGE, "usage: cvt-wtmp [-f] [-n] /var/log/wtmp*"); } int main(int argc, char **argv) { - int errs, i, nflag, rv; + int errs, i, nflag, forceflag, rv; - errs = nflag = 0; - while ((i = getopt(argc, argv, "n")) != EOF) + errs = nflag = forceflag = 0; + while ((i = getopt(argc, argv, "fn")) != EOF) switch (i) { + case 'f': + forceflag++; + break; + case 'n': nflag++; break; @@ -99,25 +103,26 @@ main(int argc, char **argv) usage(); for (;argc > 0; argc--, argv++) - convert(*argv, nflag); + convert(*argv, nflag, forceflag); return 0; } void -convert(const char *name, int nflag) +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; + 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) { @@ -166,9 +171,30 @@ convert(const char *name, int nflag) /* unreasonable, collect another entry */ if (off > sizeof buf) { - (void) unlink(xname); - errx(EX_UNAVAILABLE, "I can't seem to make sense out of file \"%s\"", - name); + 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 bogus\n" + "(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; } @@ -176,6 +202,8 @@ convert(const char *name, int nflag) if (off == sizeof(struct utmp)) { /* new wtmp record */ + which = NEW; + write_new: new++; if (!nflag) { @@ -186,6 +214,8 @@ convert(const char *name, int nflag) else if (off == sizeof(struct outmp)) { /* old fart */ + which = OLD; + write_old: old++; if (!nflag) { @@ -201,9 +231,26 @@ convert(const char *name, int nflag) } else { - warnx("Illegal record in file \"%s\", ignoring.", name); - off = 0; - continue; + 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 < shouldbe) + (void)read(fd2, &buf[off], shouldbe - off); + else + (void)lseek(fd2, shouldbe - off, SEEK_CUR); + if (which == OLD) + goto write_old; + else + goto write_new; + } } off = 0; /* |