Path: utzoo!utgpu!watmath!uunet!cs.utexas.edu!uwm.edu!gem.mps.ohio-state.edu!apple!bbn!jr@bbn.com
From: jr@bbn.com (John Robinson)
Newsgroups: gnu.emacs
Subject: Re: Editing a file as super user
Message-ID: <45953@bbn.COM>
Date: 22 Sep 89 15:43:59 GMT
References: 
Sender: news@bbn.COM
Reply-To: jr@bbn.com (John Robinson)
Distribution: gnu
Organization: BBN Systems and Technologies Corporation, Cambridge MA
Lines: 68
In-reply-to: tjfs@tadtec.uucp (Tim Steele)

In article , tjfs@tadtec (Tim Steele) writes:
>What's the favourite way of getting around the problem where a
>sysadmin "lives in Emacs" but wants to edit a privileged file?  At the
>moment I do:
>
>^Z (leave Emacs)
>
>su (become root)
>
>emacs /etc/motd (or even vi, as having 2 copies of emacs loaded kills
>our system!!)
>
>^X^C (leave superuser Emacs)
>
>^D (leave subshell)
>
>Grubby!  Any better suggestions?  I can't even edit it in place and
>save it out easily, like I can with vi, because Emacs notices I'm not
>allowed to write it and marks the buffer read only.

Mark the buffer modifiable with ^X^Q (as others pointed out).  Edit
it.  Save it somewhere you can write with ^X^W (like ~/ or /tmp/).
Then use su-command (appended below) to move or copy the file over the
old version, perhaps moving the previous one out of the way first if
necessary.  Elisp after my .sig.

(anticipating the nits: yes, I know the password echos as you type it.
However, putting the two arguments in the order they are at least
overwrites the minibuffer as soon as you finish the password.  Anyone
who wants to add the get-a-string-sliently logic to the following is
welcome to do it and repost).
--
/jr, nee John Robinson     Life did not take over the globe by combat,
jr@bbn.com or bbn!jr          but by networking -- Lynn Margulis
====8<----------------------------------------------------------------
(defun su-command (password command)
  "Prompt for root password and a command, then do the latter as root."
  (interactive "sRoot password: \nsCommand: ")
  (let ((buffer (get-buffer-create "*Shell Command Output*"))
        proc)
    (save-excursion
          (set-buffer buffer)
          (erase-buffer))
    (setq proc (start-process "su-emacs" buffer "/bin/su"
                              "-c" command))
    (if (save-excursion
          (set-buffer buffer)
          (goto-char (point-min))
          (while (not (looking-at "Password:"))
            (accept-process-output proc)
            (goto-char (point-min)))
          (erase-buffer)
          (send-string proc (concat password "\n"))
          (while (not (looking-at "\n"))
            (accept-process-output proc)
            (goto-char (point-min)))
          (delete-char 1)
          (while (not (equal (process-status proc) 'exit))
            (accept-process-output))
          (> (buffer-size) 0))
        (set-window-start (display-buffer buffer) 1)
      (message "(Command completed with no output)"))))

;;; suggested binding (# is the prompt when superuser):
;;; (global-set-key "\e#" 'su-command)
====8<----------------------------------------------------------------
/jr, nee John Robinson     Life did not take over the globe by combat,
jr@bbn.com or bbn!jr          but by networking -- Lynn Margulis