;;; net-utils.el --- network functions
-;; Copyright (C) 1998-2012 Free Software Foundation, Inc.
+;; Copyright (C) 1998-2016 Free Software Foundation, Inc.
;; Author: Peter Breton <pbreton@cs.umb.edu>
;; Created: Sun Mar 16 1997
;; * Support connections to HOST/PORT, generally for debugging and the like.
;; In other words, for doing much the same thing as "telnet HOST PORT", and
;; then typing commands.
-;;
-;; PATHS
-;;
-;; On some systems, some of these programs are not in normal user path,
-;; but rather in /sbin, /usr/sbin, and so on.
-
;;; Code:
+;; On some systems, programs like ifconfig are not in normal user
+;; path, but rather in /sbin, /usr/sbin, etc (but non-root users can
+;; still use them for queries). Actually the trend these
+;; days is for /sbin to be a symlink to /usr/sbin, but we still need to
+;; search both for older systems.
+(defun net-utils--executable-find-sbin (command)
+ "Return absolute name of COMMAND if found in an sbin directory."
+ (let ((exec-path '("/sbin" "/usr/sbin" "/usr/local/sbin")))
+ (executable-find command)))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Customization Variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
:group 'comm
:version "20.3")
-(defcustom net-utils-remove-ctl-m (memq system-type '(windows-nt msdos))
- "If non-nil, remove control-Ms from output."
- :group 'net-utils
- :type 'boolean)
-
(defcustom traceroute-program
(if (eq system-type 'windows-nt)
"tracert"
(define-obsolete-variable-alias 'ipconfig-program 'ifconfig-program "22.2")
(defcustom ifconfig-program
- (if (eq system-type 'windows-nt)
- "ipconfig"
- "ifconfig")
+ (cond ((eq system-type 'windows-nt) "ipconfig")
+ ((executable-find "ifconfig") "ifconfig")
+ ((net-utils--executable-find-sbin "ifconfig"))
+ ((net-utils--executable-find-sbin "ip"))
+ (t "ip"))
"Program to print network configuration information."
+ :version "25.1" ; add ip
:group 'net-utils
:type 'string)
'ifconfig-program-options "22.2")
(defcustom ifconfig-program-options
- (list
- (if (eq system-type 'windows-nt)
- "/all" "-a"))
+ (cond ((string-match "ipconfig\\'" ifconfig-program) '("/all"))
+ ((string-match "ifconfig\\'" ifconfig-program) '("-a"))
+ ((string-match "ip\\'" ifconfig-program) '("addr")))
"Options for the ifconfig program."
+ :version "25.1"
+ :set-after '(ifconfig-program)
:group 'net-utils
:type '(repeat string))
:group 'net-utils
:type '(repeat string))
-(defcustom arp-program "arp"
+(defcustom arp-program (or (net-utils--executable-find-sbin "arp") "arp")
"Program to print IP to address translation tables."
:group 'net-utils
:type 'string)
:group 'net-utils
:type '(repeat string))
-(defcustom smbclient-prompt-regexp "^smb: \>"
+(defcustom smbclient-prompt-regexp "^smb: >"
"Regexp which matches the smbclient program's prompt.
This variable is only used if the variable
(define-derived-mode net-utils-mode special-mode "NetworkUtil"
"Major mode for interacting with an external network utility."
(set (make-local-variable 'font-lock-defaults)
- '((net-utils-font-lock-keywords))))
+ '((net-utils-font-lock-keywords)))
+ (setq-local revert-buffer-function #'net-utils--revert-function))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Utility functions
(defun net-utils-remove-ctrl-m-filter (process output-string)
"Remove trailing control Ms."
- (let ((old-buffer (current-buffer))
- (filtered-string output-string))
- (unwind-protect
- (let ((moving))
- (set-buffer (process-buffer process))
- (let ((inhibit-read-only t))
- (setq moving (= (point) (process-mark process)))
-
- (while (string-match "\r" filtered-string)
- (setq filtered-string
- (replace-match "" nil nil filtered-string)))
-
- (save-excursion
- ;; Insert the text, moving the process-marker.
- (goto-char (process-mark process))
- (insert filtered-string)
- (set-marker (process-mark process) (point))))
- (if moving (goto-char (process-mark process))))
- (set-buffer old-buffer))))
+ (with-current-buffer (process-buffer process)
+ (save-excursion
+ (let ((inhibit-read-only t)
+ (filtered-string output-string))
+ (while (string-match "\r" filtered-string)
+ (setq filtered-string
+ (replace-match "" nil nil filtered-string)))
+ ;; Insert the text, moving the process-marker.
+ (goto-char (process-mark process))
+ (insert filtered-string)
+ (set-marker (process-mark process) (point))))))
+
+(declare-function w32-get-console-output-codepage "w32proc.c" ())
(defun net-utils-run-program (name header program args)
"Run a network information program."
- (let ((buf (get-buffer-create (concat "*" name "*"))))
+ (let ((buf (get-buffer-create (concat "*" name "*")))
+ (coding-system-for-read
+ ;; MS-Windows versions of network utilities output text
+ ;; encoded in the console (a.k.a. "OEM") codepage, which is
+ ;; different from the default system (a.k.a. "ANSI")
+ ;; codepage.
+ (if (eq system-type 'windows-nt)
+ (intern (format "cp%d" (w32-get-console-output-codepage)))
+ coding-system-for-read)))
(set-buffer buf)
(erase-buffer)
(insert header "\n")
;; General network utilities (diagnostic)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun net-utils-run-simple (buffer-name program-name args)
+;; Todo: This data could be saved in a bookmark.
+(defvar net-utils--revert-cmd nil)
+
+(defun net-utils-run-simple (buffer program-name args &optional nodisplay)
"Run a network utility for diagnostic output only."
- (interactive)
- (when (get-buffer buffer-name)
- (kill-buffer buffer-name))
- (get-buffer-create buffer-name)
- (with-current-buffer buffer-name
+ (with-current-buffer (if (stringp buffer) (get-buffer-create buffer) buffer)
+ (let ((proc (get-buffer-process (current-buffer))))
+ (when proc
+ (set-process-filter proc nil)
+ (delete-process proc)))
+ (let ((inhibit-read-only t)
+ (coding-system-for-read
+ ;; MS-Windows versions of network utilities output text
+ ;; encoded in the console (a.k.a. "OEM") codepage, which is
+ ;; different from the default system (a.k.a. "ANSI")
+ ;; codepage.
+ (if (eq system-type 'windows-nt)
+ (intern (format "cp%d" (w32-get-console-output-codepage)))
+ coding-system-for-read)))
+ (erase-buffer))
(net-utils-mode)
+ (setq-local net-utils--revert-cmd
+ `(net-utils-run-simple ,(current-buffer)
+ ,program-name ,args nodisplay))
(set-process-filter
- (apply 'start-process (format "%s" program-name)
- buffer-name program-name args)
- 'net-utils-remove-ctrl-m-filter)
- (goto-char (point-min)))
- (display-buffer buffer-name))
+ (apply 'start-process program-name
+ (current-buffer) program-name args)
+ 'net-utils-remove-ctrl-m-filter)
+ (unless nodisplay (display-buffer (current-buffer)))))
+
+(defun net-utils--revert-function (&optional ignore-auto noconfirm)
+ (message "Reverting `%s'..." (buffer-name))
+ (apply (car net-utils--revert-cmd) (cdr net-utils--revert-cmd))
+ (let ((proc (get-buffer-process (current-buffer))))
+ (when proc
+ (set-process-sentinel
+ proc
+ (lambda (process event)
+ (when (string= event "finished\n")
+ (message "Reverting `%s' done" (process-buffer process))))))))
;;;###autoload
(defun ifconfig ()
(if traceroute-program-options
(append traceroute-program-options (list target))
(list target))))
- (net-utils-run-program
+ (net-utils-run-simple
(concat "Traceroute" " " target)
- (concat "** Traceroute ** " traceroute-program " ** " target)
traceroute-program
options)))
(defvar nslookup-mode-map
(let ((map (make-sparse-keymap)))
- (define-key map "\t" 'comint-dynamic-complete)
+ (define-key map "\t" 'completion-at-point)
map))
;; Using a derived mode gives us keymaps, hooks, etc.
(defvar ftp-mode-map
(let ((map (make-sparse-keymap)))
;; Occasionally useful
- (define-key map "\t" 'comint-dynamic-complete)
+ (define-key map "\t" 'completion-at-point)
map))
(define-derived-mode ftp-mode comint-mode "FTP"