Help File
Wish List


Hosted by:
  VA Linux


Hawk / Ftwalk Examples: ftwinfo

This script is part of the Ftwalk distribution. We recommend that you run it once Ftwalk is installed, and anytime thereafter when you have doubts or questions about the state of your Ftwalk installation.

The Ftwalk installation has a file called PACKAGE, which is a packing list that contains information about each file in the Ftwalk distribution archive. The script checks the installation against this package file. The package file contains lines like the following, which specify file type, pathname, permissions, owner/group (if installed by root), timestamp, size, and checksum:

f bin/ftwalk               0755 2 2 826236048 2921488 26748
f test/ft_test             0755 2 2 807584550 1689 35759
l test/ftwalk              ../bin/ftwalk
The PACKAGE file was written by another Ftwalk script, which follows a parts list file work/FtwalkFiles.in to build a distribution archive, including the actual timestamps, file sizes and checksums. The code that generated the PACKAGE file and the archive is:

# note: the two staging directories, S and S2, and the machine type
# identifier M are passed in as command-line parameters. the first stage
# builds the main archive body (which is compressed), and the second
# stage adds the README, Install, and LICENSE files to the distribution.

    # populate _stage directory, write out packing list file with
    # updated timestamps/sizes/checksums.
    warn("making staging areas/packing list ...")
    o = open(S / "PACKAGE", "w")
    f = open("work/FtwalkFiles.in")
    while (s = f.get) {
        if (s[1] == "#")
        n = split(s, " ")
        switch (n[1]) {
          case "d":
            if (mkdir(S/n[2]) == -1)
                warn("Cannot mkdir(%s) [%m]", S / n[2])
          case "F":
            # copy these files directly to _stage2
            if (link(n[3], S2/n[2]) == -1)
                warn("Cannot link(%s, %s) [%m]", n[3], S2 / n[2])
            goto do_f
          case "f":
            if (link(n[3], S/n[2]) == -1)
                warn("Cannot link(%s, %s) [%m]", n[3], S / n[2])
      do_f: st = stat(n[3])
            o.printf("f %-24s %s %s %s %u %u %u\n", n[2], n[4], n[5]
              , n[6], st.st_mtime, st.st_size, sum(r:, n[3]))
          case "l":
            if (symlink(n[3], S/n[2]) == -1)
                warn("Cannot symlink(%s, %s) [%m]", n[3], S/n[2])
            o.printf("l %-24s %s\n", n[2], n[3])

    # archive primary staging area
    A = pwd / S2 / "ftwalk.tar"
    warn("archiving distribution to %s ...", A)
    sh("cd %s; tar cf %s .", S, A)
    warn("compressing distribution %s.Z ...", A)
    sh("compress %s", A)
    A = pwd / "ftwalk." + M + ".tar"
    warn("archiving final distribution %s ...", A)
    sh("cd %s; tar cf %s .", S2, A)
    warn("\narchived %s:\n  %s", A, ls(A))
The installation validation script combines a file search (which determines how much disk space is used under the installation directory) with additional information that is collected and printed out in the END block.

# keep the error messages in a list so they can be printed at the end.
static ERRS = list

function check_file(n, msk) {
    # n is line (split into a list) from packing list. msk is bitmask
    # to specify which stuff to check (varies by file type).
    nm = n[2]
    if ((msk & 0x01) && (st = lstat(nm)) == void)
        ERRS += sprintf("  %-25s STAT [%m]", nm)
    else {
        t = st.ls_mode[1]
        if ((msk & 0x02) && !st.isreg)
            ERRS += sprintf("  %-25s TYPE (%s != -)", nm, t)
        if ((msk & 0x04) && !st.isdir)
            ERRS += sprintf("  %-25s TYPE (%s != d)", nm, t)
        if ((msk & 0x08) && !st.islnk)
            ERRS += sprintf("  %-25s TYPE (%s != l)", nm, t)
        if ((msk & 0x10) && st.perm != (i = oct(n[3])))
            ERRS += sprintf("  %-25s PERM (%#o != %#o)", nm, st.perm, i)
        if (msk & 0x20) {
            if (st.st_size != (i = int(n[7])))
                ERRS += sprintf("  %-25s SIZE (%d != %d)", nm, st.size, i)
            else if (st.st_mtime != (i = int(n[6])))
                ERRS += sprintf("  %-25s MTIME", nm)
            else if ((msk & 0x40) && sum($r, nm) != int(n[8]))
                ERRS += sprintf("  %-25s CHECKSUM", nm)
        if ((msk & 0x80) && (i = readlink(nm)) != n[3])
            ERRS += sprintf("  %-25s LINK (%s != %s)", nm, i, n[3])

function check_package() {
    if (!(F = open("PACKAGE")))
        printf("Packing list:   ERROR [%m]\n")
    else {
        # check file definitions in packing list. count errors, buffer
        # output.
        ERRS = list
        while ((L = F.get) != void) {
            if (!L || L[1] == "#")
                continue    # ignore blank lines, comments
            N = split(L, " ")
            ST = lstat(N[2])
            switch (N[1]) {
              case "f":     # regular file
                check_file(N, 0x33)
              case "d":     # directory
                check_file(N, 0x15)
              case "l":     # symbolic link
                check_file(N, 0x89)
        printf("Packing list:   %d ERRORS\n", ERRS.length)
        if (ERRS.length > 0)
            printf("%s\n", ERRS)

function check_link(nm) {
    N = split(getenv("PATH"), ":")
    for i in N {
        if (i[1] != "/")
        if ((S = readlink(path(i, nm))) && dirname(dirname(S)) == FTROOT)
            return i
    return "NOT FOUND"

    # replace any command line arguments with FTROOT, so we can search
    # the FTROOT directory to accumulate disk space information.
    ARGV = list(FTROOT)

    # count disk space used for all files in FTROOT directory. only count
    # multiply linked files once. since "." and ".." are ignored, directories
    # will only appear once.
    if (!isdir && nlinks > 1 && ++Links[path] > 1)
    DU += st_blocks

    U = uname
    V = version
    DTFMT = "%b %d %Y %T"
    printf("Ftwalk release: %s %s %s [%s]\n", V.rev, V.name, V.mr, V.rtime)
    printf("Compiled on:    %s %s %s %s [%s]\n", V.sysname, V.release
      , V.version, V.machine, V.mtime)
    printf("Running on:     %s %s %s %s [%s]\n", U.sysname, U.release
      , U.version, U.machine, NOW)
    printf("Hostname:       %s\n", U.nodename)
    printf("Root directory: %s\n", FTROOT)
    printf("Install space:  %d blocks (%.3f MB)\n", DU, DU / 2048.0)
    printf("Log file:       %s\n", LOGFILE)
    printf("Link to fthelp: %s\n", check_link("fthelp"))
    printf("Link to ftwalk: %s\n", check_link("ftwalk"))
    # check installation files against packing list.