diff --git a/usr.sbin/ctm/ctm/Makefile b/usr.sbin/ctm/ctm/Makefile index 728d26e967dd..959c0a7e0a8d 100644 --- a/usr.sbin/ctm/ctm/Makefile +++ b/usr.sbin/ctm/ctm/Makefile @@ -1,7 +1,19 @@ +# +# ---------------------------------------------------------------------------- +# "THE BEER-WARE LICENSE" (Revision 42): +# wrote this file. As long as you retain this notice you +# can do whatever you want with this stuff. If we meet some day, and you think +# this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp +# ---------------------------------------------------------------------------- +# +# $Id$ +# -PROG= ctm_scan -NOTYET= ctm_ed.c -SRCS= ctm.c ctm_input.c ctm_pass1.c ctm_pass2.c ctm_pass3.c ctm_syntax.c -LDFLAGS+= -lmd -NOMAN= 1 +PROG= ctm +NOTYET= ctm_ed.c +SRCS= ctm.c ctm_input.c ctm_pass1.c ctm_pass2.c ctm_pass3.c \ + ctm_syntax.c ctm_ed.c +LDADD+= -lmd +NOMAN= 1 +CFLAGS+= -Wall .include diff --git a/usr.sbin/ctm/ctm/ctm.c b/usr.sbin/ctm/ctm/ctm.c index f9e6889c683e..27fcc02997a8 100644 --- a/usr.sbin/ctm/ctm/ctm.c +++ b/usr.sbin/ctm/ctm/ctm.c @@ -1,8 +1,7 @@ -/* $Id$ - * +/* * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): - * wrote this file. As long as you retain this notice you + * wrote this file. As long as you retain this notice you * can do whatever you want with this stuff. If we meet some day, and you think * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- @@ -19,6 +18,7 @@ * -B Backup to tar-file. * -c Check it out, "ma non troppo" * -d Debug TBD. + * -F Force * -m Email me instead. * -p Less paranoid. * -P Paranoid. @@ -28,13 +28,6 @@ * -T . Temporary files. * -v Tell about each file. * - * Exit-codes, bitmap, logical or of: - * 1 Couldn't do something we wanted to, not fatal. - * 2 Couldn't do something we wanted to, fatal. - * 4 Input file corrupt. - * 8 Cannot apply input file. - * 16 Corruption while applying input file. - * */ #define EXTERN /* */ @@ -46,7 +39,7 @@ int main(int argc, char **argv) { int stat=0; - int i,j,c; + int c; extern int optopt,optind; extern char * optarg; @@ -55,13 +48,14 @@ main(int argc, char **argv) setbuf(stderr,0); setbuf(stdout,0); - while((c=getopt(argc,argv,"ab:B:cd:m:pPqr:R:T:Vv")) != -1) { + while((c=getopt(argc,argv,"ab:B:cd:Fm:pPqr:R:T:Vv")) != -1) { switch (c) { - case 'p': Paranoid--; break; /* Less Paranoid */ - case 'P': Paranoid++; break; /* More Paranoid */ - case 'q': Verbose--; break; /* Quiet */ - case 'v': Verbose++; break; /* Verbose */ - case 'T': TmpDir = optarg; break; + case 'p': Paranoid--; break; /* Less Paranoid */ + case 'P': Paranoid++; break; /* More Paranoid */ + case 'q': Verbose--; break; /* Quiet */ + case 'v': Verbose++; break; /* Verbose */ + case 'T': TmpDir = optarg; break; + case 'F': Force = 1; break; case ':': fprintf(stderr,"Option '%c' requires an argument.\n",optopt); stat++; @@ -78,7 +72,7 @@ main(int argc, char **argv) if(stat) { fprintf(stderr,"%d errors during option processing\n",stat); - exit(1); + exit(2); } stat = 0; argc -= optind; @@ -87,7 +81,7 @@ main(int argc, char **argv) if(!argc) stat |= Proc("-"); - while(argc--) + while(argc-- && !stat) stat |= Proc(*argv++); return stat; @@ -125,14 +119,14 @@ Proc(char *filename) /* If we cannot seek, we're doomed, so copy to a tmp-file in that case */ if(!p && -1 == fseek(f,0,SEEK_END)) { - char *fn = tempnam(NULL,"CMTclient"); + char *fn = tempnam(TmpDir,"CMTclient"); FILE *f2 = fopen(fn,"w+"); int i; if(!f2) { perror(fn); fclose(f); - return 2; + return 4; } unlink(fn); fprintf(stderr,"Writing tmp-file \"%s\"\n",fn); @@ -144,28 +138,36 @@ Proc(char *filename) if(!p) rewind(f); + if((i=Pass1(f))) return i; + if(!p) { rewind(f); } else { pclose(f); f = popen(p,"r"); } + if((i=Pass2(f))) return i; + if(!p) { rewind(f); } else { pclose(f); f = popen(p,"r"); } + if((i=Pass3(f))) return i; + if(!p) { fclose(f); } else { pclose(f); + Free(p); } + return 0; } diff --git a/usr.sbin/ctm/ctm/ctm.h b/usr.sbin/ctm/ctm/ctm.h index d96d312b7a72..142569b38bc6 100644 --- a/usr.sbin/ctm/ctm/ctm.h +++ b/usr.sbin/ctm/ctm/ctm.h @@ -1,3 +1,14 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + * $Id$ + * + */ #include #include @@ -58,7 +69,6 @@ EXTERN u_char *Prefix; EXTERN u_char *FileName; EXTERN u_char *BaseDir; EXTERN u_char *TmpDir; -EXTERN int Verbose; /* * Paranoid -- Just in case they should be after us... @@ -74,15 +84,29 @@ EXTERN int Verbose; * 3 Show progress names, and actions. * 4 even more... * and so on + * + * ExitCode -- our Epitaph + * 0 Perfect, all input digested, no problems + * 1 Bad input, no point in retrying. + * 2 Pilot error, commandline problem &c + * 4 Out of resources. + * 8 Destination-tree not correct. + * 16 Destination-tree not correct, can force. + * 32 Internal problems. + * */ + EXTERN int Paranoid; +EXTERN int Verbose; +EXTERN int Exit; +EXTERN int Force; char * String(char *s); void Fatal_(int ln, char *fn, char *kind); #define Fatal(foo) Fatal_(__LINE__,__FILE__,foo) #define Assert() Fatal_(__LINE__,__FILE__,"Assert failed.") -#define WRONG {Assert(); return 1;} +#define WRONG {Assert(); return 32;} u_char * Ffield(FILE *fd, MD5_CTX *ctx,u_char term); @@ -90,12 +114,13 @@ int Fbytecnt(FILE *fd, MD5_CTX *ctx, u_char term); u_char * Fdata(FILE *fd, int u_chars, MD5_CTX *ctx); -#define GETFIELD(p,q) if(!((p)=Ffield(fd,&ctx,(q)))) return 1 -#define GETFIELDCOPY(p,q) if(!((p)=Ffield(fd,&ctx,(q)))) return 1; else p=String(p) -#define GETBYTECNT(p,q) if(0 >((p)= Fbytecnt(fd,&ctx,(q)))) return 1 -#define GETDATA(p,q) if(!((p) = Fdata(fd,(q),&ctx))) return 1 +#define GETFIELD(p,q) if(!((p)=Ffield(fd,&ctx,(q)))) return BADREAD +#define GETFIELDCOPY(p,q) if(!((p)=Ffield(fd,&ctx,(q)))) return BADREAD; else p=String(p) +#define GETBYTECNT(p,q) if(0 >((p)= Fbytecnt(fd,&ctx,(q)))) return BADREAD +#define GETDATA(p,q) if(!((p) = Fdata(fd,(q),&ctx))) return BADREAD int Pass1(FILE *fd); int Pass2(FILE *fd); int Pass3(FILE *fd); +int ctm_edit(u_char *script, int length, char *filein, char *fileout); diff --git a/usr.sbin/ctm/ctm/ctm_ed.c b/usr.sbin/ctm/ctm/ctm_ed.c index 691add29fa9b..fae5920e00b7 100644 --- a/usr.sbin/ctm/ctm/ctm_ed.c +++ b/usr.sbin/ctm/ctm/ctm_ed.c @@ -1,49 +1,62 @@ -int -ctm_edit(u_char *script, int length, char *filename, char *md5) -{ - u_char *ep, cmd, c; - int ln, ln2, iln; - FILE *fi,*fo; - char buf[BUFSIZ]; +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + * $Id$ + * + */ - fi = fopen(filename,"r"); - if(!fi) { - /* XXX */ - return 1; +#include "ctm.h" + +int +ctm_edit(u_char *script, int length, char *filein, char *fileout) +{ + u_char *ep, cmd; + int ln, ln2, iln, ret=0, c; + FILE *fi=0,*fo=0; + + fi = fopen(filein,"r"); + if(!fi) { + perror(filein); + return 8; } - strcpy(buf,filename); - strcat(buf,".ctm"); - fo = fopen(filename,"w"); + + fo = fopen(fileout,"w"); if(!fo) { - /* XXX */ - return 1; + perror(fileout); + fclose(fi); + return 4; } iln = 0; for(ep=script;ep < script+length;) { cmd = *ep++; - if(cmd != 'a' && cmd != 'd') ARGH + if(cmd != 'a' && cmd != 'd') { ret = 1; goto bye; } ln = 0; while(isdigit(*ep)) { ln *= 10; ln += (*ep++ - '0'); } - if(*ep++ != ' ') BARF + if(*ep++ != ' ') { ret = 1; goto bye; } ln2 = 0; while(isdigit(*ep)) { ln2 *= 10; ln2 += (*ep++ - '0'); } - if(*ep++ != '\n') BARF + if(*ep++ != '\n') { ret = 1; goto bye; } while(iln < ln) { - c = getf(fi); + c = getc(fi); putc(c,fo); - if(c == '/n') + if(c == '\n') iln++; } if(cmd == 'd') { while(ln2) { - c = getf(fi); - if(c != '/n') + c = getc(fi); + if(c != '\n') continue; iln++; ln2--; @@ -54,27 +67,26 @@ ctm_edit(u_char *script, int length, char *filename, char *md5) while(ln2) { c = *ep++; putc(c,fo); - if(c != '/n') + if(c != '\n') continue; ln2--; } continue; } - ARGH + ret = 1; + goto bye; } while(1) { - c = getf(fi); + c = getc(fi); if(c == EOF) break; putc(c,fo); } fclose(fi); fclose(fo); - if(strcmp(md5,MD5File(buf))) { - unlink(buf); - return 1; /*XXX*/ - } - if(rename(buf,filename)) { - unlink(buf); - return 1; /*XXX*/ - } + return 0; +bye: + if(fi) fclose(fi); + if(fo) fclose(fo); + return ret; } + diff --git a/usr.sbin/ctm/ctm/ctm_input.c b/usr.sbin/ctm/ctm/ctm_input.c index 2f6265f68abd..88a0fd6d782a 100644 --- a/usr.sbin/ctm/ctm/ctm_input.c +++ b/usr.sbin/ctm/ctm/ctm_input.c @@ -1,3 +1,15 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + * $Id$ + * + */ + #include "ctm.h" /*---------------------------------------------------------------------------*/ diff --git a/usr.sbin/ctm/ctm/ctm_pass1.c b/usr.sbin/ctm/ctm/ctm_pass1.c index b9314df65d23..832922ee6d24 100644 --- a/usr.sbin/ctm/ctm/ctm_pass1.c +++ b/usr.sbin/ctm/ctm/ctm_pass1.c @@ -1,4 +1,17 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + * $Id$ + * + */ + #include "ctm.h" +#define BADREAD 1 /*---------------------------------------------------------------------------*/ /* Pass1 -- Validate the incomming CTM-file. @@ -120,8 +133,10 @@ Pass1(FILE *fd) return 1; } if (-1 != getc(fd)) { - Fatal("Trailing junk in CTM-file."); - return 1; + if(!Force) { + Fatal("Trailing junk in CTM-file. Can Force with -F."); + return 16; + } } return 0; } diff --git a/usr.sbin/ctm/ctm/ctm_pass2.c b/usr.sbin/ctm/ctm/ctm_pass2.c index afbf7ca921f7..e85baffc10ce 100644 --- a/usr.sbin/ctm/ctm/ctm_pass2.c +++ b/usr.sbin/ctm/ctm/ctm_pass2.c @@ -1,4 +1,17 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + * $Id$ + * + */ + #include "ctm.h" +#define BADREAD 32 /*---------------------------------------------------------------------------*/ /* Pass2 -- Validate the incomming CTM-file. @@ -7,12 +20,13 @@ int Pass2(FILE *fd) { - u_char *p,*q; + u_char *p,*q,*md5=0; MD5_CTX ctx; int i,j,sep,cnt; u_char *trash=0,*name=0; struct CTM_Syntax *sp; struct stat st; + int ret = 0; if(Verbose>3) printf("Pass2 -- Checking if CTM-patch will apply\n"); @@ -31,6 +45,7 @@ Pass2(FILE *fd) for(;;) { if(trash) {Free(trash), trash = 0;} if(name) {Free(name), name = 0;} + if(md5) {Free(md5), md5 = 0;} cnt = -1; GETFIELD(p,' '); @@ -58,27 +73,34 @@ Pass2(FILE *fd) if(j & CTM_Q_Name_New) { /* XXX Check DR FR rec's for item */ if(-1 != stat(name,&st)) { - fprintf(stderr," %s: %s exists.\n",sp->Key,name); + fprintf(stderr," %s: %s exists.\n", + sp->Key,name); + ret |= 8; } break; } if(-1 == stat(name,&st)) { fprintf(stderr," %s: %s doesn't exists.\n", sp->Key,name); + ret |= 8; break; } if (j & CTM_Q_Name_Dir) { - if((st.st_mode & S_IFMT) != S_IFDIR) + if((st.st_mode & S_IFMT) != S_IFDIR) { fprintf(stderr, " %s: %s exist, but isn't dir.\n", sp->Key,name); + ret |= 8; + } break; } if (j & CTM_Q_Name_File) { - if((st.st_mode & S_IFMT) != S_IFREG) + if((st.st_mode & S_IFMT) != S_IFREG) { fprintf(stderr, " %s: %s exist, but isn't file.\n", sp->Key,name); + ret |= 8; + } break; } break; @@ -89,12 +111,23 @@ Pass2(FILE *fd) break; case CTM_F_MD5: if(!name) WRONG - GETFIELD(p,sep); - if((st.st_mode & S_IFMT) == S_IFREG) { - if(j & CTM_Q_MD5_Before && strcmp(MD5File(name),p)) { - fprintf(stderr," %s: %s md5 mismatch.\n",sp->Key,name); + if(j & CTM_Q_MD5_Before) { + GETFIELD(p,sep); + if((st.st_mode & S_IFMT) == S_IFREG && + strcmp(MD5File(name),p)) { + fprintf(stderr," %s: %s md5 mismatch.\n", + sp->Key,name); + ret |= 8; + } + break; } + if(j & CTM_Q_MD5_After) { + GETFIELDCOPY(md5,sep); + break; + } + /* Unqualified MD5 */ + ret = 32; break; case CTM_F_Count: GETBYTECNT(cnt,sep); @@ -102,7 +135,18 @@ Pass2(FILE *fd) case CTM_F_Bytes: if(cnt < 0) WRONG GETDATA(trash,cnt); - p = MD5Data(trash,cnt); + if(!strcmp(sp->Key,"FN")) { + p = tempnam(TmpDir,"CTMclient"); + i = ctm_edit(trash,cnt,name,p); + ret |= i; + if(i == 0 && strcmp(md5,MD5File(p))) { + fprintf(stderr," %s: %s edit fails.\n", + sp->Key,name); + ret |= 32; + } + unlink(p); + } + break; default: WRONG } @@ -112,5 +156,5 @@ Pass2(FILE *fd) GETFIELD(p,'\n'); /* */ if(strcmp(q,p)) WRONG if (-1 != getc(fd)) WRONG - return 0; + return ret; } diff --git a/usr.sbin/ctm/ctm/ctm_pass3.c b/usr.sbin/ctm/ctm/ctm_pass3.c index 5a23abaf6d05..3579104ce6f6 100644 --- a/usr.sbin/ctm/ctm/ctm_pass3.c +++ b/usr.sbin/ctm/ctm/ctm_pass3.c @@ -1,4 +1,17 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + * $Id$ + * + */ + #include "ctm.h" +#define BADREAD 32 /*---------------------------------------------------------------------------*/ /* Pass3 -- Validate the incomming CTM-file. @@ -114,6 +127,14 @@ Pass3(FILE *fd) } continue; } + if(!strcmp(sp->Key,"FN")) { + strcpy(buf,name); + strcat(buf,".ctm"); + i = ctm_edit(trash,cnt,name,buf); + if(i) { + } + rename(buf,name); + } if(!strcmp(sp->Key,"DM")) { if(0 > mkdir(name,0755)) { sprintf(buf,"mkdir -p %s",name); diff --git a/usr.sbin/ctm/ctm/ctm_syntax.c b/usr.sbin/ctm/ctm/ctm_syntax.c index 85911afad5dc..ac5039ad3e20 100644 --- a/usr.sbin/ctm/ctm/ctm_syntax.c +++ b/usr.sbin/ctm/ctm/ctm_syntax.c @@ -1,5 +1,13 @@ /* - * We redefine the names to make it look nice... + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + * $Id$ + * */ #include "ctm.h" @@ -46,6 +54,7 @@ struct CTM_Syntax Syntax[] = { { "FM", ctmFM }, { "FS", ctmFS }, { "FE", ctmFE }, + { "FN", ctmFE }, { "FR", ctmFR }, { "AS", ctmAS }, { "DM", ctmDM }, diff --git a/usr.sbin/ctm/ctm_scan/Makefile b/usr.sbin/ctm/ctm_scan/Makefile index 80f3144da44d..6230e6d678e1 100644 --- a/usr.sbin/ctm/ctm_scan/Makefile +++ b/usr.sbin/ctm/ctm_scan/Makefile @@ -1,5 +1,15 @@ - -PROG= ctm_scan -LDFLAGS+= -lmd -NOMAN= 1 +# +# ---------------------------------------------------------------------------- +# "THE BEER-WARE LICENSE" (Revision 42): +# wrote this file. As long as you retain this notice you +# can do whatever you want with this stuff. If we meet some day, and you think +# this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp +# ---------------------------------------------------------------------------- +# +# $Id$ +# +PROG= ctm_scan +LDADD+= -lmd +NOMAN= 1 +CFLAGS+= -Wall .include diff --git a/usr.sbin/ctm/ctm_scan/ctm_scan.c b/usr.sbin/ctm/ctm_scan/ctm_scan.c index cf6e38e04a17..623cd1495004 100644 --- a/usr.sbin/ctm/ctm_scan/ctm_scan.c +++ b/usr.sbin/ctm/ctm_scan/ctm_scan.c @@ -1,3 +1,14 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + * + * $Id$ + * + */ #include #include #include @@ -11,9 +22,9 @@ int barf[256]; int -pstrcmp(char **p, char **q) +pstrcmp(const void *pp, const void *qq) { - return strcmp(*p,*q); + return strcmp(*(char **)pp,*(char **)qq); } int @@ -62,7 +73,7 @@ Do(char *path) } closedir(d); if(!nde) return 0; - qsort(pde,nde,sizeof *pde,pstrcmp); + qsort(pde,nde,sizeof *pde, pstrcmp); for(k=0;k@ $fo_files - puts $fo_files "" - incr changes - return + if {$b1 == "0" || $b2 == "0"} { + puts stderr "E $b1$b2 $t1$t2 $n1" + set i [catch "exec diff -e $d1/$n1 $d2/$n2 > tmp" j] + set s [file size tmp] + if {$s < $s2} { + puts $fo_files "CTMFE $n1 $u2 $g2 $m2 $h1 $h2 $s" + flush $fo_files + exec cat tmp >@ $fo_files + puts $fo_files "" + incr changes + return + } } - puts stderr "E $b1$b2 $t1$t2 $n1" - set i [catch "exec diff -e $d1/$n1 $d2/$n2 > tmp" j] - set s [file size tmp] - puts $fo_files "CTMFE $n1 $u2 $g2 $m2 $h1 $h2 $s" + puts stderr "R $b1$b2 $t1$t2 $n1" + puts $fo_files "CTMFS $n2 $u2 $g2 $m2 $h1 $h2 $s2" flush $fo_files - exec cat tmp >@ $fo_files + exec cat $d2/$n2 >@ $fo_files puts $fo_files "" incr changes + return } ##### set l1 "" @@ -114,6 +120,11 @@ while 1 { if {$l1 == $l2} { set l1 "" ; set l2 "" ; continue } + if {$CTMignoreCVS } { + if {[regexp {/CVS/} $l1]} {set l1 ""; continue } + if {[regexp {/CVS/} $l2]} {set l2 ""; continue } + } + if {$l1 == "" } { eval CTMadd $l2 ; set l2 "" ; continue } if {$l2 == "" } { eval CTMdel $l1 ; set l1 "" ; continue } @@ -132,7 +143,7 @@ close $fo_files exec echo CTM_BEGIN 2.0 $CTMname $CTMnbr $CTMdate $CTMprefix > $tmp.begin exec echo -n "CTM_END " >> $tmp.end -set m [exec cat $tmp.begin $tmp.del $tmp.rmdir $tmp.mkdir $tmp.files $tmp.end | md5] +set m [exec cat $tmp.begin $tmp.del $tmp.rmdir $tmp.mkdir $tmp.files $tmp.end | /sbin/md5] exec echo "$m" >> $tmp.end if {!$changes} { @@ -142,6 +153,8 @@ if {!$changes} { } set nm [format "%s/%s.%04d" $dd $CTMname $CTMnbr] -exec cat $tmp.begin $tmp.del $tmp.rmdir $tmp.mkdir $tmp.files $tmp.end | gzip -9 -v > ${nm}.gz 2>@ stdout +exec cat $tmp.begin $tmp.del $tmp.rmdir $tmp.mkdir $tmp.files $tmp.end | gzip -9 -v > ${nm}.gz exec sh -c "rm -f $tmp.*" -exec sh -e -x -c "cd $CTMcopy ; /root/CTM/ctm -v -v -v ${nm}.gz" >&@ stdout +if {$CTMapply} { + exec sh -e -x -c "cd $CTMcopy ; /root/CTM/ctm -v -v -v ${nm}.gz" >&@ stdout +}