a2cb4112c5
noticed by kurt@ ok kili@
305 lines
7.7 KiB
Plaintext
305 lines
7.7 KiB
Plaintext
$OpenBSD: patch-ctm_ctm_ctm_c,v 1.2 2007/10/31 23:14:46 ajacoutot Exp $
|
|
--- ctm/ctm/ctm.c.orig Wed Oct 31 23:06:34 2007
|
|
+++ ctm/ctm/ctm.c Wed Oct 31 23:06:34 2007
|
|
@@ -14,7 +14,6 @@
|
|
* Options we'd like to see:
|
|
*
|
|
* -a Attempt best effort.
|
|
- * -B <file> Backup to tar-file.
|
|
* -d <int> Debug TBD.
|
|
* -m <mail-addr> Email me instead.
|
|
* -r <name> Reconstruct file.
|
|
@@ -22,16 +21,21 @@
|
|
*
|
|
* Options we have:
|
|
* -b <dir> Base-dir
|
|
+ * -B <file> Backup to tar-file.
|
|
+ * -t Tar command (default as in TARCMD).
|
|
* -c Check it out, don't do anything.
|
|
* -F Force
|
|
- * -p Less paranoid.
|
|
- * -P Paranoid.
|
|
* -q Tell us less.
|
|
* -T <tmpdir>. Temporary files.
|
|
* -u Set all file modification times to the timestamp
|
|
* -v Tell us more.
|
|
* -V <level> Tell us more level = number of -v
|
|
+ * -k Keep files and directories that would have been removed.
|
|
+ * -l List actions.
|
|
*
|
|
+ * Options we don't actually use:
|
|
+ * -p Less paranoid.
|
|
+ * -P Paranoid.
|
|
*/
|
|
|
|
#define EXTERN /* */
|
|
@@ -44,51 +48,94 @@ extern int Proc(char *, unsigned applied);
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
- int stat=0;
|
|
+ int stat=0, err=0;
|
|
int c;
|
|
- extern int optopt,optind;
|
|
- extern char * optarg;
|
|
unsigned applied = 0;
|
|
FILE *statfile;
|
|
+ struct CTM_Filter *nfilter = NULL; /* new filter */
|
|
u_char * basedir;
|
|
|
|
basedir = NULL;
|
|
Verbose = 1;
|
|
Paranoid = 1;
|
|
SetTime = 0;
|
|
+ KeepIt = 0;
|
|
+ ListIt = 0;
|
|
+ BackupFile = NULL;
|
|
+ TarCmd = TARCMD;
|
|
+ LastFilter = FilterList = NULL;
|
|
setbuf(stderr,0);
|
|
setbuf(stdout,0);
|
|
|
|
- while((c=getopt(argc,argv,"ab:B:cd:Fm:pPqr:R:T:uV:v")) != -1) {
|
|
+ while((c=getopt(argc,argv,"ab:B:cd:e:Fklm:pPqr:R:t:T:uV:vx:")) != -1) {
|
|
switch (c) {
|
|
case 'b': basedir = optarg; break; /* Base Directory */
|
|
+ case 'B': BackupFile = optarg; break;
|
|
case 'c': CheckIt++; break; /* Only check it */
|
|
+ case 'F': Force = 1; break;
|
|
+ case 'k': KeepIt++; break; /* Don't do removes */
|
|
+ case 'l': ListIt++; break; /* Only list actions and files */
|
|
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 't': TarCmd = optarg; break; /* archiver command */
|
|
+ case 'T': TmpDir = optarg; break; /* set temporary directory */
|
|
case 'u': SetTime++; break; /* Set timestamp on files */
|
|
+ case 'v': Verbose++; break; /* Verbose */
|
|
case 'V': sscanf(optarg,"%d", &c); /* Verbose */
|
|
Verbose += c;
|
|
break;
|
|
+ case 'e': /* filter expressions */
|
|
+ case 'x':
|
|
+ if (NULL == (nfilter = Malloc(sizeof(struct CTM_Filter)))) {
|
|
+ warnx("out of memory for expressions: \"%s\"", optarg);
|
|
+ stat++;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ (void) memset(nfilter, 0, sizeof(struct CTM_Filter));
|
|
+
|
|
+ if (0 != (err =
|
|
+ regcomp(&nfilter->CompiledRegex, optarg, REG_NOSUB))) {
|
|
+
|
|
+ char errmsg[128];
|
|
+
|
|
+ regerror(err, &nfilter->CompiledRegex, errmsg,
|
|
+ sizeof(errmsg));
|
|
+ warnx("regular expression: \"%s\"", errmsg);
|
|
+ stat++;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* note whether the filter enables or disables on match */
|
|
+ nfilter->Action =
|
|
+ (('e' == c) ? CTM_FILTER_ENABLE : CTM_FILTER_DISABLE);
|
|
+
|
|
+ /* link in the expression into the list */
|
|
+ nfilter->Next = NULL;
|
|
+ if (NULL == FilterList) {
|
|
+ LastFilter = FilterList = nfilter; /* init head and tail */
|
|
+ } else { /* place at tail */
|
|
+ LastFilter->Next = nfilter;
|
|
+ LastFilter = nfilter;
|
|
+ }
|
|
+ break;
|
|
case ':':
|
|
- fprintf(stderr,"Option '%c' requires an argument.\n",optopt);
|
|
+ warnx("option '%c' requires an argument",optopt);
|
|
stat++;
|
|
break;
|
|
case '?':
|
|
- fprintf(stderr,"Option '%c' not supported.\n",optopt);
|
|
+ warnx("option '%c' not supported",optopt);
|
|
stat++;
|
|
break;
|
|
default:
|
|
- fprintf(stderr,"Option '%c' not yet implemented.\n",optopt);
|
|
+ warnx("option '%c' not yet implemented",optopt);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(stat) {
|
|
- fprintf(stderr,"%d errors during option processing\n",stat);
|
|
+ warnx("%d errors during option processing",stat);
|
|
return Exit_Pilot;
|
|
}
|
|
stat = Exit_Done;
|
|
@@ -110,26 +157,37 @@ main(int argc, char **argv)
|
|
}
|
|
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);
|
|
- }
|
|
+ if(ListIt)
|
|
+ applied = 0;
|
|
+ else
|
|
+ if((statfile = fopen(Buffer, "r")) == NULL) {
|
|
+ if (Verbose > 0)
|
|
+ warnx("warning: %s not found", Buffer);
|
|
+ } else {
|
|
+ fscanf(statfile, "%*s %u", &applied);
|
|
+ fclose(statfile);
|
|
+ }
|
|
|
|
if(!argc)
|
|
stat |= Proc("-", applied);
|
|
|
|
while(argc-- && stat == Exit_Done) {
|
|
stat |= Proc(*argv++, applied);
|
|
- stat &= ~Exit_Version;
|
|
+ stat &= ~(Exit_Version | Exit_NoMatch);
|
|
}
|
|
|
|
if(stat == Exit_Done)
|
|
stat = Exit_OK;
|
|
|
|
- if(Verbose)
|
|
- fprintf(stderr,"Exit(%d)\n",stat);
|
|
+ if(Verbose > 0)
|
|
+ warnx("exit(%d)",stat);
|
|
+
|
|
+ if (FilterList)
|
|
+ for (nfilter = FilterList; nfilter; ) {
|
|
+ struct CTM_Filter *tmp = nfilter->Next;
|
|
+ Free(nfilter);
|
|
+ nfilter = tmp;
|
|
+ }
|
|
return stat;
|
|
}
|
|
|
|
@@ -148,13 +206,13 @@ Proc(char *filename, unsigned applied)
|
|
strcpy(p,"gunzip < ");
|
|
strcat(p,filename);
|
|
f = popen(p,"r");
|
|
- if(!f) { perror(p); return Exit_Garbage; }
|
|
+ if(!f) { warn("%s", p); return Exit_Garbage; }
|
|
} else {
|
|
p = 0;
|
|
f = fopen(filename,"r");
|
|
}
|
|
if(!f) {
|
|
- perror(filename);
|
|
+ warn("%s", filename);
|
|
return Exit_Garbage;
|
|
}
|
|
|
|
@@ -166,17 +224,27 @@ Proc(char *filename, unsigned applied)
|
|
|
|
/* 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(TmpDir,"CTMclient");
|
|
- FILE *f2 = fopen(fn,"w+");
|
|
- int i;
|
|
+ char *fn;
|
|
+ FILE *f2;
|
|
+ int fd, i;
|
|
|
|
- if(!f2) {
|
|
- perror(fn);
|
|
+ if (asprintf(&fn, "%s/CTMclient.XXXXXXXX", TmpDir) == -1) {
|
|
+ warnx("Cannot allocate memory\n");
|
|
fclose(f);
|
|
return Exit_Broke;
|
|
}
|
|
+ if ((fd = mkstemp(fn)) == -1 || (f2 = fdopen(fd, "w+")) == NULL) {
|
|
+ warn("%s", fn);
|
|
+ free(fn);
|
|
+ if (fd != -1)
|
|
+ close(fd);
|
|
+ fclose(f);
|
|
+ return Exit_Broke;
|
|
+ }
|
|
unlink(fn);
|
|
- fprintf(stderr,"Writing tmp-file \"%s\"\n",fn);
|
|
+ if (Verbose > 0)
|
|
+ fprintf(stderr,"Writing tmp-file \"%s\"\n",fn);
|
|
+ free(fn);
|
|
while(EOF != (i=getc(f)))
|
|
if(EOF == putc(i,f2)) {
|
|
fclose(f2);
|
|
@@ -192,12 +260,17 @@ Proc(char *filename, unsigned applied)
|
|
if((i=Pass1(f, applied)))
|
|
goto exit_and_close;
|
|
|
|
+ if(ListIt) {
|
|
+ i = Exit_Done;
|
|
+ goto exit_and_close;
|
|
+ }
|
|
+
|
|
if(!p) {
|
|
rewind(f);
|
|
} else {
|
|
pclose(f);
|
|
f = popen(p,"r");
|
|
- if(!f) { perror(p); return Exit_Broke; }
|
|
+ if(!f) { warn("%s", p); return Exit_Broke; }
|
|
}
|
|
|
|
i=Pass2(f);
|
|
@@ -207,7 +280,7 @@ Proc(char *filename, unsigned applied)
|
|
} else {
|
|
pclose(f);
|
|
f = popen(p,"r");
|
|
- if(!f) { perror(p); return Exit_Broke; }
|
|
+ if(!f) { warn("%s", p); return Exit_Broke; }
|
|
}
|
|
|
|
if(i) {
|
|
@@ -216,11 +289,26 @@ Proc(char *filename, unsigned applied)
|
|
}
|
|
|
|
if(CheckIt) {
|
|
- fprintf(stderr,"All checks out ok.\n");
|
|
+ if (Verbose > 0)
|
|
+ fprintf(stderr,"All checks out ok.\n");
|
|
i = Exit_Done;
|
|
goto exit_and_close;
|
|
}
|
|
+
|
|
+ /* backup files if requested */
|
|
+ if(BackupFile) {
|
|
|
|
+ i = PassB(f);
|
|
+
|
|
+ if(!p) {
|
|
+ rewind(f);
|
|
+ } else {
|
|
+ pclose(f);
|
|
+ f = popen(p,"r");
|
|
+ if(!f) { warn("%s", p); return Exit_Broke; }
|
|
+ }
|
|
+ }
|
|
+
|
|
i=Pass3(f);
|
|
|
|
exit_and_close:
|
|
@@ -232,6 +320,8 @@ exit_and_close:
|
|
if(i)
|
|
return i;
|
|
|
|
- fprintf(stderr,"All done ok\n");
|
|
+ if (Verbose > 0)
|
|
+ fprintf(stderr,"All done ok\n");
|
|
+
|
|
return Exit_Done;
|
|
}
|