summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ctm
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1996-04-29 21:02:42 +0000
committerphk <phk@FreeBSD.org>1996-04-29 21:02:42 +0000
commit4c9fab8cf79cd02d9f736ca6420d778c2f7de75a (patch)
treed469de1e9a5ad8ce95cdfbbbb3bb6170a71dbd7f /usr.sbin/ctm
parent5c83d66490e402205b37a5615569e025c3be1d6d (diff)
downloadFreeBSD-src-4c9fab8cf79cd02d9f736ca6420d778c2f7de75a.zip
FreeBSD-src-4c9fab8cf79cd02d9f736ca6420d778c2f7de75a.tar.gz
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>
Diffstat (limited to 'usr.sbin/ctm')
-rw-r--r--usr.sbin/ctm/ctm/ctm.110
-rw-r--r--usr.sbin/ctm/ctm/ctm.c7
-rw-r--r--usr.sbin/ctm/ctm/ctm.h6
-rw-r--r--usr.sbin/ctm/ctm/ctm_pass2.c14
-rw-r--r--usr.sbin/ctm/ctm/ctm_pass3.c71
-rw-r--r--usr.sbin/ctm/ctm_rmail/ctm_rmail.19
-rw-r--r--usr.sbin/ctm/ctm_rmail/ctm_rmail.c7
7 files changed, 112 insertions, 12 deletions
diff --git a/usr.sbin/ctm/ctm/ctm.1 b/usr.sbin/ctm/ctm/ctm.1
index 2c8d7f1..4f14760 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.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.
diff --git a/usr.sbin/ctm/ctm/ctm.c b/usr.sbin/ctm/ctm/ctm.c
index a1f938c..0aff1a9 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.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;
diff --git a/usr.sbin/ctm/ctm/ctm.h b/usr.sbin/ctm/ctm/ctm.h
index 34df4f9..a34a238 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.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
diff --git a/usr.sbin/ctm/ctm/ctm_pass2.c b/usr.sbin/ctm/ctm/ctm_pass2.c
index 0afa539..9ddd433 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.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);
}
diff --git a/usr.sbin/ctm/ctm/ctm_pass3.c b/usr.sbin/ctm/ctm/ctm_pass3.c
index 67e1ff8..07d3e6b 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.11 1995/07/12 09:16:13 phk Exp $
+ * $Id: ctm_pass3.c,v 1.12 1996/02/05 16:06:53 phk Exp $
*
*/
@@ -18,6 +18,17 @@
*/
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)
{
u_char *p,*q,buf[BUFSIZ];
@@ -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")) {
diff --git a/usr.sbin/ctm/ctm_rmail/ctm_rmail.1 b/usr.sbin/ctm/ctm_rmail/ctm_rmail.1
index 735e7dd..42a5102 100644
--- a/usr.sbin/ctm/ctm_rmail/ctm_rmail.1
+++ b/usr.sbin/ctm/ctm_rmail/ctm_rmail.1
@@ -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
diff --git a/usr.sbin/ctm/ctm_rmail/ctm_rmail.c b/usr.sbin/ctm/ctm_rmail/ctm_rmail.c
index bbb1cea..6b01922 100644
--- a/usr.sbin/ctm/ctm_rmail/ctm_rmail.c
+++ b/usr.sbin/ctm/ctm_rmail/ctm_rmail.c
@@ -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)
{
OpenPOWER on IntegriCloud