diff -Naur cvs-1.11.22/src/filesubr.c cvs-1.11.22.patched/src/filesubr.c --- cvs-1.11.22/src/filesubr.c 2006-05-04 08:13:40.000000000 -0700 +++ cvs-1.11.22.patched/src/filesubr.c 2007-04-14 19:52:47.803292295 -0700 @@ -21,6 +21,7 @@ #include "cvs.h" #include "xsize.h" +#include "safe.h" static int deep_remove_dir PROTO((const char *path)); @@ -391,6 +392,30 @@ } /* + * check if a file is a CVS internal file + */ +int is_cvs_file (f) + const char *f; +{ + int len; + + len = strlen(f); + + if(strncmp(f, "CVS/", 4) == 0 || + strstr(f, "/CVS/") || + strncmp(f, Tmpdir, strlen(Tmpdir)) == 0 || + (len >= 2 && f[len-2] == ',' && f[len-1] == 'v') || + strncmp(f, Tmpdir, strlen(Tmpdir)) == 0 + ) { + /* printf("%s is a CVS file\n", f); */ + return(1); + } + + /* printf("%s is *not* a CVS file\n", f); */ + return(0); +} + +/* * Rename a file and die if it fails */ void @@ -398,12 +423,24 @@ const char *from; const char *to; { + char *bak_file; + char *bak_file_ext = ".cvsbak"; + if (trace) (void) fprintf (stderr, "%s-> rename(%s,%s)\n", CLIENT_SERVER_STR, from, to); if (noexec) return; + if ((!is_cvs_file(from) && !is_cvs_file(to)) && + safe_mode("Protecting against renaming %s to %s\n", from, to)) { + bak_file = xmalloc (strlen (to) + 1 + strlen(bak_file_ext)); + sprintf(bak_file, "%s%s", to, bak_file_ext); + printf("Copying %s to %s\n", to, bak_file); + copy_file (to, bak_file); + free(bak_file); + } + if (rename (from, to) < 0) error (1, errno, "cannot rename file %s to %s", from, to); } @@ -415,12 +452,24 @@ unlink_file (f) const char *f; { + char *bak_file; + char *bak_file_ext = ".cvsbak"; + if (trace) (void) fprintf (stderr, "%s-> unlink_file(%s)\n", CLIENT_SERVER_STR, f); if (noexec) return (0); + if ((!is_cvs_file(f)) && + safe_mode("Protecting against removing %s\n", f)) { + bak_file = xmalloc (strlen (f) + 1 + strlen(bak_file_ext)); + sprintf(bak_file, "%s%s", f, bak_file_ext); + printf("Copying %s to %s\n", f, bak_file); + copy_file (f, bak_file); + free(bak_file); + } + return (CVS_UNLINK (f)); } diff -Naur cvs-1.11.22/src/main.c cvs-1.11.22.patched/src/main.c --- cvs-1.11.22/src/main.c 2006-05-15 20:12:35.000000000 -0700 +++ cvs-1.11.22.patched/src/main.c 2007-04-14 19:52:47.804292182 -0700 @@ -26,6 +26,8 @@ extern int gethostname (); #endif +#include "safe.h" + const char *program_name; const char *program_path; const char *cvs_cmd_name; @@ -243,6 +245,7 @@ { /* Omit -b because it is just for compatibility. */ "CVS global options (specified before the command name) are:\n", + " -F Override safe mode.\n", " -H Displays usage information for command.\n", " -Q Cause CVS to be really quiet.\n", " -q Cause CVS to be somewhat quiet.\n", @@ -407,11 +410,12 @@ int help = 0; /* Has the user asked for help? This lets us support the `cvs -H cmd' convention to give help for cmd. */ - static const char short_options[] = "+Qqrwtnvb:T:e:d:Hfz:s:xa"; + static const char short_options[] = "+QFqrwtnvb:T:e:d:Hfz:s:xa"; static struct option long_options[] = { {"help", 0, NULL, 'H'}, {"version", 0, NULL, 'v'}, + {"safe-mode", 0, NULL, 'S'}, {"help-commands", 0, NULL, 1}, {"help-synonyms", 0, NULL, 2}, {"help-options", 0, NULL, 4}, @@ -588,6 +592,13 @@ case 'f': use_cvsrc = 0; /* unnecessary, since we've done it above */ break; + case 'F': + printf("Turning off safe mode\n"); + safe_mode_flag = 0; /* Turn off safe mode */ + break; + case 'S': + safe_mode_flag = 1; /* Turn on safe mode */ + break; case 'z': gzip_level = strtol (optarg, &end, 10); if (*end != '\0' || gzip_level < 0 || gzip_level > 9) diff -Naur cvs-1.11.22/src/Makefile.am cvs-1.11.22.patched/src/Makefile.am --- cvs-1.11.22/src/Makefile.am 2005-04-04 13:46:07.000000000 -0700 +++ cvs-1.11.22.patched/src/Makefile.am 2007-04-14 19:52:47.803292295 -0700 @@ -73,6 +73,7 @@ repos.c \ root.c \ run.c \ + safe.c \ scramble.c \ server.c \ stack.c \ @@ -97,6 +98,7 @@ myndbm.h \ rcs.h \ root.h \ + safe.h \ server.h \ stack.h \ update.h \ diff -Naur cvs-1.11.22/src/Makefile.in cvs-1.11.22.patched/src/Makefile.in --- cvs-1.11.22/src/Makefile.in 2006-06-09 07:44:11.000000000 -0700 +++ cvs-1.11.22.patched/src/Makefile.in 2007-04-14 19:52:47.803292295 -0700 @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.6 from Makefile.am. +# Makefile.in generated by automake 1.8.3 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005 Free Software Foundation, Inc. +# 2003, 2004 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -32,6 +32,8 @@ # GNU General Public License for more details. +SOURCES = $(cvs_SOURCES) + srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ @@ -80,7 +82,7 @@ myndbm.$(OBJEXT) no_diff.$(OBJEXT) parseinfo.$(OBJEXT) \ patch.$(OBJEXT) rcs.$(OBJEXT) rcscmds.$(OBJEXT) \ recurse.$(OBJEXT) release.$(OBJEXT) remove.$(OBJEXT) \ - repos.$(OBJEXT) root.$(OBJEXT) run.$(OBJEXT) \ + repos.$(OBJEXT) root.$(OBJEXT) run.$(OBJEXT) safe.$(OBJEXT) \ scramble.$(OBJEXT) server.$(OBJEXT) stack.$(OBJEXT) \ status.$(OBJEXT) subr.$(OBJEXT) tag.$(OBJEXT) update.$(OBJEXT) \ version.$(OBJEXT) vers_ts.$(OBJEXT) watch.$(OBJEXT) \ @@ -92,6 +94,34 @@ DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles +@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/add.Po ./$(DEPDIR)/admin.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/annotate.Po ./$(DEPDIR)/buffer.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/checkin.Po ./$(DEPDIR)/checkout.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/classify.Po ./$(DEPDIR)/client.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/commit.Po ./$(DEPDIR)/create_adm.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/cvsrc.Po ./$(DEPDIR)/diff.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/edit.Po ./$(DEPDIR)/entries.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/error.Po ./$(DEPDIR)/expand_path.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/fileattr.Po ./$(DEPDIR)/filesubr.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/find_names.Po ./$(DEPDIR)/hardlink.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/hash.Po ./$(DEPDIR)/history.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ignore.Po ./$(DEPDIR)/import.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/lock.Po ./$(DEPDIR)/log.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/login.Po ./$(DEPDIR)/logmsg.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/main.Po ./$(DEPDIR)/mkmodules.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/modules.Po ./$(DEPDIR)/myndbm.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/no_diff.Po ./$(DEPDIR)/parseinfo.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/patch.Po ./$(DEPDIR)/rcs.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/rcscmds.Po ./$(DEPDIR)/recurse.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/release.Po ./$(DEPDIR)/remove.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/repos.Po ./$(DEPDIR)/root.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/run.Po ./$(DEPDIR)/safe.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/scramble.Po ./$(DEPDIR)/server.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/stack.Po ./$(DEPDIR)/status.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/subr.Po ./$(DEPDIR)/tag.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/update.Po ./$(DEPDIR)/vers_ts.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/version.Po ./$(DEPDIR)/watch.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/wrapper.Po ./$(DEPDIR)/zlib.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) @@ -247,6 +277,7 @@ repos.c \ root.c \ run.c \ + safe.c \ scramble.c \ server.c \ stack.c \ @@ -271,6 +302,7 @@ myndbm.h \ rcs.h \ root.h \ + safe.h \ server.h \ stack.h \ update.h \ @@ -426,6 +458,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repos.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/root.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/safe.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scramble.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stack.Po@am__quote@ @@ -443,14 +476,16 @@ @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` uninstall-info-am: @@ -474,11 +509,9 @@ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ - fi + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) @@ -556,7 +589,7 @@ clean-generic: distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -rm -f $(CONFIG_CLEAN_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: diff -Naur cvs-1.11.22/src/safe.c cvs-1.11.22.patched/src/safe.c --- cvs-1.11.22/src/safe.c 1969-12-31 16:00:00.000000000 -0800 +++ cvs-1.11.22.patched/src/safe.c 2007-04-14 19:52:47.804292182 -0700 @@ -0,0 +1,39 @@ +#define SAFE_DECLARE_FLAG +#include "safe.h" + +#if __STDC__ +#include +#else +#include +#endif + +#include + +#if __STDC__ +#define VA_START(args, lastarg) va_start(args, lastarg) +#else /* ! __STDC__ */ +#define VA_START(args, lastarg) va_start(args) +#endif /* __STDC__ */ + +int +#if __STDC__ +safe_mode (const char *format, ...) +#else +safe_mode (format, va_alist) + char const *format; + va_dcl +#endif +{ + va_list args; + + VA_START (args, format); + + if(safe_mode_flag) { + printf("*SAFE MODE*\n"); + vfprintf (stdout, format, args); + } + + va_end (args); + + return(safe_mode_flag); +} diff -Naur cvs-1.11.22/src/safe.h cvs-1.11.22.patched/src/safe.h --- cvs-1.11.22/src/safe.h 1969-12-31 16:00:00.000000000 -0800 +++ cvs-1.11.22.patched/src/safe.h 2007-04-14 19:52:47.804292182 -0700 @@ -0,0 +1,13 @@ + +int safe_mode (char const *, ...) + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 6) + __attribute__ ((__format__ (__printf__, 1, 2))) +#endif + ; + +#ifdef SAFE_DECLARE_FLAG +int safe_mode_flag = 0; +#else +extern int safe_mode_flag; +#endif