Date: Fri, 12 Jan 2001 16:59:42 +0200 From: "Eli Zaretskii" Sender: halo1 AT zahav DOT net DOT il To: djgpp-workers AT delorie DOT com Message-Id: <5137-Fri12Jan2001165941+0200-eliz@is.elta.co.il> X-Mailer: Emacs 20.6 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6 Subject: Preserving time stamps with djsplit and djmerge Reply-To: djgpp-workers AT delorie DOT com I always get annoyed by the fact that djsplit and djmerge don't preserve the file's time stamp and mode bits. So how about the following new feature? --- src/docs/kb/wc204.t~0 Sat Jan 6 13:03:10 2001 +++ src/docs/kb/wc204.txi Fri Jan 12 16:40:18 2001 @@ -197,3 +197,10 @@ the functions from the @code{spawn*} fam The DOS standard extensions @file{.com}, @file{.exe}, @file{.bat}, and @file{.btm} are still included in the search @emph{before} looking for the file name itself, for compatibility with stock DOS/Windows shells. + +@pindex djsplit AT r{, preserves file's time stamp} +@pindex djmerge AT r{, preserves file's time stamp} +The @code{djsplit} and @code{djmerge} utilities now preserve the +original file's time stamp and mode bits. The @samp{-t} switch to those +programs restores the old behavior, where each file was created with the +current time stamp and default attribute bits. --- src/utils/utils.t~0 Sun Dec 24 19:14:26 2000 +++ src/utils/utils.tex Fri Jan 12 16:52:42 2001 @@ -533,7 +533,7 @@ transporting files across unreliable cha floppies). @code{djsplit} takes a big file and splits it into up to 1000 smaller files. @code{djmerge} puts them back together again. -Usage: @code{djsplit} @var{inputfile} @var{chunksize} @var{outputbase} +Usage: @code{djsplit [-t]} @var{inputfile} @var{chunksize} @var{outputbase} Each output file is made from appending a sequence number to @var{outputbase}. For example: @@ -548,6 +548,13 @@ The @code{chunksize} parameter can be ex kilobytes(NNNk) or megabytes (NNNm). The number NNN @emph{must} be an integer; for example, @samp{1.1m} will @strong{not} work. +By default, @code{djsplit} creates the output files +@file{@var{outputbase}.@var{nnn}} with the same time stamp and mode bits +as the original file @file{@var{inputfile}}. (@code{djmerge} will then +recreate the file's time and modes as they originally were.) If you +want the output files to have the current time and the default attribute +bits, use the @samp{-t} switch. + @c ----------------------------------------------------------------------------- @node djmerge, texi2ps, djsplit, Top @chapter djmerge @@ -557,7 +564,7 @@ transporting files across unreliable cha floppies). @code{djsplit} takes a big file and splits it into up to 1000 smaller files. @code{djmerge} puts them back together again. -Usage: @code{djmerge} @var{inputbase} @var{outputfile} +Usage: @code{djmerge [-t]} @var{inputbase} @var{outputfile} Each input file is made from appending a sequence number to @var{inputbase}. For example, given @code{footgz.000}, @@ -569,6 +576,12 @@ djmerge footgz foo.tgz would result in @code{foo.tgz} being created. +By default, @code{djmerge} creates the output file +@file{@var{outputfile}} with the same time stamp and mode bits as the +first file @file{@var{inputbase}.000}. If you want the output file to +have the current time and the default attribute bits, use the @samp{-t} +switch. + @c ----------------------------------------------------------------------------- @node texi2ps, update, djmerge, Top @chapter texi2ps --- src/utils/djsplit.c~0 Sun Jul 12 17:29:54 1998 +++ src/utils/djsplit.c Fri Jan 12 16:15:44 2001 @@ -5,13 +5,17 @@ #include #include #include +#include +#include +#include #include static void usage(void) { - fprintf(stderr,"Usage: djsplit [inputFile] [chunkSize] [outputBase]\n"); + fprintf(stderr,"Usage: djsplit [-t] [inputFile] [chunkSize] [outputBase]\n"); fprintf(stderr, "chunksize is bytes or kbytes (ex: 1440k), creates .000, .001, etc\n"); + fprintf(stderr, " -t means don't set the chunks' time stamp and modes as for original file\n"); exit(1); } @@ -24,6 +28,20 @@ p_open(char *ob, int p) return open(partname, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666); } +static void +p_set_modes(char *ob, int p, struct stat *stbuf) +{ + char partname[FILENAME_MAX]; + struct utimbuf timbuf; + + sprintf(partname, "%s.%03d", ob, p); + timbuf.actime = stbuf->st_atime; + timbuf.modtime = stbuf->st_mtime; + utime(partname, &timbuf); + chown(partname, stbuf->st_uid, stbuf->st_gid); + chmod(partname, stbuf->st_mode); +} + char *buf; int bufsize; @@ -34,8 +52,10 @@ main(int argc, char **argv) int partnum; int inf, f; char *endp; + struct stat stbuf; + int preserve_file_time = 1; - if (argc != 4) + if (argc != 4 && argc != 5) usage(); inf = open(argv[1], O_RDONLY|O_BINARY); @@ -57,6 +77,17 @@ main(int argc, char **argv) } printf("buf size: %d\n", bufsize); + if (strcmp(argv[2], "-t") == 0) + { + preserve_file_time = 0; + ++argv; + } + else if (fstat(inf, &stbuf) != 0) + { + perror("Couldn't fstat, file's time and modes won't be preserved"); + preserve_file_time = 0; + } + chunksize = strtol(argv[2], &endp, 0); if (chunksize < 1) usage(); @@ -85,6 +116,7 @@ main(int argc, char **argv) { close(f); close(inf); + p_set_modes(argv[3], partnum, &stbuf); exit(0); } @@ -94,6 +126,7 @@ main(int argc, char **argv) if (left == 0) { close(f); + p_set_modes(argv[3], partnum, &stbuf); partnum++; f = p_open(argv[3], partnum); left = chunksize; --- src/utils/djmerge.c~0 Fri Jan 12 16:36:26 2001 +++ src/utils/djmerge.c Fri Jan 12 16:15:34 2001 @@ -5,6 +5,9 @@ #include #include #include +#include +#include +#include #ifndef O_BINARY #define O_BINARY 0 @@ -15,8 +18,9 @@ static void usage(void) { - fprintf(stderr,"Usage: djmerge [inputBase] [outputFile]\n"); + fprintf(stderr,"Usage: djmerge [-t] [inputBase] [outputFile]\n"); fprintf(stderr, "reads .000, .001, etc\n"); + fprintf(stderr, " -t means don't set the file's time stamp and modes as for original file\n"); exit(1); } @@ -35,10 +39,18 @@ main(int argc, char **argv) long r; int partnum; int outf, f; + struct stat stbuf; + int preserve_file_time = 1; - if (argc != 3) + if (argc != 3 && argc != 4) usage(); + if (strcmp(argv[1], "-t") == 0) + { + preserve_file_time = 0; + ++argv; + } + outf = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666); if (outf < 0) usage(); @@ -51,6 +63,11 @@ main(int argc, char **argv) perror(""); exit(1); } + else if (fstat(f, &stbuf) != 0) + { + perror("Couldn't fstat, file's time and modes won't be preserved"); + preserve_file_time = 0; + } while (1) { r = read(f, buf, BUFS); @@ -63,7 +80,17 @@ main(int argc, char **argv) if (f < 0) { + struct utimbuf timbuf; + close(outf); + if (preserve_file_time) + { + timbuf.actime = stbuf.st_atime; + timbuf.modtime = stbuf.st_mtime; + utime(argv[2], &timbuf); + chown(argv[2], stbuf.st_uid, stbuf.st_gid); + chmod(argv[2], stbuf.st_mode); + } exit(0); } }