A bunch of improvements. Still far to go.

This commit is contained in:
Poul-Henning Kamp 1994-09-20 07:13:39 +00:00
parent 9e6f6868ff
commit fa63aa6464
12 changed files with 288 additions and 102 deletions

View File

@ -1,7 +1,19 @@
#
# ----------------------------------------------------------------------------
# "THE BEER-WARE LICENSE" (Revision 42):
# <phk@login.dknet.dk> 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 <bsd.prog.mk>

View File

@ -1,8 +1,7 @@
/* $Id$
*
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dkuug.dk> wrote this file. As long as you retain this notice you
* <phk@login.dknet.dk> 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 <file> Backup to tar-file.
* -c Check it out, "ma non troppo"
* -d <int> Debug TBD.
* -F Force
* -m <mail-addr> Email me instead.
* -p Less paranoid.
* -P Paranoid.
@ -28,13 +28,6 @@
* -T <tmpdir>. 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;
}

View File

@ -1,3 +1,14 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dknet.dk> 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 <stdio.h>
#include <stdlib.h>
@ -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);

View File

@ -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):
* <phk@login.dknet.dk> 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");
#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) {
/* XXX */
return 1;
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;
}

View File

@ -1,3 +1,15 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dknet.dk> 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"
/*---------------------------------------------------------------------------*/

View File

@ -1,4 +1,17 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dknet.dk> 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;
}

View File

@ -1,4 +1,17 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dknet.dk> 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'); /* <MD5> */
if(strcmp(q,p)) WRONG
if (-1 != getc(fd)) WRONG
return 0;
return ret;
}

View File

@ -1,4 +1,17 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dknet.dk> 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);

View File

@ -1,5 +1,13 @@
/*
* We redefine the names to make it look nice...
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dknet.dk> 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 },

View File

@ -1,5 +1,15 @@
PROG= ctm_scan
LDFLAGS+= -lmd
NOMAN= 1
#
# ----------------------------------------------------------------------------
# "THE BEER-WARE LICENSE" (Revision 42):
# <phk@login.dkuug.dk> 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 <bsd.prog.mk>

View File

@ -1,3 +1,14 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dkuug.dk> 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 <stdio.h>
#include <unistd.h>
#include <stdlib.h>
@ -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<nde;k++) {
strcpy(buf+bufp,pde[k]);
free(pde[k]);

View File

@ -1,5 +1,8 @@
#!/usr/local/bin/tclsh
set CTMignoreCVS 0
set CTMapply 1
source $argv
set tmp $CTMtmp
@ -79,23 +82,26 @@ proc CTMchg {t1 n1 m1 u1 g1 b1 s1 h1 t2 n2 m2 u2 g2 b2 s2 h2} {
incr changes
return
}
if {$b1 != "0" || $b2 != "0"} {
puts stderr "R $b1$b2 $t1$t2 $n1"
puts $fo_files "CTMFS $n2 $u2 $g2 $m2 $h1 $h2 $s2"
flush $fo_files
exec cat $d2/$n2 >@ $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
}