diff options
author | phk <phk@FreeBSD.org> | 1996-04-29 21:02:42 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1996-04-29 21:02:42 +0000 |
commit | 4c9fab8cf79cd02d9f736ca6420d778c2f7de75a (patch) | |
tree | d469de1e9a5ad8ce95cdfbbbb3bb6170a71dbd7f /usr.sbin/ctm | |
parent | 5c83d66490e402205b37a5615569e025c3be1d6d (diff) | |
download | FreeBSD-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.1 | 10 | ||||
-rw-r--r-- | usr.sbin/ctm/ctm/ctm.c | 7 | ||||
-rw-r--r-- | usr.sbin/ctm/ctm/ctm.h | 6 | ||||
-rw-r--r-- | usr.sbin/ctm/ctm/ctm_pass2.c | 14 | ||||
-rw-r--r-- | usr.sbin/ctm/ctm/ctm_pass3.c | 71 | ||||
-rw-r--r-- | usr.sbin/ctm/ctm_rmail/ctm_rmail.1 | 9 | ||||
-rw-r--r-- | usr.sbin/ctm/ctm_rmail/ctm_rmail.c | 7 |
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) { |