home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / 3b1 / volume02 / tapeops / part02 < prev    next >
Encoding:
Internet Message Format  |  1993-03-08  |  43.9 KB

  1. Path: comp-sources-3b1
  2. From: vern@zebra.alphacdc.com (vern)
  3. Subject:  v02i036:  3B1 Tape processing utilities, Part02/04
  4. Newsgroups: comp.sources.3b1
  5. Approved: dave@galaxia.network23.com
  6. X-Checksum-Snefru: 9ed9d595 46be13d9 bee57164 a43be435
  7.  
  8. Submitted-by: vern@zebra.alphacdc.com (vern)
  9. Posting-number: Volume 2, Issue 36
  10. Archive-name: tapeops/part02
  11.  
  12. #! /bin/sh
  13. # This is a shell archive.  Remove anything before this line, then unpack
  14. # it by saving it into a file and typing "sh file".  To overwrite existing
  15. # files, type "sh file -c".  You can also feed this as standard input via
  16. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  17. # will see the following message at the end:
  18. #        "End of archive 2 (of 4)."
  19. # Contents:  backup.sh link.list squirrel.sh src/fix.cpio.c
  20. #   src/mini-z.c utils/copy.sh utils/panic.pl utils/trim.pl
  21. # Wrapped by vern@zebra on Mon Mar  8 08:57:35 1993
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. if test -f backup.sh -a "${1}" != "-c" ; then 
  24.   echo shar: Will not over-write existing file \"backup.sh\"
  25. else
  26. echo shar: Extracting \"backup.sh\" \(4216 characters\)
  27. sed "s/^X//" >backup.sh <<'END_OF_backup.sh'
  28. XHOME=`pwd`
  29. XWRKDIR=/news/backup
  30. XSRCDIR=/news/.tape.ops/src
  31. X
  32. Xfunction cleanup
  33. X{
  34. X    Tgetname -l
  35. X    rm -f /tmp/tape.vtoc
  36. X    rm -f /tmp/ss.osets
  37. X    rm -f /tmp/size*
  38. X    rm -f /tmp/BUlist*
  39. X    cd $HOME
  40. X    rm -rf $WRKDIR
  41. X}
  42. X
  43. Xif [ ! -d $WRKDIR ]
  44. Xthen
  45. X    mkdir $WRKDIR
  46. Xfi
  47. Xcd $WRKDIR
  48. X
  49. Xecho `date +%T`" Making Backup List ( approx. 5 min. )"
  50. Xecho "\tTotal time about an hour and 5 min."
  51. X>users
  52. Xfind / -print | sed -e '\:^\/news\/\.: p
  53. X\:^\/news: d
  54. X\:^\/u\/: w users
  55. X\:^\/u\/: d' | sort > $WRKDIR/BUfiles
  56. X
  57. Xsort users >> $WRKDIR/BUfiles
  58. X
  59. Xecho `date +%T`" Checking Tape"
  60. Xpau=0
  61. Xwhile [ $pau = 0 ]
  62. Xdo
  63. X    Tgetname -t
  64. X    ret=$?
  65. X    if [ $ret != 0 ]
  66. X    then
  67. X        echo "Please insert a tape. Q)uit or <cr> to continue. \c"
  68. X        read -r ch
  69. X        if [ "$ch" = "q" -o "$ch" = "Q" ]
  70. X        then
  71. X            cleanup
  72. X            exit 1
  73. X        fi
  74. X    else
  75. X        Tgetname -v > /dev/null
  76. X        ret=$?
  77. X        set `Tgetname -r | tr -d "'"`
  78. X        tname=$1
  79. X        toffset=$2
  80. X        if [ $ret = 30 ]
  81. X        then
  82. X            echo "\n\tThis tape has the \"SAFE\" key set.
  83. X\tPlease exchange it for a tape we can write onto.
  84. X\t    <cr> to continue. Q)uit."
  85. X            read -r ch
  86. X            if [ "$ch" = "q" -o "$ch" = "Q" ]
  87. X            then
  88. X                cleanup
  89. X                exit 1
  90. X            fi
  91. X        else
  92. X# 'read.vtoc -w9' will write all used chapters to standard out in column
  93. X# format.  'read.vtoc -c' puts the next chapter number and the next offset
  94. X# on standard output.  A return of '10' indicates that the tape is full.
  95. X
  96. Xecho `date +%T`" The contents of tape \""$tname"\" are:"
  97. X            $SRCDIR/read.vtoc -w9
  98. X            set `$SRCDIR/read.vtoc -c`
  99. X            chap=$1
  100. X            offset=$2
  101. X            echo \
  102. X"\tThere are "$toffset" blocks of data already on this tape.
  103. X\tOkay to write to this tape? <y/n> \c"
  104. X            read -r ch
  105. X            if [ "$ch" = "n" -o "$ch" = "N" ]
  106. X            then
  107. X                cleanup
  108. X                exit
  109. X            fi
  110. X            offset=$toffset
  111. Xecho "\n\tThe name of this tape is \"$tname\".
  112. X\tShall we keep the name? <y/n> \c "
  113. X            read -r ch
  114. X            while [ "$ch" = "n" -o "$ch" = "N" ]
  115. X            do
  116. X                echo "Enter the new name: \c"
  117. X                read tname
  118. Xecho "\tThe name will be \"$tname\". Okay? <y/n> \c"
  119. X                read -r ch
  120. X            done
  121. X        pau=1
  122. X        fi
  123. X    fi
  124. X    if [ $pau = 0 ]
  125. X    then
  126. Xecho "\tWaiting for another tape to be inserted.
  127. X\t<cr> to continue. Q)uit \c"
  128. X        read -r ch
  129. X        if [ "$ch" = "q" -o "$ch" = "Q" ]
  130. X        then
  131. X            cleanup
  132. X            exit 1
  133. X        fi
  134. X        ret=1
  135. X    fi
  136. Xdone
  137. X
  138. Xoffset=0
  139. X
  140. Xecho `date +%T`" Preparing ss.filelist."
  141. XTmakessList $offset < BUfiles > ss.filelist
  142. Xnumtps=$?
  143. Xeval set `wc -l ss.filelist`
  144. XNFILES=$1
  145. XBTYPE="Backup by Names"
  146. X
  147. Xif [ $numtps -gt 1 ]
  148. Xthen
  149. X    echo "\tYou will need $numtps tapes for this backup.
  150. X    Are they ready? <y/n>. \c"
  151. X    read ans
  152. X    if [ "$ans" = "n" -o "$ans" = "N" ]
  153. X    then
  154. X        cleanup
  155. X        exit
  156. X    fi
  157. Xfi
  158. X
  159. Xecho `date +%T`\
  160. X" Writing chapter $chap to tape '$tname' starting at block $offset."
  161. Xecho "\tFirst tape approx. 17 min., 2nd tape approx. 10 min."
  162. Xecho "ss.filelist" > BUlist$$
  163. Xcat BUlist$$ BUfiles | \
  164. X    tapecpio -ocT124 2>/tmp/size$$ | \
  165. X    dbuf -oT124O$offset > /dev/rft3
  166. Xret=$?
  167. X
  168. Xif [ "$ret" != "0" ]
  169. Xthen
  170. X    if [ $ret = 4 ]
  171. X    then
  172. X        echo "This tape operation has been aborted."
  173. X        Tgetname -l
  174. X        cleanup
  175. X        exit 1
  176. X    else
  177. X        echo "\
  178. X\tAn error has occurred while trying to create this backup-set.
  179. X\tCheck that a formatted tape has been properly inserted and has
  180. X\tfinished rewinding.  Enter <q> to quit. \c"
  181. X        read ch
  182. X        cleanup
  183. X        exit 1
  184. X    fi
  185. Xfi
  186. X
  187. Xecho `date +%T`" Performing verify pass."
  188. Xecho "\tFirst tape 13 min., 2nd tape 10 min."
  189. Xeval set `grep "blocks" /tmp/size$$`
  190. XNBLOCKS=$1
  191. X(( bytes = NBLOCKS * 512 ))
  192. Xset `wc -l ss.filelist`
  193. XNFILES=$1
  194. Xecho "NFILES = $NFILES, NBLOCKS = $NBLOCKS or $bytes bytes."
  195. Xecho "\tPlease re-insert the first tape. <cr> \c"
  196. Xread ch
  197. XTgetname -t
  198. Xdbuf -iT124O$offset"S"$NBLOCKS /dev/rft3 | cat > /dev/null
  199. Xret=$?
  200. Xecho "ret = $ret"
  201. Xif [ "$ret" != "0" ]
  202. Xthen
  203. X    echo "\
  204. X\n\tAn error has been discovered while trying to verify this tape.
  205. X\tYou will have to get another tape and start over. \c"
  206. X    read
  207. X    cleanup
  208. X    exit 1
  209. Xfi
  210. X
  211. XSSNAME="fooey"
  212. XSSCMNT=`date '+%a, %h. %d 19%y %H:%M'`
  213. Xwhich=0
  214. Xwhile [ $which -lt $numtps ]
  215. Xdo
  216. X    (( which = which + 1 ))
  217. X    if [ $which -lt $numtps ]
  218. X    then
  219. X        BACKTYPE="Backup Broken"
  220. X    else
  221. X        BACKTYPE="Complete Backup"
  222. X    fi
  223. X    if [ $which -ne 1 ]
  224. X    then
  225. X        NBLOCKS=-1
  226. X    fi
  227. X    echo "Please insert tape number $which. <cr> \c"
  228. X    read
  229. X    Tgetname -t
  230. X    Tgetname -w "$BACKTYPE" "$tname" "$SSNAME" "$SSCMNT" \
  231. X        $offset $NBLOCKS $NFILES
  232. Xdone
  233. Xecho `date +%T`" Verify Completed"
  234. X
  235. Xcleanup
  236. END_OF_backup.sh
  237. if test 4216 -ne `wc -c <backup.sh`; then
  238.     echo shar: \"backup.sh\" unpacked with wrong size!
  239. fi
  240. chmod +x backup.sh
  241. # end of overwriting check
  242. fi
  243. if test -f link.list -a "${1}" != "-c" ; then 
  244.   echo shar: Will not over-write existing file \"link.list\"
  245. else
  246. echo shar: Extracting \"link.list\" \(0 character\)
  247. sed "s/^X//" >link.list <<'END_OF_link.list'
  248. END_OF_link.list
  249. if test 0 -ne `wc -c <link.list`; then
  250.     echo shar: \"link.list\" unpacked with wrong size!
  251. fi
  252. # end of overwriting check
  253. fi
  254. if test -f squirrel.sh -a "${1}" != "-c" ; then 
  255.   echo shar: Will not over-write existing file \"squirrel.sh\"
  256. else
  257. echo shar: Extracting \"squirrel.sh\" \(4522 characters\)
  258. sed "s/^X//" >squirrel.sh <<'END_OF_squirrel.sh'
  259. X# The purpose of this script is to 'squirrel' away files in the news
  260. X# files for transfer to tape.  By linking these files to entries in
  261. X# the 'arcdir', they are protected from 'expire' yet do not use up an
  262. X# great amount of disk space.
  263. X
  264. Xif [ ! "$WRKDIR" ]
  265. Xthen
  266. X    . /news/.tape.ops/header.sh
  267. Xfi
  268. X
  269. Xcd $WRKDIR
  270. X
  271. X# To commence, let's find out the status of our files and generate
  272. X# the directories and file entries which are missing.
  273. X
  274. Xif [ ! -d $ARCDIR ]
  275. Xthen
  276. X    mkdir $ARCDIR
  277. X    chmod 755 $ARCDIR
  278. Xfi
  279. X
  280. Xif [ ! -s $PARAMS ]
  281. Xthen
  282. X    > $PARAMS
  283. X    chgrp $GRP $PARAMS
  284. X    chown $OWN $PARAMS
  285. Xfi
  286. X
  287. X# Check that the 'params' file has the proper entries.
  288. Xawk -F"    " - '{ 
  289. X        if ( $0 ~ /Next fnum to link:/ ) ok1 = 1
  290. X        if ( $0 ~ /Number of bytes held:/ ) ok2 = 1
  291. X        if ( $0 ~ /Date last squirreled:/ ) ok3 = 1
  292. X        if ( $0 ~ /Name of work tape:/ ) ok4 = 1
  293. X        if ( $0 ~ /Blocks of offset:/ ) ok5 = 1
  294. X        if ( $0 ~ /Date last taped:/ ) ok6 = 1
  295. X        if ( $0 ~ /Blocks available:/ ) ok7 = 1
  296. X        if ( $0 ~ /Next chapter number:/ ) ok8 = 1
  297. X        if ( $0 ~ /Compression factor:/ ) ok9 = 1
  298. X        }
  299. X        END{
  300. X        if ( ok1 != 1 )    print "Next fnum to link:    1"
  301. X        if ( ok2 != 1 )    print "Number of bytes held:    0"
  302. X        if ( ok3 != 1 )    print "Date last squirreled:    0"
  303. X        if ( ok4 != 1 )    print "Name of work tape:    News-000"
  304. X        if ( ok5 != 1 )    print "Blocks of offset:    0"
  305. X        if ( ok6 != 1 )    print "Date last taped:    0"
  306. X        if ( ok7 != 1 )    print "Blocks available:    45566"
  307. X        if ( ok8 != 1 )    print "Next chapter number:    0"
  308. X        if ( ok9 != 1 )    print "Compression factor:    1000"
  309. X    }' $PARAMS >> $PARAMS
  310. X
  311. Xfnum=`sed -n 's/Next fnum to link:\    //p' $PARAMS`
  312. X
  313. Xtoday=`date '+%y-%m-%d'`
  314. X
  315. X# If we have a 'link.list' file, remove entries over two months old
  316. Xif [ -s $LINKS ]
  317. Xthen
  318. X    cp $LINKS $KLINKS
  319. X    > $TMP
  320. X    awk - 'BEGIN{ now = "'"$today"'"
  321. X        split( now, old, "-" )
  322. X        old[2] -= 2
  323. X        if ( old[2] < 1 ){
  324. X            old[1] -= 1
  325. X            old[2] += 12
  326. X        }
  327. X        if ( old[1] < 70 ) old[1] += 100
  328. X        daysofmonth = "31 28 31 30 31 30 31 31 30 31 30 31"
  329. X        split( daysofmonth, days )
  330. X        if ( old[3] > days[ old[2] ] ) old[3] = days[ old[2] ]
  331. X        FS = "    "
  332. X    }
  333. X    { split( $2, was, "-" )
  334. X        if ( was[1] < 70 ) was[1] += 100
  335. X        if ( old[1] > was[1] ){ next }
  336. X        if ( old[1] == was[1] && old[2] > was[2] ){ next }
  337. X        if ( old[1] == was[1] && old[2] == was[2] && \
  338. X                old[3] > was[3] ){ next }
  339. X        print $0 >> "'$TMP'"
  340. X    }' $KLINKS
  341. X    mv $TMP $KLINKS
  342. Xelse
  343. X    > $KLINKS
  344. X    > $LINKS
  345. Xfi
  346. X
  347. Xx=fnum
  348. Xwhile [ -f $ARCDIR/$x ]
  349. Xdo
  350. X    rm -f $ARCDIR/$x
  351. X    (( x = x + 1 ))
  352. Xdone
  353. X
  354. Xrm -f $WRKDIR/contents
  355. Xrm -f $GOOFS
  356. X
  357. Xfunction recur
  358. X{
  359. X    if [ -d $1 -a `du -s $1 | cut -f1` = 1 ]
  360. X    then
  361. X        return -1
  362. X    fi
  363. X    typeset this next
  364. X    this=$1
  365. X    set `ls -1 $1`
  366. X    while [ $1 ]
  367. X    do
  368. X        next=$this/$1
  369. X        if [ -d $next ]
  370. X        then
  371. X            recur $next
  372. X        fi
  373. X        if [ -f $next ]
  374. X        then
  375. X            id=`sed -n '/^Message-ID:/ {
  376. X                s/Message-ID: //p
  377. X                q
  378. X                }' $next | tr -d "/*?^$\[\]|"`
  379. X            if [ -n "$id" ]
  380. X            then
  381. X                if
  382. X                    [ -z "`sed -n '/'"$id"'/p' $KLINKS`" ]
  383. X                then
  384. X                    if ln $next $ARCDIR/$fnum
  385. X                    then
  386. X                        let fnum="fnum+1"
  387. X                    echo "$id""\t"$today >> $KLINKS
  388. X                    else
  389. X                echo $next",  "$ARCDIR/$fnum >> $GOOFS
  390. X                    fi
  391. X                fi
  392. X            fi
  393. X        fi
  394. X        shift
  395. X    done
  396. X}
  397. X
  398. Xwhile
  399. X    read fname
  400. Xdo
  401. X    dname=`echo $fname | cut -f1 -d"#"`
  402. X    if [ -n "$dname" ]
  403. X    then
  404. X        recur $dname
  405. X    fi
  406. Xdone <$LIST
  407. X
  408. Xfunction commas
  409. X{ echo `echo $1 | awk - '{ n = length( $0 )
  410. X    s = n % 3
  411. X    if ( s == 0 ) s = 3
  412. X    m = substr( $0, 1, s )
  413. X    s++
  414. X    while ( n > s ){
  415. X        o = substr( $0, s, 3 )
  416. X        m = m","o
  417. X        s += 3
  418. X    }
  419. X    print m }' -`
  420. X}
  421. X
  422. Xnbytes=`ls -l $ARCDIR | awk - '{ sum = sum + $5 }
  423. X        END{ print sum }' - `
  424. Xcbytes=`commas $nbytes`
  425. X
  426. Xsort -d -o $LINKS $KLINKS
  427. X
  428. X> $TMP
  429. Xawk -F"    " - '{ if ( $0 ~ /Next fnum to link:/ ) $2 = "'"$fnum"'"
  430. X        if ( $0 ~ /Number of bytes held:/ ) $2 = "'"$cbytes"'"
  431. X        if ( $0 ~ /Date last squirreled:/ ) $2 = "'"$today"'"
  432. X        print $1"    "$2 >> "'$TMP'"
  433. X        }' $PARAMS
  434. Xmv $TMP $PARAMS
  435. Xchgrp $GRP $PARAMS
  436. Xchown $OWN $PARAMS
  437. Xchgrp $GRP $LINKS
  438. Xchown $OWN $LINKS
  439. Xrm -f $KLINKS
  440. X
  441. Xoffset=`sed -n 's/Blocks of offset:\    //p' $PARAMS`
  442. Xchap=`sed -n 's/Next chapter number:\    //p' $PARAMS`
  443. Xfactor=`sed -n 's/Compression factor:\    //p' $PARAMS`
  444. X
  445. X(( min_size = ( MAXOFFSET - offset ) / (10 - chap) ))  
  446. X(( this = nbytes/factor ))    # blocks for this collection
  447. X
  448. Xecho "To: netnews
  449. XSubject: File Squirreling.\n
  450. XYour 'savdir' currently has $cbytes bytes of news articles saved.
  451. X    Recommended size of next tape entry:    $min_size    blocks
  452. X    Approximate size of this collection:    $this    blocks" > $TMP
  453. Xif [ "$this" -gt "$min_size" ]
  454. Xthen
  455. X    echo "\t\tYou better transfer these to tape soon.!" >> $TMP
  456. Xfi
  457. Xecho "\nThis is from your friendly file saver." >> $TMP
  458. Xcat $TMP | /bin/rmail netnews
  459. Xrm $TMP
  460. END_OF_squirrel.sh
  461. if test 4522 -ne `wc -c <squirrel.sh`; then
  462.     echo shar: \"squirrel.sh\" unpacked with wrong size!
  463. fi
  464. chmod +x squirrel.sh
  465. # end of overwriting check
  466. fi
  467. if test -f src/fix.cpio.c -a "${1}" != "-c" ; then 
  468.   echo shar: Will not over-write existing file \"src/fix.cpio.c\"
  469. else
  470. echo shar: Extracting \"src/fix.cpio.c\" \(4621 characters\)
  471. sed "s/^X//" >src/fix.cpio.c <<'END_OF_src/fix.cpio.c'
  472. X#include <stdio.h>
  473. X#include <sys/dir.h>
  474. X#include <errno.h>
  475. X#include <sys/types.h>
  476. X#include <fcntl.h>
  477. X
  478. X/* For -c1, write to /dev/null until after the first 'TRAILER!!!'.
  479. X * otherwise write everthing up to the first 'TRAILER!!!' then exit */
  480. X
  481. X/* #define DEBUG */
  482. X
  483. Xextern char *sys_errlist[];
  484. X
  485. Xstruct utimbuf {
  486. X    time_t actime;
  487. X    time_t modtime;
  488. X};
  489. X
  490. Xstruct {
  491. X    short h_magic;                                /* short */
  492. X    dev_t h_dev;                                /* short dev_t */
  493. X    ino_t h_ino;                                /* ushort ino_t */
  494. X    ushort h_mode;                                /* ushort */
  495. X    ushort h_uid;                                /* ushort */
  496. X    ushort h_gid;                                /* ushort */
  497. X    short h_nlink;                                /* short */
  498. X    dev_t h_rdev;                                /* short dev_t */
  499. X    time_t h_mtime;                            /* long time_t */
  500. X    int h_namesize;                            /* int */
  501. X    long h_filesize;                            /* int long */
  502. X    char h_name[120];
  503. X} HDR;
  504. X
  505. Xmain( argc, argv )
  506. Xint argc;
  507. Xchar *argv[];
  508. X{
  509. X    char ch, *m, *p, *q, *w;
  510. X    int hdr, part, flag;
  511. X    int cnt, i, blocks;
  512. X    int end_cnt;
  513. X    struct utimbuf tbuf;
  514. X    FILE *sfd;
  515. X    int dfd;
  516. X    static char trail[] = "TRAILER!!!";
  517. X    static char magic[] = "070707";
  518. X    char wrkbuf[120];
  519. X    char name[80];
  520. X    char blk_buf[15];
  521. X
  522. X    flag = 0;
  523. X    part = 0;
  524. X    for ( i = 1; i < argc; i++ ) {
  525. X        p = argv[i];
  526. X        while ( *p ) {
  527. X            if ( *p == '-' ) {
  528. X                p++;
  529. X                switch ( *p ) {
  530. X                case 'c':
  531. X                    if ( *(++p) == '1' ) part = 0;
  532. X                    else part = 1;
  533. X                    break;
  534. X                case 'b': flag = 1;
  535. X                    q = blk_buf;
  536. X                    p++;
  537. X                    break;
  538. X                default: q = wrkbuf;
  539. X                    break;
  540. X                }
  541. X            }
  542. X            else while ( *p ) *q++ = *p++;
  543. X        }
  544. X        *q = '\0';
  545. X    }
  546. X    switch( flag ) {
  547. X    case 0: fprintf( stderr, "Usage: fix.cpio -b<num_blocks>\n" );
  548. X        exit( 1 );
  549. X        break;
  550. X    case 1: blocks = atoi( blk_buf );
  551. X        blocks -= 10;
  552. X        break;
  553. X    }
  554. X    hdr = 0;
  555. X    if (( sfd = fopen( "/dev/null", "w" )) == NULL ) {
  556. X        fprintf( stderr, "Can't open '/dev/null', %s\n",
  557. X            sys_errlist[errno] );
  558. X        exit( 1 );
  559. X    }
  560. X    m = magic;
  561. X#ifdef DEBUG
  562. X    printf( "Starting fix.cpio:\n" );
  563. X#endif
  564. X    cnt = 0;
  565. X    w = wrkbuf;
  566. X    hdr = 0;
  567. X    while( 1 ) {
  568. X        cnt++;
  569. X        ch = getc( stdin );
  570. X        if ( hdr ) {
  571. X            *w++ = ch;
  572. X            if ( ch == '\0' ) {
  573. X#ifdef DEBUG
  574. X            printf( "sscanf wrkbuf;\n>%s<\n", wrkbuf );
  575. X#endif
  576. X                sscanf( wrkbuf,
  577. X            "%6ho%6ho%6ho%6ho%6ho%6ho%6ho%6ho%11lo%6o%11lo%s",
  578. X                        &HDR.h_magic, &HDR.h_dev, &HDR.h_ino, &HDR.h_mode,
  579. X                        &HDR.h_uid, &HDR.h_gid, &HDR.h_nlink, &HDR.h_rdev,
  580. X                        &HDR.h_mtime, &HDR.h_namesize, &HDR.h_filesize,
  581. X                        HDR.h_name );
  582. X#ifdef DEBUG
  583. X                printf( "Bytes = %d, Blocks = %d\n", cnt, cnt/512 );
  584. X                show_hdr();
  585. X#endif
  586. X                end_cnt = HDR.h_filesize + cnt;
  587. X                fflush( sfd );
  588. X                fclose( sfd );
  589. X                if (( strcmp( trail, HDR.h_name )) == 0 ) {
  590. X                    if ( part != 0 || cnt/512 > blocks ) {
  591. X                        printf( "%d bytes, %d blocks\n", cnt, cnt/512 );
  592. X                        exit( 0 );
  593. X                    }
  594. X                    part++;
  595. X                    if (( sfd = fopen( "/dev/null", "w" )) == NULL ) {
  596. X                        fprintf( stderr, "Can't open /dev/null, %s\n",
  597. X                            sys_errlist[errno] );
  598. X                        exit( 1 );
  599. X                    }
  600. X                    end_cnt = blocks * 512;
  601. X                }
  602. X                else {
  603. X                    if ( ! part ) strcat( strcpy( name, "A" ), HDR.h_name );
  604. X                    else strcpy( name, HDR.h_name );
  605. X                    if (( sfd = fopen( name, "w" )) == NULL ) {
  606. X                        fprintf( stderr, "Can't open %s, %s\n",
  607. X                            HDR.h_name,
  608. X                            sys_errlist[errno] );
  609. X                        exit( 1 );
  610. X                    }
  611. X                    chmod( name, HDR.h_mode);
  612. X                    chown( name, HDR.h_uid, HDR.h_gid );
  613. X                    tbuf.actime = HDR.h_mtime;
  614. X                    tbuf.modtime = HDR.h_mtime;
  615. X                    utime( name, &tbuf );
  616. X                }
  617. X                hdr = 0;
  618. X                w = wrkbuf;
  619. X                m = magic;
  620. X            }
  621. X        }
  622. X        else if ( ch == *m ) {
  623. X            *w++ = ch;
  624. X            if ( *(++m) == '\0' ) hdr = 1;
  625. X        }
  626. X        else if ( m != magic ) {
  627. X            q = magic;
  628. X            while ( q < m ) {
  629. X                putc( *q, sfd );
  630. X                q++;
  631. X            }
  632. X            m = magic;
  633. X            hdr = 0;
  634. X            w = wrkbuf;
  635. X            putc( ch, sfd );
  636. X        }
  637. X        else {
  638. X            putc( ch, sfd );
  639. X/*             if ( cnt > end_cnt ) {
  640. X *                 fprintf( stderr, "File too long. Quitting! \n" );
  641. X *                 exit( -1 );
  642. X *            } */
  643. X        }
  644. X    }
  645. X}
  646. X
  647. X#ifdef DEBUG
  648. Xshow_hdr()
  649. X{
  650. X    printf( "Magic = 0%o,\tDev = %d,\tInode = %d\n\
  651. XMode = 0%o,\tUser = %d,\tGroup = %d,\n\
  652. XLinks = %d\tODev = %u,\tmtime = %ld\n\
  653. XName size = %d\tLength = %ld, Name = %s\n",
  654. X        HDR.h_magic, HDR.h_dev, HDR.h_ino, HDR.h_mode, HDR.h_uid,
  655. X        HDR.h_gid, HDR.h_nlink, HDR.h_rdev, HDR.h_mtime,
  656. X        HDR.h_namesize, HDR.h_filesize, HDR.h_name );
  657. X/*     sleep(5); */
  658. X}
  659. X#endif
  660. X
  661. X/*     short h_magic;                                    /* short */
  662. X/*     dev_t h_dev;                                    /* short dev_t */
  663. X/*     ino_t h_ino;                                    /* ushort ino_t */
  664. X/*     ushort h_mode;                                /* ushort */
  665. X/*     ushort h_uid;                                /* ushort */
  666. X/*     ushort h_gid;                                /* ushort */
  667. X/*     short h_nlink;                                /* short */
  668. X/*     dev_t h_rdev;                                /* short dev_t */
  669. X/*     time_t h_mtime;                                /* long time_t */
  670. X/*     int h_namesize;                                /* int */
  671. X/*     long h_filesize;                                /* int long */
  672. X/*     char h_name[DIRSIZ]; */
  673. X
  674. END_OF_src/fix.cpio.c
  675. if test 4621 -ne `wc -c <src/fix.cpio.c`; then
  676.     echo shar: \"src/fix.cpio.c\" unpacked with wrong size!
  677. fi
  678. # end of overwriting check
  679. fi
  680. if test -f src/mini-z.c -a "${1}" != "-c" ; then 
  681.   echo shar: Will not over-write existing file \"src/mini-z.c\"
  682. else
  683. echo shar: Extracting \"src/mini-z.c\" \(8868 characters\)
  684. sed "s/^X//" >src/mini-z.c <<'END_OF_src/mini-z.c'
  685. X/* 
  686. X * Compress - data compression program 
  687. X */
  688. X#define    min(a,b)    ((a>b) ? b : a)
  689. X
  690. X/*
  691. X * Set USERMEM to the maximum amount of physical user memory available
  692. X * in bytes.  USERMEM is used to determine the maximum BITS that can be
  693. X * used for compression.
  694. X */
  695. X
  696. X#define USERMEM     450000    /* default user memory */
  697. X#define BITS 16
  698. X#define HSIZE    69001            /* 95% occupancy */
  699. X
  700. X/*
  701. X * a code_int must be able to hold 2**BITS values of type int, and also -1
  702. X */
  703. Xtypedef long int code_int;
  704. Xtypedef long int count_int;
  705. Xtypedef unsigned char char_type;
  706. X
  707. Xchar_type magic_header[] = { "\037\235" };    /* 1F 9D */
  708. X
  709. X    /* Defines for third byte of header */
  710. X#define BIT_MASK    0x1f
  711. X#define BLOCK_MASK    0x80
  712. X    /* Masks 0x40 and 0x20 are free.
  713. X     * I think 0x20 should mean that there is
  714. X     * a fourth header byte (for expansion).
  715. X    */
  716. X#define INIT_BITS 9            /* initial number of bits/code */
  717. X
  718. X#include <stdio.h>
  719. X#include <ctype.h>
  720. X#include <signal.h>
  721. X#include <sys/types.h>
  722. X#include <sys/stat.h>
  723. X
  724. X#define ARGVAL() (*++(*argv) || (--argc && *++argv))
  725. X
  726. Xint n_bits;                                    /* number of bits/code */
  727. Xint maxbits = BITS;                        /* user settable max # bits/code */
  728. Xcode_int maxcode;                            /* maximum code, given n_bits */
  729. Xcode_int maxmaxcode = 1L << BITS;    /* should NEVER generate this code */
  730. X
  731. X#define MAXCODE(n_bits)    ((1L << (n_bits)) - 1)
  732. X
  733. Xcount_int htab [HSIZE];
  734. Xunsigned short codetab [HSIZE];
  735. X#define htabof(i)    htab[i]
  736. X#define codetabof(i)    codetab[i]
  737. X
  738. X/*
  739. X * To save much memory, we overlay the table used by compress() with those
  740. X * used by decompress().  The tab_prefix table is the same size and type
  741. X * as the codetab.  The tab_suffix table needs 2**BITS characters.  We
  742. X * get this from the beginning of htab.  The output stack uses the rest
  743. X * of htab, and contains characters.  There is plenty of room for any
  744. X * possible stack (stack used to be 8000 characters).
  745. X */
  746. X
  747. X#define tab_prefixof(i)    codetabof(i)
  748. X#define tab_suffixof(i)    ((char_type *)(htab))[i]
  749. X#define de_stack            ((char_type *)&tab_suffixof(1<<BITS))
  750. X
  751. Xcode_int free_ent = 0;            /* first unused entry */
  752. Xint exit_stat = 0;
  753. X
  754. Xcode_int getcode();
  755. X
  756. Xint nomagic = 0;    /* Use a 3-byte magic number header, unless old file */
  757. X
  758. X/*
  759. X * block compression parameters -- after all codes are used up,
  760. X * and compression rate changes, start over.
  761. X */
  762. Xint block_compress = BLOCK_MASK;
  763. Xint clear_flg = 0;
  764. X#define CHECK_GAP 10000        /* ratio check interval */
  765. X    /*
  766. X     * the next two codes should not be changed lightly, as they must not
  767. X     * lie within the contiguous general code space.
  768. X     */ 
  769. X#define FIRST    257    /* first free entry */
  770. X#define    CLEAR    256    /* table clear output code */
  771. X
  772. Xchar ofname [100];
  773. Xint (*bgnd_flag)();
  774. Xint do_decomp = 0;
  775. X
  776. Xmain( argc, argv )
  777. Xregister int argc; char **argv;
  778. X{
  779. X    char **filelist, **fileptr;
  780. X    char *cp, *rindex(), *malloc();
  781. X    extern onintr(), oops();
  782. X
  783. X    if ( (bgnd_flag = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) {
  784. X        signal ( SIGINT, onintr );
  785. X        signal ( SIGSEGV, oops );
  786. X    }
  787. X
  788. X    filelist = fileptr = (char **)(malloc(argc * sizeof(*argv)));
  789. X    *filelist = NULL;
  790. X
  791. X    if((cp = rindex(argv[0], '/')) != 0) {
  792. X        cp++;
  793. X    } else {
  794. X        cp = argv[0];
  795. X    }
  796. X    if(strcmp(cp, "mini-z") == 0) do_decomp = 1;
  797. X
  798. X    for (argc--, argv++; argc > 0; argc--, argv++) {
  799. X        *fileptr++ = *argv;    /* Build input file list */
  800. X        *fileptr = NULL;
  801. X                        /* process nextarg; */
  802. X    }
  803. X
  804. X    if(maxbits < INIT_BITS) maxbits = INIT_BITS;
  805. X    if (maxbits > BITS) maxbits = BITS;
  806. X    maxmaxcode = 1L << maxbits;
  807. X
  808. X    if (*filelist != NULL) {
  809. X        for (fileptr = filelist; *fileptr; fileptr++) {
  810. X            exit_stat = 0;
  811. X                /* Check for .Z suffix */
  812. X                    /* Open input file */
  813. X            if ((freopen(*fileptr, "r", stdin)) == NULL) {
  814. X                exit_stat = 1;
  815. X                perror(*fileptr); continue;
  816. X            }
  817. X                    /* Check the magic number */
  818. X            if (nomagic == 0) {
  819. X                if ((getchar() != (magic_header[0] & 0xFF))
  820. X                                || (getchar() != (magic_header[1] & 0xFF))) {
  821. X                    fprintf(stderr, "%s: not in compressed format\n",
  822. X                                *fileptr);
  823. X                    exit_stat = 1;
  824. X                    continue;
  825. X                }
  826. X                maxbits = getchar();    /* set -b from file */
  827. X                block_compress = maxbits & BLOCK_MASK;
  828. X                maxbits &= BIT_MASK;
  829. X                maxmaxcode = 1L << maxbits;
  830. X                if(maxbits > BITS) {
  831. X                    fprintf(stderr,
  832. X                        "%s: compressed with %d bits, can only handle %d bits\n",
  833. X                        *fileptr, maxbits, BITS);
  834. X                    exit_stat = 1;
  835. X                    continue;
  836. X                }
  837. X            }
  838. X                        /* Generate output filename */
  839. X            strcpy(ofname, *fileptr);
  840. X            ofname[strlen(*fileptr) - 2] = '\0';  /* Strip off .Z */
  841. X                /* Actually do the compression/decompression */
  842. X            decompress();
  843. X        }
  844. X    }
  845. X    exit(exit_stat);
  846. X}
  847. X
  848. Xchar_type rmask[9] = {
  849. X    0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
  850. X};
  851. X
  852. X/*
  853. X * Decompress stdin to stdout.  This routine adapts to the codes in the
  854. X * file building the "string" table on-the-fly; requiring no table to
  855. X * be stored in the compressed file.  The tables used herein are shared
  856. X * with those of the compress() routine.  See the definitions above.
  857. X */
  858. X
  859. Xdecompress() {
  860. X    register char_type *stackp;
  861. X    register int finchar;
  862. X    register code_int code, oldcode, incode;
  863. X
  864. X            /* These are the mini.z additions */
  865. X    char *patt = "Subject: ";
  866. X    char *p;
  867. X    int out;
  868. X    p = patt;
  869. X    out = 0;
  870. X
  871. X        /*
  872. X         * As above, initialize the first 256 entries in the table.
  873. X         */
  874. X    maxcode = MAXCODE(n_bits = INIT_BITS);
  875. X    for ( code = 255; code >= 0; code-- ) {
  876. X        tab_prefixof(code) = 0;
  877. X        tab_suffixof(code) = (char_type)code;
  878. X    }
  879. X    free_ent = ((block_compress) ? FIRST : 256 );
  880. X
  881. X    finchar = oldcode = getcode();
  882. X    if(oldcode == -1)    /* EOF already? */
  883. X        return;            /* Get out of here */
  884. X/*     putchar( (char)finchar );        /* first code must be 8 bits = char */
  885. X    if(ferror(stdout))                /* Crash if can't write */
  886. X        writeerr();
  887. X    stackp = de_stack;
  888. X
  889. X    while ( (code = getcode()) > -1 ) {
  890. X        if ( (code == CLEAR) && block_compress ) {
  891. X            for ( code = 255; code >= 0; code-- ) tab_prefixof(code) = 0;
  892. X            clear_flg = 1;
  893. X            free_ent = FIRST - 1;
  894. X                    /* O, untimely death! */
  895. X            if ( (code = getcode ()) == -1 ) break;
  896. X        }
  897. X        incode = code;
  898. X            /*
  899. X             * Special case for KwKwK string.
  900. X             */
  901. X        if ( code >= free_ent ) {
  902. X            *stackp++ = finchar;
  903. X            code = oldcode;
  904. X        }
  905. X
  906. X        /*
  907. X         * Generate output characters in reverse order
  908. X         */
  909. X        while ( code >= 256 ) {
  910. X            *stackp++ = tab_suffixof(code);
  911. X            code = tab_prefixof(code);
  912. X        }
  913. X        *stackp++ = finchar = tab_suffixof(code);
  914. X
  915. X        /*
  916. X         * And put them out in forward order
  917. X         */
  918. X
  919. X        /* This section corrupted for nini.z */
  920. X        do {
  921. X            --stackp;
  922. X            if ( out ) {
  923. X                putchar ( *stackp );
  924. X                if ( *stackp == '\n' ) exit( 0 );
  925. X            }
  926. X            else {
  927. X                if ( *p == *stackp ) p++;
  928. X                else p = patt;
  929. X                if ( *p == '\0' ) out = 1;
  930. X            }
  931. X        } while ( stackp > de_stack );
  932. X
  933. X        /*
  934. X         * Generate the new entry.
  935. X         */
  936. X        if ( (code=free_ent) < maxmaxcode ) {
  937. X            tab_prefixof(code) = (unsigned short)oldcode;
  938. X            tab_suffixof(code) = finchar;
  939. X            free_ent = code+1;
  940. X        } 
  941. X        /*
  942. X         * Remember previous code.
  943. X         */
  944. X        oldcode = incode;
  945. X    }
  946. X    fflush( stdout );
  947. X    if(ferror(stdout))
  948. X    writeerr();
  949. X}
  950. X
  951. X/*****************************************************************
  952. X * TAG( getcode )
  953. X *
  954. X * Read one code from the standard input.  If EOF, return -1.
  955. X * Inputs:
  956. X *     stdin
  957. X * Outputs:
  958. X *     code or -1 is returned.
  959. X */
  960. X
  961. Xcode_int
  962. Xgetcode() {
  963. X    register code_int code;
  964. X    static int offset = 0, size = 0;
  965. X    static char_type buf[BITS];
  966. X    register int r_off, bits;
  967. X    register char_type *bp = buf;
  968. X
  969. X    if ( clear_flg > 0 || offset >= size || free_ent > maxcode ) {
  970. X        /*
  971. X         * If the next entry will be too big for the current code
  972. X         * size, then we must increase the size.  This implies reading
  973. X         * a new buffer full, too.
  974. X         */
  975. X        if ( free_ent > maxcode ) {
  976. X            n_bits++;
  977. X            if ( n_bits == maxbits )
  978. X                    maxcode = maxmaxcode;    /* won't get any bigger now */
  979. X            else
  980. X                    maxcode = MAXCODE(n_bits);
  981. X        }
  982. X        if ( clear_flg > 0) {
  983. X            maxcode = MAXCODE (n_bits = INIT_BITS);
  984. X            clear_flg = 0;
  985. X        }
  986. X        size = fread( buf, 1, n_bits, stdin );
  987. X        if ( size <= 0 )
  988. X                return -1;            /* end of file */
  989. X        offset = 0;
  990. X            /* Round size down to integral number of codes */
  991. X        size = (size << 3) - (n_bits - 1);
  992. X    }
  993. X    r_off = offset;
  994. X    bits = n_bits;
  995. X        /*
  996. X         * Get to the first byte.
  997. X         */
  998. X    bp += (r_off >> 3);
  999. X    r_off &= 7;
  1000. X        /* Get first part (low order bits) */
  1001. X    code = (*bp++ >> r_off);
  1002. X    bits -= (8 - r_off);
  1003. X    r_off = 8 - r_off;        /* now, offset into code word */
  1004. X        /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
  1005. X    if ( bits >= 8 ) {
  1006. X        code |= *bp++ << r_off;
  1007. X        r_off += 8;
  1008. X        bits -= 8;
  1009. X    }
  1010. X            /* high order bits. */
  1011. X    code |= (*bp & rmask[bits]) << r_off;
  1012. X    offset += n_bits;
  1013. X    return code;
  1014. X}
  1015. X
  1016. Xchar *
  1017. Xrindex(s, c)        /* For those who don't have it in libc.a */
  1018. Xregister char *s, c;
  1019. X{
  1020. X    char *p;
  1021. X    for (p = NULL; *s; s++)
  1022. X        if (*s == c) p = s;
  1023. X    return(p);
  1024. X}
  1025. X
  1026. Xwriteerr()
  1027. X{
  1028. X    perror ( ofname );
  1029. X    unlink ( ofname );
  1030. X    exit ( 1 );
  1031. X}
  1032. X
  1033. Xonintr ( )
  1034. X{
  1035. X    unlink ( ofname );
  1036. X    exit ( 1 );
  1037. X}
  1038. X
  1039. Xoops ( )    /* wild pointer -- assume bad input */
  1040. X{
  1041. X    if ( do_decomp == 1 ) 
  1042. X        fprintf ( stderr, "uncompress: corrupt input\n" );
  1043. X    unlink ( ofname );
  1044. X    exit ( 1 );
  1045. X}
  1046. END_OF_src/mini-z.c
  1047. if test 8868 -ne `wc -c <src/mini-z.c`; then
  1048.     echo shar: \"src/mini-z.c\" unpacked with wrong size!
  1049. fi
  1050. # end of overwriting check
  1051. fi
  1052. if test -f utils/copy.sh -a "${1}" != "-c" ; then 
  1053.   echo shar: Will not over-write existing file \"utils/copy.sh\"
  1054. else
  1055. echo shar: Extracting \"utils/copy.sh\" \(7662 characters\)
  1056. sed "s/^X//" >utils/copy.sh <<'END_OF_utils/copy.sh'
  1057. X# This script is presented as a recovery tool to be used if a verify
  1058. X# failure occurs when writing to tape using these scripts.  It copies
  1059. X# data from one tape to another chapter by chapter.
  1060. X
  1061. X# It requires that the source tape be written by the 'wr.tape.sh' script
  1062. X# which is included in this collection of scripts.  Changes might be made
  1063. X# to these scripts so that other data can be copied, but I haven't had
  1064. X# need to generate such revisions.  That is left as an exercise for you.
  1065. X
  1066. X# A test is first run to determine that there is sufficient disk space
  1067. X# available to copy each chapter.  If insufficient space is available,
  1068. X# the amount of additional space required is reported.
  1069. X
  1070. X# Space can be attained by copying some files to floppy disk.  Also, if
  1071. X# you have the time to rerun the 'prep.sh' script, you can free disk space
  1072. X# by issuing the 'rm -r savdir' command..
  1073. X
  1074. X# These routines will overwrite existing tapes if you desire.  This option
  1075. X# is made at the begining of the 'wr.tape.sh' operation.  If you want to
  1076. X# add on to an existing tape, you must edit this script in the initialization
  1077. X# of the $RDPARMS routine.  You can also edit 'cp.params' from another window
  1078. X# while the read operation is running.
  1079. X
  1080. Xif [ ! "$WRKDIR" ]
  1081. Xthen
  1082. X    . /news/.tape.ops/utils/util.hdr.sh    # Use this for start up
  1083. Xfi
  1084. X
  1085. Xfunction clean
  1086. X{
  1087. X    rm -f $CONFILE
  1088. X    rm -f $CPNTRS
  1089. X    rm -f $TMP1
  1090. X    rm -f $TMP2
  1091. X    rm -f $WRKDIR/errs
  1092. X}
  1093. X
  1094. Xexport COPY=1
  1095. Xpau=0
  1096. Xwhile [ $pau -eq 0 ]
  1097. Xdo
  1098. X    Tgetname -t
  1099. X    ret=$?
  1100. X    if [ $ret -ne 0 ]
  1101. X    then
  1102. X        echo \
  1103. X"Please insert a source tape. Q)uit or <cr> to continue. \c"
  1104. X        read ch
  1105. X        if [ "$ch" = "q" -o "$ch" = "Q" ]
  1106. X        then
  1107. X            exit 1
  1108. X        fi
  1109. X    else
  1110. Xecho `date +%T`" Checking available memory and setting up files. "
  1111. X        Tgetname -v > /dev/null
  1112. X        set `Tgetname -r | tr -d "'"`
  1113. X        name=$1
  1114. X        biggest=`$SRCDIR/read.vtoc -g`
  1115. X        set `df $NEWSDEV`
  1116. X        avail=$3
  1117. X        (( dif = biggest + PERCENT - avail ))
  1118. X        if [ $dif -gt 0 ]
  1119. X        then
  1120. X    echo "The copy operation requires $dif more blocks of disk space."
  1121. X            exit
  1122. X        fi
  1123. X        pau=1
  1124. X    fi
  1125. X    if [ ! -d $CACHE ]
  1126. X    then
  1127. X        echo "There is not a 'cache' directory. Run 'set_up.sh'."
  1128. X    fi
  1129. Xdone
  1130. X
  1131. Xif [ ! -s $RDPARMS ]
  1132. Xthen
  1133. X    > $RDPARMS
  1134. Xfi
  1135. X
  1136. X# Check that the 'cp.params' file has the proper entries.
  1137. Xawk -F"    " - '{    if ( $0 ~ /Number of bytes held:/ ) ok1 = 1
  1138. X        if ( $0 ~ /Next fnum to link:/ ) ok2 = 1
  1139. X        if ( $0 ~ /Name of work tape:/ ) ok3 = 1
  1140. X        if ( $0 ~ /Blocks of offset:/ ) ok4 = 1
  1141. X        if ( $0 ~ /Date last taped:/ ) ok5 = 1
  1142. X        if ( $0 ~ /Blocks available:/ ) ok6 = 1
  1143. X        if ( $0 ~ /Next chapter number:/ ) ok7 = 1
  1144. X        if ( $0 ~ /Compression factor:/ ) ok8 = 1
  1145. X        if ( $0 ~ /Name of source tape:/ ) ok11 = 1
  1146. X        if ( $0 ~ /Next source chapter:/ ) ok9 = 1
  1147. X        if ( $0 ~ /Comment:/ ) ok10 = 1
  1148. X    }
  1149. X    END{    if ( ok1 != 1 ) print "Number of bytes held:    0"
  1150. X        if ( ok2 != 1 ) print "Next fnum to link:    0"
  1151. X        if ( ok3 != 1 ) print "Name of work tape:    blank"
  1152. X        if ( ok4 != 1 ) print "Blocks of offset:    0"
  1153. X        if ( ok5 != 1 ) print "Date last taped:    1-1-1"
  1154. X        if ( ok6 != 1 ) print "Blocks available:    45384"
  1155. X        if ( ok7 != 1 ) print "Next chapter number:    1"
  1156. X        if ( ok8 != 1 ) print "Compression factor:    1024"
  1157. X        if ( ok11 != 1 ) print "Name of source tape:    blank"
  1158. X        if ( ok9 != 1 ) print "Next source chapter:    1"
  1159. X        if ( ok10 != 1 ) print "Comment:    "
  1160. X    }' $RDPARMS >> $RDPARMS
  1161. X
  1162. X    > $TMP1
  1163. X    awk -F"    " - '{
  1164. X        if ( $0 ~ /Name of source tape:/ ) $2 = "'"$name"'"
  1165. X        print $1"    "$2 >> "'$TMP1'"
  1166. X    }' $RDPARMS
  1167. X    mv $TMP1 $RDPARMS
  1168. X
  1169. Xpau=0
  1170. Xwhile [ "$pau" -eq 0 ]
  1171. Xdo
  1172. X    $WRKDIR/trim.sh test
  1173. X    blks=$?
  1174. X
  1175. X    if [ $blks -eq 0 ]
  1176. X    then
  1177. Xecho "\tInsert the source tape now. <cr> to continue, Q)uit, N)ew? \c"
  1178. X        read ch
  1179. X        if [ "$ch" = "q" -o "$ch" = "Q" ]
  1180. X        then
  1181. X            clean
  1182. X            exit
  1183. X        elif [ "$ch" = "n" -o "$ch" = "N" ]
  1184. X        then
  1185. X            > $TMP1
  1186. X            awk -F"    " - '{
  1187. X                if ( $0 ~ /Next source chapter:/ ) $2 = 1
  1188. X                print $1"    "$2 >> "'$TMP1'"
  1189. X            }' $RDPARMS
  1190. X            mv $TMP1 $RDPARMS
  1191. X        fi
  1192. X        ret=1
  1193. X        while [ $ret != 0 ]
  1194. X        do
  1195. X            echo `date +%T`" Starting read operations. "
  1196. X            today=`date '+%y-%m-%d'`
  1197. X
  1198. X            Tgetname -t
  1199. X            ret=$?
  1200. X            if [ $ret != 0 ]
  1201. X            then
  1202. Xecho "Please insert the source tape. <cr> to continue, Q)uit? \c"
  1203. X                read  ch
  1204. X                if [ "$ch" = "q" -o "$ch" = "Q" ]
  1205. X                then
  1206. X                    exit 1
  1207. X                fi
  1208. X                ret=1
  1209. X            else
  1210. X                Tgetname -v
  1211. X                set `Tgetname -r | tr -d "'"`
  1212. X                name=$1
  1213. X                toffset=$2
  1214. X            fi
  1215. X        done
  1216. X
  1217. X# Get params
  1218. X        chap=`sed -n 's/Next source chapter:\    //p' $RDPARMS`
  1219. X        fname=`sed -n 's/Name of source tape:\    //p' $RDPARMS`
  1220. X        if [ "$fname" != "$name" ]
  1221. X        then
  1222. X            echo \
  1223. X"I was looking for tape '$fname' but have '$name' installed.
  1224. XEnter 'c' if you want to change tapes. \c"
  1225. X            read ch
  1226. X            if [ "$ch" = "c" -o "$ch" = "C" ]
  1227. X            then
  1228. X                continue;
  1229. X            fi
  1230. X            > $TMP1
  1231. X            awk -F"    " - '{ 
  1232. X                if ( $0 ~ /Name of source tape:/ )
  1233. X                    $2 = "'"$fname"'"
  1234. X                print $1"    "$2 >> "'$TMP1'"
  1235. X                }' $RDPARMS
  1236. X            mv $TMP1 $RDPARMS
  1237. X        fi
  1238. X        set `$SRCDIR/read.vtoc -r$chap`
  1239. X        if [ $3 -ne 0 ]
  1240. X        then
  1241. X            fchap=$1
  1242. X            offset=$2
  1243. X            blocks=$3
  1244. X            if [ -d $ARCDIR ]
  1245. X            then
  1246. X            echo `date +%T`" Purging old 'arcdir' directory. "
  1247. X                rm -r $ARCDIR
  1248. X            fi
  1249. X            mkdir $ARCDIR
  1250. X        echo `date +%T`" The contents of tape \"$name\" are:"
  1251. X            $SRCDIR/read.vtoc -w9
  1252. X            cd $ARCDIR
  1253. X            echo `date +%T`\
  1254. X" Reading chapter $chap from tape '$name' starting at $offset offset."
  1255. X            dbuf -iT248O$offset /dev/rft3 2>/dev/null | \
  1256. X        execStrip tapecpio -icdR"T248" >/dev/null 2>$WRKDIR/errs
  1257. X            ret=$?
  1258. X
  1259. X            cd $WRKDIR
  1260. X            if [ $ret != 0 ]
  1261. X            then
  1262. X                echo "\tThis chapter appears corrupted.
  1263. X\tShall we attempt to recover? <y/n> \c"
  1264. X                read ch
  1265. X                if [ "$ch" = "y" -o "$ch" = "Y" ]
  1266. X                then
  1267. X                    sleep 5
  1268. X                    recov.sh
  1269. X                else
  1270. X                    echo "Shall we quit? <y/n> \c"
  1271. X                    read ch
  1272. X                    if [ "$ch" = "y" -o "$ch" = "Y" ]
  1273. X                    then
  1274. X                        exit
  1275. X                    fi
  1276. X                    echo "Pressing on."
  1277. X                rm -f $SAVDIR/contents $SAVDIR/ss.filelist
  1278. X                fi
  1279. X            fi
  1280. X
  1281. X            (( chap = chap + 1 ))
  1282. X            $SRCDIR/read.vtoc -r$chap > /dev/null
  1283. X            ret=$?
  1284. X            if [ $chap -ge $ret ]
  1285. X            then
  1286. X                echo "This was the last chapter on this tape."
  1287. X            fi
  1288. X
  1289. X            > $TMP1
  1290. X            awk -F"    " - '{
  1291. X                if ( $0 ~ /Next source chapter:/ )
  1292. X                    $2 = "'"$chap"'"
  1293. X                print $1"    "$2 >> "'$TMP1'"
  1294. X            }' $RDPARMS
  1295. X            mv $TMP1 $RDPARMS
  1296. X        fi
  1297. X    fi
  1298. X    $WRKDIR/trim.pl
  1299. X    ret=$?
  1300. X    if [ $ret -ne 0 ]
  1301. X    then
  1302. X        continue
  1303. X    fi
  1304. X
  1305. X    echo "\tIt is okay to change tapes now."
  1306. X
  1307. X    echo `date +%T`" Changing arrangement of the 'contents' file. "
  1308. X
  1309. X# Sort the 'contents' then run 'group' to place followup articles
  1310. X# following the original.  'Group' also produces 'c.pntrs' which is
  1311. X# a listing of the files in the same order that they appear
  1312. X# in the 'contents'.
  1313. X
  1314. X    sort -fd -o $CONFILE $CONFILE
  1315. X    $SRCDIR/group $CONFILE
  1316. X
  1317. X    (( chap = chap - 1 ))
  1318. X    $SRCDIR/read.vtoc -w9
  1319. X    $SRCDIR/read.vtoc -w9 > xyz
  1320. X    for i in 1 2 3 4 5 6 7 8 9
  1321. X    do
  1322. X        while
  1323. X            read line
  1324. X        do
  1325. X            set $line
  1326. X            if [ "$1" = "$i" ]
  1327. X            then
  1328. X                CHAP=$1
  1329. X                SSNAME=$2
  1330. X                SSCMNT="$3 $4 $5 $6 $7"
  1331. X                NFILES=$8
  1332. X                OFFSET=$9
  1333. X                shift
  1334. X                NBLOCKS=$9
  1335. X            fi
  1336. X        done < xyz
  1337. X        if [ "$CHAP" = "$chap" ]
  1338. X        then
  1339. X            while
  1340. X                echo \
  1341. X"\nThe comment will be: '$SSCMNT'. Okay? <y/n> \c"
  1342. X                read ch
  1343. X                [ "$ch" = "n" -o "$ch" = "N" ]
  1344. X            do
  1345. X                read SSCMNT?"Enter comment: "
  1346. X            done
  1347. X            > $TMP1
  1348. X    awk -F"    " - '{ if ( $0 ~ /Comment:/ ) $2 = "'"$SSCMNT"'"
  1349. X            print $1"    "$2 >> "'$TMP1'"
  1350. X            }' $RDPARMS
  1351. X            mv $TMP1 $RDPARMS
  1352. X                break
  1353. X        fi
  1354. X    done
  1355. X    rm -f xyz
  1356. X
  1357. X    echo `date +%T`\
  1358. X" Insert the target tape now. <cr> to continue, Q)uit, N)ew? \c"
  1359. X    read ch
  1360. X    if [ "$ch" = "q" -o "$ch" = "Q" ]
  1361. X    then
  1362. X        clean
  1363. X        exit
  1364. X    elif [ "$ch" = "n" -o "$ch" = "N" ]
  1365. X    then
  1366. X        > $TMP1
  1367. X        awk -F"    " - '{
  1368. X        if ( $0 ~ /Number of bytes held:/ ) $2 = 0
  1369. X        if ( $0 ~ /Blocks of offset:/ ) $2 = 0
  1370. X        if ( $0 ~ /Blocks available:/ ) $2 = "'"$MAXOFFSET"'"
  1371. X        if ( $0 ~ /Next chapter number:/ ) $2 = 1
  1372. X        print $1"    "$2 >> "'$TMP1'"
  1373. X        }' $PARAMS
  1374. X        mv $TMP1 $RDPARMS
  1375. X    fi
  1376. X
  1377. X    $WRKDIR/wr.tape.sh
  1378. X
  1379. Xdone
  1380. Xclean
  1381. XTgetname -l
  1382. Xexit 0
  1383. END_OF_utils/copy.sh
  1384. if test 7662 -ne `wc -c <utils/copy.sh`; then
  1385.     echo shar: \"utils/copy.sh\" unpacked with wrong size!
  1386. fi
  1387. chmod +x utils/copy.sh
  1388. # end of overwriting check
  1389. fi
  1390. if test -f utils/panic.pl -a "${1}" != "-c" ; then 
  1391.   echo shar: Will not over-write existing file \"utils/panic.pl\"
  1392. else
  1393. echo shar: Extracting \"utils/panic.pl\" \(1265 characters\)
  1394. sed "s/^X//" >utils/panic.pl <<'END_OF_utils/panic.pl'
  1395. X
  1396. X# The purpose of this script is to prepare the 'squirrel'ed files
  1397. X# for transfer to tape.  This consists of building a 'contents'
  1398. X# file from the "Subject" line in the posted articles.  The 'contents'
  1399. X# is sorted and similar titles are moved together for easier reference.
  1400. X# The articles are then compressed and moved to the 'savdir' where
  1401. X# they can copied to tape.
  1402. X
  1403. Xexport NEWSDEV=/dev/fp002
  1404. Xexport WRKDIR=/news/.tape.ops/utils
  1405. Xexport CACHE=$WRKDIR/cache
  1406. Xexport ARCDIR=$WRKDIR/arcdir
  1407. Xexport RDPARMS=$WRKDIR/rd.params
  1408. Xexport PARAMS=$WRKDIR/rd.params        # was "wr.params"
  1409. Xexport SAVDIR=$WRKDIR/savdir
  1410. Xexport CONFILE=$WRKDIR/contents
  1411. Xexport SRCDIR=/news/.tape.ops/src
  1412. Xexport PNTRS=$WRKDIR/pntrs
  1413. Xexport CPNTRS=$WRKDIR/c.pntrs
  1414. Xexport LIST=$WRKDIR/save.list        # Directory list to be saved
  1415. Xexport LINKS=$WRKDIR/link.list
  1416. Xexport KLINKS=$WRKDIR/wrk.links
  1417. Xexport GOOFS=$WRKDIR/goofs
  1418. Xexport TMP1=$WRKDIR/tmpp1
  1419. Xexport TMP2=$WRKDIR/tmpp2
  1420. Xexport COPY=1
  1421. Xexport GRP=news
  1422. Xexport OWN=netnews
  1423. Xexport PERCENT=6200    # This is the last five percent of disk space
  1424. Xexport MAXOFFSET=45384  # or B1FE 512 byte blocks = 23329792 bytes
  1425. X# was 45566
  1426. X# If we add 2 blocks for header, B200 512 byte blocks
  1427. X# or 1DAA blocks per stream???
  1428. X# The MAXOFFSET revised 9-29-92 by experimentation.
  1429. X
  1430. Xtrim.pl
  1431. END_OF_utils/panic.pl
  1432. if test 1265 -ne `wc -c <utils/panic.pl`; then
  1433.     echo shar: \"utils/panic.pl\" unpacked with wrong size!
  1434. fi
  1435. chmod +x utils/panic.pl
  1436. # end of overwriting check
  1437. fi
  1438. if test -f utils/trim.pl -a "${1}" != "-c" ; then 
  1439.   echo shar: Will not over-write existing file \"utils/trim.pl\"
  1440. else
  1441. echo shar: Extracting \"utils/trim.pl\" \(7267 characters\)
  1442. sed "s/^X//" >utils/trim.pl <<'END_OF_utils/trim.pl'
  1443. Xeval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}'
  1444. X    if 0;
  1445. X
  1446. Xrequire 'importenv.pl';
  1447. Xrequire 'flush.pl';
  1448. X
  1449. Xprint &ntime(time)," Making preparations to move files. ";
  1450. X
  1451. Xif ( $WRKDIR   eq "" ) { $WRKDIR = "/news/.tape.ops/utils" };
  1452. Xif ( $ARCDIR   eq "" ) { $ARCDIR = $WRKDIR . "/arcdir" };
  1453. Xif ( $SAVDIR   eq "" ) { $SAVDIR = $WRKDIR . "/savdir" };
  1454. Xif ( $CACHE    eq "" ) { $CACHE  = $WRKDIR . "/cache" };
  1455. Xif ( $SRCDIR   eq "" ) { $SRCDIR = "/news/.tape.ops/src" };
  1456. Xif ( $RDPARMS  eq "" ) { $RDPARMS = $WRKDIR . "/rd.params" };
  1457. Xif ( $CONFILE  eq "" ) { $CONFILE = $WRKDIR . "/contents" };
  1458. Xif ( $SSFILE   eq "" ) { $SSFILE = $WRKDIR . "/ss.filelist" };
  1459. Xif ( $PNTRS    eq "" ) { $PNTRS = $WRKDIR . "/pntrs" };
  1460. Xif ( $CPNTRS   eq "" ) { $CPNTRS = $WRKDIR . "/c.pntrs" };
  1461. Xif ( $TMP1     eq "" ) { $TMP2 = $WRKDIR . "/tmpp1" };
  1462. Xif ( $TMP2     eq "" ) { $TMP2 = $WRKDIR . "/tmpp2" };
  1463. Xif ( $GRP      eq "" ) { $GRP = "news" };
  1464. Xif ( $OWN      eq "" ) { $OWN = "netnews" };
  1465. Xif ( $COPY     eq "" ) { $COPY = "1" };
  1466. Xif ( $MAXOFFSET == 0 ) { $MAXOFFSET = 45384 };
  1467. X
  1468. X# The length of the cpio header is 76 bytes plus length of name plus
  1469. X# a trailing '\0'.  We need headers for 'contents', 'ss.filelist' and
  1470. X# 'TRAILER!!!', these have name lengths of 8, 11 and 10.
  1471. X    $hdr = 77;
  1472. X
  1473. Xif ( -e "carry" ) {
  1474. X    open( PARMS, "<carry" );
  1475. X    while ( <PARMS> ) { ( $limit, $sum, $fnum) = split; }
  1476. X}
  1477. Xelse {
  1478. X# "contents" = 8, "ss.filelist" = 11, "TRAILER!!!" = 10.
  1479. X#        8 + 11 + 10 = 29.
  1480. X    $sum = ( $hdr * 3 ) + 29 + 10;
  1481. X    $fnum = 1;
  1482. X    open( PARMS, $RDPARMS );
  1483. X    while ( <PARMS> ) {
  1484. X        if ( /^Blocks of offset:\t(.*)/ ) { $offset = $1; }
  1485. X        if ( /^Next chapter number:\t(.*)/ ) { $chap = $1; }
  1486. X        $limit = int(( $MAXOFFSET - $offset ) / ( 10 - $chap ));
  1487. X    }
  1488. X    while (( $limit % 248 ) != 0 ) { $limit++; }
  1489. X}
  1490. Xclose( PARMS );
  1491. X
  1492. Xprint "Moving $limit blocks.\n";
  1493. X$max = int( $limit * 512 );
  1494. X
  1495. Xif ( ! -d $CACHE  ) { mkdir( $CACHE, 0666 ); }
  1496. Xif ( ! -d $ARCDIR ) { mkdir( $ARCDIR, 0666 ); }
  1497. Xif ( ! -d $SAVDIR ) { mkdir( $SAVDIR, 0666 ); }
  1498. Xopen( CON, ">>$CONFILE" );
  1499. Xopen( SS,  ">>$SSFILE" );
  1500. Xprint SS "-contents\n";
  1501. X
  1502. Xsystem( "rm -f $CACHE/contents $CACHE/ss.filelist" );
  1503. Xopen( FRM, "ls -l $CACHE | cut -c27-37,51- | sort -nr |" );
  1504. X$first = 1;
  1505. Xwhile( <FRM> ) {
  1506. X    if ( $_ != 0 ) {
  1507. X        chop;
  1508. X        if ( $first ) {
  1509. X            print &ntime(time),
  1510. X                " Moving residual 'cache'  to 'savdir'.\n";
  1511. X            $first = 0;
  1512. X        }
  1513. X        &move_em( $CACHE, $_ );
  1514. X    }
  1515. X    else { &flush( FRM ); }
  1516. X}
  1517. Xclose( FRM );
  1518. X
  1519. Xsystem( "rm -f $ARCDIR/contents $ARCDIR/ss.filelist" );
  1520. Xopen( FRM, "ls -l $ARCDIR | cut -c27-37,51- | sort -nr |" );
  1521. X$first = 1;
  1522. Xwhile( <FRM> ) {
  1523. X    if ( $_ != 0 ) {
  1524. X        chop;
  1525. X        if ( $first ) {
  1526. X            print &ntime(time),
  1527. X                " Moving data in  'arcdir' to 'savdir'.\n";
  1528. X            $first = 0;
  1529. X        }
  1530. X        &move_em( $ARCDIR, $_ );
  1531. X    }
  1532. X    else { &flush( FRM ); }
  1533. X}
  1534. Xclose( FRM );
  1535. X
  1536. X$move = 1;
  1537. Xopen( FRM, "ls -l $CACHE |" );
  1538. Xwhile( <FRM> ) {
  1539. X    if ( /^total (.*)/ ) {
  1540. X        $move = $1;
  1541. X    }
  1542. X}
  1543. X&flush( FRM );
  1544. Xclose( FRM );
  1545. X
  1546. Xopen( FRM, "ls -l $ARCDIR | cut -c27-37,51- | sort -nr |" );
  1547. X$first = 1;
  1548. Xwhile( <FRM> ) {
  1549. X    chop;
  1550. X    if ( $_ == 0 ) { last; }
  1551. X    if ( $move ) {
  1552. X        if ( $first ) {
  1553. X            print &ntime(time),
  1554. X                " Moving residual 'arcdir' to 'cache'.\n";
  1555. X            $first = 0;
  1556. X        }
  1557. X        ($size, $fname) = split( ' ' );
  1558. X        if ( $fname eq "" ) { next; }
  1559. X        system( "mv $ARCDIR/$fname $CACHE/$$.$fname" );
  1560. X    }
  1561. X    else {
  1562. X        print &ntime(time)," Moving 'arcdir' to 'cache'.\n";
  1563. X        system( "rm -fr cache; mv arcdir cache" );
  1564. X        last;
  1565. X    }
  1566. X}
  1567. X&flush( FRM );
  1568. Xclose( FRM );
  1569. X
  1570. Xclose( CON );
  1571. Xclose( SS );
  1572. X
  1573. X# Prepare report
  1574. Xsystem( "rm -f $SAVDIR/contents $SAVDIR/ss.filelist" );
  1575. Xlink( $CONFILE, "$SAVDIR/contents" );
  1576. Xlink( $SSFILE, "$SAVDIR/ss.filelist" );
  1577. X
  1578. Xprint &ntime(time)," Counting actual size of 'savdir'.\n";
  1579. X$ssize = 0;
  1580. X$scnt = 0;
  1581. X$shdrs = 0;
  1582. Xopen( FRM, "ls -l $SAVDIR | cut -c27-37,51- |" );
  1583. Xwhile( <FRM> ) {
  1584. X    ( $xsize, $ssname ) = split( ' ' );
  1585. X    if ( $xsize == 0 ) { next; }
  1586. X    $ssize += $xsize;
  1587. X    $shdrs += $hdr + length( $ssname );
  1588. X    $scnt++;
  1589. X}
  1590. Xclose( FRM );
  1591. X
  1592. X$left = $max - $sum;
  1593. X$blks = $sum / 512;
  1594. X$err = int ( $left / ( $fnum + 2 ));
  1595. X
  1596. X$sdiff = $max - $ssize;
  1597. X$sblks = $ssize / 512;
  1598. X$comp = $ssize + $shdrs + $hdr + 10;
  1599. X$cblks = $comp / 512;
  1600. X$cdiff = $max - $comp;
  1601. X
  1602. Xopen( RPT, ">>data" );
  1603. Xprint( RPT &ntime(time),
  1604. X    " Data for target chapter $chap, Nominal size of $limit blocks.\n" );
  1605. Xprint( RPT "Desired blks  = $limit,\t\tbytes = $max\n" );
  1606. Xprintf( RPT "Measured blks = %.2f,\tbytes = %d\n", $blks, $sum );
  1607. Xprintf( RPT "Actual blks   = %.2f,\tbytes = %d\n", $sblks, $ssize );
  1608. Xprintf( RPT "Compensated   = %.2f,\tbytes = %d\n", $cblks, $comp );
  1609. Xprint( RPT "Actual Files  = $scnt,\t\tMeasured Files = $fnum\n" );
  1610. Xprint( RPT "Desired - Actual = $sdiff\tDesired - Measured = $left\n" );
  1611. Xprint( RPT "Bytes per file   = $err\t\tDesired - Comp     = $cdiff\n\n" );
  1612. Xclose RPT;
  1613. X
  1614. X$diff = $limit - $blks;
  1615. Xif ( $diff gt 1 ) {
  1616. X
  1617. X    printf( "\n\tWe will have %.2f empty blocks remaining.
  1618. X\tShall we read another chapter? <y/n> ", $diff );
  1619. X    $ch = <STDIN>;
  1620. X    if ( $ch =~ /^[y,Y]/ ) {
  1621. X        open( PARMS, ">carry" );
  1622. X        print PARMS "$limit $sum $fnum";
  1623. X        close PARMS;
  1624. X        exit 1;
  1625. X    }
  1626. X}
  1627. X
  1628. Xsystem( "rm -f carry" );
  1629. Xexit 0;
  1630. X
  1631. Xsub move_em {
  1632. X    local( $from, $wrk ) = @_;
  1633. X
  1634. X    local( $size, $fname ) = split( ' ', $wrk );
  1635. X    if ( $fname eq "" || $size == 0 ) { next; }
  1636. X
  1637. X    if ( $sum + $size + 120 < $max ) { 
  1638. X        $pid = open( ZCAT, "$SRCDIR/mini-z $from/$fname |" );
  1639. X        while( <ZCAT> ) {
  1640. X            chop;
  1641. X            $subj = $_;
  1642. X        }
  1643. X# This patch inserted to cull duplicates when confused.
  1644. X#        if ( $subj eq $old_subj && $size == $old_size ) {
  1645. X#            system( "rm -f $from/$fname" );
  1646. X#            return;
  1647. X#        }
  1648. X#        $old_subj = $subj;
  1649. X#        $old_size = $size;
  1650. X# We need to add the size of a $hdr + length( $fnum ) plus 2 for '.Z'.
  1651. X# For 'contents' we add length( $subj ) plus tab + length( $fnum ) + '\n'.
  1652. X# For 'ss.filelist' we need length ( $fnum ) + '-' + '.Z\n'.
  1653. X        $tsum = $sum + $size + $hdr + length( $subj )
  1654. X            + ( length( $fnum ) * 3 ) + 8;
  1655. X        if ( $tsum <  $max ) {
  1656. X            print CON "$subj\t$fnum\n";
  1657. X            print SS "-$fnum.Z\n";
  1658. X            system( "mv $from/$fname $SAVDIR/$fnum.Z" );
  1659. X            $fnum++;
  1660. X            $sum = $tsum;
  1661. X        }
  1662. X        if ( $max - $sum < 150 ) { &flush( FRM ); }
  1663. X    }
  1664. X}
  1665. X
  1666. X
  1667. XCONFIG: {
  1668. X    package ctime;
  1669. X
  1670. X    @DoW = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
  1671. X    @MoY = ('Jan','Feb','Mar','Apr','May','Jun',
  1672. X        'Jul','Aug','Sep','Oct','Nov','Dec');
  1673. X}
  1674. X
  1675. Xsub ntime {
  1676. X    package ctime;
  1677. X
  1678. X    local($time) = @_;
  1679. X    local($[) = 0;
  1680. X    local($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
  1681. X
  1682. X    # Determine what time zone is in effect.
  1683. X    # Use GMT if TZ is defined as null, local time if TZ undefined.
  1684. X    # There's no portable way to find the system default timezone.
  1685. X
  1686. X    $TZ = defined($ENV{'TZ'}) ? ( $ENV{'TZ'} ? $ENV{'TZ'} : 'GMT' ) : '';
  1687. X    ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
  1688. X        ($TZ eq 'GMT') ? gmtime($time) : localtime($time);
  1689. X
  1690. X    # Hack to deal with 'PST8PDT' format of TZ
  1691. X    # Note that this can't deal with all the esoteric forms, but it
  1692. X    # does recognize the most common: [:]STDoff[DST[off][,rule]]
  1693. X
  1694. X    if($TZ=~/^([^:\d+\-,]{3,})([+-]?\d{1,2}(:\d{1,2}){0,2})([^\d+\-,]{3,})?/){
  1695. X        $TZ = $isdst ? $4 : $1;
  1696. X    }
  1697. X    $TZ .= ' ' unless $TZ eq '';
  1698. X
  1699. X    $year += ($year < 70) ? 2000 : 1900;
  1700. X    sprintf("%02d:%02d:%02d", $hour, $min, $sec );
  1701. X#    sprintf("%s %s %2d %2d:%02d:%02d %s%4d\n",
  1702. X#      $DoW[$wday], $MoY[$mon], $mday, $hour, $min, $sec, $TZ, $year);
  1703. X}
  1704. END_OF_utils/trim.pl
  1705. if test 7267 -ne `wc -c <utils/trim.pl`; then
  1706.     echo shar: \"utils/trim.pl\" unpacked with wrong size!
  1707. fi
  1708. chmod +x utils/trim.pl
  1709. # end of overwriting check
  1710. fi
  1711. echo shar: End of archive 2 \(of 4\).
  1712. cp /dev/null ark2isdone
  1713. MISSING=""
  1714. for I in 1 2 3 4 ; do
  1715.     if test ! -f ark${I}isdone ; then
  1716.     MISSING="${MISSING} ${I}"
  1717.     fi
  1718. done
  1719. if test "${MISSING}" = "" ; then
  1720.     echo You have unpacked all 4 archives.
  1721.     rm -f ark[1-9]isdone
  1722. else
  1723.     echo You still need to unpack the following archives:
  1724.     echo "        " ${MISSING}
  1725. fi
  1726. ##  End of shell archive.
  1727. exit 0
  1728.  
  1729. Vernon C. Hoxie                                {ncar,csn}!scicom!zebra!vern
  1730. 3975 W. 29th Ave.                                   vern@zebra.alphacdc.COM
  1731. Denver, Colo., 80212          voice: 303-477-1780        uucp: 303-455-2670
  1732.  
  1733. -- 
  1734. David H. Brierley
  1735. Home: dave@galaxia.network23.com; Work: dhb@quahog.ssd.ray.com
  1736. Send comp.sources.3b1 submissions to comp-sources-3b1@galaxia.network23.com
  1737. %% Pardon me Professor, can I be excused, my brain is full. **
  1738.