diff -Nur pax-3.3-gcc/src/ar_io.c pax-3.3-modifyWarn/src/ar_io.c --- pax-3.3-gcc/src/ar_io.c 2003-04-22 15:15:50.000000000 +1000 +++ pax-3.3-modifyWarn/src/ar_io.c 2003-04-22 15:15:50.000000000 +1000 @@ -492,8 +492,9 @@ if (!invld_rec) return(0); - paxwarn(1,"Cannot append, device record size %d does not support %s spec", - rdblksz, argv0); + paxwarn(1, + "Cannot append, device record size %d does not support %s spec", + rdblksz, argv0); return(-1); } diff -Nur pax-3.3-gcc/src/ar_subs.c pax-3.3-modifyWarn/src/ar_subs.c --- pax-3.3-gcc/src/ar_subs.c 2003-04-22 15:15:50.000000000 +1000 +++ pax-3.3-modifyWarn/src/ar_subs.c 2003-04-22 15:15:50.000000000 +1000 @@ -459,7 +459,8 @@ * the link table). */ if ((fd = open(arcn->org_name, O_RDONLY, 0)) < 0) { - syswarn(1,errno, "Unable to open %s to read", + syswarn (errno == ENOENT ? 2 : 1, errno, + "Unable to open %s to read", arcn->org_name); purg_lnk(arcn); continue; @@ -940,8 +941,8 @@ * first open source file and then create the destination file */ if ((fdsrc = open(arcn->org_name, O_RDONLY, 0)) < 0) { - syswarn(1, errno, "Unable to open %s to read", - arcn->org_name); + syswarn (errno == ENOENT ? 2 : 1, errno, + "Unable to open %s to read", arcn->org_name); purg_lnk(arcn); continue; } diff -Nur pax-3.3-gcc/src/buf_subs.c pax-3.3-modifyWarn/src/buf_subs.c --- pax-3.3-gcc/src/buf_subs.c 2003-02-03 19:06:43.000000000 +1000 +++ pax-3.3-modifyWarn/src/buf_subs.c 2003-04-22 15:15:50.000000000 +1000 @@ -594,7 +594,7 @@ /* * wr_rdfile() * fill write buffer with the contents of a file. We are passed an open - * file descriptor to the file an the archive structure that describes the + * file descriptor to an archive structure that describes the * file we are storing. The variable "left" is modified to contain the * number of bytes of the file we were NOT able to write to the archive. * it is important that we always write EXACTLY the number of bytes that @@ -602,7 +602,7 @@ * bigger, so reading to the end of file would create an improper archive, * we just detect this case and warn the user. We never create a bad * archive if we can avoid it. Of course trying to archive files that are - * active is asking for trouble. It we fail, we pass back how much we + * active is asking for trouble. If we fail, we pass back how much we * could NOT copy and let the caller deal with it. * Return: * 0 ok, -1 if archive write failure. a short read of the file returns a @@ -640,11 +640,11 @@ if (res < 0) syswarn(1, errno, "Read fault on %s", arcn->org_name); else if (size != 0L) - paxwarn(1, "File changed size during read %s", arcn->org_name); + paxwarn(2, "File changed size during read %s", arcn->org_name); else if (fstat(ifd, &sb) < 0) syswarn(1, errno, "Failed stat on %s", arcn->org_name); else if (arcn->sb.st_mtime != sb.st_mtime) - paxwarn(1, "File %s was modified during copy to archive", + paxwarn(2, "File %s was modified during copy to archive", arcn->org_name); *left = size; return(0); @@ -813,12 +813,12 @@ syswarn(1, errno, "Failed write during copy of %s to %s", arcn->org_name, arcn->name); else if (cpcnt != arcn->sb.st_size) - paxwarn(1, "File %s changed size during copy to %s", + paxwarn(2, "File %s changed size during copy to %s", arcn->org_name, arcn->name); else if (fstat(fd1, &sb) < 0) syswarn(1, errno, "Failed stat of %s", arcn->org_name); else if (arcn->sb.st_mtime != sb.st_mtime) - paxwarn(1, "File %s was modified during copy to %s", + paxwarn(2, "File %s was modified during copy to %s", arcn->org_name, arcn->name); /* diff -Nur pax-3.3-gcc/src/cpio.1 pax-3.3-modifyWarn/src/cpio.1 --- pax-3.3-gcc/src/cpio.1 2001-05-12 06:02:16.000000000 +1000 +++ pax-3.3-modifyWarn/src/cpio.1 2003-04-22 15:15:50.000000000 +1000 @@ -39,7 +39,7 @@ .Sh SYNOPSIS .Nm cpio .Fl o -.Op Fl aABcLvzZ +.Op Fl aABcLMvzZ .Op Fl C Ar bytes .Op Fl F Ar archive .Op Fl H Ar format @@ -58,7 +58,7 @@ .Op Ar "< archive" .Nm cpio .Fl p -.Op Fl adlLmuv +.Op Fl adlLmMuv .Ar destination-directory .Ar "< name-list" .Sh DESCRIPTION @@ -117,6 +117,8 @@ .El .It Fl L Follow symbolic links. +.It Fl M +Do not treat files being modified or deleted during the copy as an error. .It Fl v Be verbose about operations. List filenames as they are written to the archive. @@ -255,7 +257,9 @@ find a file while writing an archive, or cannot preserve the user ID, group ID, file mode, or access and modification times when the .Fl p -option is specified, a diagnostic message is written to standard +option is specified, or a file is modified or deleted when the +.Fl M +option is not specified, a diagnostic message is written to standard error and a non-zero exit value will be returned, but processing will continue. In the case where diff -Nur pax-3.3-gcc/src/extern.h pax-3.3-modifyWarn/src/extern.h --- pax-3.3-gcc/src/extern.h 2003-04-22 15:15:50.000000000 +1000 +++ pax-3.3-modifyWarn/src/extern.h 2003-04-22 15:15:50.000000000 +1000 @@ -223,6 +223,7 @@ extern int Dflag; extern int Hflag; extern int Lflag; +extern int Mflag; extern int Xflag; extern int Yflag; extern int Zflag; diff -Nur pax-3.3-gcc/src/file_subs.c pax-3.3-modifyWarn/src/file_subs.c --- pax-3.3-gcc/src/file_subs.c 2003-02-03 19:06:43.000000000 +1000 +++ pax-3.3-modifyWarn/src/file_subs.c 2003-04-22 15:15:50.000000000 +1000 @@ -1003,11 +1003,11 @@ * they can create inconsistant archive copies. */ if (cpcnt != arcn->sb.st_size) - paxwarn(1, "File changed size %s", arcn->org_name); + paxwarn(2, "File changed size during read %s", arcn->org_name); else if (fstat(fd, &sb) < 0) syswarn(1, errno, "Failed stat on %s", arcn->org_name); else if (arcn->sb.st_mtime != sb.st_mtime) - paxwarn(1, "File %s was modified during read", arcn->org_name); + paxwarn(2, "File %s was modified during read", arcn->org_name); else if (lseek(fd, (off_t)0L, SEEK_SET) < 0) syswarn(1, errno, "File rewind failed on: %s", arcn->org_name); else { diff -Nur pax-3.3-gcc/src/ftree.c pax-3.3-modifyWarn/src/ftree.c --- pax-3.3-gcc/src/ftree.c 2002-10-17 05:20:02.000000000 +1000 +++ pax-3.3-modifyWarn/src/ftree.c 2003-04-22 15:15:50.000000000 +1000 @@ -404,7 +404,8 @@ paxwarn(1,"File system cycle found at %s",ftent->fts_path); continue; case FTS_DNR: - syswarn(1, ftent->fts_errno, + syswarn(ftent->fts_errno == ENOENT ? 2 : 1, + ftent->fts_errno, "Unable to read directory %s", ftent->fts_path); continue; case FTS_ERR: @@ -412,10 +413,13 @@ "File system traversal error"); continue; case FTS_NS: - case FTS_NSOK: - syswarn(1, ftent->fts_errno, + syswarn(ftent->fts_errno == ENOENT ? 2 : 1, + ftent->fts_errno, "Unable to access %s", ftent->fts_path); continue; + case FTS_NSOK: + paxwarn(1, "Unable to access %s", ftent->fts_path); + continue; } /* @@ -470,7 +474,8 @@ */ if ((cnt = readlink(ftent->fts_path, arcn->ln_name, PAXPATHLEN)) < 0) { - syswarn(1, errno, "Unable to read symlink %s", + syswarn(errno == ENOENT ? 2 : 1, errno, + "Unable to read symlink %s", ftent->fts_path); continue; } diff -Nur pax-3.3-gcc/src/options.c pax-3.3-modifyWarn/src/options.c --- pax-3.3-gcc/src/options.c 2003-04-22 15:15:50.000000000 +1000 +++ pax-3.3-modifyWarn/src/options.c 2003-04-22 15:15:50.000000000 +1000 @@ -198,8 +198,8 @@ /* * process option flags */ - while ((c=getopt(argc,argv,"ab:cdf:iklno:p:rs:tuvwx:zB:DE:G:HLPT:U:XYZ")) - != -1) { + while ((c=getopt(argc,argv, + "ab:cdf:iklno:p:rs:tuvwx:zB:DE:G:HLMPT:U:XYZ")) != -1) { switch (c) { case 'a': /* @@ -451,6 +451,14 @@ Lflag = 1; flg |= CLF; break; + case 'M': + /* + * ignore file modified or deleted errors. + * non-standard option. + */ + Mflag = 1; + flg |= CMF; + break; case 'O': /* * Force one volume. Non standard option. @@ -613,7 +621,7 @@ * process option flags */ while ((c = getoldopt(argc, argv, - "b:cef:hmopqruts:vwxzBC:HI:LOPXZ014578")) != -1) { + "b:cef:hmopqruts:vwxzBC:HI:LMOPXZ014578")) != -1) { switch(c) { case 'b': /* @@ -765,6 +773,13 @@ */ Lflag = 1; break; + case 'M': + /* + * ignore file modified or deleted errors. + * non-standard option. + */ + Mflag = 1; + break; case 'P': /* * do not remove leading '/' from pathnames @@ -1032,7 +1047,8 @@ act = -1; nodirs = 1; listf = stderr; - while ((c=getopt(argc,argv,"abcdfiklmoprstuvzABC:E:F:H:I:LO:SZ6")) != -1) + while ((c=getopt(argc,argv, + "abcdfiklmoprstuvzABC:E:F:H:I:LMO:SZ6")) != -1) switch (c) { case 'a': /* @@ -1203,6 +1219,12 @@ */ Lflag = 1; break; + case 'M': + /* + * ignore file modified or deleted errors. + * non-standard option. + */ + Mflag = 1; case 'S': /* * swap halfwords after reading data @@ -1257,6 +1279,17 @@ * no read errors allowed on updates/append operation! */ maxflt = 0; + /* + * This is not a good idea for 2 reasons. Firstly the number of + * files supplied on stdin may be huge - storing them in memory + * is not such a good idea. Secondly cpio traditionally does not + * die if it can not find a file name. Instead it behaves like + * pax does when reading the files from stdin - it continues, but + * exits with a non-zero exit status. + * + * By not reading the files here cpio is forced to behave like pax + * does. + * while ((str = getln(stdin)) != NULL) { ftree_add(str, NULL); } @@ -1264,6 +1297,7 @@ paxwarn(1, "Problem while reading stdin"); cpio_usage(); } + */ break; default: cpio_usage(); @@ -1551,14 +1585,14 @@ (void)fputs("[-U user] ... [-G group] ...\n ", stderr); (void)fputs("[-T [from_date][,to_date]] ... ", stderr); (void)fputs(" [pattern ...]\n", stderr); - (void)fputs(" pax -w [-dituvzHLOPX] [-b blocksize] ", stderr); + (void)fputs(" pax -w [-dituvzHLMOPX] [-b blocksize] ", stderr); (void)fputs("[ [-a] [-f archive] ] [-x format] \n", stderr); (void)fputs(" [-B bytes] [-s replstr] ... ", stderr); (void)fputs("[-o options] ... [-U user] ...", stderr); (void)fputs("\n [-G group] ... ", stderr); (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr); (void)fputs("[file ...]\n", stderr); - (void)fputs(" pax -r -w [-diklntuvDHLOPXYZ] ", stderr); + (void)fputs(" pax -r -w [-diklntuvDHLMOPXYZ] ", stderr); (void)fputs("[-p string] ... [-s replstr] ...", stderr); (void)fputs("\n [-U user] ... [-G group] ... ", stderr); (void)fputs("[-T [from_date][,to_date][/[c][m]]] ... ", stderr); @@ -1574,7 +1608,7 @@ void tar_usage(void) { - (void)fputs("usage: tar [-]{crtux}[-befhmopqsvwzHLOPXZ014578] [blocksize] ", + (void)fputs("usage: tar [-]{crtux}[-befhmopqsvwzHLMOPXZ014578] [blocksize] ", stderr); (void)fputs("[archive] [replstr] [-C directory] [-I file] [file ...]\n", stderr); @@ -1589,10 +1623,10 @@ void cpio_usage(void) { - (void)fputs("usage: cpio -o [-aABcLvVzZ] [-C bytes] [-H format] [-O archive]\n", stderr); + (void)fputs("usage: cpio -o [-aABcLMvVzZ] [-C bytes] [-H format] [-O archive]\n", stderr); (void)fputs(" [-F archive] < name-list [> archive]\n", stderr); (void)fputs(" cpio -i [-bBcdfmnrsStuvVzZ6] [-C bytes] [-E file] [-H format]\n", stderr); (void)fputs(" [-I archive] [-F archive] [pattern...] [< archive]\n", stderr); - (void)fputs(" cpio -p [-adlLmuvV] destination-directory < name-list\n", stderr); + (void)fputs(" cpio -p [-adlLmMuvV] destination-directory < name-list\n", stderr); exit(1); } diff -Nur pax-3.3-gcc/src/options.h pax-3.3-modifyWarn/src/options.h --- pax-3.3-gcc/src/options.h 1996-06-24 00:20:37.000000000 +1000 +++ pax-3.3-modifyWarn/src/options.h 2003-04-22 15:15:50.000000000 +1000 @@ -82,18 +82,19 @@ #define CGF 0x00200000 /* nonstandard extension */ #define CHF 0x00400000 /* nonstandard extension */ #define CLF 0x00800000 /* nonstandard extension */ -#define CPF 0x01000000 /* nonstandard extension */ -#define CTF 0x02000000 /* nonstandard extension */ -#define CUF 0x04000000 /* nonstandard extension */ -#define CXF 0x08000000 -#define CYF 0x10000000 /* nonstandard extension */ -#define CZF 0x20000000 /* nonstandard extension */ +#define CMF 0x01000000 /* nonstandard extension */ +#define CPF 0x02000000 /* nonstandard extension */ +#define CTF 0x04000000 /* nonstandard extension */ +#define CUF 0x08000000 /* nonstandard extension */ +#define CXF 0x10000000 +#define CYF 0x20000000 /* nonstandard extension */ +#define CZF 0x40000000 /* nonstandard extension */ /* * ascii string indexed by bit position above (alter the above and you must * alter this string) used to tell the user what flags caused us to complain */ -#define FLGCH "abcdfiklnoprstuvwxBDEGHLPTUXYZ" +#define FLGCH "abcdfiklnoprstuvwxBDEGHLMPTUXYZ" /* * legal pax operation bit patterns @@ -110,7 +111,7 @@ * Illegal option flag subsets based on pax operation */ -#define BDEXTR (AF|BF|LF|TF|WF|XF|CBF|CHF|CLF|CPF|CXF) +#define BDEXTR (AF|BF|LF|TF|WF|XF|CBF|CHF|CLF|CMF|CPF|CXF) #define BDARCH (CF|KF|LF|NF|PF|RF|CDF|CEF|CYF|CZF) #define BDCOPY (AF|BF|FF|OF|XF|CBF|CEF) -#define BDLIST (AF|BF|IF|KF|LF|OF|PF|RF|TF|UF|WF|XF|CBF|CDF|CHF|CLF|CPF|CXF|CYF|CZF) +#define BDLIST (AF|BF|IF|KF|LF|OF|PF|RF|TF|UF|WF|XF|CBF|CDF|CHF|CLF|CMF|CPF|CXF|CYF|CZF) diff -Nur pax-3.3-gcc/src/pax.1 pax-3.3-modifyWarn/src/pax.1 --- pax-3.3-gcc/src/pax.1 2003-04-22 15:15:50.000000000 +1000 +++ pax-3.3-modifyWarn/src/pax.1 2003-04-22 15:15:50.000000000 +1000 @@ -109,7 +109,7 @@ .Op Ar pattern ... .Nm pax .Fl w -.Op Fl dituvzHLPX +.Op Fl dituvzHLMPX .Bk -words .Op Fl b Ar blocksize .Ek @@ -835,6 +835,8 @@ system traversal. .It Fl L Follow all symbolic links to perform a logical file system traversal. +.It Fl M +Do not treat files being modified or deleted during the copy as an error. .It Fl O Force the archive to be one volume. If a volume ends prematurely, @@ -1123,8 +1125,11 @@ find a file when writing an archive, or cannot preserve the user ID, group ID, or file mode when the .Fl p -option is specified, a diagnostic message is written to standard error -and a non-zero exit status will be returned, but processing will continue. +option is specified, or a file is modified or deleted when the +.Fl M +option is not specified, a diagnostic message is written to standard +error and a non-zero exit status will be returned, but processing +will continue. In the case where .Nm cannot create a link to a file, @@ -1175,6 +1180,7 @@ .Fl G , .Fl H , .Fl L , +.Fl M , .Fl O , .Fl P , .Fl T , diff -Nur pax-3.3-gcc/src/pax.c pax-3.3-modifyWarn/src/pax.c --- pax-3.3-gcc/src/pax.c 2003-04-22 15:15:50.000000000 +1000 +++ pax-3.3-modifyWarn/src/pax.c 2003-04-22 15:15:50.000000000 +1000 @@ -92,6 +92,7 @@ int Dflag; /* same as uflag except inode change time */ int Hflag; /* follow command line symlinks (write only) */ int Lflag; /* follow symlinks when writing */ +int Mflag; /* follow symlinks when writing */ int Xflag; /* archive files with same device id only */ int Yflag; /* same as Dflg except after name mode */ int Zflag; /* same as uflg except after name mode */ diff -Nur pax-3.3-gcc/src/tar.1 pax-3.3-modifyWarn/src/tar.1 --- pax-3.3-gcc/src/tar.1 2003-03-13 06:12:35.000000000 +1000 +++ pax-3.3-modifyWarn/src/tar.1 2003-04-22 15:15:50.000000000 +1000 @@ -39,7 +39,7 @@ .Sh SYNOPSIS .Nm tar .Sm off -.Oo \&- Oc {crtux} Op befhmopqsvwzHLOPXZ014578 +.Oo \&- Oc {crtux} Op befhmopqsvwzHLMOPXZ014578 .Sm on .Op Ar blocksize .Op Ar archive @@ -208,6 +208,8 @@ In extract mode this means that a directory entry in the archive will not overwrite an existing symbolic link, but rather what the link ultimately points to. +.It Fl M +Do not treat files being modified or deleted during the copy as an error. .It Fl P Do not strip leading slashes .Pq Sq / @@ -282,7 +284,9 @@ find a file while writing an archive, or cannot preserve the user ID, group ID, file mode, or access and modification times when the .Fl p -option is specified, a diagnostic message is written to standard +option is specified, or a file is modified or deleted when the +.Fl M +option is not specified, a diagnostic message is written to standard error and a non-zero exit value will be returned, but processing will continue. In the case where @@ -330,6 +334,8 @@ .Sh CAVEATS The .Fl L -flag is not portable to other versions of +and +.Fl M +flags are not portable to other versions of .Nm -where it may have a different meaning. +where they may have a different meaning. diff -Nur pax-3.3-gcc/src/tty_subs.c pax-3.3-modifyWarn/src/tty_subs.c --- pax-3.3-gcc/src/tty_subs.c 2003-03-05 06:27:58.000000000 +1000 +++ pax-3.3-modifyWarn/src/tty_subs.c 2003-04-22 15:15:50.000000000 +1000 @@ -142,19 +142,17 @@ } /* - * paxwarn() - * write a warning message to stderr. if "set" the exit value of pax - * will be non-zero. + * vsyswarn() + * write a warning message to stderr. If the parameter "set" is: + * 0 the exit value of pax will unaffected. + * 1 the exit value of pax will be non-zero. + * 2 the exit value of pax be non-zero if the -M flag has been given, + * otherwise the exit value is uneffected and a warning is printed. */ -void -paxwarn(int set, const char *fmt, ...) +static void +vsyswarn(int set, int errnum, const char *fmt, va_list ap) { - va_list ap; - - va_start(ap, fmt); - if (set) - exit_val = 1; /* * when vflag we better ship out an extra \n to get this message on a * line by itself @@ -165,15 +163,38 @@ vfpart = 0; } (void)fprintf(stderr, "%s: ", argv0); + if (set == 2 && Mflag) + (void)fprintf(stderr, "Warning - "); + else if (set) + exit_val = 1; (void)vfprintf(stderr, fmt, ap); - va_end(ap); + + /* + * format and print the errno + */ + if (errnum > 0) + (void)fprintf(stderr, ": %s", strerror(errnum)); (void)fputc('\n', stderr); } /* + * paxwarn() + * Shorthand interface to vsyswarn() above. + */ + +void +paxwarn(int set, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vsyswarn(set, 0, fmt, ap); + va_end(ap); +} + +/* * syswarn() - * write a warning message to stderr. if "set" the exit value of pax - * will be non-zero. + * Shorthand interface to vsyswarn() above. */ void @@ -182,25 +203,6 @@ va_list ap; va_start(ap, fmt); - if (set) - exit_val = 1; - /* - * when vflag we better ship out an extra \n to get this message on a - * line by itself - */ - if (vflag && vfpart) { - (void)fflush(listf); - (void)fputc('\n', stderr); - vfpart = 0; - } - (void)fprintf(stderr, "%s: ", argv0); - (void)vfprintf(stderr, fmt, ap); + vsyswarn(set, errnum, fmt, ap); va_end(ap); - - /* - * format and print the errno - */ - if (errnum > 0) - (void)fprintf(stderr, ": %s", strerror(errnum)); - (void)fputc('\n', stderr); }