home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / os / linux / 8357 < prev    next >
Encoding:
Text File  |  1992-08-15  |  8.9 KB  |  261 lines

  1. Newsgroups: comp.os.linux
  2. Path: sparky!uunet!world!dsb
  3. From: dsb@world.std.com (David Boyce)
  4. Subject: Keeping track of Linux system configurations
  5. Message-ID: <Bt1wwz.78q@world.std.com>
  6. Organization: The World Public Access UNIX, Brookline, MA
  7. Date: Sun, 16 Aug 1992 00:48:34 GMT
  8. Lines: 251
  9.  
  10.     I posted an article a little while ago in which I basically
  11. said we should pay more attention to Linux configuration issues,
  12. meaning things like where files go, what their modes are, etc.
  13. Just to speak of devices: half of the existing users have
  14. serial devices starting at ttys0; the other half start
  15. at ttys1. Some of them use /dev/sd01 and some /dev/sda1.
  16. Some /dev/hd0, some /dev/hda. I myself know that I should
  17. be using /dev/fd0, but I don't know what its major and minor
  18. are. It's not mentioned in the FAQ; I could download the
  19. entire new mcc-interim release to see what fd0 is but I don't
  20. want to do that. Or I could post a note asking, but I don't want
  21. to waste hundreds or even thousands of dollars. Anyway, this
  22. kind of thing is irritating now and it will get worse as
  23. users proliferate and versions accumulate.
  24.     So, in the spirit of Doing Something About It, I've written
  25. a script which I think could be useful for passing configuration
  26. info around. It's called "treestat" and I've included it below.
  27. Basically, it takes a snapshot of a set of files on your
  28. system and contains that snapshot within itself. Then if you move it
  29. to a different machine it will tell you how that system differs.
  30.     There is a usage message (run it with no arguments to see it)
  31. and some additional info at the top of the script, but the basic usage
  32. of treestat is exceedingly simple. User A, wanting to record the
  33. state of his system, runs "cd /; treestat -record". He then gives
  34. treestat (which has just modified itself) to user B.
  35. If user B runs "treestat -compare" he will see on
  36. stdout the ways in which his files differ from those recorded
  37. by user A. Note that treestat is a configuration tool, not a versioning
  38. tool. Thus it does not check whether files are identical via checksums
  39. or the like. It cares only about the presence or absence of each
  40. pathname and whether it has the correct owner/group/mode/major/minor.
  41. Also note that it ignores any additional files user B might have
  42. that aren't part of the canonical set defined by user A.
  43.  
  44.     I'd appreciate it if (at least) the people in charge of mcc-interim,
  45. MJ, TAMU, etc. would give it a look and let me know if you find it
  46. useful, tell me of any improvements you'd like to see, bugs found, etc.
  47.  
  48.     My idea is that people making "standard" releases, such as
  49. mcc-interim, MJ, and TAMU would
  50.  
  51. -> add treestat to their release
  52. -> run treestat -record just before making the release
  53. -> place it alone on their ftp site as "treestat.mcc.98.Z" or whatever.
  54.  
  55.     Then users who are running an old and maybe handmade version of linux
  56. could simply download treestat.mcc.98 and run it with -compare to see how
  57. they've diverged from mcc 0.98.
  58.  
  59. ---------------- Cut Here ---------------------------------------------
  60. #!/bin/sh
  61. # Copyright (c) 1992 David Boyce
  62. # You may distribute this under the terms of the GNU General Public License,
  63. # version 2.
  64.  
  65. # Run this with the -compare option to check your system.
  66.  
  67. #   This script was designed for Linux but should work on most *ixes,
  68. # modulo the awk and -g issues mentioned below.
  69. #   The format used for describing files is the SVR4 package format. This was
  70. # chosen simply because it's common and well-known. The format is pretty
  71. # self-explanatory. The output from -compare is simply a normal diff between
  72. # two SVR4 package format files.
  73. #  This might have been more elegant as a perl script, but the whole point
  74. # requires assuming as few tools and as few nonstandard features as possible.
  75. # As far as I know, it requires only sh, awk, ls, cat, xargs, and diff to run
  76. # on the local system. Generating a profile requires a few more but then you
  77. # expect everything to be in place there. As for special features, it requires
  78. # that the version of awk be either GNU awk (gawk) or the "new awk" (aka nawk)
  79. # shipped with SVR4. Also, the sense of the -g flag to ls is inverted between
  80. # SysV and BSD. I set it up in the BSD way, which also works with GNU ls and
  81. # thus Linux. On SysV machines you might have to remove the -g flag.
  82.  
  83. usage()
  84. {
  85.     cat <<CATEOF
  86. Usage: $ARG0 -compare|-fixscript|-record|-version|-printcanon
  87.     Exactly one of the above options must be used.
  88. -compare compares the system description contained in this script against the
  89.     system it's running on. Only files included in the canonical list within
  90.     the script are compared; extra files on the local system are ignored.
  91.     NOTE: Use "$ARG0 -compare" to check your system.
  92. -fixscript is like -compare but its output is in the form of a shell script
  93.     to bring local modes into line with the canonical. I.e.
  94.     "$ARG0 -fixscript | sh -xe" will normalize your local file modes.
  95. -record causes $ARG0 TO REPLACE ITSELF with a new version that describes
  96.     the current system. By default the list of files is derived via an
  97.     internal "find \`pwd\` -print | egrep -v '^/tmp|^/usr/tmp|^/usr/src|...'"
  98.     but you can generate any file list you like by any method you like and
  99.     pipe it to stdin, and that will be used instead. Note that supplied
  100.     filenames must be rooted. Typical usage: "cd /; $ARG0 -record".
  101.     Only people creating a canonical system description need this.
  102. -version simply prints out the name of the system currently described.
  103. -printcanon causes the canonical system description within the script to be
  104.     printed to stdout.
  105. CATEOF
  106.     exit 1
  107. }
  108.  
  109. # Convert "ls -dilsg" output to SVR4 "package" format.
  110. pkgfmt()
  111. {
  112.     awk "
  113.     function mode(perms) {
  114.         extra = 0;
  115.         perms = substr(perms, 2);
  116.         gsub(\"S\", \"s\", perms);
  117.         gsub(\"t\", \"s\", perms);
  118.         gsub(\"T\", \"s\", perms);
  119.         if(substr(perms, 3, 1) == \"s\") extra += 4;
  120.         if(substr(perms, 6, 1) == \"s\") extra += 2;
  121.         if(substr(perms, 9, 1) == \"s\") extra += 1;
  122.         gsub(\"s\", \"x\", perms);
  123.         gsub(\"rwx\", \"7\", perms);
  124.         gsub(\"rw-\", \"6\", perms);
  125.         gsub(\"r-x\", \"5\", perms);
  126.         gsub(\"r--\", \"4\", perms);
  127.         gsub(\"-wx\", \"3\", perms);
  128.         gsub(\"-w-\", \"2\", perms);
  129.         gsub(\"--x\", \"1\", perms);
  130.         gsub(\"---\", \"0\", perms);
  131.         return extra perms;
  132.     }
  133.     function ftype(perms, links, inode, fname) {
  134.         type = substr(perms,1,1);
  135.         sub(\"-\",\"f\",type);
  136.         sub(\"l\",\"s\",type);
  137.         if(links > 1) {
  138.         if(inodemap[inode]) {
  139.             type = \"l\";
  140.             symval = inodemap[inode];
  141.         } else {
  142.             inodemap[inode] = fname;
  143.         }
  144.         }
  145.         return type;
  146.     }
  147.     {
  148.         inode = \$1;
  149.         fld3 = \$3;
  150.         links = \$4;
  151.         owner = \$5;
  152.         group = \$6;
  153.         devval  = \$7 \$8;
  154.         fname = substr(\$11, 2);
  155.         if(length(fname) < 1) next;
  156.         devname = substr(\$12, 2);
  157.         symval = \$13
  158.     }
  159.     {
  160.         type = ftype(fld3, links, inode, fname);
  161.         if((type == \"s\") || (type == \"l\")) {
  162.         print type,\"none\",fname \"=\" symval,owner,group,mode(fld3);
  163.         } else if((type == \"b\") || (type == \"c\")) {
  164.         print type,devval,devname,owner,group,mode(fld3);
  165.         } else {
  166.         print type,\"none\",fname,owner,group,mode(fld3);
  167.         }
  168.     }
  169.     "
  170. }
  171.  
  172. # Query user for data.
  173. resp() { echo "$1"; read $2; }
  174.  
  175. record()
  176. {
  177.     set -e
  178.     NEWVERS=$RMTMPDIR/$ARG0
  179.     PWD=${PWD:-`pwd`}
  180.     resp "Enter an identifying name/version for this system's $PWD: \c" \
  181.         SNAPSHOT </dev/tty
  182.     chmod u+w $0
  183.     cp $0 $TMPDIR
  184.     awk "/^exit 0/{print; exit} {print}" < $0 > $NEWVERS
  185.     echo "$SYSMARK $SNAPSHOT" >> $NEWVERS
  186.     if tty -s ; then
  187.     find $PWD -print                    |\
  188.         egrep -v "$ARG0|^/tmp/|^/usr/tmp/|^/usr/src/|^/usr/spool/"    |\
  189.         egrep -v "^/usr/man/cat"                    |\
  190.         sort                            |\
  191.         xargs ls -dilsg                        |\
  192.         pkgfmt >> $NEWVERS
  193.     else
  194.     sort | xargs ls -dilsg | pkgfmt >> $NEWVERS
  195.     fi
  196.     if cat $NEWVERS > $0; then
  197.     rm -f $NEWVERS
  198.     fi
  199. }
  200.  
  201. printcanon()
  202. {
  203.     awk <$0 '{if(data) print} /^exit 0/{data=1}'
  204. }
  205.  
  206. compare()
  207. {
  208.     printcanon > $CANON
  209.     echo "$SYSMARK local" > $LOCAL
  210.     awk 'NR>1 {split($3,a,"="); print "/" a[1]}' < $CANON        |\
  211.     xargs ls -dilsg 2>/dev/null                    |\
  212.     pkgfmt >> $LOCAL
  213.     diff $CANON $LOCAL
  214. }
  215.  
  216. fixscript()
  217. {
  218.     while read FIRST TYPE MM FNAME OWNER GROUP MODE; do
  219.     case $FIRST=-=$TYPE in
  220.         \<=-=[fdbc])
  221.         case $TYPE=-=$MM in
  222.             [bc]=-=*,*)
  223.             echo rm -f /$FNAME '&&' mknod /$FNAME $TYPE \
  224.                 `echo $MM | awk -F, '{print $1,$2}'`
  225.             ;;
  226.         esac
  227.         if [ -f /$FNAME -o "$MM" != "none" ]; then
  228.             echo chown $OWNER /$FNAME
  229.             echo chgrp $GROUP /$FNAME
  230.             echo chmod $MODE  /$FNAME
  231.         else
  232.             echo ": Missing: /$FNAME"
  233.         fi
  234.         ;;
  235.     esac
  236.     done
  237. }
  238.  
  239. ARG0=`basename $0`
  240. TMPDIR=${TMPDIR:-/tmp}
  241. RMTMPDIR=$TMPDIR/tmp.$$
  242. LOCAL=$RMTMPDIR/local.$ARG0
  243. CANON=$RMTMPDIR/canon.$ARG0
  244. SYSMARK="System:"
  245.  
  246. mkdir -p $RMTMPDIR 2>/dev/null
  247.  
  248. case "$1" in
  249.     -c*) compare ;;
  250.     -f*) compare | fixscript ;;
  251.     -p*) printcanon ;;
  252.     -r*) record ;;
  253.     -v*) egrep "^$SYSMARK" $0 ;;
  254.     *) usage ;;
  255. esac
  256.  
  257. rm -rf $RMTMPDIR
  258. exit 0 # This must remain as the last line!
  259. -- 
  260. David Boyce    dsb@world.std.com    617-576-1540
  261.