Support for "-u" which sets the timestamp from the delta on the file.
Intended for sup mirrors etc. Not well tested yet. Reviewed by: phk Submitted by: Giles Lean <giles@nemeton.com.au> Submitted by: John Hay <jhay@mikom.csir.co.za>
This commit is contained in:
parent
89d8a80418
commit
c936f2cb5a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=15456
@ -10,7 +10,7 @@
|
||||
.\"
|
||||
.\" CTM and ctm(1) by <phk@login.dknet.dk>
|
||||
.\"
|
||||
.\" $Id: ctm.1,v 1.3 1996/01/31 01:58:29 nate Exp $
|
||||
.\" $Id: ctm.1,v 1.4 1996/02/05 16:06:44 phk Exp $
|
||||
.\"
|
||||
.Dd Mar 25, 1995
|
||||
.Os
|
||||
@ -20,7 +20,7 @@
|
||||
.Nd source code mirror program
|
||||
.Sh SYNOPSIS
|
||||
.Nm ctm
|
||||
.Op Fl cFpPqv
|
||||
.Op Fl cFpPquv
|
||||
.Op Fl b Ar basedir
|
||||
.Op Fl T Ar tmpdir
|
||||
.Op Fl V Ar level
|
||||
@ -59,7 +59,7 @@ Before working one a file
|
||||
.Ar name
|
||||
.Nm ctm
|
||||
first checks for the existence of the file
|
||||
.Ar name#ctm .
|
||||
.Ar name.ctm .
|
||||
If this file exists,
|
||||
.Nm ctm
|
||||
works on it instead.
|
||||
@ -112,6 +112,10 @@ Tell us less.
|
||||
Put temporary files under
|
||||
.Ar tmpdir .
|
||||
|
||||
.It Fl u
|
||||
Set modification time of created and modified files to the CTM delta
|
||||
creation time.
|
||||
|
||||
.It Fl v
|
||||
Tell us more.
|
||||
|
||||
|
@ -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.11 1995/05/30 03:47:19 rgrimes Exp $
|
||||
* $Id: ctm.c,v 1.12 1996/02/05 16:06:46 phk Exp $
|
||||
*
|
||||
* This is the client program of 'CTM'. It will apply a CTM-patch to a
|
||||
* collection of files.
|
||||
@ -28,6 +28,7 @@
|
||||
* -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
|
||||
*
|
||||
@ -54,10 +55,11 @@ main(int argc, char **argv)
|
||||
basedir = NULL;
|
||||
Verbose = 1;
|
||||
Paranoid = 1;
|
||||
SetTime = 0;
|
||||
setbuf(stderr,0);
|
||||
setbuf(stdout,0);
|
||||
|
||||
while((c=getopt(argc,argv,"ab:B:cd:Fm:pPqr:R:T:V:v")) != -1) {
|
||||
while((c=getopt(argc,argv,"ab:B:cd:Fm:pPqr:R:T:uV:v")) != -1) {
|
||||
switch (c) {
|
||||
case 'b': basedir = optarg; break; /* Base Directory */
|
||||
case 'c': CheckIt++; break; /* Only check it */
|
||||
@ -67,6 +69,7 @@ main(int argc, char **argv)
|
||||
case 'v': Verbose++; break; /* Verbose */
|
||||
case 'T': TmpDir = optarg; break;
|
||||
case 'F': Force = 1; break;
|
||||
case 'u': SetTime++; break; /* Set timestamp on files */
|
||||
case 'V': sscanf(optarg,"%d", &c); /* Verbose */
|
||||
Verbose += c;
|
||||
break;
|
||||
|
@ -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.7 1995/05/30 03:47:21 rgrimes Exp $
|
||||
* $Id: ctm.h,v 1.8 1996/02/05 16:06:47 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -17,9 +17,11 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define VERSION "2.0"
|
||||
#define MAXSIZE (1024*1024*10)
|
||||
@ -104,6 +106,8 @@ EXTERN int Verbose;
|
||||
EXTERN int Exit;
|
||||
EXTERN int Force;
|
||||
EXTERN int CheckIt;
|
||||
EXTERN int SetTime;
|
||||
EXTERN struct timeval Times[2];
|
||||
|
||||
#define Exit_OK 0
|
||||
#define Exit_Garbage 1
|
||||
|
@ -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.10 1995/11/10 12:17:23 phk Exp $
|
||||
* $Id: ctm_pass2.c,v 1.11 1996/02/05 16:06:52 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -89,6 +89,12 @@ Pass2(FILE *fd)
|
||||
ret |= Exit_NotOK;
|
||||
break;
|
||||
}
|
||||
if (SetTime && getuid() && (getuid() != st.st_uid)) {
|
||||
fprintf(stderr,
|
||||
" %s: %s not mine, cannot set time.\n",
|
||||
sp->Key,name);
|
||||
ret |= Exit_NotOK;
|
||||
}
|
||||
if (j & CTM_Q_Name_Dir) {
|
||||
if((st.st_mode & S_IFMT) != S_IFDIR) {
|
||||
fprintf(stderr,
|
||||
@ -155,14 +161,18 @@ Pass2(FILE *fd)
|
||||
fprintf(stderr," %s: %s edit returned %d.\n",
|
||||
sp->Key,name,j);
|
||||
ret |= j;
|
||||
unlink(p);
|
||||
Free(p);
|
||||
return ret;
|
||||
} else if(strcmp(md5,MD5File(p,md5_1))) {
|
||||
fprintf(stderr," %s: %s edit fails.\n",
|
||||
sp->Key,name);
|
||||
ret |= Exit_Mess;
|
||||
unlink(p);
|
||||
Free(p);
|
||||
return ret;
|
||||
}
|
||||
unlink(p);
|
||||
unlink(p);
|
||||
Free(p);
|
||||
}
|
||||
|
||||
|
@ -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.11 1995/07/12 09:16:13 phk Exp $
|
||||
* $Id: ctm_pass3.c,v 1.12 1996/02/05 16:06:53 phk Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -17,6 +17,17 @@
|
||||
/* Pass3 -- Validate the incoming CTM-file.
|
||||
*/
|
||||
|
||||
int
|
||||
settime(const char *name, const struct timeval *times)
|
||||
{
|
||||
if (SetTime)
|
||||
if (utimes(name,times)) {
|
||||
fprintf(stderr, " utimes(): %s: %s\n", name, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Pass3(FILE *fd)
|
||||
{
|
||||
@ -28,6 +39,7 @@ Pass3(FILE *fd)
|
||||
FILE *ed=0;
|
||||
struct stat st;
|
||||
char md5_1[33];
|
||||
struct timeval times[2];
|
||||
|
||||
if(Verbose>3)
|
||||
printf("Pass3 -- Applying the CTM-patch\n");
|
||||
@ -40,6 +52,59 @@ Pass3(FILE *fd)
|
||||
GETFIELD(p,' '); if(strcmp(TimeStamp,p)) WRONG
|
||||
GETFIELD(p,'\n'); if(strcmp(Prefix,p)) WRONG
|
||||
|
||||
/*
|
||||
* This would be cleaner if mktime() worked in UTC rather than
|
||||
* local time.
|
||||
*/
|
||||
if (SetTime) {
|
||||
struct tm tm;
|
||||
char *tz;
|
||||
char buf[5];
|
||||
int i;
|
||||
|
||||
#define SUBSTR(off,len) strncpy(buf, &TimeStamp[off], len), buf[len] = '\0'
|
||||
#define WRONGDATE { fprintf(stderr, " %s failed date validation\n",\
|
||||
TimeStamp); WRONG}
|
||||
|
||||
if (strlen(TimeStamp) != 15 || TimeStamp[14] != 'Z') WRONGDATE
|
||||
for (i = 0; i < 14; i++)
|
||||
if (!isdigit(TimeStamp[i])) WRONGDATE
|
||||
|
||||
tz = getenv("TZ");
|
||||
if (setenv("TZ", "UTC", 1) < 0) WRONG
|
||||
tzset();
|
||||
|
||||
tm.tm_isdst = tm.tm_gmtoff = 0;
|
||||
|
||||
SUBSTR(0, 4);
|
||||
tm.tm_year = atoi(buf) - 1900;
|
||||
SUBSTR(4, 2);
|
||||
tm.tm_mon = atoi(buf) - 1;
|
||||
if (tm.tm_mon < 0 || tm.tm_mon > 11) WRONGDATE
|
||||
SUBSTR(6, 2);
|
||||
tm.tm_mday = atoi(buf);
|
||||
if (tm.tm_mday < 1 || tm.tm_mday > 31) WRONG;
|
||||
SUBSTR(8, 2);
|
||||
tm.tm_hour = atoi(buf);
|
||||
if (tm.tm_hour > 24) WRONGDATE
|
||||
SUBSTR(10, 2);
|
||||
tm.tm_min = atoi(buf);
|
||||
if (tm.tm_min > 59) WRONGDATE
|
||||
SUBSTR(12, 2);
|
||||
tm.tm_sec = atoi(buf);
|
||||
if (tm.tm_min > 62) WRONGDATE /* allow leap seconds */
|
||||
|
||||
times[0].tv_sec = times[1].tv_sec = mktime(&tm);
|
||||
if (times[0].tv_sec == -1) WRONGDATE
|
||||
times[0].tv_usec = times[1].tv_usec = 0;
|
||||
|
||||
if (tz) {
|
||||
if (setenv("TZ", tz, 1) < 0) WRONGDATE
|
||||
} else {
|
||||
unsetenv("TZ");
|
||||
}
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
Delete(md5);
|
||||
Delete(uid);
|
||||
@ -105,6 +170,7 @@ Pass3(FILE *fd)
|
||||
sp->Key,name);
|
||||
WRONG
|
||||
}
|
||||
if (settime(name,times)) WRONG
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(sp->Key,"FE")) {
|
||||
@ -128,6 +194,7 @@ Pass3(FILE *fd)
|
||||
sp->Key,name);
|
||||
WRONG
|
||||
}
|
||||
if (settime(name,times)) WRONG
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(sp->Key,"FN")) {
|
||||
@ -145,6 +212,7 @@ Pass3(FILE *fd)
|
||||
sp->Key,name);
|
||||
WRONG
|
||||
}
|
||||
if (settime(name,times)) WRONG
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(sp->Key,"DM")) {
|
||||
@ -156,6 +224,7 @@ Pass3(FILE *fd)
|
||||
fprintf(stderr,"<%s> mkdir failed\n",name);
|
||||
WRONG
|
||||
}
|
||||
if (settime(name,times)) WRONG
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(sp->Key,"FR")) {
|
||||
|
@ -21,7 +21,7 @@ deltas via mail
|
||||
.Ar ctm-delta
|
||||
.Ar mail-alias
|
||||
.Nm ctm_rmail
|
||||
.Op Fl Dfv
|
||||
.Op Fl Dfuv
|
||||
.Op Fl l Ar log
|
||||
.Op Fl p Ar piecedir
|
||||
.Op Fl d Ar deltadir
|
||||
@ -148,6 +148,13 @@ Don't worry about zillions of background
|
||||
processes loading your machine, since locking is used to prevent more than one
|
||||
.Xr ctm
|
||||
invocation at a time.
|
||||
.It Fl u
|
||||
Pass the
|
||||
.Fl u
|
||||
flag to the
|
||||
.Xr ctm
|
||||
command when applying the complete deltas, causing it to set the modification
|
||||
time of created and modified files to the CTM delta creation time.
|
||||
.It Fl v
|
||||
Pass the
|
||||
.Fl v
|
||||
|
@ -30,6 +30,7 @@ char *delta_dir = NULL; /* Where to store completed deltas. */
|
||||
char *base_dir = NULL; /* The tree to apply deltas to. */
|
||||
int delete_after = 0; /* Delete deltas after ctm applies them. */
|
||||
int apply_verbose = 0; /* Run with '-v' */
|
||||
int set_time = 0; /* Set the time of the files that is changed. */
|
||||
|
||||
void apply_complete(void);
|
||||
int read_piece(char *input_file);
|
||||
@ -61,9 +62,10 @@ main(int argc, char **argv)
|
||||
|
||||
err_prog_name(argv[0]);
|
||||
|
||||
OPTIONS("[-Df] [-p piecedir] [-d deltadir] [-b basedir] [-l log] [file ...]")
|
||||
OPTIONS("[-Dfuv] [-p piecedir] [-d deltadir] [-b basedir] [-l log] [file ...]")
|
||||
FLAG('D', delete_after)
|
||||
FLAG('f', fork_ctm)
|
||||
FLAG('u', set_time)
|
||||
FLAG('v', apply_verbose)
|
||||
STRING('p', piece_dir)
|
||||
STRING('d', delta_dir)
|
||||
@ -196,7 +198,8 @@ apply_complete()
|
||||
if (stat(fname, &sb) < 0)
|
||||
break;
|
||||
|
||||
sprintf(buf, "(cd %s && ctm %s%s%s) 2>&1", base_dir,
|
||||
sprintf(buf, "(cd %s && ctm %s%s%s%s) 2>&1", base_dir,
|
||||
set_time ? "-u " : "",
|
||||
apply_verbose ? "-v " : "", here, fname);
|
||||
if ((ctm = popen(buf, "r")) == NULL)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user