Karsten Hopp e5bffa
To: vim-dev@vim.org
Karsten Hopp e5bffa
Subject: patch 7.1.017
Karsten Hopp e5bffa
Fcc: outbox
Karsten Hopp e5bffa
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp e5bffa
Mime-Version: 1.0
Karsten Hopp e5bffa
Content-Type: text/plain; charset=ISO-8859-1
Karsten Hopp e5bffa
Content-Transfer-Encoding: 8bit
Karsten Hopp e5bffa
------------
Karsten Hopp e5bffa
Karsten Hopp e5bffa
Patch 7.1.017
Karsten Hopp e5bffa
Problem:    ":confirm w" does give a prompt when 'readonly' is set, but not
Karsten Hopp e5bffa
	    when the file permissions are read-only.  (Michael Schaap)
Karsten Hopp e5bffa
Solution:   Provide a dialog in both situations.  (Chris Lubinski)
Karsten Hopp e5bffa
Files:	    src/ex_cmds.c, src/fileio.c, src/proto/fileio.pro
Karsten Hopp e5bffa
Karsten Hopp e5bffa
Karsten Hopp e5bffa
*** ../vim-7.1.016/src/ex_cmds.c	Tue Jun 19 11:54:23 2007
Karsten Hopp e5bffa
--- src/ex_cmds.c	Tue Jun 19 22:37:25 2007
Karsten Hopp e5bffa
***************
Karsten Hopp e5bffa
*** 2912,2933 ****
Karsten Hopp e5bffa
  }
Karsten Hopp e5bffa
  
Karsten Hopp e5bffa
  /*
Karsten Hopp e5bffa
!  * Check if a buffer is read-only.  Ask for overruling in a dialog.
Karsten Hopp e5bffa
!  * Return TRUE and give an error message when the buffer is readonly.
Karsten Hopp e5bffa
   */
Karsten Hopp e5bffa
      static int
Karsten Hopp e5bffa
  check_readonly(forceit, buf)
Karsten Hopp e5bffa
      int		*forceit;
Karsten Hopp e5bffa
      buf_T	*buf;
Karsten Hopp e5bffa
  {
Karsten Hopp e5bffa
!     if (!*forceit && buf->b_p_ro)
Karsten Hopp e5bffa
      {
Karsten Hopp e5bffa
  #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
Karsten Hopp e5bffa
  	if ((p_confirm || cmdmod.confirm) && buf->b_fname != NULL)
Karsten Hopp e5bffa
  	{
Karsten Hopp e5bffa
  	    char_u	buff[IOSIZE];
Karsten Hopp e5bffa
  
Karsten Hopp e5bffa
! 	    dialog_msg(buff, _("'readonly' option is set for \"%s\".\nDo you wish to write anyway?"),
Karsten Hopp e5bffa
  		    buf->b_fname);
Karsten Hopp e5bffa
  
Karsten Hopp e5bffa
  	    if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) == VIM_YES)
Karsten Hopp e5bffa
--- 2912,2946 ----
Karsten Hopp e5bffa
  }
Karsten Hopp e5bffa
  
Karsten Hopp e5bffa
  /*
Karsten Hopp e5bffa
!  * Check if a buffer is read-only (either 'readonly' option is set or file is
Karsten Hopp e5bffa
!  * read-only). Ask for overruling in a dialog. Return TRUE and give an error
Karsten Hopp e5bffa
!  * message when the buffer is readonly.
Karsten Hopp e5bffa
   */
Karsten Hopp e5bffa
      static int
Karsten Hopp e5bffa
  check_readonly(forceit, buf)
Karsten Hopp e5bffa
      int		*forceit;
Karsten Hopp e5bffa
      buf_T	*buf;
Karsten Hopp e5bffa
  {
Karsten Hopp e5bffa
!     struct stat	st;
Karsten Hopp e5bffa
! 
Karsten Hopp e5bffa
!     /* Handle a file being readonly when the 'readonly' option is set or when
Karsten Hopp e5bffa
!      * the file exists and permissions are read-only.
Karsten Hopp e5bffa
!      * We will send 0777 to check_file_readonly(), as the "perm" variable is
Karsten Hopp e5bffa
!      * important for device checks but not here. */
Karsten Hopp e5bffa
!     if (!*forceit && (buf->b_p_ro
Karsten Hopp e5bffa
! 		|| (mch_stat((char *)buf->b_ffname, &st) >= 0
Karsten Hopp e5bffa
! 		    && check_file_readonly(buf->b_ffname, 0777))))
Karsten Hopp e5bffa
      {
Karsten Hopp e5bffa
  #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
Karsten Hopp e5bffa
  	if ((p_confirm || cmdmod.confirm) && buf->b_fname != NULL)
Karsten Hopp e5bffa
  	{
Karsten Hopp e5bffa
  	    char_u	buff[IOSIZE];
Karsten Hopp e5bffa
  
Karsten Hopp e5bffa
! 	    if (buf->b_p_ro)
Karsten Hopp e5bffa
! 		dialog_msg(buff, _("'readonly' option is set for \"%s\".\nDo you wish to write anyway?"),
Karsten Hopp e5bffa
! 		    buf->b_fname);
Karsten Hopp e5bffa
! 	    else
Karsten Hopp e5bffa
! 		dialog_msg(buff, _("File permissions of \"%s\" are read-only.\nIt may still be possible to write it.\nDo you wish to try?"),
Karsten Hopp e5bffa
  		    buf->b_fname);
Karsten Hopp e5bffa
  
Karsten Hopp e5bffa
  	    if (vim_dialog_yesno(VIM_QUESTION, NULL, buff, 2) == VIM_YES)
Karsten Hopp e5bffa
***************
Karsten Hopp e5bffa
*** 2941,2949 ****
Karsten Hopp e5bffa
--- 2954,2967 ----
Karsten Hopp e5bffa
  	}
Karsten Hopp e5bffa
  	else
Karsten Hopp e5bffa
  #endif
Karsten Hopp e5bffa
+ 	if (buf->b_p_ro)
Karsten Hopp e5bffa
  	    EMSG(_(e_readonly));
Karsten Hopp e5bffa
+ 	else
Karsten Hopp e5bffa
+ 	    EMSG2(_("E505: \"%s\" is read-only (add ! to override)"),
Karsten Hopp e5bffa
+ 		    buf->b_fname);
Karsten Hopp e5bffa
  	return TRUE;
Karsten Hopp e5bffa
      }
Karsten Hopp e5bffa
+ 
Karsten Hopp e5bffa
      return FALSE;
Karsten Hopp e5bffa
  }
Karsten Hopp e5bffa
  
Karsten Hopp e5bffa
*** ../vim-7.1.016/src/fileio.c	Thu May 10 19:32:17 2007
Karsten Hopp e5bffa
--- src/fileio.c	Thu Jun 28 21:54:18 2007
Karsten Hopp e5bffa
***************
Karsten Hopp e5bffa
*** 424,430 ****
Karsten Hopp e5bffa
  	 */
Karsten Hopp e5bffa
  	if (!p_odev && mch_nodetype(fname) == NODE_WRITABLE)
Karsten Hopp e5bffa
  	{
Karsten Hopp e5bffa
! 	    filemess(curbuf, fname, (char_u *)_("is a device (disabled with 'opendevice' option"), 0);
Karsten Hopp e5bffa
  	    msg_end();
Karsten Hopp e5bffa
  	    msg_scroll = msg_save;
Karsten Hopp e5bffa
  	    return FAIL;
Karsten Hopp e5bffa
--- 424,430 ----
Karsten Hopp e5bffa
  	 */
Karsten Hopp e5bffa
  	if (!p_odev && mch_nodetype(fname) == NODE_WRITABLE)
Karsten Hopp e5bffa
  	{
Karsten Hopp e5bffa
! 	    filemess(curbuf, fname, (char_u *)_("is a device (disabled with 'opendevice' option)"), 0);
Karsten Hopp e5bffa
  	    msg_end();
Karsten Hopp e5bffa
  	    msg_scroll = msg_save;
Karsten Hopp e5bffa
  	    return FAIL;
Karsten Hopp e5bffa
***************
Karsten Hopp e5bffa
*** 2734,2739 ****
Karsten Hopp e5bffa
--- 2734,2765 ----
Karsten Hopp e5bffa
  #endif
Karsten Hopp e5bffa
  
Karsten Hopp e5bffa
  /*
Karsten Hopp e5bffa
+  * Return TRUE if a file appears to be read-only from the file permissions.
Karsten Hopp e5bffa
+  */
Karsten Hopp e5bffa
+     int
Karsten Hopp e5bffa
+ check_file_readonly(fname, perm)
Karsten Hopp e5bffa
+     char_u	*fname;		/* full path to file */
Karsten Hopp e5bffa
+     int		perm;		/* known permissions on file */
Karsten Hopp e5bffa
+ {
Karsten Hopp e5bffa
+ #ifndef USE_MCH_ACCESS
Karsten Hopp e5bffa
+     int	    fd = 0;
Karsten Hopp e5bffa
+ #endif
Karsten Hopp e5bffa
+ 
Karsten Hopp e5bffa
+     return (
Karsten Hopp e5bffa
+ #ifdef USE_MCH_ACCESS
Karsten Hopp e5bffa
+ # ifdef UNIX
Karsten Hopp e5bffa
+ 	(perm & 0222) == 0 ||
Karsten Hopp e5bffa
+ # endif
Karsten Hopp e5bffa
+ 	mch_access((char *)fname, W_OK)
Karsten Hopp e5bffa
+ #else
Karsten Hopp e5bffa
+ 	(fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0
Karsten Hopp e5bffa
+ 					? TRUE : (close(fd), FALSE)
Karsten Hopp e5bffa
+ #endif
Karsten Hopp e5bffa
+ 	);
Karsten Hopp e5bffa
+ }
Karsten Hopp e5bffa
+ 
Karsten Hopp e5bffa
+ 
Karsten Hopp e5bffa
+ /*
Karsten Hopp e5bffa
   * buf_write() - write to file "fname" lines "start" through "end"
Karsten Hopp e5bffa
   *
Karsten Hopp e5bffa
   * We do our own buffering here because fwrite() is so slow.
Karsten Hopp e5bffa
***************
Karsten Hopp e5bffa
*** 3219,3235 ****
Karsten Hopp e5bffa
  	 * Check if the file is really writable (when renaming the file to
Karsten Hopp e5bffa
  	 * make a backup we won't discover it later).
Karsten Hopp e5bffa
  	 */
Karsten Hopp e5bffa
! 	file_readonly = (
Karsten Hopp e5bffa
! # ifdef USE_MCH_ACCESS
Karsten Hopp e5bffa
! #  ifdef UNIX
Karsten Hopp e5bffa
! 		    (perm & 0222) == 0 ||
Karsten Hopp e5bffa
! #  endif
Karsten Hopp e5bffa
! 		    mch_access((char *)fname, W_OK)
Karsten Hopp e5bffa
! # else
Karsten Hopp e5bffa
! 		    (fd = mch_open((char *)fname, O_RDWR | O_EXTRA, 0)) < 0
Karsten Hopp e5bffa
! 						   ? TRUE : (close(fd), FALSE)
Karsten Hopp e5bffa
! # endif
Karsten Hopp e5bffa
! 		    );
Karsten Hopp e5bffa
  	if (!forceit && file_readonly)
Karsten Hopp e5bffa
  	{
Karsten Hopp e5bffa
  	    if (vim_strchr(p_cpo, CPO_FWRITE) != NULL)
Karsten Hopp e5bffa
--- 3245,3252 ----
Karsten Hopp e5bffa
  	 * Check if the file is really writable (when renaming the file to
Karsten Hopp e5bffa
  	 * make a backup we won't discover it later).
Karsten Hopp e5bffa
  	 */
Karsten Hopp e5bffa
! 	file_readonly = check_file_readonly(fname, (int)perm);
Karsten Hopp e5bffa
! 
Karsten Hopp e5bffa
  	if (!forceit && file_readonly)
Karsten Hopp e5bffa
  	{
Karsten Hopp e5bffa
  	    if (vim_strchr(p_cpo, CPO_FWRITE) != NULL)
Karsten Hopp e5bffa
*** ../vim-7.1.016/src/proto/fileio.pro	Sat May  5 19:59:00 2007
Karsten Hopp e5bffa
--- src/proto/fileio.pro	Thu Jun 28 21:09:59 2007
Karsten Hopp e5bffa
***************
Karsten Hopp e5bffa
*** 2,7 ****
Karsten Hopp e5bffa
--- 2,8 ----
Karsten Hopp e5bffa
  void filemess __ARGS((buf_T *buf, char_u *name, char_u *s, int attr));
Karsten Hopp e5bffa
  int readfile __ARGS((char_u *fname, char_u *sfname, linenr_T from, linenr_T lines_to_skip, linenr_T lines_to_read, exarg_T *eap, int flags));
Karsten Hopp e5bffa
  int prep_exarg __ARGS((exarg_T *eap, buf_T *buf));
Karsten Hopp e5bffa
+ int check_file_readonly __ARGS((char_u *fname, int perm));
Karsten Hopp e5bffa
  int buf_write __ARGS((buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_T end, exarg_T *eap, int append, int forceit, int reset_changed, int filtering));
Karsten Hopp e5bffa
  void msg_add_fname __ARGS((buf_T *buf, char_u *fname));
Karsten Hopp e5bffa
  void msg_add_lines __ARGS((int insert_space, long lnum, long nchars));
Karsten Hopp e5bffa
*** ../vim-7.1.016/src/version.c	Thu Jun 28 21:23:52 2007
Karsten Hopp e5bffa
--- src/version.c	Thu Jun 28 21:49:29 2007
Karsten Hopp e5bffa
***************
Karsten Hopp e5bffa
*** 668,669 ****
Karsten Hopp e5bffa
--- 668,671 ----
Karsten Hopp e5bffa
  {   /* Add new patch number below this line */
Karsten Hopp e5bffa
+ /**/
Karsten Hopp e5bffa
+     17,
Karsten Hopp e5bffa
  /**/
Karsten Hopp e5bffa
Karsten Hopp e5bffa
-- 
Karsten Hopp e5bffa
CUSTOMER:     Well, can you hang around a couple of minutes?  He won't be
Karsten Hopp e5bffa
              long.
Karsten Hopp e5bffa
MORTICIAN:    Naaah, I got to go on to Robinson's -- they've lost nine today.
Karsten Hopp e5bffa
CUSTOMER:     Well, when is your next round?
Karsten Hopp e5bffa
MORTICIAN:    Thursday.
Karsten Hopp e5bffa
DEAD PERSON:  I think I'll go for a walk.
Karsten Hopp e5bffa
                                  The Quest for the Holy Grail (Monty Python)
Karsten Hopp e5bffa
Karsten Hopp e5bffa
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp e5bffa
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp e5bffa
\\\        download, build and distribute -- http://www.A-A-P.org        ///
Karsten Hopp e5bffa
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///