diff options
author | phk <phk@FreeBSD.org> | 1996-02-05 16:06:55 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1996-02-05 16:06:55 +0000 |
commit | 20dc7e151c09bca6d413128cb1d0026164283639 (patch) | |
tree | ea4349e8a5900a751337834c697140f006faae27 | |
parent | 3a86983b1ac388d1ba017c384d01e94228c5040d (diff) | |
download | FreeBSD-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.1 | 23 | ||||
-rw-r--r-- | usr.sbin/ctm/ctm/ctm.c | 45 | ||||
-rw-r--r-- | usr.sbin/ctm/ctm/ctm.h | 14 | ||||
-rw-r--r-- | usr.sbin/ctm/ctm/ctm_input.c | 43 | ||||
-rw-r--r-- | usr.sbin/ctm/ctm/ctm_pass1.c | 10 | ||||
-rw-r--r-- | usr.sbin/ctm/ctm/ctm_pass2.c | 17 | ||||
-rw-r--r-- | usr.sbin/ctm/ctm/ctm_pass3.c | 29 | ||||
-rw-r--r-- | usr.sbin/ctm/ctm/ctm_syntax.c | 13 |
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 }; |