summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1996-02-05 16:06:55 +0000
committerphk <phk@FreeBSD.org>1996-02-05 16:06:55 +0000
commit20dc7e151c09bca6d413128cb1d0026164283639 (patch)
treeea4349e8a5900a751337834c697140f006faae27
parent3a86983b1ac388d1ba017c384d01e94228c5040d (diff)
downloadFreeBSD-src-20dc7e151c09bca6d413128cb1d0026164283639.zip
FreeBSD-src-20dc7e151c09bca6d413128cb1d0026164283639.tar.gz
Add support for local modifications to the tree, by using FOO.ctm instead
of FOO if present. Various other tweaks. Submitted by: Christian Haury <Christian.Haury@sagem.fr>
-rw-r--r--usr.sbin/ctm/ctm/ctm.123
-rw-r--r--usr.sbin/ctm/ctm/ctm.c45
-rw-r--r--usr.sbin/ctm/ctm/ctm.h14
-rw-r--r--usr.sbin/ctm/ctm/ctm_input.c43
-rw-r--r--usr.sbin/ctm/ctm/ctm_pass1.c10
-rw-r--r--usr.sbin/ctm/ctm/ctm_pass2.c17
-rw-r--r--usr.sbin/ctm/ctm/ctm_pass3.c29
-rw-r--r--usr.sbin/ctm/ctm/ctm_syntax.c13
8 files changed, 144 insertions, 50 deletions
diff --git a/usr.sbin/ctm/ctm/ctm.1 b/usr.sbin/ctm/ctm/ctm.1
index 2bc871f..2c8d7f1 100644
--- a/usr.sbin/ctm/ctm/ctm.1
+++ b/usr.sbin/ctm/ctm/ctm.1
@@ -10,7 +10,7 @@
.\"
.\" CTM and ctm(1) by <phk@login.dknet.dk>
.\"
-.\" $Id: ctm.1,v 1.2 1995/03/26 20:09:46 phk Exp $
+.\" $Id: ctm.1,v 1.3 1996/01/31 01:58:29 nate Exp $
.\"
.Dd Mar 25, 1995
.Os
@@ -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 @@ The
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 @@ are explicitly prohibited as a security measure.
.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.
@@ -99,6 +115,11 @@ Put temporary files under
.It Fl v
Tell us more.
+.It Fl V Ar level
+Tell us more.
+.Ar Level
+is the level of verbosity.
+
.El
diff --git a/usr.sbin/ctm/ctm/ctm.c b/usr.sbin/ctm/ctm/ctm.c
index 05ab0cc..a1f938c 100644
--- a/usr.sbin/ctm/ctm/ctm.c
+++ b/usr.sbin/ctm/ctm/ctm.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: ctm.c,v 1.10 1995/03/26 20:09:50 phk Exp $
+ * $Id: ctm.c,v 1.11 1995/05/30 03:47:19 rgrimes Exp $
*
* This is the client program of 'CTM'. It will apply a CTM-patch to a
* collection of files.
@@ -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 @@ main(int argc, char **argv)
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 @@ main(int argc, char **argv)
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 @@ main(int argc, char **argv)
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 @@ Proc(char *filename, unsigned applied)
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 @@ Proc(char *filename, unsigned applied)
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 @@ Proc(char *filename, unsigned applied)
i=Pass3(f);
exit_and_close:
- if(!p) {
+ if(!p)
fclose(f);
- } else {
+ else
pclose(f);
- Free(p);
- }
+
if(i)
return i;
diff --git a/usr.sbin/ctm/ctm/ctm.h b/usr.sbin/ctm/ctm/ctm.h
index a444f98..34df4f9 100644
--- a/usr.sbin/ctm/ctm/ctm.h
+++ b/usr.sbin/ctm/ctm/ctm.h
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: ctm.h,v 1.6 1995/03/04 20:36:45 phk Exp $
+ * $Id: ctm.h,v 1.7 1995/05/30 03:47:21 rgrimes Exp $
*
*/
@@ -24,6 +24,9 @@
#define VERSION "2.0"
#define MAXSIZE (1024*1024*10)
+#define SUBSUFF ".ctm"
+#define TMPSUFF ".ctmtmp"
+
/* 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 @@ extern struct CTM_Syntax Syntax[];
#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 *Nbr;
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 @@ EXTERN int CheckIt;
#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 @@ u_char * Fdata(FILE *fd, int u_chars, MD5_CTX *ctx);
#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);
diff --git a/usr.sbin/ctm/ctm/ctm_input.c b/usr.sbin/ctm/ctm/ctm_input.c
index 582bdf7..284272d 100644
--- a/usr.sbin/ctm/ctm/ctm_input.c
+++ b/usr.sbin/ctm/ctm/ctm_input.c
@@ -6,21 +6,13 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id$
+ * $Id: ctm_input.c,v 1.4 1994/09/22 02:49:18 phk Exp $
*
*/
#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)
{
@@ -111,3 +103,36 @@ Fdata(FILE *fd, int u_chars, MD5_CTX *ctx)
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);
+}
diff --git a/usr.sbin/ctm/ctm/ctm_pass1.c b/usr.sbin/ctm/ctm/ctm_pass1.c
index 223d66c..d0bf6c3 100644
--- a/usr.sbin/ctm/ctm/ctm_pass1.c
+++ b/usr.sbin/ctm/ctm/ctm_pass1.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: ctm_pass1.c,v 1.10 1995/05/30 03:47:23 rgrimes Exp $
+ * $Id: ctm_pass1.c,v 1.11 1995/07/12 09:16:08 phk Exp $
*
*/
@@ -63,8 +63,8 @@ Pass1(FILE *fd, unsigned applied)
}
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 @@ Pass1(FILE *fd, unsigned applied)
putc('\n',stderr);
continue;
}
+
+ Delete(md5);
+ Delete(trash);
+
q = MD5End (&ctx,md5_1);
if(Verbose > 2)
printf("Expecting Global MD5 <%s>\n",q);
diff --git a/usr.sbin/ctm/ctm/ctm_pass2.c b/usr.sbin/ctm/ctm/ctm_pass2.c
index 4e25719..0afa539 100644
--- a/usr.sbin/ctm/ctm/ctm_pass2.c
+++ b/usr.sbin/ctm/ctm/ctm_pass2.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: ctm_pass2.c,v 1.9 1995/07/12 09:16:10 phk Exp $
+ * $Id: ctm_pass2.c,v 1.10 1995/11/10 12:17:23 phk Exp $
*
*/
@@ -44,9 +44,9 @@ Pass2(FILE *fd)
/* 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 @@ Pass2(FILE *fd)
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 @@ Pass2(FILE *fd)
return ret;
}
unlink(p);
- free(p);
+ Free(p);
}
break;
@@ -171,6 +171,11 @@ Pass2(FILE *fd)
}
}
}
+
+ Delete(trash);
+ Delete(name);
+ Delete(md5);
+
q = MD5End (&ctx,md5_1);
GETFIELD(p,'\n'); /* <MD5> */
if(strcmp(q,p)) WRONG
diff --git a/usr.sbin/ctm/ctm/ctm_pass3.c b/usr.sbin/ctm/ctm/ctm_pass3.c
index 8cef972..67e1ff8 100644
--- a/usr.sbin/ctm/ctm/ctm_pass3.c
+++ b/usr.sbin/ctm/ctm/ctm_pass3.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: ctm_pass3.c,v 1.10 1995/05/30 03:47:27 rgrimes Exp $
+ * $Id: ctm_pass3.c,v 1.11 1995/07/12 09:16:13 phk Exp $
*
*/
@@ -41,13 +41,13 @@ Pass3(FILE *fd)
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 @@ Pass3(FILE *fd)
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 @@ Pass3(FILE *fd)
}
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 @@ Pass3(FILE *fd)
}
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
diff --git a/usr.sbin/ctm/ctm/ctm_syntax.c b/usr.sbin/ctm/ctm/ctm_syntax.c
index 89ea54f..30e2435 100644
--- a/usr.sbin/ctm/ctm/ctm_syntax.c
+++ b/usr.sbin/ctm/ctm/ctm_syntax.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: ctm_syntax.c,v 1.4 1994/09/22 02:49:21 phk Exp $
+ * $Id: ctm_syntax.c,v 1.5 1995/05/30 03:47:28 rgrimes Exp $
*
*/
@@ -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 };
OpenPOWER on IntegriCloud