[net.emacs] GNU Emacs changes ownerships

escott@BONNIE.UCI.EDU (Scott Menter) (07/30/86)

Hi everyone.

Before I go ahead and take the time to make the changes myself, does
anybody have a patch for GNU Emacs v17.61 that make it keep the old
ownerships for a file upon saving?

Or is this perhaps accomplished in a later version...?

Thanks!

 +------------------------------------------------------------------------+
  E. Scott Menter                           Internet:   escott@ics.uci.edu
  UCI Systems Support Group                 UUCP: ...!ucbvax!ucivax!escott

  "...Say, Foz, about my vocals..."
 +------------------------------------------------------------------------+

krus@diku.UUCP (Lars Povlsen) (08/07/86)

In article <8607301814.AA08129@ucbvax.Berkeley.EDU> escott@BONNIE.UCI.EDU.UUCP writes:
>Hi everyone.

>Before I go ahead and take the time to make the changes myself, does
>anybody have a patch for GNU Emacs v17.61 that make it keep the old
>ownerships for a file upon saving?

>Or is this perhaps accomplished in a later version...?

Since I was hoping to have that bug (feature?) fixed in later versions
and running 17.49 myself, I decided not to wait for it.

The changes involve adding two C functions to get/set user/group-id,
and changing the emacs lisp routine that saves buffers, basic-save-buffer.

The fiddling with emacs C part do not affect other parts of emacs, and
is easy to check with eval.

Since I have been missing this for a long time I decided to post,
lots of others should miss it. 

--------------------------------------------------------------------------
			Lars Povlsen, diku!krus/diku!postmaster
			Institute of Datalogy, University of Copenhagen
--------------------------------------------------------------------------
(Boy, have I locked up uucp/news a million times before this!)

Here's the diff -c's, remember :: from version 17.49

*** files.el.orig	Wed Aug  6 12:47:47 1986
--- files.el	Wed Aug  6 15:05:58 1986
***************
*** 524,530
    "Save the current buffer in its visited file, if it has been modified."  
    (interactive)
    (if (buffer-modified-p)
!       (let (setmodes tempsetmodes)
  	(or buffer-file-name
  	    (setq buffer-file-name
  		  (read-file-name "File to save in: ")

--- 524,530 -----
    "Save the current buffer in its visited file, if it has been modified."  
    (interactive)
    (if (buffer-modified-p)
!       (let (setmodes tempsetmodes ownership)
  	(or buffer-file-name
  	    (setq buffer-file-name
  		  (read-file-name "File to save in: ")
***************
*** 529,534
  	    (setq buffer-file-name
  		  (read-file-name "File to save in: ")
  		  default-directory (file-name-directory buffer-file-name)))
  	(if (not (file-writable-p buffer-file-name))
  	    (if (yes-or-no-p
  		 (format "File %s is write-protected; try to save anyway? "

--- 529,540 -----
  	    (setq buffer-file-name
  		  (read-file-name "File to save in: ")
  		  default-directory (file-name-directory buffer-file-name)))
+ 	;;; Remeber original owner
+ 	;;; krus@diku Aug 6 15:05:13 1986
+ 	(if (string-equal
+ 	     (user-real-login-name) "root")
+ 	    (setq ownership (file-owner buffer-file-name))
+ 	  (setq ownership nil))
  	(if (not (file-writable-p buffer-file-name))
  	    (if (yes-or-no-p
  		 (format "File %s is write-protected; try to save anyway? "
***************
*** 561,566
  	  ;; temporarily while we write it.
  	  ;; But no need to do so if we have just backed up the file
  	  ;; (if setmodes is set) because in that case we are superseding.
  	  (cond ((and tempsetmodes (not setmodes))
  		 ;; Change the mode back, after writing.
  		 (setq setmodes (file-modes buffer-file-name))

--- 567,574 -----
  	  ;; temporarily while we write it.
  	  ;; But no need to do so if we have just backed up the file
  	  ;; (if setmodes is set) because in that case we are superseding.
+ 	  ;; Also, if ownership has been set, (root), will do chown
+ 	  ;; to restore ownership of original file
  	  (cond ((and tempsetmodes (not setmodes))
  		 ;; Change the mode back, after writing.
  		 (setq setmodes (file-modes buffer-file-name))
***************
*** 566,571
  		 (setq setmodes (file-modes buffer-file-name))
  		 (set-file-modes buffer-file-name 511)))
  	  (write-region (point-min) (point-max) buffer-file-name nil t)
  	  (if setmodes
  	      (condition-case ()
  		   (set-file-modes buffer-file-name setmodes)

--- 574,584 -----
  		 (setq setmodes (file-modes buffer-file-name))
  		 (set-file-modes buffer-file-name 511)))
  	  (write-region (point-min) (point-max) buffer-file-name nil t)
+ 	  ;;; restore ownership/modes
+ 	  ;;; krus@diku Aug 6 15:05:55 1986
+ 	  (if ownership
+ 	      (progn
+ 		    (set-file-owner buffer-file-name ownership)))
  	  (if setmodes
  	      (condition-case ()
  		   (set-file-modes buffer-file-name setmodes)
  
*** fileio.c.orig	Wed Aug  6 10:39:20 1986
--- fileio.c	Wed Aug  6 13:22:43 1986
***************
*** 717,722
    return Qnil;
  }
  
  close_file_unwind (fd)
       Lisp_Object fd;
  {

--- 717,770 -----
    return Qnil;
  }
  
+ DEFUN ("file-owner", Ffile_owner, Sfile_owner, 1, 1, 0,
+   "Return ownership of FILE, as a vector (uid,gid).")
+   (filename)
+      Lisp_Object filename;
+ {
+   Lisp_Object abspath,owner[2];
+   struct stat st;
+ 
+   abspath = Fexpand_file_name (filename, bf_cur->directory);
+ 
+   /* Remove final slash, if any.
+      stat behaves differently depending!  */
+   if (XSTRING (abspath)->data[XSTRING (abspath)->size - 1] == '/')
+     {
+       if (EQ (abspath, filename))
+ 	abspath = Fcopy_sequence (abspath);
+       XSTRING (abspath)->data[XSTRING (abspath)->size - 1] = 0;
+     }
+ 
+   if (stat (XSTRING (abspath)->data, &st) < 0)
+     return Qnil;
+ 
+   XFASTINT (owner[0]) = st.st_uid;
+   XFASTINT (owner[1]) = st.st_gid;
+ 
+   return Flist(2,owner);
+ }
+ 
+ DEFUN ("set-file-owner", Fset_file_owner, Sset_file_owner, 2, 2, 0,
+   "Set ownership of FILE, as the vector (uid,gid).")
+   (filename,owner)
+      Lisp_Object filename,*owner;
+ {
+    unsigned char *fn;
+ 
+    if(Flength(owner) != 2)
+      return Qnil;
+ 
+    filename = Fexpand_file_name (filename, bf_cur->directory);
+    fn = XSTRING (filename)->data;
+ 
+    if(-1 == chown(fn, XFASTINT (Fcar (owner)),
+ 		  XFASTINT (Fcar (Fcdr (owner)))))
+      return Qnil;
+    else
+      return Qt;
+ }
+ 
  close_file_unwind (fd)
       Lisp_Object fd;
  {
***************
*** 1195,1200
    defsubr (&Sfile_directory_p);
    defsubr (&Sfile_modes);
    defsubr (&Sset_file_modes);
    defsubr (&Sinsert_file_contents);
    defsubr (&Swrite_region);
    defsubr (&Sverify_visited_file_modtime);

--- 1243,1250 -----
    defsubr (&Sfile_directory_p);
    defsubr (&Sfile_modes);
    defsubr (&Sset_file_modes);
+   defsubr (&Sfile_owner);
+   defsubr (&Sset_file_owner);
    defsubr (&Sinsert_file_contents);
    defsubr (&Swrite_region);
    defsubr (&Sverify_visited_file_modtime);

-- 
--------------------------------------------------------------------------
			Lars Povlsen, diku!krus/diku!postmaster
			Institute of Datalogy, University of Copenhagen
--------------------------------------------------------------------------

escott@BONNIE.UCI.EDU (Scott Menter) (08/09/86)

Hi again.

In article <2537@diku.UUCP>, Lars Povlsen <seismo!mcvax!diku!krus> answers me:
> In article <8607301814.AA08129@ucbvax.Berkeley.EDU>
> 					escott@BONNIE.UCI.EDU.UUCP writes:

>>Hi everyone.
> 
>>Before I go ahead and take the time to make the changes myself, does
>>anybody have a patch for GNU Emacs v17.61 that make it keep the old
>>ownerships for a file upon saving?
> 
>>Or is this perhaps accomplished in a later version...?
> 
> Since I was hoping to have that bug (feature?) fixed in later versions
> and running 17.49 myself, I decided not to wait for it.
> 
> The changes involve adding two C functions to get/set user/group-id,
> and changing the emacs lisp routine that saves buffers, basic-save-buffer.
> 
> The fiddling with emacs C part do not affect other parts of emacs, and
> is easy to check with eval.
> 
> Since I have been missing this for a long time I decided to post,
> lots of others should miss it. 
> 
>  --------------------------------------------------------------------------
> 			Lars Povlsen, diku!krus/diku!postmaster
> 			Institute of Datalogy, University of Copenhagen
>  --------------------------------------------------------------------------
> (Boy, have I locked up uucp/news a million times before this!)
> 
> Here's the diff -c's, remember :: from version 17.49

[Huge listing not reproduced here (you're welcome 8^)]

I got a couple of other private replies, for which I thank the senders
again here.  I don't have the energy to quote those replies here too,
but basically they all said to
	(setq backup-by-copying t)

Well, this works very nicely, thank you, for the file which I'm
editing.  However, it is interesting to note that the backup file (the
one with the tilde after the name) gets the default ownerships of the
user, not those of the file it is backing up.  This is a small
consideration, and I'll probably just let it go at that.

Since the diffs are for an older version, I'm not even sure if I can
apply them, and backup-by-copying does most of the trick.  However, I
agree with Lars (now *that* is an authentic European name), this stuff
belongs in the source.  One day...

 --------------------------------------------------------------------------
  E. Scott Menter                           Internet:   escott@ics.uci.edu
  UCI ICS Computing Support Group           UUCP: ...!ucbvax!ucivax!escott
                                            Snail:  Univ of Calif ICS Dept
  "...Say, Foz, about my vocals..."                 Irvine, Calif    92717
 --------------------------------------------------------------------------

crl@Newton.Purdue.EDU (08/09/86)

From: Charles R. LaBrec <crl@Newton.Purdue.EDU>

It should be pointed out that the diffs posted to do ownership
changing of files only does any good if you're running as the
super-user, since chown() requires it.  Setting backup-by-copying is
the only way to ever guarantee that ownerships do not change.  As a
snap suggestion, perhaps the interpretation of backup-by-copying could
be changed such that if it is a list, the first value is like setting
backup-by-copying-when-linked, the second does copying if ownership
would change, the third if group membership would change, etc.

Charles LaBrec
crl @ newton.PURDUE.EDU