~ TCOPY.BCK[ TCOPY.BCK)BACK/GROUP=0 [-.TCOPY]*.* []TCOPY.BCK/SAV SYSTEM DGbV5.3 _RTODTO::  _$1$DUA7: V5.3 ~ *[SRC.TCOPY]TCOPY.C;1+,1B.$/ 4N$#-0B0123KPWO$56nYs7@8qiϧ9 ]GHJF/*' * TCOPY.C - copy tape to tape or disk.6 * Copyright (C) Nick Brown 1990. All rights reserved. */ #include fab #include rab #include nam#include dvidef#include devdef#include dcdef#include climsgdef#include ssdef#include iodef#include descriptypedef struct { unsigned short status; unsigned short count; int devinfo;} IOSB;typedef struct { short buflen; short code; int bufaddr; int retlen; } ITEMLIST;/*A * The next declaration allows us to access external VMS symbols. */typedef int EXTERNAL ();/*- * Possible responses to confirmation prompt. */#define OK_NO 0#define OK_YES 1#define OK_ALL 2#define OK_QUIT 3/*4 * Structure to represent an open tape or disk file.I * Some fields are only used for disk or tape, and we don't overlay them, * but what the hell. */typedef struct { int tape; short chan; struct RAB *rabptr; struct NAM *namptr;} DT;/*A * Variables that match CLI parameters, and so have to be global.< * These are recognisable by their capitalised first letter. */static int Log;static int Check;static int Debug;static int Confirm;/*N * Variable to keep track of multiple EOF writes, to ensure EOT is written OK. */static int last_wrote_eof;/*( * Limits on the program's buffer space. */#define MAXBUF 65535'#define STREAM_BUFFER (200000 + MAXBUF)#define MAXREC 256#define READ 0#define WRITE 1/*! * EOF record character in files. */#define EOFCHAR '*'(#define FILETYPE 0x4E425443 /* 'NBTC' */#define VERSION 1/* * Here beginneth the code... */main (argc, argv) int argc; char *argv [];{ char value [255]; char infile [255]; char outfile [255]; typedef struct { int filetype; int version; } HEADER;6 static HEADER master_header = { FILETYPE, VERSION }; HEADER read_header; int count; DT input; DT output;/*# * Get the command line parameters. */) if (my_present("P1") == CLI$_PRESENT) {4 if (my_get_value("P1", infile) == CLI$_ABSENT) {) panic("get_args: problem with P1"); } } else {' panic("get_args: no parameter P1"); }) if (my_present("P2") == CLI$_PRESENT) {5 if (my_get_value("P2", outfile) == CLI$_ABSENT) {) panic("get_args: problem with P2"); } } else {' panic("get_args: no parameter P2"); }, Log = (my_present("LOG") == CLI$_PRESENT);0 Check = (my_present("CHECK") == CLI$_PRESENT);0 Debug = (my_present("DEBUG") == CLI$_PRESENT);4 Confirm = (my_present("CONFIRM") == CLI$_PRESENT);" input.tape = check_tape(infile);$ output.tape = check_tape(outfile); if (input.tape) {# input.chan = open_tape(infile); } else {$ open_file(&input, infile, READ);: count = tc_read(&input, &read_header, sizeof(HEADER));% if ( (count != sizeof(HEADER)). || (read_header.filetype != FILETYPE) ) { EXTERNAL tcopy_badfile; lib$stop(tcopy_badfile, 2,A input.namptr->nam$b_rsl, input.namptr->nam$l_rsa); } } if (output.tape) {% output.chan = open_tape(outfile); } else {' open_file(&output, outfile, WRITE);6 tc_write(&output, &master_header, sizeof(HEADER)); } copy_tape(&input, &output);/*' * Output the log message, if required. */ if (Log) {! log_message(&input, &output); }}/*G * Output the log message with the input and output tape or file names. */log_message (input, output) DT *input; DT *output;{ static int len; static char dispnam [256]; char input_dispnam [256]; char output_dispnam [256]; int status; EXTERNAL tcopy_tapecopied; EXTERNAL tcopy_imagecopied; int signal; int input_size; char *input_ptr; int output_size; char *output_ptr; static ITEMLIST items [] = {9 sizeof(dispnam), DVI$_DISPLAY_DEVNAM, &dispnam, &len, 0, 0, 0, 0 }; if (input->tape) { signal = tcopy_tapecopied;? status = sys$getdviw(0, input->chan, 0, items, 0, 0, 0, 0); crash_if_bad(status);# strcpy(input_dispnam, dispnam); input_ptr = input_dispnam;' input_size = strlen(input_dispnam); } else { signal = tcopy_imagecopied;* input_size = input->namptr->nam$b_rsl;1 input_ptr = (char *)input->namptr->nam$l_rsa; } if (output->tape) {@ status = sys$getdviw(0, output->chan, 0, items, 0, 0, 0, 0); crash_if_bad(status);$ strcpy(output_dispnam, dispnam); output_ptr = output_dispnam;) output_size = strlen(output_dispnam); } else {, output_size = output->namptr->nam$b_rsl;3 output_ptr = (char *)output->namptr->nam$l_rsa; }H lib$signal(signal, 4, input_size, input_ptr, output_size, output_ptr);}/*B * Open a file for read or write, and fill in the DT block fields. */#open_file (dt, name, read_or_write) DT *dt; char *name; int read_or_write;{ char *expanded_name; char *resultant_name;) static char here [] = "SYS$DISK:[]*.*"; struct FAB *fabptr; struct RAB *rabptr; struct NAM *namptr; int i;& fabptr = malloc(sizeof(struct FAB));, for (i = 0; i < sizeof(struct FAB); i++) { ((char *)fabptr)[i] = 0; }& rabptr = malloc(sizeof(struct RAB));, for (i = 0; i < sizeof(struct RAB); i++) { ((char *)rabptr)[i] = 0; }& namptr = malloc(sizeof(struct NAM));, for (i = 0; i < sizeof(struct NAM); i++) { ((char *)namptr)[i] = 0; }' expanded_name = malloc(NAM$C_MAXRSS);( resultant_name = malloc(NAM$C_MAXRSS);/*& * Set up the FABs and related blocks. */ fabptr->fab$b_bid = FAB$C_BID; fabptr->fab$b_bln = FAB$C_BLN; fabptr->fab$b_rfm = FAB$C_VAR;F fabptr->fab$b_fac = (read_or_write == READ ? FAB$M_GET : FAB$M_PUT); fabptr->fab$l_fna = name; fabptr->fab$l_nam = namptr;0 fabptr->fab$b_fns = strlen(fabptr->fab$l_fna); fabptr->fab$l_dna = here;0 fabptr->fab$b_dns = strlen(fabptr->fab$l_dna); rabptr->rab$b_bid = RAB$C_BID; rabptr->rab$b_bln = RAB$C_BLN; rabptr->rab$l_fab = fabptr; namptr->nam$b_bid = NAM$C_BID; namptr->nam$b_bln = NAM$C_BLN;$ namptr->nam$l_esa = expanded_name;# namptr->nam$b_ess = NAM$C_MAXRSS;% namptr->nam$l_rsa = resultant_name;# namptr->nam$b_rss = NAM$C_MAXRSS; if (read_or_write == READ) { sys$open(fabptr, 0, 0);' if ((fabptr->fab$l_sts & 1) != 1) { EXTERNAL tcopy_openin; lib$stop(tcopy_openin, 2,4 namptr->nam$b_esl, namptr->nam$l_esa," fabptr->fab$l_sts); } } else { sys$create(fabptr, 0, 0);' if ((fabptr->fab$l_sts & 1) != 1) { EXTERNAL tcopy_openout; lib$stop(tcopy_openout, 2,4 namptr->nam$b_esl, namptr->nam$l_esa," fabptr->fab$l_sts); } } sys$connect(rabptr, 0, 0);% if ((rabptr->rab$l_sts & 1) != 1) { EXTERNAL tcopy_miscerr; lib$stop(tcopy_miscerr, 1, rabptr->rab$l_stv, rabptr->rab$l_sts); } dt->rabptr = rabptr; dt->namptr = namptr;}/*D * Check that a given string refers to either a tape or a disk file./ * If it's a tape, it must be mounted /FOREIGN. */check_tape (str) char *str;{ $DESCRIPTOR(descrip, ""); static int len; static int devtype; static int devchar; int status; int tape; static ITEMLIST items [] = {3 sizeof(devtype), DVI$_DEVCLASS, &devtype, &len,2 sizeof(devchar), DVI$_DEVCHAR, &devchar, &len, 0, 0, 0, 0 }; descrip.dsc$a_pointer = str;% descrip.dsc$w_length = strlen(str);/*( * Get the device class from the device./ * If it's a tape, it must be mounted /FOREIGN.7 * If it's not a valid device, assume it's a disk file. */: status = sys$getdviw(0, 0, &descrip, items, 0, 0, 0, 0); if (status == SS$_NORMAL) {! tape = (devtype == DC$_TAPE); if (tape) {' if ((devchar & DEV$M_FOR) == 0) {" EXTERNAL tcopy_notforeign;& lib$stop(tcopy_notforeign, 0); } } }" else if (status == SS$_IVDEVNAM) tape = 0;# else if (status == SS$_NOSUCHDEV) tape = 0; else { crash_if_bad(status); } return tape;}/*% * Assign a channel to a tape device. */open_tape (dev) char *dev;{ $DESCRIPTOR(tape, ""); int status; short chan; tape.dsc$a_pointer = dev;" tape.dsc$w_length = strlen(dev);* status = sys$assign(&tape, &chan, 0, 0); crash_if_bad(status); return chan;}/*% * Routine to actually copy the tape. */copy_tape (input, output) DT *input; DT *output;{' char buffer [STREAM_BUFFER + MAXBUF];& char *eob = &buffer[sizeof(buffer)]; char *bp; int offsets [MAXREC + 1]; int index; int records_in_file; int write_this_file; int files_read; int files_written; int i; int eof; int eot; int just_seen_eof; int count; int n_eofs;/*+ * Rewind both tapes to the start position. */ tc_rewind(input); tc_rewind(output);/*+ * This loop reads a buffer full of blocks. * Repeat until we see an EOT: * (two consecutive EOF marks on tape, or EOF on disk)... */ eot = 0; just_seen_eof = 0; last_wrote_eof = 0; records_in_file = 0; write_this_file = 1; files_read = 0; files_written = 0; while (!eot) { bp = buffer; offsets[index = 0] = 0; eof = 0;/*C * Read up to STREAM_BUFFER bytes, or MAXREC records, or until EOF. */A while ((!eof) && ((eob - bp) > MAXBUF) && (index < MAXREC)) {) count = tc_read(input, bp, MAXBUF); if (count < 0) { eof = 1; if (Log) {D printf("End of file after %d records\n", records_in_file); }/*H * If we are still at the beginning of the tape, ignore any empty files.I * We do this by cancelling EOF here, so the file read count will not get, * incremented, and no EOF will be written. */: if ((files_read == 0) && (records_in_file == 0)) { eof = 0; } records_in_file = 0; if (just_seen_eof) { eot = 1; } else { just_seen_eof = 1; if (eof) { ++files_read; } } } else {/*8 * Possibly echo (part of) the first record of the file. */# if (records_in_file == 0) {# if ((Log) || (Confirm)) { echo_n (bp, count); } if (Confirm) {" int ok = ok_to_copy(); if (ok == OK_NO) {" write_this_file = 0; }$ else if (ok == OK_YES) {" write_this_file = 1; }$ else if (ok == OK_ALL) {" write_this_file = 1; Confirm = 0; }% else if (ok == OK_QUIT) {" write_this_file = 0; eof = 1; eot = 1; } else {6 panic("Strange result from ok_to_copy"); } } } eof = 0; just_seen_eof = 0; bp = bp + count; ++records_in_file;' offsets[++index] = bp - buffer; } } if (write_this_file) {# for (i = 0; i < index; i++) {, char *address = &buffer[offsets[i]];* count = offsets[i+1] - offsets[i];) tc_write(output, address, count); } if (eof) { tc_write_eof(output); ++files_written; } } }/*@ * N_EOFS ensures that the tape ends with exactly two EOF marks. */ n_eofs = 2 - last_wrote_eof; for (i = 0; i < n_eofs; i++) { tc_write_eof(output); }}/*/ * Read a tape record from a tape or disk file. */tc_read (dt, buffer, bufsize) DT *dt; char *buffer; int bufsize;{ int status; int count; int operation; IOSB iosb; if (dt->tape) { operation = IO$_READVBLK; if (Check) {" operation |= IO$M_DATACHECK; }: status = sys$qiow(0, dt->chan, operation, &iosb, 0, 0,3 buffer, bufsize, 0, 0, 0, 0); if (Debug) {F printf("read %d bytes, status=0x%x\n", iosb.count, iosb.status); } crash_if_bad(status);' if (iosb.status == SS$_ENDOFFILE) { count = -1; } else { crash_if_bad(iosb.status); count = iosb.count; } } else {# dt->rabptr->rab$l_ubf = buffer;# dt->rabptr->rab$w_usz = MAXBUF;' status = sys$get(dt->rabptr, 0, 0); crash_if_bad(status);" count = dt->rabptr->rab$w_rsz; if (count == 1) { if (*buffer != EOFCHAR) {3 panic("Strange record in tape image file"); } else { count = -1; } } } return count;}/*. * Write a tape record to a tape or disk file. */tc_write (dt, buffer, count) DT *dt; char *buffer; int count;{ int status; IOSB iosb; int operation; if (dt->tape) { operation = IO$_WRITEVBLK; if (Check) {" operation |= IO$M_DATACHECK; }: status = sys$qiow(0, dt->chan, operation, &iosb, 0, 0,1 buffer, count, 0, 0, 0, 0); if (Debug) {D printf("written %d bytes, status=0x%x\n", count, iosb.status); } crash_if_bad(status); crash_if_bad(iosb.status); } else {# dt->rabptr->rab$l_rbf = buffer;" dt->rabptr->rab$w_rsz = count;' status = sys$put(dt->rabptr, 0, 0); crash_if_bad(status); } last_wrote_eof = 0;}/* * Rewind a tape. */tc_rewind (dt) DT *dt;{ int status; IOSB iosb; if (dt->tape) {; status = sys$qiow(0, dt->chan, IO$_REWIND, &iosb, 0, 0,( 0, 0, 0, 0, 0, 0); if (Debug) {6 printf("rewinding, status=0x%x\n", iosb.status); } crash_if_bad(status); crash_if_bad(iosb.status); }}/*, * Write an EOF mark to a tape or disk file.H * In the case of the disk file, we cheat, using the knowledge that realE * tape records are never less than 14 blocks long. So we can use a; * one-byte record containing an EOFCHAR to represent EOF. */tc_write_eof (dt) DT *dt;{ int status; IOSB iosb;) static char eofstring [] = { EOFCHAR }; if (dt->tape) {< status = sys$qiow(0, dt->chan, IO$_WRITEOF, &iosb, 0, 0,( 0, 0, 0, 0, 0, 0); if (Debug) {8 printf("written EOF, status=0x%x\n", iosb.status); } crash_if_bad(status); crash_if_bad(iosb.status); } else { tc_write(dt, eofstring, 1); } last_wrote_eof = 1;}/*C * Function to call cli$get_value with valid descriptor parameters. */staticmy_get_value (qualifier, value) char *qualifier; char *value;{! $DESCRIPTOR(qualifier_des, ""); $DESCRIPTOR(value_des, ""); int result; short retlen;* qualifier_des.dsc$a_pointer = qualifier;1 qualifier_des.dsc$w_length = strlen(qualifier);" value_des.dsc$a_pointer = value; value_des.dsc$w_length = 255;> result = cli$get_value(&qualifier_des, &value_des, &retlen); if (result & 1) { value[retlen] = '\0'; } return result;}/*B * Function to call cli$present with a valid descriptor parameter. */staticmy_present (qualifier) char *qualifier;{! $DESCRIPTOR(qualifier_des, ""); int result;* qualifier_des.dsc$a_pointer = qualifier;1 qualifier_des.dsc$w_length = strlen(qualifier);' result = cli$present(&qualifier_des); return result;}/*7 * Routine to crash the program if anything goes wrong. */crash_if_bad (status) int status;{ if ((status & 1) == 0) { lib$stop(status, 0); }}/*H * Function to handle unexpected events (that indicate internal errors). */static panic (s) char *s;{ EXTERNAL tcopy_panic;) lib$stop(tcopy_panic, 2, strlen(s), s);}/*- * Function to get user confirmation of copy. */ ok_to_copy (){ char reply [255];* $DESCRIPTOR(reply_des, reply);3 $DESCRIPTOR(text_copy, "OK to copy this file: ");s int result; short replen; while (1) {c char *cp;u int error = 0;> result = lib$get_command(&reply_des, &text_copy, &replen); if ((result & 1) != 1) { lib$stop(result);i }o reply[replen] = '\0';c/ for (cp = reply; (*cp) && (!error); cp++) {t switch (*cp) { case 'N':n case 'n':e return OK_NO;* break; case 'Y':a case 'y':s return OK_YES; break; case 'A':n case 'a':  return OK_ALL; break; case 'Q':L case 'q':  return OK_QUIT;e break; case ' ':S case '\t': break; default: error = 1; break; }e }t } } /*& * Echo the first few bytes of a file. */techo_n (bp, count) char *bp; int count;{  char line [80];s int i;- for (i = 0; (i < 64) && (i < count); i++) {t char c = bp[i];t0 line[i] = ((c < 32) || (c > 126)) ? '.' : c; }t line[i] = '\0';t# printf("Record 1: '%s'\n", line); }kp track of multiple EOF writes, to ensure EOT is written OK. */static int last_wrote_eof;/*( * Limits on the program's buffer space. */#define MAXBUF 65535'#define STREAM_BUFFER (200000 + MAXBUF)#define MAXREC 256#define READ 0#define WRITE 1/*! * EOF record character in fil*[SRC.TCOPY]TCOPY.CLD;1+,2B./ 42-0B0123KPWO56 4s7*8`oj9 ]GHJDEFINE VERB TCOPY IMAGE "TCOPY" PARAMETER P11 PROMPT="Input tape or image file", VALUE (TYPE=$FILE, REQUIRED) PARAMETER P22 PROMPT="Output tape or image file", VALUE (TYPE=$FILE, REQUIRED) QUALIFIER LOG NEGATABLE QUALIFIER CHECK NEGATABLE QUALIFIER CONFIRM NEGATABLE QUALIFIER DEBUG NEGATABLE*[SRC.TCOPY]TCOPY.EXE;1+,3B./ 4-0B0123 KPWO56@5_s7l8 ;`9 ]GHJ"0DX0205(s TCOPYV1.0`s05-05   ? ! VAXCRTL_001! LIBRTL_001! MTHRTL_001P1P1get_args: problem with P1get_args: no parameter P1P2P2get_args: problem with P2get_args: no parameter P2LOGCHECKDEBUGCONFIRMEnd of file after %d records Strange result from ok_to_copyread %d bytes, status=0x%x Strange record in tape image filewritten %d bytes, status=0x%x rewinding, status=0x%x written EOF, status=0x%x OK to copy this file: Record 1: '%s' CTBN SYS$DISK:[]*.**|^;SjTct\ЮtݮtPP1ޣLDͺͼͽZ;[ЮL;ݮLPͺЮD?ͺPQP2P@DQPPPޣ΄΄ΈaPߟD(Pޣ ΀΀΄7PߟDVޣ:pͲʹ͵\ͶЮpͶݮpPͲͲP1ޣ=H@ͤͥ͢Zͦͪͬͭ[ͮЮHͦݮHP͢Ю@ͮͪ?ͪ͢PQP2P@@QPPIޣ@|ݮ|΀KPߟDj#ޣZxݮxݮ|&PߟDEޣtl͚͜͝\͞Юl͞ݮlP͚͚QPQQdޣxh͔͕͒\͖Юh͖ݮhP͒͒YQPQQޣ~d͍͊͌\͎Юd͎ݮdVP͊͊QPQQÄ`͂̈́ͅ\͆Ю`͆ݮ` P͂͂QPQQ \z|}Ì~Ю\~ݮ\Pz|~|~Tz|~PRR(PLPPUIPCߟ2RDU$PR UPRQQ QsUXrtuÌvЮXvݮXPr|~|~Tr|~PRR)PLPPVJPDߟ3PRDV$PR VPRQQ QV\TjlmÍnЮTnݮTaPj|~?jPPQP QkPPvP CTBNPݠ~ߟ"YPbdeÍfЮPfݮPPb|~?bPPQP Q!'dP^[TЬRbRޟ X|~|~ 2~PQP Q'ߤ WPVޟXТ QVСWЬRbM|~|~ 2~PQP Qߤ UsPSPТ QSСUUSWVXy^mXP~-PRQP`POQD~ PTQP`PCQ`~PSQP`P_Q~PV~PUbPլ WPWWЬ,S(ݢ,P480ݢ0~P5dDR<c`V  Uլ 5|~RˏPPNݢݣ ~ߟ*O3|~RˏPPݢݣ ~ߟ2|~TˏPPݤݤ ߟ:ЬPTS <^IRSŒЬݬyP|~|~T|~PTT)PLPPUJPDߟd3PTDU$PT UPTQQ Q/UPP^RЬݬP|~?PPQP Q2P^9YWPЬRbZ|~|~|~|~$2~ PSէ<~(8S Sf ^ݬݬPߟD  ^S]R?ˏP\\ P2\LQaRa\\ 11\ 11\A1\PPA8||f?PPPPPPRQa1R1)1P^,TRլ1ЬSBcQQ Q~.PQPPBRR@RӔB߭t-<`^,n䐏PC7ݬ!^| VX^,n䐏Qݬf^PRݬl$լ ݬf  RP|VD^,nȐSȞw؞kܕlլݬfЬ̑lլ  lլ,n䞭l լ Ь l լЬlլ ݬf^<`^,n䐏Tl լЬ^<`^,n䐏Uݬj^e(pH{p (80d8@, TAPECOPIEDtape !AD copied to !AD2 IMAGECOPIEDtape image !AD copied to !AD6 NOTFOREIGN tape(s) must be mounted /FOREIGN4BADFILE"file !AD is not a TCOPY tape image,OPENINerror opening !AD as input.OPENOUTerror opening !AD as output2MISCERRmiscellaneous error - STV = !XL&PANICpanic - text is "!AD"TCOPY@@ `HP @VAXCRTLLIBRTLMTHRTL*[SRC.TCOPY]TCOPY.HLP;1+,i. / 4L -0B0123KPWO56`L}Gb7@uGb89GHJ 1 TCOPY A program to copy tapes.D TCOPY allows direct tape-to-tape copies, on systems with more thanD one tape drive, or copying of tapes via an intermediate disk file. Format:# $ TCOPY tape1 tape2 [/qualifiers]' $ TCOPY tape image-file [/qualifiers]' $ TCOPY image-file tape [/qualifiers]- $ TCOPY image-file image-file [/qualifiers]2 More_about_TCOPYC TCOPY allows you to make exact copies of VMS, Ultrix, diagnostic,H and other tapes, without the need for two tape drives. If you have two9 drives, you can use TCOPY without any extra disk space.L Naturally, TCOPY should not be used in violation of any software licensing agreements.E TCOPY requires no privileges to run (obviously, NETMBX is needed if3 an intermediate file is create on a remote node).@ If you have any questions, comments, or bugs to report, please contact: Nick Brown Council of Europe BP 431 R6 67006 Strasbourg FranceI Known problem: Some TK50s have trouble reading multiple BACKUP savesetsJ created by TCOPY. They seem to lose spacing information. Juggling with SET MAGTAPE sometimes helps. 2 ParametersInputC Either the tape to be copied, or the name of a file containing a  previously copied tape image.E If the input device is a tape, the volume must be mounted /FOREIGN.B TCOPY will not allow files which are not valid tape images to be copied to tape.OutputE Either the destination tape to be written, or the name of a file to) receive a tape image of the input tape.F If the output device is a tape, the volume must be mounted /FOREIGN. 2 Qualifiers/CHECK /CHECK /NOCHECK (default)E Specifies that all read and write I/O operations on tapes should beB modified with IO$M_CHECK; see the I/O User's Guide. This option< gives enhanced reliability, but causes serious performance/ degradation, particularly on streaming tapes./CONFIRM /CONFIRM /NOCONFIRM (default)C Specifies that the user be prompted for confirmation of each fileE copy. Possible responses are YES, NO, ALL, or QUIT. ALL causes allD subsequent copies to be done without confirmation; QUIT terminates4 TCOPY immediately (an EOT is written to the tape).I By selectively omitting files, the output tape image can effectively beH an edited version of the input. Be careful: one operating system file6 is typically represented by more than one tape file. /FILE_LOG /FILE_LOG /NOFILE_LOG (default)I This qualifier instructs TCOPY to echo the first 64 bytes of each file,H and to indicate after each file how many records were read. A successB message is also produced after the tape or image file is copied. 2 Examples 1. $ MOUNT /FOREIGN MUA0: $ MOUNT /FOREIGN MSA0: $ TCOPY MUA0: MSA0:/ Copies a tape from one drive to another. 2. $ MOUNT /FOREIGN MUA0: $ TCOPY MUA0: TEMP.TAPE $ DISMOUNT MUA0: $ MOUNT /FOREIGN MUXr~ TCOPY.BCKi0B[SRC.TCOPY]TCOPY.HLP;1L QA0: $ TCOPY TEMP.TAPE MUA0: $ DISMOUNT MUA0: $ DELETE TEMP.TAPE;*> This shows how to copy a tape with only one tape drive.*[SRC.TCOPY]TCOPY.OBJ;1+,5B./ 4n -0B0123KPWO56@s7@&8<`9 ]GHJ&2TCOPYV1.026-MAY-1990 08:44VAX C V3.0-031PCTBNPP1PP1Pget_args: problem with P1 Pget_args: no parameter P1:PP2=PP2@Pget_args: problem with P2ZPget_args: no parameter P2tPLOGxPCHECK~PDEBUGPCONFIRM P  8PSYS$DISK:[]*.*TPLHPHPEnd of file after %d records PStrange result from ok_to_copyPread %d bytes, status=0x%x PStrange record in tape image file Pwritten %d bytes, status=0x%x (Prewinding, status=0x%x xP*@Pwritten EOF, st CC$RMS_FAB CC$RMS_RAB CC$RMS_NAMECHO_N OK_TO_COPY CRASH_IF_BAD TC_WRITE_EOF TC_REWINDTC_WRITETC_READ COPY_TAPE OPEN_TAPE CHECK_TAPE OPEN_FILE LOG_MESSAGE LOG_MESSAGE COPY_TAPETC_WRITELIB$STOP TCOPY_BADFILETC_READ OPEN_FILE OPEN_TAPE CHECK_TAPE LIB$SIGNALSTRLENSTRCPY CRASH_IF_BAD SYS$GETDVIWTCOPY_IMAGECOPIEDTCOPY_TAPECOPIED TCOPY_MISCERR SYS$CONNECT TCOPY_OPENOUT SYS$CREATELIB$STOP TCOPY_OPENINSYS$OPENSTRLENMALLOC CRASH_IF_BADLIB$STOPTCOPY_NOTFOREIGN SYS$GETDVIWSTRLEN CRASH_IF_BAD SYS$ASSIGNSTRLEN TC_WRITE_EOFTC_WRITE OK_TO_COPYECHO_NPRINTFTC_READ TC_REWINDSYS$GET CRASH_IF_BADPRINTFSYS$QIOWSYS$PUT CRASH_IF_BADPRINTFSYS$QIOW CRASH_IF_BADPRINTFSYS$QIOWatus=0x%x ]POK to copy this file: tPRecord 1: '%s' P|^ C$MAIN_ARGSSTct\ЮtݮtSTRLENP CLI$PRESENTP1ޣLDͺͼͽZ;[ЮL;ݮLSTRLENPͺЮD?ͺ CLI$GET_VALUEPQP2P@DQPPPޣ΄΄ΈSTRLENP TCOPY_PANICLIB$STOP(Pޣ ΀΀΄STRLENP TCOPY_PANICLIB$STOPޣ:pͲʹ͵\ͶЮpͶݮpSTRLENPͲ CLI$PRESENTP1ޣ=H@ͤͥ͢Zͦͪͬͭ[ͮЮHͦݮHSTRLENP͢Ю@ͮͪ?ͪ͢ CLI$GET_VALUEPQP2P@@QPPIޣ@|ݮ|΀STRLENP TCOPY_PANICLIB$STOP#ޣZxݮxݮ|STRLENP TCOPY_PANICLIB$STOPޣtl͚͜͝\͞Юl͞ݮlSTRLENP͚͚ CLI$PRESENTQPQQdޣxh͔͕͒\͖Юh͖ݮhSTRLENP͒͒ CLI$PRESENTQPQQޣ~d͍͊͌\͎Юd͎ݮdSTRLENP͊͊ CLI$PRESENTQPQQÄ`͂̈́ͅ\͆Ю`͆ݮ`STRLENP͂͂ CLI$PRESENTQPQQ \z|}Ì~Ю\~ݮ\STRLENPz|~|~Tz|~ SYS$GETDVIWPRR(PLPPUIPCTCOPY_NOTFOREIGNLIB$STOP2RDU$PR UPRQQ QLIB$STOPUXrtuÌvЮXvݮXSTRLENPr|~|~Tr|~ SYS$GETDVIWPRR)PLPPVJPDTCOPY_NOTFOREIGNLIB$STOP3PRDV$PR VPRQQ QLIB$STOPV\TjlmÍnЮTnݮTSTRLENPj|~?j SYS$ASSIGNPQP QLIB$STOP鰭PP OPEN_FILETC_READP CTBNPݠ~ TCOPY_BADFILELIB$STOPYPbdeÍfЮPfݮPSTRLENPb|~?b SYS$ASSIGNPQP QLIB$STOP찭! OPEN_FILETC_WRITE COPY_TAPEd LOG_MESSAGEP^TЬRbRTCOPY_TAPECOPIEDX|~|~ 2~ SYS$GETDVIWPQP QLIB$STOPߤ STRCPYWSTRLENPVTCOPY_IMAGECOPIEDXТ QVСWЬRbM|~|~ 2~ SYS$GETDVIWPQP QLIB$STOPߤ STRCPYUSTRLENPSPТ QSСUUSWVX LIB$SIGNAL^XP~MALLOCPRQP`POQD~MALLOCPTQP`PCQ`~MALLOCPSQP`P_Q~MALLOCPV~MALLOCPUbPլ WPWWЬ,S(ݢ,STRLENP480ݢ0STRLENP5dDR<c`V  Uլ 5|~RSYS$OPENˏPPNݢݣ ~ TCOPY_OPENINLIB$STOP3|~R SYS$CREATEˏPPݢݣ ~ TCOPY_OPENOUTLIB$STOP|~T SYS$CONNECTˏPPݤݤ  TCOPY_MISCERRLIB$STOPЬPTS <^RSŒЬݬSTRLENP|~|~T|~ SYS$GETDVIWPTT)PLPPUJPDTCOPY_NOTFOREIGNLIB$STOP3PTDU$PT UPTQQ QLIB$STOPUPP^RЬݬSTRLENP|~? SYS$ASSIGNPQP QLIB$STOP2P^YWPЬRbZ|~|~|~|~$2~ SYS$QIOWPSէ<~(PRINTFS SLIB$STOP/FAO=24IMAGECOPIED /FAO=2.severity informational.severity error8NOTFOREIGN /FAO=0:BADFILE /FAO=12OPENIN /FAO=13OPENOUT /FAO=17MISCERR /FAO=1.severity fatal-PANIC /FAO=1.end*[SRC.TCOPY]TCOPYMSG.OBJ;1+,8B./ 4%-0B0123KPWO56`쫨q7@8`$=`9 ]GHJ2TCOPYMSG023-MAY-1990 14:3723-MAY-1990 14:37VAX-11 Message V04-00k$ABS$ MSG$SECTIONMSG$AAAAAAAAAAAMSG$AAAAAAAAAABMSG$AAAAAAAAAACD TCOPY_PANIC: TCOPY_MISCERR2 TCOPY_OPENOUT* TCOPY_OPENIN" TCOPY_BADFILETCOPY_NOTFOREIGNTCOPY_IMAGECOPIED TCOPY_TAPECOPIEDTCOPY$_FACILITY%PeP*P'P(pH{p (80d8@, TAPECOPIEDtape !AD copied to !AD2 IMAGECOPIEDtape image !AD copied to !AD6 NOTFOREIGN tape(s) must be mounted /FOREIGN4BADFILE"file !AD is not a TCOPY tape image,OPENINerror opening !AD as input.OPENOUTerror opening !AD as output2MISCERRmiscellaneous error - STV = !XL&PANICpanic - text is "!AD"TCOPYF