Date: Mon, 05 Feb 1996 13:18:19 +0100 From: Poul-Henning Kamp <phk@critter.tfs.com> To: haury@sagem.fr Cc: hackers@freebsd.org Subject: Re: CTM: evolutions of ctm Message-ID: <1780.823522699@critter.tfs.com> In-Reply-To: Your message of "Fri, 02 Feb 1996 09:31:17 %2B0100." <199602020831.JAA02040@sagem.fr>
next in thread | previous in thread | raw e-mail | index | archive | help
Hi Christian,
I applied your patch and merged it with my own patches, here is the resulting
patch, could you take a look ?
I change "#ctm" to ".ctm" and ".ctm" to ".ctmtmp", that should make it
easier for make I belive ?
If this patch is OK for you, I will commit it to the source.
Poul-Henning
Index: ctm.1
===================================================================
RCS file: /home/ncvs/src/usr.sbin/ctm/ctm/ctm.1,v
retrieving revision 1.3
diff -u -r1.3 ctm.1
--- ctm.1 1996/01/31 01:58:29 1.3
+++ ctm.1 1996/02/02 07:11:22
@@ -21,7 +21,9 @@
.Sh SYNOPSIS
.Nm ctm
.Op Fl cFpPqv
+.Op Fl b Ar basedir
.Op Fl T Ar tmpdir
+.Op Fl V Ar level
.Ar file Op ...
.Sh DESCRIPTION
.Nm Ctm
@@ -53,6 +55,15 @@
command runs in a number of passes. It will process the entire
input file in each pass, before commencing with the next pass.
+Before working one a file
+.Ar name
+.Nm ctm
+first checks for the existence of the file
+.Ar name#ctm .
+If this file exists,
+.Nm ctm
+works on it instead.
+
Pass 1 will validate that the input file is OK. The syntax, the data
and the global MD5 checksum will be checked. If any of these fail,
.Nm ctm
@@ -77,6 +88,11 @@
.Bl -tag -width indent -compact
+.It Fl b Ar basedir
+Prepend the path
+.Ar basedir
+on every filename.
+
.It Fl c
Check it out, don't do anything.
@@ -98,6 +114,11 @@
.It Fl v
Tell us more.
+
+.It Fl V Ar level
+Tell us more.
+.Ar Level
+is the level of verbosity.
.El
Index: ctm.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/ctm/ctm/ctm.c,v
retrieving revision 1.11
diff -u -r1.11 ctm.c
--- ctm.c 1995/05/30 03:47:19 1.11
+++ ctm.c 1996/02/02 07:19:07
@@ -14,7 +14,6 @@
* Options we'd like to see:
*
* -a Attempt best effort.
- * -b <dir> Base-dir
* -B <file> Backup to tar-file.
* -d <int> Debug TBD.
* -m <mail-addr> Email me instead.
@@ -22,6 +21,7 @@
* -R <file> Read list of files to reconstruct.
*
* Options we have:
+ * -b <dir> Base-dir
* -c Check it out, don't do anything.
* -F Force
* -p Less paranoid.
@@ -29,6 +29,7 @@
* -q Tell us less.
* -T <tmpdir>. Temporary files.
* -v Tell us more.
+ * -V <level> Tell us more level = number of -v
*
*/
@@ -46,16 +47,19 @@
int c;
extern int optopt,optind;
extern char * optarg;
- FILE *statfile;
unsigned applied = 0;
+ FILE *statfile;
+ u_char * basedir;
+ basedir = NULL;
Verbose = 1;
Paranoid = 1;
setbuf(stderr,0);
setbuf(stdout,0);
- while((c=getopt(argc,argv,"ab:B:cd:Fm:pPqr:R:T:Vv")) != -1) {
+ while((c=getopt(argc,argv,"ab:B:cd:Fm:pPqr:R:T:V:v")) != -1) {
switch (c) {
+ case 'b': basedir = optarg; break; /* Base Directory */
case 'c': CheckIt++; break; /* Only check it */
case 'p': Paranoid--; break; /* Less Paranoid */
case 'P': Paranoid++; break; /* More Paranoid */
@@ -63,6 +67,9 @@
case 'v': Verbose++; break; /* Verbose */
case 'T': TmpDir = optarg; break;
case 'F': Force = 1; break;
+ case 'V': sscanf(optarg,"%d", &c); /* Verbose */
+ Verbose += c;
+ break;
case ':':
fprintf(stderr,"Option '%c' requires an argument.\n",optopt);
stat++;
@@ -85,8 +92,23 @@
argc -= optind;
argv += optind;
- if((statfile = fopen(CTM_STATUS, "r")) == NULL)
- fprintf(stderr, "Warning: " CTM_STATUS " not found.\n");
+ if (basedir == NULL) {
+ Buffer = (u_char *)Malloc(BUFSIZ + strlen(SUBSUFF) +1);
+ CatPtr = Buffer;
+ *Buffer = '\0';
+ } else {
+ Buffer = (u_char *)Malloc(strlen(basedir)+ BUFSIZ + strlen(SUBSUFF) +1);
+ strcpy(Buffer, basedir);
+ CatPtr = Buffer + strlen(basedir);
+ if (CatPtr[-1] != '/') {
+ strcat(Buffer, "/");
+ CatPtr++;
+ }
+ }
+ strcat(Buffer, CTM_STATUS);
+
+ if((statfile = fopen(Buffer, "r")) == NULL)
+ fprintf(stderr, "Warning: %s not found.\n", Buffer);
else {
fscanf(statfile, "%*s %u", &applied);
fclose(statfile);
@@ -119,7 +141,7 @@
p = 0;
f = stdin;
} else if(p && (!strcmp(p,".gz") || !strcmp(p,".Z"))) {
- p = Malloc(100);
+ p = alloca(20 + strlen(filename));
strcpy(p,"gunzip < ");
strcat(p,filename);
f = popen(p,"r");
@@ -136,7 +158,7 @@
if(Verbose > 1)
fprintf(stderr,"Working on <%s>\n",filename);
- if(FileName) Free(FileName);
+ Delete(FileName);
FileName = String(filename);
/* If we cannot seek, we're doomed, so copy to a tmp-file in that case */
@@ -199,12 +221,11 @@
i=Pass3(f);
exit_and_close:
- if(!p) {
+ if(!p)
fclose(f);
- } else {
+ else
pclose(f);
- Free(p);
- }
+
if(i)
return i;
Index: ctm.h
===================================================================
RCS file: /home/ncvs/src/usr.sbin/ctm/ctm/ctm.h,v
retrieving revision 1.7
diff -u -r1.7 ctm.h
--- ctm.h 1995/05/30 03:47:21 1.7
+++ ctm.h 1996/02/02 07:29:14
@@ -24,6 +24,9 @@
#define VERSION "2.0"
#define MAXSIZE (1024*1024*10)
+#define SUBSUFF "#ctm"
+#define TMPSUFF ".ctm"
+
/* The fields... */
#define CTM_F_MASK 0xff
#define CTM_F_Name 0x01
@@ -39,6 +42,7 @@
#define CTM_Q_Name_File 0x0100
#define CTM_Q_Name_Dir 0x0200
#define CTM_Q_Name_New 0x0400
+#define CTM_Q_Name_Subst 0x0800
#define CTM_Q_MD5_After 0x0100
#define CTM_Q_MD5_Before 0x0200
#define CTM_Q_MD5_Chunk 0x0400
@@ -53,6 +57,8 @@
#define Malloc malloc
#define Free free
+#define Delete(foo) if (!foo) ; else {Free(foo); foo = 0; }
+#define String(foo) strdup(foo)
#ifndef EXTERN
# define EXTERN extern
@@ -63,8 +69,9 @@
EXTERN u_char *TimeStamp;
EXTERN u_char *Prefix;
EXTERN u_char *FileName;
-EXTERN u_char *BaseDir;
EXTERN u_char *TmpDir;
+EXTERN u_char *CatPtr;
+EXTERN u_char *Buffer;
/*
* Paranoid -- Just in case they should be after us...
@@ -108,13 +115,13 @@
#define Exit_Done 64
#define Exit_Version 128
-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 Exit_Mess;}
u_char * Ffield(FILE *fd, MD5_CTX *ctx,u_char term);
+u_char * Fname(FILE *fd, MD5_CTX *ctx,u_char term,int qual, int verbose);
int Fbytecnt(FILE *fd, MD5_CTX *ctx, u_char term);
@@ -124,6 +131,7 @@
#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
+#define GETNAMECOPY(p,q,r,v) if(!((p)=Fname(fd,&ctx,(q),(r),(v)))) return BADREAD; else p=String(p)
int Pass1(FILE *fd, unsigned applied);
int Pass2(FILE *fd);
Index: ctm_input.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/ctm/ctm/ctm_input.c,v
retrieving revision 1.4
diff -u -r1.4 ctm_input.c
--- ctm_input.c 1994/09/22 02:49:18 1.4
+++ ctm_input.c 1996/02/02 07:29:41
@@ -13,14 +13,6 @@
#include "ctm.h"
/*---------------------------------------------------------------------------*/
-char *
-String(char *s)
-{
- char *p = malloc(strlen(s) + 1);
- strcpy(p,s);
- return p;
-}
-/*---------------------------------------------------------------------------*/
void
Fatal_(int ln, char *fn, char *kind)
{
@@ -110,4 +102,37 @@
}
p[u_chars] = '\0';
return p;
+}
+
+/*---------------------------------------------------------------------------*/
+/* get the filename in the next field, prepend BaseDir and give back the result
+ strings. The sustitute filename is return (the one with the suffix SUBSUFF)
+ if it exists and the qualifier contains CTM_Q_Name_Subst
+ NOTA: Buffer is already initialize with BaseDir, CatPtr is the insertion
+ point on this buffer + the length test in Ffield() is enough for Fname() */
+
+u_char *
+Fname(FILE *fd, MD5_CTX *ctx,u_char term,int qual, int verbose)
+{
+ u_char * p;
+ struct stat st;
+
+ if ((p = Ffield(fd,ctx,term)) == NULL) return(NULL);
+
+ strcpy(CatPtr, p);
+
+ if (!(qual & CTM_Q_Name_Subst)) return(Buffer);
+
+ p = Buffer + strlen(Buffer);
+
+ strcat(Buffer, SUBSUFF);
+
+ if ( -1 == stat(Buffer, &st) ) {
+ *p = '\0';
+ } else {
+ if(verbose > 2)
+ fprintf(stderr,"Using %s as substitute file\n", Buffer);
+ }
+
+ return (Buffer);
}
Index: ctm_pass1.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/ctm/ctm/ctm_pass1.c,v
retrieving revision 1.11
diff -u -r1.11 ctm_pass1.c
--- ctm_pass1.c 1995/07/12 09:16:08 1.11
+++ ctm_pass1.c 1996/02/02 07:24:06
@@ -63,8 +63,8 @@
}
for(;;) {
- if(md5) {Free(md5), md5 = 0;}
- if(trash) {Free(trash), trash = 0;}
+ Delete(md5);
+ Delete(trash);
cnt = -1;
GETFIELD(p,' '); /* CTM_something */
@@ -184,6 +184,10 @@
putc('\n',stderr);
continue;
}
+
+ Delete(md5);
+ Delete(trash);
+
q = MD5End (&ctx,md5_1);
if(Verbose > 2)
printf("Expecting Global MD5 <%s>\n",q);
Index: ctm_pass2.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/ctm/ctm/ctm_pass2.c,v
retrieving revision 1.10
diff -u -r1.10 ctm_pass2.c
--- ctm_pass2.c 1995/11/10 12:17:23 1.10
+++ ctm_pass2.c 1996/02/02 07:19:46
@@ -44,9 +44,9 @@
/* XXX drop or use ? */
for(;;) {
- if(trash) {Free(trash), trash = 0;}
- if(name) {Free(name), name = 0;}
- if(md5) {Free(md5), md5 = 0;}
+ Delete(trash);
+ Delete(name);
+ Delete(md5);
cnt = -1;
GETFIELD(p,' ');
@@ -69,7 +69,7 @@
switch (j & CTM_F_MASK) {
case CTM_F_Name:
- GETFIELDCOPY(name,sep);
+ GETNAMECOPY(name,sep,j,0);
/* XXX Check DR DM rec's for parent-dir */
if(j & CTM_Q_Name_New) {
/* XXX Check DR FR rec's for item */
@@ -163,7 +163,7 @@
return ret;
}
unlink(p);
- free(p);
+ Free(p);
}
break;
@@ -171,6 +171,11 @@
}
}
}
+
+ Delete(trash);
+ Delete(name);
+ Delete(md5);
+
q = MD5End (&ctx,md5_1);
GETFIELD(p,'\n'); /* <MD5> */
if(strcmp(q,p)) WRONG
Index: ctm_pass3.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/ctm/ctm/ctm_pass3.c,v
retrieving revision 1.11
diff -u -r1.11 ctm_pass3.c
--- ctm_pass3.c 1995/07/12 09:16:13 1.11
+++ ctm_pass3.c 1996/02/02 07:16:02
@@ -41,13 +41,13 @@
GETFIELD(p,'\n'); if(strcmp(Prefix,p)) WRONG
for(;;) {
- if(md5) {Free(md5), md5 = 0;}
- if(uid) {Free(uid), uid = 0;}
- if(gid) {Free(gid), gid = 0;}
- if(mode) {Free(mode), mode = 0;}
- if(md5before) {Free(md5before), md5before = 0;}
- if(trash) {Free(trash), trash = 0;}
- if(name) {Free(name), name = 0;}
+ Delete(md5);
+ Delete(uid);
+ Delete(gid);
+ Delete(mode);
+ Delete(md5before);
+ Delete(trash);
+ Delete(name);
cnt = -1;
GETFIELD(p,' ');
@@ -69,7 +69,7 @@
sep = '\n';
switch (j & CTM_F_MASK) {
- case CTM_F_Name: GETFIELDCOPY(name,sep); break;
+ case CTM_F_Name: GETNAMECOPY(name,sep,j, Verbose); break;
case CTM_F_Uid: GETFIELDCOPY(uid,sep); break;
case CTM_F_Gid: GETFIELDCOPY(gid,sep); break;
case CTM_F_Mode: GETFIELDCOPY(mode,sep); break;
@@ -132,7 +132,7 @@
}
if(!strcmp(sp->Key,"FN")) {
strcpy(buf,name);
- strcat(buf,".ctm");
+ strcat(buf,TMPSUFF);
i = ctm_edit(trash,cnt,name,buf);
if(i) {
fprintf(stderr," %s %s Edit failed with code %d.\n",
@@ -177,6 +177,15 @@
}
WRONG
}
+
+ Delete(md5);
+ Delete(uid);
+ Delete(gid);
+ Delete(mode);
+ Delete(md5before);
+ Delete(trash);
+ Delete(name);
+
q = MD5End (&ctx,md5_1);
GETFIELD(p,'\n');
if(strcmp(q,p)) WRONG
Index: ctm_syntax.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/ctm/ctm/ctm_syntax.c,v
retrieving revision 1.5
diff -u -r1.5 ctm_syntax.c
--- ctm_syntax.c 1995/05/30 03:47:28 1.5
+++ ctm_syntax.c 1996/02/02 07:11:24
@@ -25,28 +25,29 @@
#define File CTM_Q_Name_File
#define Dir CTM_Q_Name_Dir
#define New CTM_Q_Name_New
+#define Subst CTM_Q_Name_Subst
#define After CTM_Q_MD5_After
#define Before CTM_Q_MD5_Before
#define Chunk CTM_Q_MD5_Chunk
#define Force CTM_Q_MD5_Force
static int ctmFM[] = /* File Make */
- { Name|File|New, Uid, Gid, Mode,
+ { Name|File|New|Subst, Uid, Gid, Mode,
MD5|After|Chunk, Count, Bytes,0 };
static int ctmFS[] = /* File Substitute */
- { Name|File, Uid, Gid, Mode,
+ { Name|File|Subst, Uid, Gid, Mode,
MD5|Before|Force, MD5|After|Chunk, Count, Bytes,0 };
static int ctmFE[] = /* File Edit */
- { Name|File, Uid, Gid, Mode,
+ { Name|File|Subst, Uid, Gid, Mode,
MD5|Before, MD5|After, Count, Bytes,0 };
static int ctmFR[] = /* File Remove */
- { Name|File, MD5|Before, 0 };
+ { Name|File|Subst, MD5|Before, 0 };
static int ctmAS[] = /* Attribute Substitute */
- { Name, Uid, Gid, Mode, 0 };
+ { Name|Subst, Uid, Gid, Mode, 0 };
static int ctmDM[] = /* Directory Make */
{ Name|Dir|New , Uid, Gid, Mode, 0 };
--
Poul-Henning Kamp | phk@FreeBSD.ORG FreeBSD Core-team.
http://www.freebsd.org/~phk | phk@login.dknet.dk Private mailbox.
whois: [PHK] | phk@ref.tfs.com TRW Financial Systems, Inc.
Future will arrive by its own means, progress not so.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1780.823522699>
