diff --git a/tools/get-its-dates/README.txt b/tools/get-its-dates/README.txt new file mode 100644 index 00000000..9e2cf64e --- /dev/null +++ b/tools/get-its-dates/README.txt @@ -0,0 +1,54 @@ +The get-its-dates tool accepts a directory of ITS files on the host, presumably extracted from an ITS tape, +and generates a list of Linux timestamps, suitable to be used by the touch program, and in the same +format as found here: https://github.com/PDP-10/its/blob/master/build/timestamps.txt. + +To build the tool, you'll need a scala build environment and SBT. The best way to get this environment +is to install SBT following the instructions on this page: https://docs.scala-lang.org/getting-started/sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.html. + +Once your environment is setup, use the command: 'sbt assembly'. The output should look like this: + +$ sbt assembly +[info] welcome to sbt 1.4.4 (Ubuntu Java 11.0.18) +[info] loading settings for project get-its-dates-build from assembly.sbt,metals.sbt ... +[info] loading project definition from /mnt/its/ITS/ws/its/tools/get-its-dates/project +[info] loading settings for project get-its-dates from build.sbt ... +[info] set current project to get-its-dates (in build file:/mnt/its/ITS/ws/its/tools/get-its-dates/) +[info] compiling 2 Scala sources to /mnt/its/ITS/ws/its/tools/get-its-dates/target/scala-2.13/classes ... +[info] Including: scala-library-2.13.4.jar +[info] Checking every *.class/*.jar file's SHA-1. +[info] Merging files... +[warn] Merging 'NOTICE' with strategy 'rename' +[warn] Merging 'LICENSE' with strategy 'rename' +[warn] Merging 'META-INF/MANIFEST.MF' with strategy 'discard' +[warn] Strategy 'discard' was applied to a file +[warn] Strategy 'rename' was applied to 2 files +[info] SHA-1: d054c5f3b80a5905840f5fc3b44f2e7896d5192e +[success] Total time: 6 s, completed Mar 7, 2023, 12:56:51 PM +$ + +This produces an executable JAR file. Then, invoke the JAR by running: + +java -jar ./target/scala-2.13/get-its-dates-assembly-0.1.jar + +The output will contain lines with timestamp specifications suitable for adding to build/timestamps.txt. + +For example, assume you have a directory called "mudtmp" located in /path/to/stuff/mudtmp, and it contains these files +extracted from an ITS tape: + +$ ls -l --full-time /path/to/stuff/mudtmp +total 20 +-rw-rw-r-- 1 eswenson eswenson 14390 1983-02-08 22:00:07.000000000 -0800 added.files +-rw-rw-r-- 1 eswenson eswenson 35 1978-01-08 06:39:37.000000000 -0800 dump.bit +$ + +Running the tool with: + +java -jar ./target/scala-2.13/get-its-dates-assembly-0.1.jar /path/to/stuff/mudtmp /path/to/stuff + +Will generate + +mudtmp/added.files 198302082200.07 +mudtmp/dump.bit 197801080639.37 + + + diff --git a/tools/get-its-dates/build.sbt b/tools/get-its-dates/build.sbt new file mode 100644 index 00000000..0628d88f --- /dev/null +++ b/tools/get-its-dates/build.sbt @@ -0,0 +1,5 @@ +name := "get-its-dates" + +version := "0.1" + +scalaVersion := "2.13.4" diff --git a/tools/get-its-dates/project/assembly.sbt b/tools/get-its-dates/project/assembly.sbt new file mode 100644 index 00000000..09c90ca0 --- /dev/null +++ b/tools/get-its-dates/project/assembly.sbt @@ -0,0 +1 @@ +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6") \ No newline at end of file diff --git a/tools/get-its-dates/project/build.properties b/tools/get-its-dates/project/build.properties new file mode 100644 index 00000000..efae80e9 --- /dev/null +++ b/tools/get-its-dates/project/build.properties @@ -0,0 +1 @@ +sbt.version = 1.4.4 \ No newline at end of file diff --git a/tools/get-its-dates/project/metals.sbt b/tools/get-its-dates/project/metals.sbt new file mode 100644 index 00000000..05fd2b38 --- /dev/null +++ b/tools/get-its-dates/project/metals.sbt @@ -0,0 +1,6 @@ +// DO NOT EDIT! This file is auto-generated. + +// This file enables sbt-bloop to create bloop config files. + +addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.6") + diff --git a/tools/get-its-dates/src/main/scala/Finder.scala b/tools/get-its-dates/src/main/scala/Finder.scala new file mode 100644 index 00000000..5cad0c78 --- /dev/null +++ b/tools/get-its-dates/src/main/scala/Finder.scala @@ -0,0 +1,67 @@ +import java.io._ +import java.nio.file._ +import java.nio.file.attribute._ +import java.nio.file.FileVisitResult._ +import java.nio.file.FileVisitOption._ +import java.nio.file.Files +import java.nio.file.FileSystems +import java.nio.file.Path +import java.nio.file.StandardCopyOption._ +import scala.io.Source +import scala.language.postfixOps +import scala.util.Try +import java.time.ZonedDateTime +import java.time.format.DateTimeFormatter +import java.time.ZoneId +import java.time.LocalDateTime +import java.util.TimeZone +import java.util.Locale +import java.time.Instant +import java.util.Calendar +import java.time.ZoneOffset + +class Finder(showDirs: Boolean, prefix: String) extends SimpleFileVisitor[Path] { + val format = DateTimeFormatter.ofPattern("yyyyMMddHHmm.ss") + val now: Calendar = Calendar.getInstance() + val timeZone: TimeZone = now.getTimeZone() + val cal: Calendar = Calendar.getInstance(timeZone, Locale.US) + + override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = { + if (attrs.isRegularFile) { + val absolutePath = file.toAbsolutePath.toString + val pathToPrint = absolutePath.replace(prefix, "") + val attrs = Files.readAttributes(file, classOf[BasicFileAttributes]) + val creationDate = attrs.creationTime() + + cal.setTimeInMillis(creationDate.toMillis) + + val dstOffset = cal.get(Calendar.DST_OFFSET) + val adjustedCreationDate = dstOffset match { + case 0 => + creationDate.toMillis() + case 3600000 => + creationDate.toMillis() + dstOffset + case _ => + creationDate.toMillis() + } + + val ldt: LocalDateTime = LocalDateTime.ofEpochSecond(adjustedCreationDate / 1000, 0, ZoneOffset.ofTotalSeconds(cal.get(Calendar.ZONE_OFFSET) / 1000)) + System.out.println(s"${pathToPrint} ${ldt.format(format)}") + } + return CONTINUE + } + + override def preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult = { + if (showDirs) + println(s"Processing directory: ${dir.toAbsolutePath()}") + return CONTINUE + } + + override def visitFileFailed(file: Path, ioe: IOException): FileVisitResult = { + System.err.println(ioe) + return CONTINUE + } + + def done() = { + } +} diff --git a/tools/get-its-dates/src/main/scala/GetItsDates.scala b/tools/get-its-dates/src/main/scala/GetItsDates.scala new file mode 100644 index 00000000..13a80721 --- /dev/null +++ b/tools/get-its-dates/src/main/scala/GetItsDates.scala @@ -0,0 +1,18 @@ +import java.nio.file._ + +object GetItsDates extends App { + if (this.args.size != 2) { + println(s"Syntax is:") + println(s" get-its-datess ") + } + else { + val rootDir = this.args(0) + val prefix = this.args(1) + val finder = new Finder(false, prefix) + Files.walkFileTree( + Paths.get(rootDir), + finder + ) + finder.done() + } +}