+(defun vc-cvs-find-admin-dir (file)
+ "Return the administrative directory of FILE."
+ (vc-find-root file "CVS"))
+
+(defun vc-cvs-ignore (file &optional _directory _remove)
+ "Ignore FILE under CVS."
+ (vc-cvs-append-to-ignore (file-name-directory file) file))
+
+(defun vc-cvs-append-to-ignore (dir str &optional old-dir)
+ "In DIR, add STR to the .cvsignore file.
+If OLD-DIR is non-nil, then this is a directory that we don't want
+to hear about anymore."
+ (with-current-buffer
+ (find-file-noselect (expand-file-name ".cvsignore" dir))
+ (when (ignore-errors
+ (and buffer-read-only
+ (eq 'CVS (vc-backend buffer-file-name))
+ (not (vc-editable-p buffer-file-name))))
+ ;; CVSREAD=on special case
+ (vc-checkout buffer-file-name t))
+ (goto-char (point-max))
+ (unless (bolp) (insert "\n"))
+ (insert str (if old-dir "/\n" "\n"))
+ ;; FIXME this is a pcvs variable.
+ (if (bound-and-true-p cvs-sort-ignore-file)
+ (sort-lines nil (point-min) (point-max)))
+ (save-buffer)))