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

  1. Path: comp-sources-3b1
  2. From: vern@zebra.alphacdc.com (vern)
  3. Subject:  v02i035:  3B1 Tape processing utilities, Part01/04
  4. Newsgroups: comp.sources.3b1
  5. Approved: dave@galaxia.network23.com
  6. X-Checksum-Snefru: 77d30b12 0e0a9515 6508a26c 288abdcf
  7.  
  8. Submitted-by: vern@zebra.alphacdc.com (vern)
  9. Posting-number: Volume 2, Issue 35
  10. Archive-name: tapeops/part01
  11.  
  12.     This is a collection of shell scripts, 'c' code and perl scripts
  13. which I put together to archive certain newsgroups.  It is presented as
  14. a guide for others who might wish to use the AT&T 3b1 tape in a manner
  15. other than the one provided by AT&T.  The processes are slow and not
  16. very neat, but they serve me well.
  17.  
  18. Vernon C. Hoxie                                {ncar,csn}!scicom!zebra!vern
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of archive 1 (of 4)."
  27. # Contents:  Files README src src/pick.files.c utils utils/wr.tape.sh
  28. #   wr.tape.sh
  29. # Wrapped by vern@zebra on Mon Mar  8 08:57:29 1993
  30. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  31. if test -f Files -a "${1}" != "-c" ; then 
  32.   echo shar: Will not over-write existing file \"Files\"
  33. else
  34. echo shar: Extracting \"Files\" \(551 characters\)
  35. sed "s/^X//" >Files <<'END_OF_Files'
  36. X.
  37. X./README
  38. X./header.sh
  39. X./prep.sh
  40. X./rd.tape.sh
  41. X./save.list
  42. X./squirrel.sh
  43. X./src
  44. X./src/Makefile
  45. X./src/group.c
  46. X./src/pick.files.c
  47. X./src/read.vtoc.c
  48. X./src/fix.cpio.c
  49. X./src/mini-z.c
  50. X./wr.tape.sh
  51. X./Files
  52. X./params
  53. X./backup.sh
  54. X./link.list
  55. X./mk.index.sh
  56. X./utils
  57. X./utils/util.rd.sh
  58. X./utils/util.hdr.sh
  59. X./utils/wr.tape.sh
  60. X./utils/convert.sh
  61. X./utils/copy.sh
  62. X./utils/util.sq.sh
  63. X./utils/recov.sh
  64. X./utils/trim.sh
  65. X./utils/util.prep.sh
  66. X./utils/trim.pl
  67. X./utils/fix-1.sh
  68. X./utils/rewind.sh
  69. X./utils/panic.sh
  70. X./utils/wrk.pl
  71. X./utils/panic.pl
  72. X./utils/set_up.sh
  73. X./utils/zap.sh
  74. END_OF_Files
  75. if test 551 -ne `wc -c <Files`; then
  76.     echo shar: \"Files\" unpacked with wrong size!
  77. fi
  78. # end of overwriting check
  79. fi
  80. if test -f README -a "${1}" != "-c" ; then 
  81.   echo shar: Will not over-write existing file \"README\"
  82. else
  83. echo shar: Extracting \"README\" \(8672 characters\)
  84. sed "s/^X//" >README <<'END_OF_README'
  85. X    This is a collection of shell scripts, 'c' code and perl scripts
  86. Xwhich I put together to archive certain newsgroups.  It is presented as
  87. Xa guide for others who might wish to use the AT&T 3b1 tape in a manner
  88. Xother than the one provided by AT&T.  The processes are slow and not
  89. Xvery neat, but they serve me well.
  90. X
  91. X    I hope that you will be able to get ideas from these for any
  92. Xapplication you may want to try to build.
  93. X
  94. X    There is no "manual" for these except this README.  If you have
  95. Xquestions, either post to the net or contact me as
  96. X'vern@zebra.alphacdc.com.
  97. X
  98. X    The information about the tape drive interface is scanty and
  99. Xmuch of what I do in these scripts is strictly by guess work.
  100. X
  101. Xheader.sh:
  102. X    This is a collection of parameters used by 'squirrel.sh', 'prep.sh',
  103. X'wr.tape.sh' and 'rd.tape.sh'.  I keep all the current news articles
  104. Xin '/news'.  This collection of scripts are kept in '/news/.tape.ops'
  105. Xfor no special reason.  They can be maintained in any directory but the
  106. Xowner of the news administration must have read/write permission.  At one
  107. Xtime, I keep the scripts in '/usr/lib/news' and the working files
  108. Xin '/news/.tape.ops' hence the two identical parameters of CMDDIR and
  109. XWRKDIR.
  110. X
  111. Xparams:
  112. X    This is a file which keep track of operations between some of
  113. Xthe other scripts.  You should move it to another name and let the working
  114. Xscripts generate one for your application.
  115. X
  116. Xsave.list:
  117. X    A manually generated list of the newsgroups you wish to archive.
  118. X
  119. Xlink.list:
  120. X    A collection of 'Message ID:'s of articles which have been
  121. Xarchived in the last two months.  It is maintained by 'squirrel.sh'.
  122. X
  123. Xsquirrel.sh:
  124. X    This script scans the NEWSPOOL directory for articles in the
  125. Xgroups designated for archiving in the 'save.list' file and which are
  126. Xnot in the 'link.list' file.  It is run daily.
  127. X
  128. X    When new articles for archiving are found, they are linked into
  129. Xthe 'arcdir'.  This protects the articles from getting zapped
  130. Xby 'expire' and does not consume extra disk space for articles still in
  131. Xtheir own newgroups.  Articles are linked in numerical order with the
  132. Xsequence continuity controlled by the 'Next fnum to Link:' entry in
  133. Xthe 'params' file.
  134. X
  135. X    After each run of 'squirrel.sh', a notice of the current status
  136. Xis mailed to OWN as defined in 'header.sh'.
  137. X
  138. X    The 'params' file entries for 'Next fnum to link:', 'Number of
  139. Xbytes held:' and 'Date last squirreled:' are updated.
  140. X
  141. Xprep.sh:
  142. X    This script extracts the 'Subject:' line from each of the
  143. Xarticles in the 'arcdir' and puts them into the 'contents' file.  The
  144. Xc-code program 'group' is called to reorder the subject into
  145. Xalphabetical order and to group follow-up articles next to the original
  146. Xarticle.  This is to make recover of like subject easier.
  147. X
  148. X    'Prep.sh' also compressed each article and moves it in 'savdir'
  149. Xfor transfer to tape.  An estimate of additional space available on the
  150. Xtape is made and a new 'Compression factor:' is entered into
  151. Xthe 'params' file.  The mathematical integrity of this number is in
  152. Xserious doubt.  It is used only in for estimating the number of bytes to
  153. X'squirrel' before the next taping session.
  154. X
  155. Xwr.tape.sh:
  156. X    This is the script which actually writes to the tape.  The call
  157. Xto 'Tgetname -v' generates a file, '/tmp/tape.vtoc' which contains
  158. Xinformation about the tape from the the tape header.  'Tgetname()' is
  159. Xpart of the tape library distributed by AT&T.  The c-code program in the
  160. X'src' directory reads and '/tmp/tape.vtoc' and presents the information for
  161. Xdisplay and for use in writing to the tape.  Refer to the comments at
  162. Xthe beginning of 'src/read.vtoc.c' for more information. 
  163. X
  164. X    Options to 'Tgetname()' are:
  165. X-v "Read the Volume Table of Contents from the tape and put it into
  166. X/tmp/tape.vtoc."
  167. X-r "Calculate the next free space from the /tmp/tape.vtoc' file."
  168. X-b "Same as -v and -b plus prints the name of the tape and the next free
  169. Xblock number.
  170. X-3 "For 3b2 type tapes"
  171. X-w "Write new parameters to the tape header."
  172. X
  173. X    Another program from the tape library is 'TmakessList()'.  This
  174. Xis used to generate the 'ss.filelist'.  This must be the first file in
  175. Xeach block ( or chapter as I call them -vch ) recorded.
  176. XThe 'ss.filelist' contains the offest into the block (chapter) for
  177. Xrecovery of individual files.  The 'rd.tape.sh' script will recover
  178. Xfiles by 'Subject:'.  The 'src/pick.files' cross references
  179. Xthe 'Subject:' line to the numeric name used in archiving the files
  180. Xin 'arcdir'.
  181. X
  182. X    I originally believed that 'TmakessList()' returned the number
  183. Xof tapes that would be required.  That is the reason for the 'while'
  184. Xloop in 'wr.tape.sh' which tests for '$numtps'.  I tried to trim the
  185. Xnumber of files so that they would exactly fill the ninth chapter.  This
  186. Xresulted in a disaster.  Even after trimming, there were more files
  187. Xavailable and the damned thing went back to the beginning of the tape
  188. Xand overwrote the first chapter.  I recommend that the ninth chapter of
  189. Xyour tape not be written to.  Use the scripts in the 'utils' directory
  190. Xto copy the tape and snuggly fit the files onto the available space.
  191. X
  192. X    'Wr.tape.sh' also updates the tape header by calling 'Tgetname
  193. X-w' and it updates the 'Compression Factor:' and 'Number of bytes held:'
  194. Xand other entries in the 'params' file.
  195. X
  196. X    Upon successful completion, it purges all the directories and
  197. Xfiles no longer needed.
  198. X
  199. Xrd.tape.sh:
  200. X    This displays the Tape Table of Contents and permits you to
  201. Xselect one chapter of the tape for examination.  When the chapter has
  202. Xbeen selected, the 'contents' file for that chapter is recovered and
  203. Xdisplayed by 'src/pick.files'.  The desired articles then recovered and
  204. Xput into subdirectories which consist of the name of the tape and the
  205. Xchapter read.
  206. X
  207. Xpick.files:
  208. X    This is a c-code program which displays the the 'Subject:' line
  209. Xfrom the articles which are in the selected chapter of the tape.  An
  210. Xincremental search for subjects is made with 'control-S' for searching
  211. Xforward and 'control-R' for reverse searching.  The 'Mark' key will
  212. Xhighlight the selected line.  All selected lines are converted to the
  213. Xarticle number and the desired articles are recovered from the tape.
  214. X
  215. X    This program has some glitches which I live with but which really
  216. Xshould be corrected.  Because of not properly accounting for line wrapping,
  217. Xthe marked article may be different from the article being displayed.
  218. XYou should 'Page Up' and 'Page Down' to refresh the display
  219. Xbefore 'Exit'ing the program.  Also, two 'Esc's are required to leave
  220. Xthe search mode and initiate a new search.
  221. X
  222. Xmk.index.sh:
  223. X    This script reads all the chapters on the tape and generates a
  224. Xcomposite table of contents.  This composite contains the
  225. Xcross-reference to the articles number required by 'cpio' to recover
  226. Xindividual articles and the chapter in which the article is stored.
  227. XThis last value is needed when recovering articles.
  228. X
  229. Xbackup.sh:
  230. X    This script creates a complete backup of the files on the disk.
  231. XThere is a sed script to ignore all news articles and to put all user
  232. Xfiles at the end of list for restoration.  This 'feature'? is intended
  233. Xto alleviate some disk fragmentation after restoration.
  234. X
  235. X    It is intended that the tapes generated by this script will be
  236. Xable to be run from a 'floppy boot' disk I have made according to the
  237. Xinstructions from Lenny Tropiano.  These are available at the osu
  238. Xarchive in ftp/pub/att7300/kernel/conf.sh.Z.  As yet, I haven't had the
  239. Xneed to use them for that purpose.  Anyone like to live dangerously?
  240. X
  241. Xutils: directory
  242. X    These are a collection of shell scripts and perl scripts which
  243. Xwill copy tapes recorded by 'wr.tape.sh' and pack them neatly into the
  244. Xnine available blocks.  The 'src/mini.z' program was written to
  245. Xuncompress each article up to the 'Subject:' line and then quit.  This
  246. Xwas needed to produce new 'contents' files when the data is rerecorded.
  247. X
  248. XOther comments:
  249. X    'tapecpio()' is a variation of the standard 'cpio' with addition
  250. Xof the -T and -O options.  The '-T' desigantes a buffer size in kilobytes,
  251. Xe.g. -T120 uses a buffer of 124 * 1024 bytes.  The '-O' ( Oh not zero )
  252. Xdesigantes an offest into the tape where transfer is to
  253. Xbegin. e.g. -O128 will begin writing at the 128th block of the tape.
  254. X
  255. X    'dbuf()' provides for souble buffering of the data to and
  256. Xfrom 'tapecpio'.  The -T and -O options have the same meaning as
  257. Xin 'tapecpio()'.
  258. X
  259. X    When working with the scripts in the 'utils' directory, I
  260. Xlearned that tape will write multiples of the block size designated
  261. Xwhether or not the block is filled with data.
  262. X
  263. XVernon C. Hoxie                                {ncar,csn}!scicom!zebra!vern
  264. X3975 W. 29th Ave.                                   vern@zebra.alphacdc.COM
  265. XDenver, Colo., 80212          voice: 303-477-1780        uucp: 303-455-2670
  266. END_OF_README
  267. if test 8672 -ne `wc -c <README`; then
  268.     echo shar: \"README\" unpacked with wrong size!
  269. fi
  270. # end of overwriting check
  271. fi
  272. if test ! -d src ; then
  273.     echo shar: Creating directory \"src\"
  274.     mkdir src
  275. fi
  276. if test -f src/pick.files.c -a "${1}" != "-c" ; then 
  277.   echo shar: Will not over-write existing file \"src/pick.files.c\"
  278. else
  279. echo shar: Extracting \"src/pick.files.c\" \(11051 characters\)
  280. sed "s/^X//" >src/pick.files.c <<'END_OF_src/pick.files.c'
  281. X/* This is a program to display the 'contents' file a previously    */
  282. X/* selected chapter of an archive tape produced by the 'prep' and     */
  283. X/* 'wr.tape' scripts.  This program is designed to be specifically     */
  284. X/* called by 'rd.tape'.  It expects that 'rd.tape' has already read     */
  285. X/* a 'contents' file from the tape and that file is in the current     */
  286. X/* working directory.                             */
  287. X/*     This file produces a scrollable menu from which specific     */
  288. X/*     titles can be selected by positioning the cursor next to     */
  289. X/*     the desired title and pressing the 'Mark' key.  Selected     */
  290. X/*     titles are indicated by highlightling.  Any previoulsy         */
  291. X/*     selected title can be de-selected by again positioning the     */
  292. X/*     cursor next to the title and pressing the 'Mark' key.         */
  293. X/* The output of this program is to a 'pntrs' file in the current     */
  294. X/* working directory.  Since all files produced by 'prep' are numerical */
  295. X/* with a '.Z' suffix, this is the format of the entries in 'pntrs'.     */
  296. X/*     Cursor motion is currently limited to the 'up-arrow',         */
  297. X/*     'dn-arrow', 'Home', 'Shift-Home', 'Page' and 'Shift Page' keys. */
  298. X
  299. X#include <ctype.h>
  300. X#include <fcntl.h>
  301. X#include <malloc.h>
  302. X#include <stdio.h>
  303. X#include <sys/window.h>
  304. X#include <sys/termio.h>
  305. X
  306. X#define LINES 23
  307. X#define HALFL LINES/2
  308. X#define PFILE "r.pntrs"
  309. X/* Can we legally copy definitions from <mewu.h> ? */
  310. Xtypedef struct
  311. X{
  312. X    char        *mi_name;    /* name of item            */
  313. X    char        mi_flags;    /* flags                        */
  314. X    int        mi_val;        /* user-supplied value    */
  315. X} mitem_t;
  316. X
  317. Xmitem_t *curr_item, *start_item, *top_item, *end_item;
  318. X
  319. Xstruct termio tt;
  320. Xstatic struct uwdata uw = { 0, 12, 720, 276, 0x1 };
  321. X    /* 80 chars per line *  9 pixels per char = 720  */
  322. X    /* 23 LINES per page * 12 pixels per line = 276 */
  323. Xstatic struct umdata um = { 0x09, 0, 12, 720, 12, 0 };
  324. Xstatic struct utdata ud = { WTXTPROMPT,
  325. X"<Find>/^S = Search, <^Find>/^R = Reverse, <:q> or <Exit> to leave." };
  326. Xstatic struct utdata ue = { WTXTCMD,
  327. X"<Mark> to save/unsave item, <ESC><ESC> to reset." };
  328. X
  329. Xint lncnt;
  330. Xchar search_buf[64];
  331. XFILE *fn;
  332. X
  333. Xmain()
  334. X{
  335. X    int i, fd;
  336. X    if (( fd = open( "/dev/window", O_RDWR )) < 0 )
  337. X    {
  338. X        perror( "Opening window" );
  339. X        exit();
  340. X    }
  341. X    ioctl( fd, TCGETA, &tt );
  342. X    tt.c_iflag &= ~02000;    /* Disable start/stop */
  343. X    tt.c_lflag &= ~0112;        /* Set raw mode, no echo */
  344. X    tt.c_cc[VMIN] = 1;
  345. X    tt.c_cc[VTIME] = 1;
  346. X    ioctl( fd, TCSETA, &tt );
  347. X    ioctl( fd, WIOCSETD, &uw );
  348. X    ioctl( fd, WIOCSETTEXT, &ud );
  349. X    ioctl( fd, WIOCSETTEXT, &ue );
  350. X    ioctl( fd, WIOCSETMOUSE, &um );
  351. X    close(0); dup(fd);
  352. X    close(1); dup(fd);
  353. X    close(2); dup(fd);
  354. X    close(fd);
  355. X    lncnt = set_data();
  356. X    lncnt = 1;
  357. X    printf( "\033[2J" );        /* Erase screen */ 
  358. X    write_page( start_item );
  359. X    while ( do_funct( ));
  360. X        /* Home, Erase entire screen, Attributes to normal. */
  361. X    printf( "\033[2J\033[1;1H\033[0m" );
  362. X    fn = fopen( PFILE, "w+" );
  363. X    for ( curr_item = start_item; curr_item < end_item; curr_item++ )
  364. X        if ( curr_item->mi_flags )
  365. X                    fprintf( fn, "%d.Z ", curr_item->mi_val );
  366. X    lncnt = ftell( fn );
  367. X    fclose( fn );
  368. X    exit( lncnt );
  369. X}
  370. X
  371. Xint
  372. Xset_data( )
  373. X{
  374. X    int in, lcnt;
  375. X    long size;
  376. X    char *p, *pq;
  377. X    char *r1;
  378. X    mitem_t *wrkptr;
  379. X    in = open("contents", O_RDONLY );
  380. X    size = lseek( in, 0, 2 );
  381. X    lseek( in, 0, 0 );
  382. X    r1 = malloc( size );
  383. X    read( in, r1, size );
  384. X    close( in );
  385. X    for( p = r1, lcnt = 0; p <= r1 + size ; p++ )
  386. X        if ( *p == '\n' ) lcnt++;
  387. X    start_item = (mitem_t *)calloc( lcnt, sizeof( mitem_t));
  388. X    for( p = pq = r1, wrkptr = start_item; p <= r1 + size; p++ ) {
  389. X        if ( *p == '\t' ) {
  390. X            *p = '\0';
  391. X            wrkptr->mi_name = pq;
  392. X            wrkptr->mi_val = atoi( ++p );
  393. X            wrkptr++;
  394. X        }
  395. X        else if ( *p == '\n' ) pq = ++p;
  396. X    }
  397. X    end_item = --wrkptr;
  398. X    return( lcnt );
  399. X}
  400. X
  401. Xdo_funct( ch )
  402. Xchar ch;
  403. X{
  404. X    int i, x, y, button, reason, pos;
  405. X    char report[25];
  406. X    char *r;
  407. X
  408. X    ch = getchar();
  409. X    if ( ch >= ' ' ) {
  410. X        if ( ch == ':' && ( ch = getchar()) == 'q' )
  411. X            return( 0 );
  412. X        search( toupper( ch ));
  413. X    }
  414. X    else if ( ch == '\022' || ch == '\023' || ch == '\b' )
  415. X        search( ch );        /* \022 = control S, \023 = control R */
  416. X    else if ( ch == '\033' ) {
  417. X        if (( ch = getchar()) == '[') {
  418. X            switch ( ch = getchar() ) {
  419. X            case 'A':                         /* "Up Arrow" */
  420. X                move_up();
  421. X                break;
  422. X            case 'B':                        /* "Down Arrow" */
  423. X                move_down();
  424. X                break;
  425. X            case 'H':                        /* "Home" */
  426. X                home();
  427. X                break;
  428. X            case 'U':
  429. X                write_page( top_item + LINES + HALFL);    /* "Page" */
  430. X                break;
  431. X            case 'V':
  432. X                 write_page( top_item - LINES + HALFL);    /* "^Page" */
  433. X                break;
  434. X            case '?':        /* "Mouse" */
  435. X                r = report;
  436. X                while (( ch = getchar( )) != 'M' ) 
  437. X                    *r++ = ch;
  438. X                *r = '\0';
  439. X                r = report;
  440. X                x = 0;
  441. X                while ( *r != ';' )
  442. X                    x = (x * 10)    + ( *r++ & 0x0f );
  443. X                y = 0;
  444. X                r++;
  445. X                while ( *r != ';' )
  446. X                    y = (y * 10)    + ( *r++ & 0x0f );
  447. X                button = 0;
  448. X                r++;
  449. X                while ( *r != ';' )
  450. X                     button = (button * 10) + ( *r++ & 0x0f );
  451. X                reason = 0;
  452. X                r++;
  453. X                while ( *r )
  454. X                    reason = (reason * 10) + ( *r++ & 0x0f );
  455. X                if ( reason & 0x8 ) {
  456. X                    i = lncnt - 1;
  457. X                    pos = y / 12;
  458. X                    if ( pos < i ) move_up();
  459. X                    else if ( pos > i ) move_down();
  460. X                    um.um_y = 12 * i;
  461. X                    ioctl( 1, WIOCSETMOUSE, &um );
  462. X                }
  463. X                switch ( button ) {
  464. X                case 1:  /* Right button */
  465. X                    if ( lncnt < 12 ) home();
  466. X                    else tail();
  467. X                    break;
  468. X                case 2: /* Middle button */
  469. X                    if ( lncnt == 1 )
  470. X                        move_up();
  471. X                    else if ( lncnt == LINES )
  472. X                        move_down();
  473. X                    else if ( lncnt < 12 ) {
  474. X                        write_page( top_item + LINES + HALFL);    /* "Page" */
  475. X                 }
  476. X                    else {
  477. X                        write_page( top_item + LINES + HALFL);    /* "Page" */
  478. X                    }
  479. X                    break;
  480. X                case 4:  /* Left button */
  481. X                    mark();
  482. X                    break;
  483. X                }
  484. X            }
  485. X        }
  486. X        else if ( ch == 'O' ) {
  487. X            switch ( ch = getchar() ) {
  488. X            case 'k':                        /* Exit */
  489. X            case 'o': return( 0 );         /* Save */
  490. X            case 'x':                        /* Find */
  491. X                search( '\023' );
  492. X                break;
  493. X            case 'X':                        /* ^Find */
  494. X                search( '\022' );
  495. X                break;
  496. X            }
  497. X        }
  498. X        else if ( ch == 'N' ) {
  499. X            switch ( ch = getchar() ) {
  500. X            case 'i':
  501. X                mark();    /* "Mark" */
  502. X                break;
  503. X            case 'M':
  504. X                tail();    /* "^Home" */
  505. X                break;
  506. X            }
  507. X        }
  508. X        else {
  509. X            search( 0 );
  510. X        }
  511. X    }
  512. X    return( 1 );
  513. X}
  514. X
  515. Xsearch( arg )
  516. Xchar arg;
  517. X{
  518. X    struct utdata uf;
  519. X    struct utdata ug;
  520. X    static mitem_t *anchor;
  521. X    static char *hdrp;
  522. X    static char *old_ptr = NULL;
  523. X    static char *search_ptr = search_buf;
  524. X    static int search_dir = 0;
  525. X    static int pass = 0;
  526. X    mitem_t *here;
  527. X    char *p, *q, *r;
  528. X    short n, m;
  529. X
  530. X    if ( arg > 0 && pass < 0 ) return;
  531. X    if ( arg >= ' ' ) {
  532. X        *search_ptr++ = arg;
  533. X        *search_ptr = '\0';
  534. X    }
  535. X    else if ( arg == '\022' ) {
  536. X        hdrp = "Reverse search: ";
  537. X        search_dir = -1;
  538. X    }
  539. X    else if ( arg == '\023' ) {
  540. X        hdrp = "Searching for:  ";
  541. X        search_dir = 1;
  542. X    }
  543. X    else if ( arg == '\b' ) {
  544. X        if ( search_ptr > search_buf ) {
  545. X            *--search_ptr = '\0';
  546. X            search_dir = - search_dir;
  547. X            search ( 2 );
  548. X            search_dir = - search_dir;
  549. X        }
  550. X        return;
  551. X    }
  552. X    else if ( arg == 0 ) {
  553. X        search_ptr = search_buf;
  554. X        search_dir = 0;
  555. X        hdrp = "";
  556. X        pass = -1;
  557. X        n = 0;
  558. X    }
  559. X    else if ( arg == 1 ) {
  560. X        if ( arg ) hdrp = "Search failed!";
  561. X        n = 0;
  562. X        pass = -3;
  563. X    }
  564. X    else if ( arg == 2 ) {;}    /* Dummy for backspace recursion. */
  565. X    else return;
  566. X
  567. X    if ( ++pass == 1 ) {
  568. X        anchor = curr_item - search_dir;
  569. X        if ( anchor < start_item ) anchor = end_item;
  570. X        else if ( anchor > end_item ) anchor = start_item;
  571. X    }
  572. X    if ( pass == 2 && search_ptr == search_buf )
  573. X            search_ptr = old_ptr;
  574. X
  575. X            /* Limit search pointer to search buffer. */
  576. X    if ( arg > 3  && ( n = search_ptr - search_buf ) < 0 )
  577. X            search_ptr = search_buf;
  578. X    else if ( n >= sizeof( search_buf ))
  579. X            search_ptr = search_buf + sizeof( search_buf ) - 1;
  580. X
  581. X    uf.ut_num = WTXTSLK1;
  582. X    sprintf( uf.ut_text, "%d %s%.*s", pass, hdrp, n, search_buf );
  583. X    ioctl( 1, WIOCSETTEXT, &uf );
  584. X
  585. X    if ( pass <= 1 ) return;
  586. X
  587. X    old_ptr = search_ptr;
  588. X    here = curr_item;
  589. X    while ( 1 )
  590. X    {
  591. X        here += search_dir;
  592. X        if ( here > end_item ) here = start_item;
  593. X        else if ( here < start_item ) here = end_item;
  594. X        if ( here == anchor ) {
  595. X            search( 1 );
  596. X            return;
  597. X        }
  598. X        q = here->mi_name;
  599. Xmore:
  600. X        p = search_buf;
  601. X        while ( *q && toupper(*q) != *p ) q++;
  602. X        if ( *q == '\0' ) continue;
  603. X
  604. X        r = q;
  605. X        while ( toupper(*q) == *p ) q++, p++;
  606. X        if ( *p == '\0' ) {
  607. X            if ( here < top_item || here > top_item + LINES )
  608. X                write_page( here );
  609. X
  610. X            m = r - here->mi_name;
  611. X            n = here - top_item + 1;
  612. X            printf( "\033[%d;%dH", n, m );
  613. X             curr_item = here;
  614. X            break;
  615. X        }
  616. X        goto more;
  617. X    }
  618. X}
  619. X
  620. Xwrite_page( obj_item )
  621. Xmitem_t *obj_item;
  622. X{
  623. X    int i;
  624. X    mitem_t *wrkptr;
  625. X
  626. X    top_item = obj_item - HALFL;
  627. X    if (( top_item + LINES ) >= end_item ) top_item = end_item - LINES;
  628. X    if ( top_item < start_item ) top_item = start_item;
  629. X    printf( "\033[1;1H" );    /* Home */
  630. X    for ( i = 1, wrkptr = top_item; i <= LINES ; i++, wrkptr++ ) {
  631. X        if ( wrkptr > end_item ) break;
  632. X        if ( wrkptr->mi_flags ) printf( "\015\033[7m" ); /* Reverse */
  633. X        else printf( "\015\033[0m" );                            /* Normal video */
  634. X        printf( "\033[=0w%s\033[0K", wrkptr->mi_name );
  635. X        if ( wrkptr == obj_item ) lncnt = i;
  636. X        if ( i < LINES ) putchar( '\n' );
  637. X    }
  638. X    curr_item = obj_item;
  639. X    printf( "\033[%d;1H", lncnt );         /* Cursor to 'lncnt' */
  640. X}
  641. X    
  642. Xmark()
  643. X{
  644. X    curr_item->mi_flags = ! curr_item->mi_flags;
  645. X    if ( curr_item->mi_flags )
  646. X        printf( "\033[7m" );            /* Reverse video */
  647. X    else
  648. X        printf( "\033[0m" );            /* Normal video */
  649. X    printf( "\015\033[=0w%s\033[0K", curr_item->mi_name );
  650. X}
  651. X
  652. Xtail()
  653. X{
  654. X    if ( curr_item == end_item )
  655. X    {
  656. X        putchar( '\007' ); /* Beep */
  657. X        return;
  658. X    }
  659. X    write_page( end_item );
  660. X}
  661. X
  662. Xhome()
  663. X{
  664. X    if ( curr_item == start_item )
  665. X    {
  666. X        putchar( '\007' ); /* Beep */
  667. X        return;
  668. X    }
  669. X    write_page( start_item );
  670. X}
  671. X
  672. X        /* Move up means move toward beginning of buffer. */
  673. Xmove_up()
  674. X{
  675. X    if ( --curr_item < start_item ) {
  676. X        putchar( '\007' ); /* Beep */
  677. X        curr_item = start_item;
  678. X        lncnt = 1;
  679. X    }
  680. X    else if ( curr_item < top_item ) {
  681. X        printf( "\033[1T" );                    /* Scroll down 1 line */
  682. X        if ( curr_item->mi_flags )
  683. X            printf( "\033[7m" );                /* Reverse video */
  684. X        else
  685. X            printf( "\033[0m" );                /* Normal video */
  686. X/* 
  687. X * \033[1;1H    = go to line 1, col 1
  688. X * \033[=0w        = line wrapping off,
  689. X * %s                = write mi_name,
  690. X * \033[0K        = erase to end of line,
  691. X * \015            = put cursor at beginning of line
  692. X */
  693. X        printf( "\033[1;1H\033[=0w%s\033[0K\015",
  694. X                curr_item->mi_name );
  695. X        top_item = curr_item;
  696. X        lncnt = 1;
  697. X    }
  698. X    else {
  699. X        lncnt = curr_item - top_item + 1;
  700. X        printf( "\033[%d;1H", lncnt );
  701. X    }
  702. X}
  703. X
  704. X        /* Move down means move toward end of buffer. */
  705. Xmove_down()
  706. X{
  707. X    if ( ++curr_item >= end_item ) {
  708. X        curr_item = end_item;
  709. X        putchar( '\007' ); /* Beep */
  710. X        lncnt = LINES;
  711. X    }
  712. X    else if ( curr_item > top_item + LINES ) {
  713. X        printf( "\033[1S" );                    /* scroll up 1 line */
  714. X        if ( curr_item->mi_flags )
  715. X            printf( "\033[7m" );                /* Reverse video */
  716. X        else
  717. X            printf( "\033[0m" );                /* Normal video */
  718. X/* 
  719. X * \033[1S            = scroll up 1 line,
  720. X * \033[%d;1        = %d = LINES, go to beginning of bottom line
  721. X * \033[=0w            = line wrapping off,
  722. X * %s                    = write mi_name,
  723. X * \033[0K            = erase to end of line
  724. X * \015                = put cursor at beginning of line
  725. X */
  726. X        printf( "\033[%d;1H\033[=0w%s\033[0K\015",
  727. X                    LINES, curr_item->mi_name );
  728. X        top_item = curr_item - LINES - 1;
  729. X        lncnt = LINES;
  730. X    }
  731. X    else {
  732. X        lncnt = curr_item - top_item + 1;
  733. X        printf( "\033[%d;1H", lncnt );
  734. X    }
  735. X}
  736. END_OF_src/pick.files.c
  737. if test 11051 -ne `wc -c <src/pick.files.c`; then
  738.     echo shar: \"src/pick.files.c\" unpacked with wrong size!
  739. fi
  740. # end of overwriting check
  741. fi
  742. if test ! -d utils ; then
  743.     echo shar: Creating directory \"utils\"
  744.     mkdir utils
  745. fi
  746. if test -f utils/wr.tape.sh -a "${1}" != "-c" ; then 
  747.   echo shar: Will not over-write existing file \"utils/wr.tape.sh\"
  748. else
  749. echo shar: Extracting \"utils/wr.tape.sh\" \(8996 characters\)
  750. sed "s/^X//" >utils/wr.tape.sh <<'END_OF_utils/wr.tape.sh'
  751. X# This is the sequence of operations to write squirrelled files to tape.
  752. X# It requires that:
  753. X#    1. The files have been previously compressed and moved
  754. X#     into the 'savdir'.
  755. X#    2.    A 'pntrs' file exists which is a listing of the 'savdir' sans .Z
  756. X#    3. A 'contents' file exists which contains the 'Subject: ' of each
  757. X#    file in 'savdir' with a cross reference to its name in 'arcdir'.
  758. X#
  759. X#    These files are normally generated by 'prep' and this program
  760. X# is called by 'prep'.  However, these operations may be aborted during
  761. X# a 'prep' run and resumed by calling this program as a separate
  762. X# operation if these three parameters exist.
  763. X
  764. Xfunction cleanup
  765. X{
  766. X    rm -fr $SAVDIR
  767. X    rm -f /tmp/tape.vtoc
  768. X    rm -f /tmp/ss.osets
  769. X    rm -f /tmp/size*
  770. X    rm -f ss.filelist
  771. X    rm -f $PNTRS
  772. X    rm -f $CPNTRS
  773. X    rm -f BUfiles
  774. X    rm -f $CONFILE
  775. X    rm -f bk.contents
  776. X    rm -f bk.pntrs
  777. X    rm -f /tmp/BUlist*
  778. X}
  779. X
  780. Xif [ ! "$WRKDIR" ]
  781. Xthen
  782. X    echo "This script must be run as a function of another process
  783. Xso that the correct files are accessed."
  784. X    exit 1
  785. Xfi
  786. X
  787. X# This should be the start of the program
  788. X
  789. Xecho `date +%T`" Starting write operations. "
  790. X
  791. Xif [ ! -f $PARAMS ]
  792. Xthen
  793. X    echo "Whoops! There is no 'params' file so we don't know
  794. Xwhat to write. "
  795. X    exit 1
  796. Xfi
  797. X
  798. Xif [ ! -f $CONFILE ]
  799. Xthen
  800. X    echo "Whoops! There is no 'contents' file so we don't know
  801. Xwhat to write. "
  802. X    exit 1
  803. Xfi
  804. X
  805. X# These copies are made so that 'wr.tape.sh' may be resumed after
  806. X# preparing another tape.
  807. Xcp $CONFILE bk.contents
  808. Xcp $CPNTRS bk.pntrs
  809. X
  810. X# Get params
  811. Xname=`sed -n 's/Name of work tape:\    //p' $PARAMS`
  812. Xpoffset=`sed -n 's/Blocks of offset:\    //p' $PARAMS`
  813. Xtdate=`sed -n 's/Date last taped:\    //p' $PARAMS`
  814. Xblks=`sed -n 's/Blocks available:\    //p' $PARAMS`
  815. Xpchap=`sed -n 's/Next chapter number:\    //p' $PARAMS`
  816. XSSCMNT=`sed -n 's/Comment:\    //p' $PARAMS`
  817. X
  818. Xpau=0
  819. Xwhile [ "$pau" = "0" ]
  820. Xdo
  821. X    Tgetname -t
  822. X    ret=$?
  823. X    if [ $ret != 0 ]
  824. X    then
  825. X        echo "Please insert a tape. Q)uit or <cr> to continue. \c"
  826. X        read  ch
  827. X        if [ "$ch" = "q" -o "$ch" = "Q" ]
  828. X        then
  829. X            exit 1
  830. X        fi
  831. X    else
  832. X        Tgetname -v > /dev/null
  833. X        ret=$?
  834. X        set `Tgetname -r | tr -d "'"`
  835. X        tname=$1
  836. X        toffset=$2
  837. X        Tgetname -b
  838. X        if [ $ret = 30 ]
  839. X        then
  840. X            echo "\n\tThis tape has the \"SAFE\" key set.
  841. X\tPlease exchange it for a tape we can write onto.
  842. X\t    <cr> to continue. Q)uit."
  843. X            read -r ch
  844. X            if [ "$ch" = "q" -o "$ch" = "Q" ]
  845. X            then
  846. X                exit 1
  847. X            fi
  848. X        else
  849. X            if [ "$tname" != "$name" ]
  850. X            then
  851. X                echo \
  852. X"\tYou may have inserted the wrong tape.
  853. X\tThis tape name is \"$tname\" and I was expecting \"$name\"."
  854. X                while
  855. X                    echo \
  856. X                    "\t\tIs '$name' okay? <y/n> \c"
  857. X                    read ch
  858. X                    [ "$ch" = "n" -o "$ch" = "N" ]
  859. X                do
  860. X                    read name?"Enter new name: "
  861. X                done
  862. X            fi
  863. X# 'read.vtoc -w9' will write all used chapters to standard out in column
  864. X# format.  'read.vtoc -c' puts the next chapter number and the next offset
  865. X# on standard output.  A return of '10' indicates that the tape is full.
  866. X
  867. Xecho `date +%T`" The contents of tape \"$name\" are:"
  868. X            $SRCDIR/read.vtoc -w9
  869. X            set `$SRCDIR/read.vtoc -c$pchap`
  870. X            chap=$1
  871. X            offset=$2
  872. X            if [ "$pchap" -ne "$chap" ]
  873. X            then
  874. X                echo \
  875. X    "\n\tThere is a descrepancy about which chapter should be written next.
  876. X    The parameters file says chapter '$pchap' (default).
  877. X    The tape header says chapter '$chap'.
  878. X    Enter your choice for the chapter number. \c"
  879. X                read chap
  880. X                if [ "$chap" = "" ]
  881. X                then
  882. X                    chap=$pchap
  883. X                fi
  884. X            fi
  885. X            if [ "$poffset" -ne "$offset" ]
  886. X            then
  887. X                echo \
  888. X    "\n\tThere is a descrepancy about the amount of offset.
  889. X    The parameters file says to start at '$poffset' (default).
  890. X    The tape header says to start at '$offset'.
  891. X    Enter your choice for the amount of offset. \c"
  892. X                read offset
  893. X                if [ "$offset" = "" ]
  894. X                then
  895. X                    offset=$poffset
  896. X                fi
  897. X            fi
  898. X        pau=1
  899. X        fi
  900. X    fi
  901. X    if [ "$ch" = "n" -o "$ch" = "N" ]
  902. X    then
  903. Xecho "\tWaiting for another tape to be inserted.
  904. X\t<cr> to continue. Q)uit \c"
  905. X        read -r ch
  906. X        if [ "$ch" = "q" -o "$ch" = "Q" ]
  907. X        then
  908. X            exit 1
  909. X        fi
  910. X        pau=0
  911. X    fi
  912. Xdone
  913. X
  914. X# Whew, don't ask me how we got through all those queries but I think
  915. X# that there is one path through there that doesn't have a stop.
  916. X
  917. Xecho `date +%T`\
  918. X" Preparing file lists. Chapter '$chap', Tape '$name', Offset $offset."
  919. Xscalped=0
  920. X
  921. Xcd $SAVDIR
  922. Xwhile
  923. X    rm -f contents
  924. X    ln $CONFILE contents
  925. X    echo "contents" > $WRKDIR/BUfiles
  926. X    while
  927. X        read pntr
  928. X    do
  929. X        echo "$pntr.Z" >> $WRKDIR/BUfiles
  930. X    done < $CPNTRS
  931. X    TmakessList $offset <$WRKDIR/BUfiles > ss.filelist
  932. X    numtps=$?
  933. X    [ $numtps -gt 1 ]
  934. Xdo
  935. X# This trims down the entries in the 'savdir' until it will fit on
  936. X# the end of the tape.  The CPNTRS file will also be trimmed.  Later
  937. X# we will remove the entries in ARCDIR which are still in CPNTRS.
  938. X# The rest of ARCDIR will be relabelled for the next tape.
  939. X    > $TMP2
  940. X    if [ $scalped -eq 0 ]
  941. X    then
  942. X        echo \
  943. X"\tStandby! The file list is being trimmed to fit the tape!!
  944. X\tThere will be some messages issued stating:
  945. X\t\t'insert next floppy tape'.
  946. X\tIgnore those messages and respond with a <cr>."
  947. X        scalped=1
  948. X    fi
  949. X    last=`sed -n '$ p;$ !w '$TMP2'' $CPNTRS`
  950. X    echo "last = $last"
  951. X# This line must be '/<tab>'$last'$/...
  952. X    sed -e '/    '$last'$/ d' $CONFILE > $TMP1
  953. X    if [ ! -d $WRKDIR/scalped ]
  954. X    then mkdir $WRKDIR/scalped; fi
  955. X    if [ "X_$COPY" = "X_1" ]
  956. X    then mv $SAVDIR/$last.Z $CACHE/$$$last.Z; fi
  957. X    mv $TMP1 $CONFILE
  958. X    mv $TMP2 $CPNTRS
  959. Xdone
  960. X
  961. Xif [ $chap -eq 9 -a $scalped -eq 0 ]
  962. Xthen
  963. X    echo \
  964. X"\tThis is the last chapter available on this tape and space is going
  965. X\tto be left over.  Do you want to abort now and rerun this after you
  966. X\thave collected more files? <y> to abort, <n> to continue. \c"
  967. X    read ch
  968. X    if [ "$ch" = "y" -o "$ch" = "Y" ]
  969. X    then
  970. X        cleanup
  971. X        exit 1
  972. X    fi
  973. Xfi
  974. X
  975. Xecho `date +%T`\
  976. X" Writing chapter '$chap' to tape '$name' starting at block $offset."
  977. Xecho "ss.filelist" > /tmp/BUlist$$
  978. Xcat /tmp/BUlist$$ $WRKDIR/BUfiles | tapecpio -ocvT124 2>/tmp/size$$ | \
  979. X       dbuf -oT124O$offset > /dev/rft3
  980. Xret=$?
  981. Xif [ "$ret" != "0" ]
  982. Xthen
  983. X    if [ $ret = 4 ]
  984. X    then
  985. X        echo "This tape operation has been aborted."
  986. X        exit 1
  987. X    else
  988. X        echo "\
  989. X\tAn error has occurred while trying to create this backup-set.
  990. X\tCheck that a formatted tape has been properly inserted and has
  991. X\tfinished rewinding.  Enter <q> to quit. \c"
  992. X        read ch
  993. X        exit 1
  994. X    fi
  995. Xfi
  996. X
  997. Xeval set `grep "blocks" /tmp/size$$`
  998. XNBLOCKS=$1
  999. X
  1000. Xset `wc -l ss.filelist`
  1001. XNFILES=$1
  1002. X
  1003. Xecho "\
  1004. X$NBLOCKS blocks and $NFILES files written to target chapter $chap\n" \
  1005. X>> $WRKDIR/data
  1006. X
  1007. Xecho `date +%T`" Performing verify pass."
  1008. X
  1009. Xdbuf -iT124O$offset"S"$NBLOCKS /dev/rft3 > /dev/null
  1010. Xret=$?
  1011. X
  1012. Xif [ "$ret" != "0" ]
  1013. Xthen
  1014. X    echo "\
  1015. X\tAn error has been discovered while trying to verify this tape.
  1016. X\tYou should use copy the existing data on this tape to another
  1017. X\ttape using '/news/.tape.ops/start/copy.sh'.  Read the comments
  1018. X\tat the beginning of that program before proceeding."
  1019. X    read
  1020. X    exit 1
  1021. Xfi
  1022. X
  1023. Xecho `date +%T`" Updating data block."
  1024. Xcase $chap in
  1025. X    1) SSNAME="This";;
  1026. X    2) SSNAME="need";;
  1027. X    3) SSNAME="for";;
  1028. X    4) SSNAME=" a ";;
  1029. X    5) SSNAME="name";;
  1030. X    6) SSNAME=" is ";;
  1031. X    7) SSNAME="very";;
  1032. X    8) SSNAME="silly";;
  1033. X    9) SSNAME="stuff";;
  1034. Xesac
  1035. X
  1036. Xif [ "$COPY" = "0" ]
  1037. Xthen
  1038. X    SSCMNT=`date '+%a, %h. %d 19%y %H:%M'`
  1039. Xfi
  1040. XTgetname -w "Backup by Names" "$name" "$SSNAME" "$SSCMNT" \
  1041. X        $offset $NBLOCKS $NFILES
  1042. X#            "$BTYPE"       "$TPNAME" "$SSNAME" "$SSCMNT"
  1043. X#               $OFFSET $NBLOCKS $NFILES
  1044. Xret=$?
  1045. Xif [ "$ret" != "0" ]
  1046. Xthen
  1047. X    echo "\tAn error has occurred while trying to update the data block.
  1048. X\tError number = "$ret
  1049. X    exit 1
  1050. Xfi
  1051. X
  1052. Xcd $WRKDIR
  1053. X
  1054. XTgetname -v
  1055. Xecho `date +%T`" Verification complete.  The new contents are:"
  1056. X$SRCDIR/read.vtoc -w9
  1057. Xif [ "$COPY" = "0" ]
  1058. Xthen
  1059. X    chap=$?
  1060. Xelse
  1061. X    (( chap = chap + 1 ))
  1062. Xfi
  1063. X
  1064. Xif [ $chap -gt 9 -o $scalped -ne 0 ]
  1065. Xthen
  1066. Xecho "\tThis tape should be marked FULL and a new tape used next time."
  1067. X    offset=0
  1068. X    name=`echo $name | awk - '{ FS = "-"
  1069. X        printf("%s-%03d", $1, ++$2 ) }' -`
  1070. X    blks=$MAXOFFSET
  1071. X    chap=1
  1072. Xelse
  1073. X    set `$SRCDIR/read.vtoc -c$chap`
  1074. X    chap=$1
  1075. X    offset=$2
  1076. X    (( blks = $MAXOFFSET - offset ))
  1077. Xfi
  1078. Xtoday=`date '+%y-%m-%d'`
  1079. X
  1080. X> $TMP1
  1081. Xchgrp news $TMP1
  1082. Xchown netnews $TMP1
  1083. Xecho `date +%T`" Purging directories and support files."
  1084. X
  1085. Xif [ $COPY -eq 0 ]
  1086. Xthen
  1087. X    while
  1088. X        read pntr
  1089. X    do
  1090. X        rm -f $ARCDIR/$pntr
  1091. X    done <$CPNTRS
  1092. X
  1093. X    fnum=1
  1094. X    ls -1 $ARCDIR > $PNTRS
  1095. X    while
  1096. X        read pntr
  1097. X    do
  1098. X        if [ ! -f $ARCDIR/$fnum ]
  1099. X        then
  1100. X            mv $ARCDIR/$pntr $ARCDIR/$fnum
  1101. X            (( fnum = fnum + 1 ))
  1102. X        fi
  1103. X    done < $PNTRS
  1104. X
  1105. X    factor=`sed -n 's/Compression factor:\    //p' $PARAMS`
  1106. X    nbytes=`sed -n 's/Number of bytes held:\    //p' $PARAMS`
  1107. X    xbytes=`echo $nbytes | tr -d ","`
  1108. X
  1109. X    if [ $chap -gt 1 ]
  1110. X    then
  1111. X        (( factor = (( xbytes/NBLOCKS ) + factor)/2 ))
  1112. X    fi
  1113. Xfi
  1114. X
  1115. Xawk -F"    " - '{ if ( $0 ~ /Next fnum to link:/ ) $2 = "'"$fnum"'"
  1116. X        if ( $0 ~ /Number of bytes held:/ ) $2 = 0
  1117. X        if ( $0 ~ /Name of work tape:/ ) $2 = "'"$name"'"
  1118. X        if ( $0 ~ /Blocks of offset:/ ) $2 = "'"$offset"'"
  1119. X        if ( $0 ~ /Date last taped:/ ) $2 = "'"$today"'"
  1120. X        if ( $0 ~ /Blocks available:/ ) $2 = "'"$blks"'"
  1121. X        if ( $0 ~ /Next chapter number:/ ) $2 = "'"$chap"'"
  1122. X        if ( $0 ~ /Compression factor:/ ) $2 = "'"$factor"'"
  1123. X        print $1"    "$2 >> "'$TMP1'"
  1124. X        }' $PARAMS
  1125. Xmv $TMP1 $PARAMS
  1126. X
  1127. Xcleanup
  1128. X
  1129. Xecho `date +%T`" Taping finished."
  1130. Xexit 0
  1131. END_OF_utils/wr.tape.sh
  1132. if test 8996 -ne `wc -c <utils/wr.tape.sh`; then
  1133.     echo shar: \"utils/wr.tape.sh\" unpacked with wrong size!
  1134. fi
  1135. chmod +x utils/wr.tape.sh
  1136. # end of overwriting check
  1137. fi
  1138. if test -f wr.tape.sh -a "${1}" != "-c" ; then 
  1139.   echo shar: Will not over-write existing file \"wr.tape.sh\"
  1140. else
  1141. echo shar: Extracting \"wr.tape.sh\" \(9244 characters\)
  1142. sed "s/^X//" >wr.tape.sh <<'END_OF_wr.tape.sh'
  1143. X# This is the sequence of operations to write squirrelled files to tape.
  1144. X# It requires that:
  1145. X#    1. The files have been previously compressed and moved
  1146. X#     into the 'savdir'.
  1147. X#    2.    A 'pntrs' file exists which is a listing of the 'savdir' sans .Z
  1148. X#    3. A 'contents' file exists which contains the 'Subject: ' of each
  1149. X#    file in 'savdir' with a cross reference to its name in 'arcdir'.
  1150. X#
  1151. X#    These files are normally generated by 'prep' and this program
  1152. X# is called by 'prep'.  However, these operations may be aborted during
  1153. X# a 'prep' run and resumed by calling this program as a separate
  1154. X# operation if these three parameters exist.
  1155. X
  1156. Xfunction cleanup
  1157. X{
  1158. X    rm -fr $SAVDIR
  1159. X    rm -f /tmp/tape.vtoc
  1160. X    rm -f /tmp/ss.osets
  1161. X    rm -f /tmp/size*
  1162. X    rm -f $PWD/ss.filelist
  1163. X    rm -f $PNTRS
  1164. X    rm -f $CPNTRS
  1165. X    rm -f BUfiles
  1166. X    rm -f $CONFILE
  1167. X    rm -f bk.contents
  1168. X    rm -f bk.pntrs
  1169. X    rm -f /tmp/BUlist*
  1170. X}
  1171. X
  1172. Xif [ ! "$WRKDIR" ]
  1173. Xthen
  1174. X    echo "This script must be run as a function of another process
  1175. Xso that the correct files are accessed."
  1176. X    exit 1
  1177. Xfi
  1178. X
  1179. X# This should be the start of the program
  1180. X
  1181. Xecho `date +%T`" Starting writing operations. "
  1182. X
  1183. Xif [ ! -f $PARAMS ]
  1184. Xthen
  1185. X    echo "Whoops! There is no 'params' file so we don't know
  1186. Xwhat to write. "
  1187. X    exit 1
  1188. Xfi
  1189. X
  1190. Xif [ ! -f $CONFILE ]
  1191. Xthen
  1192. X    echo "Whoops! There is no 'contents' file so we don't know
  1193. Xwhat to write. "
  1194. X    exit 1
  1195. Xfi
  1196. X
  1197. X# These copies are made so that 'wr.tape.sh' may be resumed after
  1198. X# preparing another tape.
  1199. Xcp $CONFILE bk.contents
  1200. Xcp $CPNTRS bk.pntrs
  1201. X
  1202. X# Get params
  1203. Xname=`sed -n 's/Name of work tape:\    //p' $PARAMS`
  1204. Xpoffset=`sed -n 's/Blocks of offset:\    //p' $PARAMS`
  1205. Xtdate=`sed -n 's/Date last taped:\    //p' $PARAMS`
  1206. Xblks=`sed -n 's/Blocks available:\    //p' $PARAMS`
  1207. Xpchap=`sed -n 's/Next chapter number:\    //p' $PARAMS`
  1208. X
  1209. Xpau=0
  1210. Xwhile [ $pau = 0 ]
  1211. Xdo
  1212. X    Tgetname -t
  1213. X    ret=$?
  1214. X    if [ $ret != 0 ]
  1215. X    then
  1216. X        echo "Please insert a tape. Q)uit or <cr> to continue. \c"
  1217. X        read -r ch
  1218. X        if [ "$ch" = "q" -o "$ch" = "Q" ]
  1219. X        then
  1220. X            exit 1
  1221. X        fi
  1222. X    else
  1223. X# From here on, the tape drive is locked, any 'exit' must perform
  1224. X# 'Tgetname -l' to unlock the drive before leaving.
  1225. X        Tgetname -v > /dev/null
  1226. X        ret=$?
  1227. X        set `Tgetname -r | tr -d "'"`
  1228. X        tname=$1
  1229. X        toffset=$2
  1230. X        if [ $ret = 30 ]
  1231. X        then
  1232. X            Tgetname -l
  1233. X            echo "\n\tThis tape has the \"SAFE\" key set.
  1234. X\tPlease exchange it for a tape we can write onto.
  1235. X\t    <cr> to continue. Q)uit."
  1236. X            read -r ch
  1237. X            if [ "$ch" = "q" -o "$ch" = "Q" ]
  1238. X            then
  1239. X                exit 1
  1240. X            fi
  1241. X        elif
  1242. X# 'read.vtoc -w9' will write all used chapters to standard out in column
  1243. X# format.  'read.vtoc -c' puts the next chapter number and the next offset
  1244. X# on standard output.  A return of '10' indicates that the tape is full.
  1245. X
  1246. Xecho `date +%T`" The contents of tape \""$tname"\" are:"
  1247. X            $SRCDIR/read.vtoc -w9
  1248. X            set `$SRCDIR/read.vtoc -c`
  1249. X            chap=$1
  1250. X            offset=$2
  1251. X            [ $chap -gt 9 ]
  1252. X        then
  1253. X            Tgetname -l
  1254. Xecho "\tWhoops!  This tape has all the chapters filled.  Shall we q)uit
  1255. X\tnow so that you restart another day or w)ait for another tape to cycle?
  1256. X\tEnter \"q\" or \"w\" to wait. \c"
  1257. X            read ch
  1258. X            if [ "$ch" = "q" -o "$ch" = "Q" ]
  1259. X            then
  1260. X                exit 1
  1261. X            fi
  1262. X        else
  1263. X            if [ "$poffset" -ne "$offset" -o "$pchap" -ne "$chap" ]
  1264. X            then
  1265. X                echo \
  1266. X    "\tThere is a descrepancy about which chapter should be written
  1267. X    next.  The parameters file says chapter $pchap at offset $poffset
  1268. X    while the tape says chapter $chap should be at $offset blocks.
  1269. X    Enter your choice for the chapter number. \c"
  1270. X                read ichap
  1271. X                if [ "$ichap" = "$pchap" ]
  1272. X                then
  1273. X                    chap=$pchap
  1274. X                    offset=$poffset
  1275. X                fi
  1276. X                echo \
  1277. X"Enter a value for the offset if $offset is unsatisfactory.
  1278. X        <cr> for OK. \c"
  1279. X                read ch
  1280. X                if [ "$ch" != "" ]
  1281. X                then
  1282. X                    offset=$ch
  1283. X                fi
  1284. X            fi
  1285. X            if [ "$tname" != "$name" ]
  1286. X            then
  1287. X                echo \
  1288. X"\tYou may have inserted the wrong tape.
  1289. X\tThis tape name is \""$tname"\" and I was expecting \""$name"\".
  1290. X\tThere are "$toffset" blocks of data already on this tape.
  1291. X\tOkay to write to this tape? <y/n> \c"
  1292. X                read -r ch
  1293. X                if [ "$ch" = "y" -o "$ch" = "Y" ]
  1294. X                then
  1295. Xecho "Shall we change the name to \""$name"\" or leave it \""$tname"\"?
  1296. XEnter 'k' to keep it as \""$tname"\", <cr> to continue. \c"
  1297. X                    read ch
  1298. X                    if
  1299. X                    [ "$ch" = "k" -o "$ch" = "K" ]
  1300. X                    then
  1301. X                        name=$tname
  1302. X                    fi
  1303. X                fi
  1304. X            fi
  1305. X        pau=1
  1306. X        fi
  1307. X    fi
  1308. X    if [ "$ch" = "w" -o "$ch" = "W" -o "$ch" = "n" -o "$ch" = "N" ]
  1309. X    then
  1310. Xecho "\tWaiting for another tape to be inserted.
  1311. X\t<cr> to continue. Q)uit \c"
  1312. X        read -r ch
  1313. X        if [ "$ch" = "q" -o "$ch" = "Q" ]
  1314. X        then
  1315. X            Tgetname -l
  1316. X            exit 1
  1317. X        fi
  1318. X        ret=1
  1319. X    fi
  1320. Xdone
  1321. X
  1322. X# Whew, don't ask me how we got through all those queries but I think
  1323. X# that there is one path through there that doesn't have a stop.
  1324. X
  1325. Xecho `date +%T`" Preparing file lists. "
  1326. Xscalped=0
  1327. X
  1328. Xcd $SAVDIR
  1329. Xwhile
  1330. X    rm -f contents
  1331. X    ln $CONFILE contents
  1332. X    echo "contents" > $WRKDIR/BUfiles
  1333. X    while
  1334. X        read pntr
  1335. X    do
  1336. X        echo "$pntr.Z" >> $WRKDIR/BUfiles
  1337. X    done < $CPNTRS
  1338. X    TmakessList $offset <$WRKDIR/BUfiles > ss.filelist
  1339. X    numtps=$?
  1340. X    [ $numtps -gt 1 ]
  1341. Xdo
  1342. X# This trims down the entries in the 'savdir' until it will fit on
  1343. X# the end of the tape.  The CPNTRS file will also be trimmed.  Later
  1344. X# we will remove the entries in ARCDIR which are still in CPNTRS.
  1345. X# The rest of ARCDIR will be relabelled for the next tape.
  1346. X    > $TMP2
  1347. X    if [ $scalped -eq 0 ]
  1348. X    then
  1349. X        echo \
  1350. X"\tStandby! The file list is being trimmed to fit the tape!!
  1351. X\tThere will be some messages issued stating:
  1352. X\t\t'insert next floppy tape'.
  1353. X\tIgnore those messages and respond with a <cr>."
  1354. X        scalped=1
  1355. X    fi
  1356. X    last=`sed -n '$ !w '"$TMP2"'
  1357. X            $ p' < $CPNTRS`
  1358. X    sed '$ d' < $CONFILE > $TMP1
  1359. X    mv $TMP1 $CONFILE
  1360. X    mv $TMP2 $CPNTRS
  1361. Xdone
  1362. X
  1363. Xif [ $chap -eq 9 -a $scalped -eq 0 ]
  1364. Xthen
  1365. X    echo \
  1366. X"\tThis is the last chapter available on this tape and space is going
  1367. X\tto be left over.  Do you want to abort now and rerun this after you
  1368. X\thave collected more files? <y> to abort, <n> to continue. \c"
  1369. X    read ch
  1370. X    if [ "$ch" = "y" -o "$ch" = "Y" ]
  1371. X    then
  1372. X        Tgetname -l
  1373. X        cleanup
  1374. X        exit 1
  1375. X    fi
  1376. Xfi
  1377. X
  1378. Xecho `date +%T`\
  1379. X" Writing chapter $chap to tape '$name' starting at block $offset."
  1380. Xecho "ss.filelist" > /tmp/BUlist$$
  1381. Xcat /tmp/BUlist$$ $WRKDIR/BUfiles | tapecpio -ocvT124 2>/tmp/size$$ | \
  1382. X       dbuf -oT124O$offset > /dev/rft3
  1383. Xret=$?
  1384. Xif [ "$ret" != "0" ]
  1385. Xthen
  1386. X    if [ $ret = 4 ]
  1387. X    then
  1388. X        echo "This tape operation has been aborted."
  1389. X        Tgetname -l
  1390. X        exit 1
  1391. X    else
  1392. X        echo "\
  1393. X\tAn error has occurred while trying to create this backup-set.
  1394. X\tCheck that a formatted tape has been properly inserted and has
  1395. X\tfinished rewinding.  Enter <q> to quit. \c"
  1396. X        read ch
  1397. X        Tgetname -l
  1398. X        exit 1
  1399. X    fi
  1400. Xfi
  1401. X
  1402. Xeval set `grep "blocks" /tmp/size$$`
  1403. XNBLOCKS=$1
  1404. X
  1405. Xset `wc -l ss.filelist`
  1406. XNFILES=$1
  1407. X
  1408. Xecho `date +%T`" Performing verify pass."
  1409. X
  1410. Xdbuf -iT124O$offset"S"$NBLOCKS /dev/rft3 | cat > /dev/null
  1411. Xret=$?
  1412. X
  1413. Xif [ "$ret" != "0" ]
  1414. Xthen
  1415. X    echo "\
  1416. X\tAn error has been discovered while trying to verify this tape.
  1417. X\tYou should use copy the existing data on this tape to another
  1418. X\ttape using '/news/.tape.ops/start/copy.sh'.  Read the comments
  1419. X\tat the beginning of that program before proceeding."
  1420. X    read
  1421. X    Tgetname -l
  1422. X    exit 1
  1423. Xfi
  1424. X
  1425. Xif [ "$COPY" != "0" ]
  1426. Xthen
  1427. X    SSNAME="Copy"
  1428. Xelse
  1429. X    case $chap in
  1430. X        1) SSNAME="This";;
  1431. X        2) SSNAME="need";;
  1432. X        3) SSNAME="for";;
  1433. X        4) SSNAME=" a ";;
  1434. X        5) SSNAME="name";;
  1435. X        6) SSNAME=" is ";;
  1436. X        7) SSNAME="very";;
  1437. X        8) SSNAME="silly";;
  1438. X        9) SSNAME="stuff";;
  1439. X    esac
  1440. Xfi
  1441. XSSCMNT=`date '+%a, %h. %d 19%y %H:%M'`
  1442. XTgetname -w "Backup by Names" "$name" "$SSNAME" "$SSCMNT" \
  1443. X        $offset $NBLOCKS $NFILES
  1444. X#            "$BTYPE"       "$TPNAME" "$SSNAME" "$SSCMNT"
  1445. X#               $OFFSET $NBLOCKS $NFILES
  1446. Xret=$?
  1447. Xif [ "$ret" != "0" ]
  1448. Xthen
  1449. X    echo "\tAn error has occurred while trying to update the data block.
  1450. X\tError number = "$ret
  1451. X    Tgetname -l
  1452. X    exit 1
  1453. Xfi
  1454. X
  1455. Xcd $WRKDIR
  1456. X
  1457. XTgetname -v
  1458. XTgetname -l
  1459. Xecho `date +%T`" Verification complete.  The new contents are:"
  1460. X$SRCDIR/read.vtoc -w9
  1461. Xchap=$?
  1462. X
  1463. Xif [ $chap -gt 9 -o $scalped -ne 0 ]
  1464. Xthen
  1465. Xecho "\tThis tape should be marked FULL and a new tape used next time."
  1466. X    offset=0
  1467. X    name=`echo $name | awk - '{ FS = "-"
  1468. X        printf("%s-%03d", $1, ++$2 ) }' -`
  1469. X    blks=$MAXOFFSET
  1470. X    chap=1
  1471. Xelse
  1472. X    Tgetname -v
  1473. X    set `$SRCDIR/read.vtoc -c$chap`
  1474. X    chap=$1
  1475. X    offset=$2
  1476. X    (( blks = $MAXOFFSET - offset ))
  1477. Xfi
  1478. Xtoday=`date '+%y-%m-%d'`
  1479. X
  1480. X> $TMP1
  1481. Xchgrp news $TMP1
  1482. Xchown netnews $TMP1
  1483. Xecho `date +%T`" Purging directories and support files."
  1484. X
  1485. Xif [ $COPY -eq 0 ]
  1486. Xthen
  1487. X    while
  1488. X        read pntr
  1489. X    do
  1490. X        rm -f $ARCDIR/$pntr
  1491. X    done <$CPNTRS
  1492. X
  1493. X    fnum=1
  1494. X    ls -1 $ARCDIR > $PNTRS
  1495. X    while
  1496. X        read pntr
  1497. X    do
  1498. X        if [ ! -f $ARCDIR/$fnum ]
  1499. X        then
  1500. X            mv $ARCDIR/$pntr $ARCDIR/$fnum
  1501. X            (( fnum = fnum + 1 ))
  1502. X        fi
  1503. X    done < $PNTRS
  1504. X
  1505. X    factor=`sed -n 's/Compression factor:\    //p' $PARAMS`
  1506. X    nbytes=`sed -n 's/Number of bytes held:\    //p' $PARAMS`
  1507. X    xbytes=`echo $nbytes | tr -d ","`
  1508. X
  1509. X    if [ $chap -gt 1 ]
  1510. X    then
  1511. X        (( factor = (( xbytes/NBLOCKS ) + factor)/2 ))
  1512. X    fi
  1513. Xfi
  1514. X
  1515. Xawk -F"    " - '{ if ( $0 ~ /Next fnum to link:/ ) $2 = "'"$fnum"'"
  1516. X        if ( $0 ~ /Number of bytes held:/ ) $2 = 0
  1517. X        if ( $0 ~ /Name of work tape:/ ) $2 = "'"$name"'"
  1518. X        if ( $0 ~ /Blocks of offset:/ ) $2 = "'"$offset"'"
  1519. X        if ( $0 ~ /Date last taped:/ ) $2 = "'"$today"'"
  1520. X        if ( $0 ~ /Blocks available:/ ) $2 = "'"$blks"'"
  1521. X        if ( $0 ~ /Next chapter number:/ ) $2 = "'"$chap"'"
  1522. X        if ( $0 ~ /Compression factor:/ ) $2 = "'"$factor"'"
  1523. X        print $1"    "$2 >> "'$TMP1'"
  1524. X        }' $PARAMS
  1525. Xmv $TMP1 $PARAMS
  1526. X
  1527. Xcleanup
  1528. X
  1529. Xecho `date +%T`" Taping finished."
  1530. Xexit 0
  1531. END_OF_wr.tape.sh
  1532. if test 9244 -ne `wc -c <wr.tape.sh`; then
  1533.     echo shar: \"wr.tape.sh\" unpacked with wrong size!
  1534. fi
  1535. chmod +x wr.tape.sh
  1536. # end of overwriting check
  1537. fi
  1538. echo shar: End of archive 1 \(of 4\).
  1539. cp /dev/null ark1isdone
  1540. MISSING=""
  1541. for I in 1 2 3 4 ; do
  1542.     if test ! -f ark${I}isdone ; then
  1543.     MISSING="${MISSING} ${I}"
  1544.     fi
  1545. done
  1546. if test "${MISSING}" = "" ; then
  1547.     echo You have unpacked all 4 archives.
  1548.     rm -f ark[1-9]isdone
  1549. else
  1550.     echo You still need to unpack the following archives:
  1551.     echo "        " ${MISSING}
  1552. fi
  1553. ##  End of shell archive.
  1554. exit 0
  1555.  
  1556.  
  1557. Vernon C. Hoxie                                {ncar,csn}!scicom!zebra!vern
  1558. 3975 W. 29th Ave.                                   vern@zebra.alphacdc.COM
  1559. Denver, Colo., 80212          voice: 303-477-1780        uucp: 303-455-2670
  1560.  
  1561. -- 
  1562. David H. Brierley
  1563. Home: dave@galaxia.network23.com; Work: dhb@quahog.ssd.ray.com
  1564. Send comp.sources.3b1 submissions to comp-sources-3b1@galaxia.network23.com
  1565. %% Pardon me Professor, can I be excused, my brain is full. **
  1566.