summaryrefslogtreecommitdiffstats
path: root/tools/3.0-upgrade
diff options
context:
space:
mode:
authorjoerg <joerg@FreeBSD.org>1996-12-16 16:12:35 +0000
committerjoerg <joerg@FreeBSD.org>1996-12-16 16:12:35 +0000
commit9c54862a3510bbc916453d7fe374a0f6a715bed5 (patch)
tree2a3278f6fd4d56a0a2d1119e043b90e64571b297 /tools/3.0-upgrade
parent061daf5353a3d359f721ada88b18f25afd0a67d0 (diff)
downloadFreeBSD-src-9c54862a3510bbc916453d7fe374a0f6a715bed5.zip
FreeBSD-src-9c54862a3510bbc916453d7fe374a0f6a715bed5.tar.gz
Start collecting transition tools for upgrading a system to 3.0.
Subject to be moved elsewhere in case we decided on a more cmplete upgrade toolset. Right now, put it here so that people can upgrade their wtmp files if they want. Note that the tool is not yet fully bullet-prrof. It tries to do its best however.
Diffstat (limited to 'tools/3.0-upgrade')
-rw-r--r--tools/3.0-upgrade/Makefile5
-rw-r--r--tools/3.0-upgrade/cvt-wtmp.c237
2 files changed, 242 insertions, 0 deletions
diff --git a/tools/3.0-upgrade/Makefile b/tools/3.0-upgrade/Makefile
new file mode 100644
index 0000000..68ab9f1
--- /dev/null
+++ b/tools/3.0-upgrade/Makefile
@@ -0,0 +1,5 @@
+all: cvt-wtmp
+
+cvt-wtmp: cvt-wtmp.c /usr/include/utmp.h
+
+.include <bsd.prog.mk>
diff --git a/tools/3.0-upgrade/cvt-wtmp.c b/tools/3.0-upgrade/cvt-wtmp.c
new file mode 100644
index 0000000..9d034b1
--- /dev/null
+++ b/tools/3.0-upgrade/cvt-wtmp.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 1996 Joerg Wunsch
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (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$
+ *
+ */
+
+/*
+ * Heuristics to convert old wtmp format to new one.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+#include <utmp.h>
+
+
+#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);
+
+/*
+ * NB: We cannot convert lastlog yet, but we don't need either.
+ */
+
+void
+usage(void)
+{
+ errx(EX_USAGE, "usage: cvt-wtmp [-n] /var/log/wtmp*");
+}
+
+
+int
+main(int argc, char **argv)
+{
+ int errs, i, nflag, rv;
+
+ errs = nflag = 0;
+ while ((i = getopt(argc, argv, "n")) != EOF)
+ switch (i)
+ {
+ case 'n':
+ nflag++;
+ break;
+
+ default:
+ errs++;
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc <= 0 || errs)
+ usage();
+
+ for (;argc > 0; argc--, argv++)
+ convert(*argv, nflag);
+
+ return 0;
+}
+
+void
+convert(const char *name, int nflag)
+{
+ 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;
+ int old, new;
+ time_t now, early, *t;
+ struct tm tm;
+ struct utmp u;
+ struct outmp *ou;
+
+ 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(struct outmp))
+ /* go on */
+ continue;
+ if (*t < early || *t > now)
+ {
+ /* 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);
+ }
+ continue;
+ }
+ /* time is reasonable, we seem to have collected a full entry */
+ if (off == sizeof(struct utmp))
+ {
+ /* new wtmp record */
+ 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 */
+ 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
+ {
+ warnx("Illegal record in file \"%s\", ignoring.", name);
+ off = 0;
+ continue;
+ }
+ off = 0;
+ /*
+ * Since the wtmp file is in chronologically acsending order, we
+ * can move the `early' time as we go. Allow for one hour
+ * time-of-day adjustments.
+ */
+ early = *t - 3600;
+ memset(buf, 0, sizeof buf);
+ }
+ close(fd2);
+
+ printf("File \"%s\": %d old and %d new records found.\n",
+ name, old, new);
+
+ if (nflag)
+ return;
+
+ (void) close(fd1);
+ (void) snprintf(yname, sizeof yname, "%s.bak", name);
+
+ if (rename(name, yname) == -1)
+ err(EX_OSERR, "Cannot rename \"%s\" to \"%s\"", name, yname);
+
+ if (rename(xname, name) == -1)
+ err(EX_OSERR, "Cannot rename \"%s\" to \"%s\"", xname, name);
+
+ if (utimes(name, tv) == -1)
+ warn("Cannot adjust access and modification times for \"%s\"", name);
+}
+
OpenPOWER on IntegriCloud